LCOV - code coverage report
Current view: top level - EnergyPlus - HeatBalanceSurfaceManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 79.4 % 5902 4688
Test Date: 2025-07-17 05:04:31 Functions: 89.4 % 47 42

            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      2799882 : 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      2799882 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     159          803 :         DisplayString(state, "Initializing Surfaces");
     160              :     }
     161      2799882 :     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      2799882 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     166          803 :         DisplayString(state, "Calculate Outside Surface Heat Balance");
     167              :     }
     168      2799882 :     CalcHeatBalanceOutsideSurf(state);
     169      2799882 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     170          803 :         DisplayString(state, "Calculate Inside Surface Heat Balance");
     171              :     }
     172      2799882 :     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      2799882 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     177          803 :         DisplayString(state, "Calculate Air Heat Balance");
     178              :     }
     179      2799882 :     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      2799877 :     UpdateFinalSurfaceHeatBalance(state);
     185              : 
     186              :     // Before we leave the Surface Manager the thermal histories need to be updated
     187      2799877 :     if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
     188      2624518 :         UpdateThermalHistories(state); // Update the thermal histories
     189              :     }
     190              : 
     191      2799877 :     if (state.dataHeatBal->AnyCondFD) {
     192      1930572 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     193      1772040 :             auto const &surface = state.dataSurface->Surface(SurfNum);
     194      1772040 :             int const ConstrNum = surface.Construction;
     195      1772040 :             if (ConstrNum <= 0) {
     196            0 :                 continue; // Shading surface, not really a heat transfer surface
     197              :             }
     198      1772040 :             if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) {
     199        67284 :                 continue; //  Windows simulated in Window module
     200              :             }
     201      1704756 :             if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) {
     202        50430 :                 continue;
     203              :             }
     204      1654326 :             state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
     205              :         }
     206              :     }
     207              : 
     208      2799877 :     ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
     209              : 
     210      2799877 :     ReportSurfaceHeatBalance(state);
     211      2799877 :     if (state.dataGlobal->ZoneSizingCalc) {
     212       834366 :         OutputReportTabular::GatherComponentLoadsSurface(state);
     213              :     }
     214              : 
     215      2799877 :     CalcThermalResilience(state);
     216              : 
     217      2799877 :     if (state.dataOutRptTab->displayThermalResilienceSummary) {
     218      1086699 :         ReportThermalResilience(state);
     219              :     }
     220              : 
     221      2799877 :     if (state.dataOutRptTab->displayCO2ResilienceSummary) {
     222        19089 :         ReportCO2Resilience(state);
     223              :     }
     224              : 
     225      2799877 :     if (state.dataOutRptTab->displayVisualResilienceSummary) {
     226        92393 :         ReportVisualResilience(state);
     227              :     }
     228              : 
     229      2799877 :     state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
     230      2799877 : }
     231              : 
     232              : // Beginning Initialization Section of the Module
     233              : //******************************************************************************
     234              : 
     235      2800078 : void UpdateVariableAbsorptances(EnergyPlusData &state)
     236              : {
     237      2800078 :     auto &s_mat = state.dataMaterial;
     238      2803927 :     for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
     239         3849 :         auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
     240         3849 :         auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
     241         3849 :         assert(thisMaterial != nullptr);
     242         3849 :         if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
     243            0 :             if (thisMaterial->absorpThermalVarSched != nullptr) {
     244            0 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
     245              :             }
     246            0 :             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         3849 :             if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
     252         3849 :                 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         3849 :             if (thisMaterial->absorpThermalVarCurve != nullptr) {
     261         3849 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
     262         3849 :                     max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
     263              :             }
     264         3849 :             if (thisMaterial->absorpSolarVarCurve != nullptr) {
     265         3849 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
     266         3849 :                     max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
     267              :             }
     268              :         }
     269      2800078 :     }
     270      2800078 : }
     271              : 
     272      2800078 : 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      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     300          803 :         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      2800078 :     DataSurfaces::SetSurfaceOutBulbTempAt(state);
     312      2800078 :     DataSurfaces::CheckSurfaceOutBulbTempAt(state);
     313              : 
     314      2800078 :     DataSurfaces::SetSurfaceWindSpeedAt(state);
     315      2800078 :     DataSurfaces::SetSurfaceWindDirAt(state);
     316      2800078 :     if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
     317       620862 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     318       613426 :             if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
     319         2706 :                 auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
     320         2706 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
     321         2706 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
     322         2706 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
     323         2706 :                 state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
     324              :             }
     325              :         }
     326              :     }
     327              :     // Overwriting surface and zone level environmental data with EMS override value
     328      2800078 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     329     45429895 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     330     45010347 :             if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
     331            0 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
     332              :             }
     333     45010347 :             if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
     334            0 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
     335              :             }
     336     45010347 :             if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
     337            0 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
     338              :             }
     339     45010347 :             if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
     340            0 :                 state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
     341              :             }
     342     45010347 :             if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
     343            0 :                 state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
     344              :             }
     345              :         }
     346              :     }
     347              : 
     348              :     // Do the Begin Simulation initializations
     349      2800078 :     if (state.dataGlobal->BeginSimFlag) {
     350          803 :         AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
     351         1606 :         state.dataHeatBalSurf->InterZoneWindow =
     352          803 :             std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
     353         1606 :                         state.dataViewFactor->EnclSolInfo.end(),
     354         5198 :                         [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
     355              :     }
     356      2800078 :     if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
     357         6010 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     358        10426 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     359         5219 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     360         5219 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
     361         5219 :                 int const lastSurf = thisSpace.HTSurfaceLast;
     362        50843 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     363        45624 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
     364        45624 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
     365        45624 :                     state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
     366        45624 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
     367        45624 :                     state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
     368        45624 :                     state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
     369        45624 :                     state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
     370              :                 }
     371         5207 :             }
     372              :         }
     373              :     }
     374              : 
     375              :     // variable thermal solar absorptance overrides
     376      2800078 :     UpdateVariableAbsorptances(state);
     377              : 
     378              :     // Do the Begin Environment initializations
     379      2800078 :     if (state.dataGlobal->BeginEnvrnFlag) {
     380         6396 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     381          803 :             DisplayString(state, "Initializing Temperature and Flux Histories");
     382              :         }
     383         6396 :         InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
     384              :     }
     385              : 
     386              :     // Calc movable insulation properties
     387      2800078 :     if (state.dataSurface->AnyMovableInsulation) {
     388        10122 :         EvalOutsideMovableInsulation(state);
     389        10122 :         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      2800078 :     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      2800078 :     SolarShading::TimestepInitComplexFenestration(state);
     400              : 
     401              :     // Calculate exterior-surface multipliers that account for anisotropy of
     402              :     // sky radiance
     403      2800078 :     if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
     404       916956 :         SolarShading::AnisoSkyViewFactors(state);
     405              :     } else {
     406      1883122 :         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      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     412          803 :         DisplayString(state, "Initializing Window Shading");
     413              :     }
     414              : 
     415      2800078 :     SolarShading::WindowShadingManager(state);
     416              : 
     417      2800078 :     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      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     422          803 :         DisplayString(state, "Computing Interior Absorption Factors");
     423              :     }
     424      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     425          803 :         HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
     426              :     }
     427      2800078 :     ComputeIntThermalAbsorpFactors(state);
     428              : 
     429              :     // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
     430      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     431          803 :         DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
     432              :     }
     433      2800078 :     ComputeIntSWAbsorpFactors(state);
     434              : 
     435      2800078 :     if (state.dataHeatBalSurf->InterZoneWindow) {
     436        12147 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     437            6 :             DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
     438              :         }
     439        12147 :         ComputeDifSolExcZonesWIZWindows(state);
     440              :     }
     441              : 
     442      2800078 :     Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
     443              : 
     444      5600156 :     HeatBalanceIntRadExchange::CalcInteriorRadExchange(
     445      2800078 :         state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
     446              : 
     447      2800078 :     if (state.dataSurface->AirflowWindows) {
     448         4044 :         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      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     454          803 :         DisplayString(state, "Initializing Solar Heat Gains");
     455              :     }
     456              : 
     457      2800078 :     InitSolarHeatGains(state);
     458              : 
     459      2800078 :     Dayltg::manageDaylighting(state);
     460              : 
     461      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     462          803 :         DisplayString(state, "Initializing Internal Heat Gains");
     463              :     }
     464      2800078 :     InternalHeatGains::ManageInternalHeatGains(state, false);
     465      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     466          803 :         DisplayString(state, "Initializing Interior Solar Distribution");
     467              :     }
     468      2800078 :     InitIntSolarDistribution(state);
     469              : 
     470      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     471          803 :         DisplayString(state, "Initializing Interior Convection Coefficients");
     472              :     }
     473      2800078 :     Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
     474              : 
     475      2800078 :     if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
     476              :         //    if (firstTime) CALL DisplayString('Reporting Surfaces')
     477              :         //    CALL ReportSurfaces
     478          803 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     479          803 :             DisplayString(state, "Gathering Information for Predefined Reporting");
     480              :         }
     481          803 :         GatherForPredefinedReport(state);
     482              :     }
     483              : 
     484              :     // Initialize the temperature history terms for conduction through the surfaces
     485      2800078 :     if (state.dataHeatBal->AnyCondFD) {
     486       158532 :         HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
     487              :     }
     488              : 
     489     22623034 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     490     39694512 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     491     19871556 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     492     19871556 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     493     19871556 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     494    167531295 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     495    147659739 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
     496    147659739 :                 if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     497      2094168 :                     surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
     498      1944150 :                     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    145715589 :                 int const ConstrNum = surface.Construction;
     504    145715589 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
     505    145715589 :                 state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
     506    145715589 :                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
     507    145715589 :                 if (construct.NumCTFTerms <= 1) {
     508      9355335 :                     continue;
     509              :                 }
     510              : 
     511   1047114040 :                 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    910753786 :                     Real64 const ctf_cross(construct.CTFCross[Term]);
     523              : 
     524    910753786 :                     Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     525    910753786 :                     Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     526    910753786 :                     Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
     527    910753786 :                     Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
     528    910753786 :                     state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
     529    910753786 :                         ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
     530              : 
     531    910753786 :                     state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
     532    910753786 :                         construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
     533              :                 }
     534              :             }
     535     19822956 :         }
     536              :     }
     537      2800078 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
     538       646938 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     539       976482 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     540       488241 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     541       488241 :                 int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     542       488241 :                 int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     543      3778335 :                 for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     544      3290094 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
     545      3290094 :                     int const ConstrNum = surface.Construction;
     546      3290094 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
     547      3290094 :                     if (!construct.SourceSinkPresent) {
     548      2730924 :                         continue;
     549              :                     }
     550       559170 :                     if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     551       161478 :                         surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
     552       161478 :                         continue;
     553              :                     }
     554       397692 :                     state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
     555       397692 :                     state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
     556       397692 :                     if (construct.NumCTFTerms <= 1) {
     557            0 :                         continue;
     558              :                     }
     559      4376034 :                     for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     560      3978342 :                         Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     561      3978342 :                         Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     562      3978342 :                         Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
     563              : 
     564      3978342 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
     565              : 
     566      3978342 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
     567              : 
     568      3978342 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
     569      3978342 :                             construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
     570      3978342 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
     571              : 
     572      3978342 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
     573      3978342 :                             construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
     574      3978342 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
     575              :                     }
     576              :                 }
     577       488241 :             } // ...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     22623034 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     583     39694512 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     584     19871556 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     585     19871556 :             int const firstSurf = thisSpace.HTSurfaceFirst;
     586     19871556 :             int const lastSurf = thisSpace.HTSurfaceLast;
     587    189903633 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     588    170032077 :                 state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
     589    170032077 :                 state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
     590    170032077 :                 state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
     591    170032077 :                 state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
     592    170032077 :                 state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
     593    170032077 :                 state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
     594              : 
     595    170032077 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
     596    170032077 :                 state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
     597    170032077 :                 state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
     598    170032077 :                 state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
     599              : 
     600              :             } // ...end of Zone Surf loop
     601     19822956 :         }
     602              :     } // ...end of Zone loop
     603              : 
     604      3023890 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
     605       223812 :         auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
     606       223812 :         thisSurfQRadFromHVAC.HTRadSys = 0.0;
     607       223812 :         thisSurfQRadFromHVAC.HWBaseboard = 0.0;
     608       223812 :         thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
     609       223812 :         thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
     610       223812 :         thisSurfQRadFromHVAC.CoolingPanel = 0.0;
     611      2800078 :     }
     612              : 
     613      2800078 :     if (state.dataGlobal->ZoneSizingCalc) {
     614       834366 :         GatherComponentLoadsSurfAbsFact(state);
     615              :     }
     616              : 
     617      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     618          803 :         DisplayString(state, "Completed Initializing Surface Heat Balance");
     619              :     }
     620      2800078 :     state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
     621      2800078 : }
     622              : 
     623          803 : 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          803 :     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          803 :     int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
     645          803 :     Array1D_int numSurfaces(SurfaceClassCount);
     646          803 :     Array1D_int numExtSurfaces(SurfaceClassCount);
     647              :     int frameDivNum;
     648              :     bool isExterior;
     649          803 :     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          803 :     Real64 windowAreaWMult(0.0);
     661          803 :     Real64 fenTotArea(0.0);
     662          803 :     Real64 fenTotAreaNorth(0.0);
     663          803 :     Real64 fenTotAreaNonNorth(0.0);
     664          803 :     Real64 ufactArea(0.0);
     665          803 :     Real64 ufactAreaNorth(0.0);
     666          803 :     Real64 ufactAreaNonNorth(0.0);
     667          803 :     Real64 shgcArea(0.0);
     668          803 :     Real64 shgcAreaNorth(0.0);
     669          803 :     Real64 shgcAreaNonNorth(0.0);
     670          803 :     Real64 vistranArea(0.0);
     671          803 :     Real64 vistranAreaNorth(0.0);
     672          803 :     Real64 vistranAreaNonNorth(0.0);
     673          803 :     Real64 intFenTotArea(0.0);
     674          803 :     Real64 intUfactArea(0.0);
     675          803 :     Real64 intShgcArea(0.0);
     676          803 :     Real64 intVistranArea(0.0);
     677              :     bool isNorth;
     678              : 
     679          803 :     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          803 :     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          803 :     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          803 :     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          803 :     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          803 :     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          803 :     numSurfaces = 0;
     769          803 :     numExtSurfaces = 0;
     770              : 
     771          803 :     computedNetArea.allocate(state.dataSurface->TotSurfaces);
     772          803 :     computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
     773              : 
     774              :     // set up for EIO <FenestrationAssembly> output
     775          803 :     if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
     776           18 :         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          803 :     std::vector<std::pair<int, int>> uniqConsFrame;
     783          803 :     std::pair<int, int> consAndFrame;
     784              : 
     785              :     // set up for EIO <FenestrationShadedState> output
     786          803 :     bool fenestrationShadedStateHeaderShown(false);
     787              :     static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
     788          803 :     std::vector<std::pair<int, int>> uniqShdConsFrame;
     789          803 :     std::pair<int, int> shdConsAndFrame;
     790              : 
     791        48135 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
     792        47332 :         auto &surface = state.dataSurface->Surface(iSurf);
     793        47332 :         surfName = surface.Name;
     794              :         // only exterior surfaces including underground
     795        47332 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
     796        25201 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
     797        22355 :             isExterior = true;
     798        22355 :             switch (surface.Class) {
     799        13915 :             case DataSurfaces::SurfaceClass::Wall:
     800              :             case DataSurfaces::SurfaceClass::Floor:
     801              :             case DataSurfaces::SurfaceClass::Roof: {
     802        13915 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
     803        13915 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     804        13915 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
     805        13915 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
     806        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
     807        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
     808        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
     809        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
     810        13915 :                 OutputReportPredefined::PreDefTableEntry(
     811        13915 :                     state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
     812        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
     813        13915 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
     814        13915 :                 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        13915 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     818        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
     819        13915 :                 curTilt = surface.Tilt;
     820        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
     821        13915 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     822         9277 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     823         2389 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
     824         6888 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     825         2204 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
     826         4684 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     827         2413 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
     828         2271 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     829         2271 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
     830              :                     }
     831              :                 }
     832        13915 :             } break;
     833         6349 :             case DataSurfaces::SurfaceClass::Window:
     834              :             case DataSurfaces::SurfaceClass::TDD_Dome: {
     835         6349 :                 auto &construct = state.dataConstruction->Construct(surface.Construction);
     836         6349 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     837         6349 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
     838         6349 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
     839         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
     840         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
     841         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
     842              :                 // if the construction report is requested the SummerSHGC is already calculated
     843         6349 :                 if (construct.SummerSHGC != 0) {
     844         5681 :                     SHGCSummer = construct.SummerSHGC;
     845         5681 :                     TransVisNorm = construct.VisTransNorm;
     846              :                 } else {
     847              :                     // must calculate Summer SHGC
     848          668 :                     if (!construct.WindowTypeEQL) {
     849          668 :                         Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
     850          668 :                         construct.SummerSHGC = SHGCSummer;
     851          668 :                         construct.VisTransNorm = TransVisNorm;
     852          668 :                         construct.SolTransNorm = TransSolNorm;
     853              :                     }
     854              :                 }
     855              :                 // include the frame area if present
     856         6349 :                 windowArea = surface.GrossArea;
     857         6349 :                 frameArea = 0.0;
     858         6349 :                 dividerArea = 0.0;
     859         6349 :                 frameDivNum = surface.FrameDivider;
     860         6349 :                 if (frameDivNum != 0) {
     861          381 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     862          381 :                     frameWidth = frameDivider.FrameWidth;
     863          381 :                     frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
     864          381 :                     windowArea += frameArea;
     865          381 :                     dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
     866          381 :                                                                frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
     867          381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
     868          381 :                     OutputReportPredefined::PreDefTableEntry(
     869          381 :                         state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
     870          381 :                     OutputReportPredefined::PreDefTableEntry(
     871          381 :                         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          381 :                     std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     875          381 :                     const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     876          381 :                     const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     877          381 :                     const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     878              : 
     879          381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
     880              : 
     881          381 :                     Real64 uValueAssembly = 0.0;
     882          381 :                     Real64 shgcAssembly = 0.0;
     883          381 :                     Real64 vtAssembly = 0.0;
     884              : 
     885          381 :                     Window::GetWindowAssemblyNfrcForReport(
     886              :                         state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
     887          381 :                     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          381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
     893          381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
     894          381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
     895              : 
     896              :                     // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
     897          381 :                     if (state.dataGeneral->Constructions) {
     898          340 :                         consAndFrame = std::make_pair(surface.Construction, frameDivNum);
     899          340 :                         if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
     900           30 :                             uniqConsFrame.push_back(consAndFrame);
     901           30 :                             print(state.files.eio,
     902              :                                   FenestrationAssemblyFormat,
     903           30 :                                   construct.Name,
     904           30 :                                   frameDivider.Name,
     905              :                                   NFRCname,
     906              :                                   uValueAssembly,
     907              :                                   shgcAssembly,
     908              :                                   vtAssembly);
     909              :                         }
     910              :                     }
     911              :                 }
     912         6349 :                 windowAreaWMult = windowArea * mult;
     913         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
     914         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
     915         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
     916        12698 :                 OutputReportPredefined::PreDefTableEntry(
     917         6349 :                     state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
     918         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
     919         6349 :                 computedNetArea(surface.BaseSurf) -= windowAreaWMult;
     920         6349 :                 nomUfact = state.dataHeatBal->NominalU(surface.Construction);
     921         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
     922              : 
     923         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
     924         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
     925         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
     926         6349 :                 curAzimuth = surface.Azimuth;
     927              :                 // Round to two decimals, like the display in tables
     928         6349 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     929         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
     930         6349 :                 isNorth = false;
     931         6349 :                 curTilt = surface.Tilt;
     932         6349 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
     933         6349 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     934         5952 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     935         1479 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
     936         1479 :                         isNorth = true;
     937         4473 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     938         1089 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
     939         3384 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     940         2298 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
     941         1086 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     942         1086 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
     943              :                     }
     944              :                 }
     945              : 
     946              :                 // Report table for every shading control state
     947         6349 :                 const unsigned int totalStates = surface.windowShadingControlList.size();
     948         6349 :                 if (frameDivNum != 0) {
     949          381 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     950          422 :                     for (unsigned int i = 0; i < totalStates; ++i) {
     951           41 :                         const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     952           41 :                         const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     953           41 :                         const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     954              : 
     955           41 :                         const int stateConstrNum = surface.shadedConstructionList[i];
     956           41 :                         const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     957           41 :                         const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     958           41 :                         std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
     959              : 
     960           82 :                         OutputReportPredefined::PreDefTableEntry(
     961           41 :                             state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
     962           82 :                         OutputReportPredefined::PreDefTableEntry(
     963           82 :                             state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
     964           41 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
     965           41 :                         OutputReportPredefined::PreDefTableEntry(state,
     966           41 :                                                                  state.dataOutRptPredefined->pdchFenShdVisTr,
     967              :                                                                  constructionName,
     968           41 :                                                                  state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
     969           41 :                                                                  3);
     970              : 
     971           41 :                         Real64 stateAssemblyUValue{0.0};
     972           41 :                         Real64 stateAssemblySHGC{0.0};
     973           41 :                         Real64 stateAssemblyVT{0.0};
     974              : 
     975           41 :                         Window::GetWindowAssemblyNfrcForReport(
     976              :                             state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
     977              : 
     978           41 :                         std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     979           82 :                         OutputReportPredefined::PreDefTableEntry(
     980           41 :                             state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
     981              : 
     982           82 :                         OutputReportPredefined::PreDefTableEntry(
     983           82 :                             state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
     984           82 :                         OutputReportPredefined::PreDefTableEntry(
     985           82 :                             state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
     986           82 :                         OutputReportPredefined::PreDefTableEntry(
     987           82 :                             state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
     988              : 
     989           41 :                         if (state.dataGeneral->Constructions) {
     990           23 :                             if (!fenestrationShadedStateHeaderShown) {
     991            4 :                                 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            4 :                                 fenestrationShadedStateHeaderShown = true;
     997              :                             }
     998              : 
     999           23 :                             shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
    1000           23 :                             if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
    1001           14 :                                 uniqShdConsFrame.push_back(shdConsAndFrame);
    1002           14 :                                 print(state.files.eio,
    1003              :                                       FenestrationShadedStateFormat,
    1004              :                                       constructionName,
    1005              :                                       stateUValue,
    1006              :                                       stateSHGC,
    1007           14 :                                       state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
    1008           14 :                                       frameDivider.Name,
    1009              :                                       NFRCname,
    1010              :                                       stateAssemblyUValue,
    1011              :                                       stateAssemblySHGC,
    1012              :                                       stateAssemblyVT);
    1013              :                             }
    1014              :                         }
    1015              :                     }
    1016              :                 }
    1017              : 
    1018         6349 :                 curWSC = surface.activeWindowShadingControl;
    1019              :                 // compute totals for area weighted averages
    1020         6349 :                 fenTotArea += windowAreaWMult;
    1021         6349 :                 ufactArea += nomUfact * windowAreaWMult;
    1022         6349 :                 shgcArea += SHGCSummer * windowAreaWMult;
    1023         6349 :                 vistranArea += TransVisNorm * windowAreaWMult;
    1024         6349 :                 if (isNorth) {
    1025         1479 :                     fenTotAreaNorth += windowAreaWMult;
    1026         1479 :                     ufactAreaNorth += nomUfact * windowAreaWMult;
    1027         1479 :                     shgcAreaNorth += SHGCSummer * windowAreaWMult;
    1028         1479 :                     vistranAreaNorth += TransVisNorm * windowAreaWMult;
    1029              :                 } else {
    1030         4870 :                     fenTotAreaNonNorth += windowAreaWMult;
    1031         4870 :                     ufactAreaNonNorth += nomUfact * windowAreaWMult;
    1032         4870 :                     shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
    1033         4870 :                     vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
    1034              :                 }
    1035              :                 // shading
    1036         6349 :                 if (surface.HasShadeControl) {
    1037          151 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
    1038          302 :                     OutputReportPredefined::PreDefTableEntry(
    1039          302 :                         state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
    1040              :                     // shading report
    1041          302 :                     OutputReportPredefined::PreDefTableEntry(
    1042              :                         state,
    1043          151 :                         state.dataOutRptPredefined->pdchWscShading,
    1044              :                         surfName,
    1045          151 :                         WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
    1046          302 :                     OutputReportPredefined::PreDefTableEntry(
    1047              :                         state,
    1048          151 :                         state.dataOutRptPredefined->pdchWscControl,
    1049              :                         surfName,
    1050          151 :                         WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
    1051              : 
    1052              :                     // output list of all possible shading constructions for shaded windows including those with storms
    1053          151 :                     std::string names;
    1054          306 :                     for (int construction : surface.shadedConstructionList) {
    1055          155 :                         if (!names.empty()) {
    1056            4 :                             names.append("; ");
    1057              :                         }
    1058          155 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1059          151 :                     }
    1060          151 :                     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          151 :                     }
    1066          151 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
    1067              : 
    1068          151 :                     if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
    1069           30 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
    1070              :                     } else {
    1071          121 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
    1072              :                     }
    1073          151 :                 } else {
    1074         6198 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
    1075              :                 }
    1076         6349 :             } break;
    1077          401 :             case DataSurfaces::SurfaceClass::Door: {
    1078          401 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1079          401 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1080          401 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1081          802 :                 OutputReportPredefined::PreDefTableEntry(
    1082          802 :                     state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
    1083          401 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
    1084          401 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
    1085          401 :                 OutputReportPredefined::PreDefTableEntry(
    1086          401 :                     state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1087          401 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
    1088          401 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
    1089          401 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1090          401 :             } break;
    1091         1690 :             default:
    1092         1690 :                 break;
    1093              :             }
    1094        22355 :         } else {
    1095              :             // interior surfaces
    1096        24977 :             isExterior = false;
    1097        24977 :             if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
    1098         6320 :                 (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
    1099        24883 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1100        24883 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1101        24883 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1102        24883 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1103        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
    1104        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
    1105        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
    1106        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
    1107        49766 :                 OutputReportPredefined::PreDefTableEntry(
    1108        24883 :                     state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
    1109        24883 :                 OutputReportPredefined::PreDefTableEntry(
    1110        24883 :                     state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1111        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
    1112        24883 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
    1113        24883 :                 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        24883 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
    1117        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
    1118        24883 :                 curTilt = surface.Tilt;
    1119        24883 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
    1120        24883 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
    1121        16511 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
    1122         6101 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
    1123        10410 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
    1124         3423 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
    1125         6987 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
    1126         3567 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
    1127         3420 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
    1128         3420 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
    1129              :                     }
    1130              :                 }
    1131              :                 // interior window report
    1132        24977 :             } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
    1133           14 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1134           14 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1135           14 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
    1136           14 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1137           14 :                 if (!has_prefix(surface.Name,
    1138              :                                 "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
    1139           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
    1140           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
    1141           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
    1142              :                     // include the frame area if present
    1143           12 :                     windowArea = surface.GrossArea;
    1144           12 :                     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           12 :                     windowAreaWMult = windowArea * mult;
    1150           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
    1151           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
    1152           12 :                     computedNetArea(surface.BaseSurf) -= windowAreaWMult;
    1153           12 :                     nomUfact = state.dataHeatBal->NominalU(surface.Construction);
    1154           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
    1155           12 :                     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           12 :                         if (construct.SummerSHGC != 0) {
    1159           12 :                             SHGCSummer = construct.SummerSHGC;
    1160           12 :                             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           12 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
    1169           12 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
    1170              :                         // compute totals for area weighted averages
    1171           12 :                         intShgcArea += SHGCSummer * windowAreaWMult;
    1172           12 :                         intVistranArea += TransVisNorm * windowAreaWMult;
    1173              :                     }
    1174           12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
    1175              :                     // compute totals for area weighted averages
    1176           12 :                     intFenTotArea += windowAreaWMult;
    1177           12 :                     intUfactArea += nomUfact * windowAreaWMult;
    1178              :                 }
    1179           94 :             } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
    1180           80 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1181           80 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1182           80 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1183           80 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1184           80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
    1185           80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
    1186           80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
    1187           80 :                 OutputReportPredefined::PreDefTableEntry(
    1188           80 :                     state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1189           80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
    1190           80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
    1191           80 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1192              :             }
    1193              :         }
    1194        47332 :         int currSurfaceClass = int(surface.Class);
    1195        47332 :         assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
    1196        47332 :         assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
    1197        47332 :         ++numSurfaces(currSurfaceClass);
    1198        47332 :         if (isExterior) {
    1199        22355 :             ++numExtSurfaces(currSurfaceClass);
    1200              :         }
    1201        47332 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) {
    1202         6361 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    1203          543 :                 ++numSurfaces((int)surface.OriginalClass);
    1204          543 :                 if (isExterior) {
    1205          541 :                     ++numExtSurfaces((int)surface.OriginalClass);
    1206              :                 }
    1207              :             }
    1208              :         }
    1209          803 :     }
    1210              :     // for fins and overhangs just add them explicitly since not otherwise classified
    1211          803 :     int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
    1212          803 :                        state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
    1213          803 :     numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1214          803 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1215          803 :     int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
    1216          803 :                   state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
    1217          803 :     numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1218          803 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1219              :     // go through all the surfaces again and this time insert the net area results
    1220        48135 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
    1221        47332 :         auto const &surface = state.dataSurface->Surface(iSurf);
    1222        47332 :         DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
    1223              :         // exterior surfaces including underground
    1224        47332 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
    1225        25201 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
    1226        22355 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1227              :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1228        13915 :                 surfName = surface.Name;
    1229        13915 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
    1230              :             }
    1231              :         } else {
    1232        24977 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1233              :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1234        22346 :                 surfName = surface.Name;
    1235        22346 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
    1236              :             }
    1237              :         } // interior surfaces
    1238          803 :     }
    1239              :     // total
    1240          803 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
    1241          803 :     if (fenTotArea > 0.0) {
    1242          706 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
    1243          706 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
    1244          706 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
    1245              :     } else {
    1246           97 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
    1247           97 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
    1248           97 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
    1249              :     }
    1250              :     // north
    1251          803 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
    1252          803 :     if (fenTotAreaNorth > 0.0) {
    1253          818 :         OutputReportPredefined::PreDefTableEntry(
    1254          818 :             state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
    1255          818 :         OutputReportPredefined::PreDefTableEntry(
    1256          818 :             state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
    1257          818 :         OutputReportPredefined::PreDefTableEntry(
    1258         1227 :             state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
    1259              :     } else {
    1260          394 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
    1261          394 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
    1262          394 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
    1263              :     }
    1264              :     // non-north
    1265          803 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
    1266          803 :     if (fenTotAreaNonNorth > 0.0) {
    1267         1410 :         OutputReportPredefined::PreDefTableEntry(
    1268         1410 :             state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
    1269         1410 :         OutputReportPredefined::PreDefTableEntry(
    1270         1410 :             state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
    1271         1410 :         OutputReportPredefined::PreDefTableEntry(
    1272         2115 :             state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
    1273              :     } else {
    1274           98 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
    1275           98 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
    1276           98 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
    1277              :     }
    1278              :     // interior fenestration totals
    1279          803 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
    1280          803 :     if (intFenTotArea > 0.0) {
    1281           12 :         OutputReportPredefined::PreDefTableEntry(
    1282           12 :             state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
    1283           12 :         OutputReportPredefined::PreDefTableEntry(
    1284           12 :             state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
    1285           12 :         OutputReportPredefined::PreDefTableEntry(
    1286           18 :             state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
    1287              :     } else {
    1288          797 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
    1289          797 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
    1290          797 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
    1291              :     }
    1292              :     // counts
    1293          803 :     OutputReportPredefined::PreDefTableEntry(
    1294          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1295          803 :     OutputReportPredefined::PreDefTableEntry(
    1296          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1297          803 :     OutputReportPredefined::PreDefTableEntry(
    1298          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1299          803 :     OutputReportPredefined::PreDefTableEntry(
    1300          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1301          803 :     OutputReportPredefined::PreDefTableEntry(
    1302          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1303          803 :     OutputReportPredefined::PreDefTableEntry(
    1304          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1305          803 :     OutputReportPredefined::PreDefTableEntry(
    1306          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1307          803 :     OutputReportPredefined::PreDefTableEntry(
    1308          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1309          803 :     OutputReportPredefined::PreDefTableEntry(
    1310          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1311          803 :     OutputReportPredefined::PreDefTableEntry(
    1312          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1313          803 :     OutputReportPredefined::PreDefTableEntry(
    1314          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1315          803 :     OutputReportPredefined::PreDefTableEntry(
    1316          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1317          803 :     OutputReportPredefined::PreDefTableEntry(
    1318          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1319          803 :     OutputReportPredefined::PreDefTableEntry(
    1320          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1321          803 :     OutputReportPredefined::PreDefTableEntry(
    1322          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1323          803 :     OutputReportPredefined::PreDefTableEntry(
    1324          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1325          803 :     OutputReportPredefined::PreDefTableEntry(
    1326          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1327          803 :     OutputReportPredefined::PreDefTableEntry(
    1328          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1329          803 :     OutputReportPredefined::PreDefTableEntry(
    1330          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1331          803 :     OutputReportPredefined::PreDefTableEntry(
    1332          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1333          803 :     OutputReportPredefined::PreDefTableEntry(
    1334          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1335          803 :     OutputReportPredefined::PreDefTableEntry(
    1336          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1337          803 :     OutputReportPredefined::PreDefTableEntry(
    1338          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1339          803 :     OutputReportPredefined::PreDefTableEntry(
    1340          803 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1341          803 :     OutputReportPredefined::PreDefTableEntry(
    1342          803 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1343          803 :     OutputReportPredefined::PreDefTableEntry(state,
    1344          803 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1345              :                                              "Tubular Daylighting Device Dome",
    1346          803 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1347          803 :     OutputReportPredefined::PreDefTableEntry(state,
    1348          803 :                                              state.dataOutRptPredefined->pdchSurfCntTot,
    1349              :                                              "Tubular Daylighting Device Diffuser",
    1350          803 :                                              numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1351          803 :     OutputReportPredefined::PreDefTableEntry(state,
    1352          803 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1353              :                                              "Tubular Daylighting Device Diffuser",
    1354          803 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1355          803 : }
    1356              : 
    1357          803 : 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          803 :     state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1369          803 :     state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1370          803 :     state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1371          803 :     state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1372          803 :     state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1373          803 :     state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1374          803 :     state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1375          803 :     state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
    1376          803 :     state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
    1377          803 :     state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
    1378          803 :     state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
    1379          803 :     state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
    1380          803 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1381           36 :         state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1382           36 :         state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1383              :     }
    1384              : 
    1385          803 :     state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
    1386          803 :     state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1387          803 :     state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1388          803 :     state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1389          803 :     state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1390          803 :     state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1391          803 :     state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1392              : 
    1393          803 :     state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1394          803 :     state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
    1395          803 :     state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1396          803 :     state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1397          803 :     state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1398              : 
    1399          803 :     state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
    1400          803 :     state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
    1401          803 :     state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
    1402          803 :     state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1403          803 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1404          803 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1405              : 
    1406          803 :     state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
    1407          803 :     state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
    1408          803 :     state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
    1409          803 :     state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
    1410        16060 :     for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1411        15257 :         state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1412        15257 :         state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1413        15257 :         state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1414        15257 :         state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1415              :     }
    1416              : 
    1417          803 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1418          140 :         state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
    1419              : 
    1420          140 :         state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1421          140 :         state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1422          140 :         state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1423          140 :         state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1424              : 
    1425         2800 :         for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1426         2660 :             state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1427         2660 :             state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1428         2660 :             state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1429         2660 :             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1430              :         }
    1431              :     }
    1432              : 
    1433          803 :     state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1434          803 :     state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1435          803 :     state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1436          803 :     state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1437          803 :     state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1438              : 
    1439          803 :     state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1440          803 :     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1441              : 
    1442          803 :     state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1443          803 :     state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1444          803 :     state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1445              : 
    1446          803 :     state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1447          803 :     state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1448              : 
    1449          803 :     state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1450          803 :     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1451              : 
    1452          803 :     state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1453          803 :     state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1454          803 :     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1455              : 
    1456          803 :     state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1457          803 :     state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1458          803 :     state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1459              : 
    1460          803 :     state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1461          803 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1462          803 :     state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1463              : 
    1464          803 :     state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1465          803 :     state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1466              : 
    1467          803 :     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1468          803 :     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1469              : 
    1470          803 :     state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1471          803 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1472          803 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1473          803 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1474          803 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1475              : 
    1476          803 :     state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1477          803 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1478          803 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1479          803 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1480          803 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1481              : 
    1482          803 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1483          803 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1484          803 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1485          803 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1486          803 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1487              : 
    1488          803 :     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1489          803 :     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1490          803 :     state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1491          803 :     state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1492          803 :     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1493              : 
    1494          803 :     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
    1495              : 
    1496          803 :     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1497          803 :     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1498              : 
    1499          803 :     state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1500          803 :     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1501          803 :     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1502              : 
    1503          803 :     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1504          803 :     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1505              : 
    1506          803 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1507           36 :         state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1508           36 :         state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
    1509           36 :         state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1510           36 :         state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1511           36 :         state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1512           36 :         state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1513           36 :         state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1514           36 :         state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1515              :     }
    1516              : 
    1517          803 :     state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1518          803 :     state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1519          803 :     state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1520          803 :     state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1521          803 :     state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1522          803 :     state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1523          803 :     state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1524          803 :     state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
    1525          803 :     state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
    1526          803 :     state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
    1527              : 
    1528              :     // allocate terms used for pool surface heat balance
    1529          803 :     state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
    1530          803 :     state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1531              : 
    1532              :     // allocate term used as sink for PV electricity
    1533          803 :     state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1534              : 
    1535              :     // Allocate the moisture balance arrays
    1536          803 :     state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1537          803 :     state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1538          803 :     state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1539          803 :     state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1540          803 :     state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1541          803 :     state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1542          803 :     state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1543          803 :     state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1544          803 :     state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1545          803 :     state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1546          803 :     state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1547          803 :     state.dataMstBal->HSurrFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1548              : 
    1549          803 :     state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1550          803 :     state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1551              : 
    1552          803 :     state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1553          803 :     state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1554          803 :     state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
    1555          803 :     state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1556          803 :     state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1557              : 
    1558          803 :     DisplayString(state, "Setting up Surface Reporting Variables");
    1559              :     // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
    1560        48135 :     for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
    1561        47332 :         auto &surface = state.dataSurface->Surface(loop);
    1562        47332 :         if (!surface.HeatTransSurf) {
    1563         1707 :             continue;
    1564              :         }
    1565        91250 :         SetupOutputVariable(state,
    1566              :                             "Surface Inside Face Temperature",
    1567              :                             Constant::Units::C,
    1568        45625 :                             state.dataHeatBalSurf->SurfTempIn(loop),
    1569              :                             OutputProcessor::TimeStepType::Zone,
    1570              :                             OutputProcessor::StoreType::Average,
    1571        45625 :                             surface.Name);
    1572        91250 :         SetupOutputVariable(state,
    1573              :                             "Surface Inside Face Interior Movable Insulation Temperature",
    1574              :                             Constant::Units::C,
    1575        45625 :                             state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
    1576              :                             OutputProcessor::TimeStepType::Zone,
    1577              :                             OutputProcessor::StoreType::Average,
    1578        45625 :                             surface.Name);
    1579              : 
    1580        45625 :         if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1581        91170 :             SetupOutputVariable(state,
    1582              :                                 "Surface Outside Face Temperature",
    1583              :                                 Constant::Units::C,
    1584        45585 :                                 state.dataHeatBalSurf->SurfTempOut(loop),
    1585              :                                 OutputProcessor::TimeStepType::Zone,
    1586              :                                 OutputProcessor::StoreType::Average,
    1587        45585 :                                 surface.Name);
    1588              :         }
    1589              : 
    1590        91250 :         SetupOutputVariable(state,
    1591              :                             "Surface Inside Face Adjacent Air Temperature",
    1592              :                             Constant::Units::C,
    1593        45625 :                             state.dataHeatBal->SurfTempEffBulkAir(loop),
    1594              :                             OutputProcessor::TimeStepType::Zone,
    1595              :                             OutputProcessor::StoreType::Average,
    1596        45625 :                             surface.Name);
    1597        91250 :         SetupOutputVariable(state,
    1598              :                             "Surface Inside Face Convection Heat Transfer Coefficient",
    1599              :                             Constant::Units::W_m2K,
    1600        45625 :                             state.dataHeatBalSurf->SurfHConvInt(loop),
    1601              :                             OutputProcessor::TimeStepType::Zone,
    1602              :                             OutputProcessor::StoreType::Average,
    1603        45625 :                             surface.Name);
    1604        91250 :         SetupOutputVariable(state,
    1605              :                             "Surface Inside Face Convection Heat Gain Rate",
    1606              :                             Constant::Units::W,
    1607        45625 :                             state.dataHeatBalSurf->SurfQdotConvInRep(loop),
    1608              :                             OutputProcessor::TimeStepType::Zone,
    1609              :                             OutputProcessor::StoreType::Average,
    1610        45625 :                             surface.Name);
    1611        91250 :         SetupOutputVariable(state,
    1612              :                             "Surface Inside Face Convection Heat Gain Rate per Area",
    1613              :                             Constant::Units::W_m2,
    1614        45625 :                             state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
    1615              :                             OutputProcessor::TimeStepType::Zone,
    1616              :                             OutputProcessor::StoreType::Average,
    1617        45625 :                             surface.Name);
    1618        91250 :         SetupOutputVariable(state,
    1619              :                             "Surface Inside Face Convection Heat Gain Energy",
    1620              :                             Constant::Units::J,
    1621        45625 :                             state.dataHeatBalSurf->SurfQConvInRep(loop),
    1622              :                             OutputProcessor::TimeStepType::Zone,
    1623              :                             OutputProcessor::StoreType::Sum,
    1624        45625 :                             surface.Name);
    1625              : 
    1626        91250 :         SetupOutputVariable(state,
    1627              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
    1628              :                             Constant::Units::W,
    1629        45625 :                             state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
    1630              :                             OutputProcessor::TimeStepType::Zone,
    1631              :                             OutputProcessor::StoreType::Average,
    1632        45625 :                             surface.Name);
    1633        91250 :         SetupOutputVariable(state,
    1634              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
    1635              :                             Constant::Units::W_m2,
    1636        45625 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
    1637              :                             OutputProcessor::TimeStepType::Zone,
    1638              :                             OutputProcessor::StoreType::Average,
    1639        45625 :                             surface.Name);
    1640        91250 :         SetupOutputVariable(state,
    1641              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
    1642              :                             Constant::Units::J,
    1643        45625 :                             state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
    1644              :                             OutputProcessor::TimeStepType::Zone,
    1645              :                             OutputProcessor::StoreType::Sum,
    1646        45625 :                             surface.Name);
    1647              : 
    1648        45625 :         if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1649        78528 :             SetupOutputVariable(state,
    1650              :                                 "Surface Inside Face Solar Radiation Heat Gain Rate",
    1651              :                                 Constant::Units::W,
    1652        39264 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
    1653              :                                 OutputProcessor::TimeStepType::Zone,
    1654              :                                 OutputProcessor::StoreType::Average,
    1655        39264 :                                 surface.Name);
    1656        78528 :             SetupOutputVariable(state,
    1657              :                                 "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
    1658              :                                 Constant::Units::W_m2,
    1659        39264 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
    1660              :                                 OutputProcessor::TimeStepType::Zone,
    1661              :                                 OutputProcessor::StoreType::Average,
    1662        39264 :                                 surface.Name);
    1663        78528 :             SetupOutputVariable(state,
    1664              :                                 "Surface Inside Face Solar Radiation Heat Gain Energy",
    1665              :                                 Constant::Units::J,
    1666        39264 :                                 state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
    1667              :                                 OutputProcessor::TimeStepType::Zone,
    1668              :                                 OutputProcessor::StoreType::Sum,
    1669        39264 :                                 surface.Name);
    1670              : 
    1671        78528 :             SetupOutputVariable(state,
    1672              :                                 "Surface Inside Face Lights Radiation Heat Gain Rate",
    1673              :                                 Constant::Units::W,
    1674        39264 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
    1675              :                                 OutputProcessor::TimeStepType::Zone,
    1676              :                                 OutputProcessor::StoreType::Average,
    1677        39264 :                                 surface.Name);
    1678        78528 :             SetupOutputVariable(state,
    1679              :                                 "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
    1680              :                                 Constant::Units::W_m2,
    1681        39264 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
    1682              :                                 OutputProcessor::TimeStepType::Zone,
    1683              :                                 OutputProcessor::StoreType::Average,
    1684        39264 :                                 surface.Name);
    1685        78528 :             SetupOutputVariable(state,
    1686              :                                 "Surface Inside Face Lights Radiation Heat Gain Energy",
    1687              :                                 Constant::Units::J,
    1688        39264 :                                 state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
    1689              :                                 OutputProcessor::TimeStepType::Zone,
    1690              :                                 OutputProcessor::StoreType::Sum,
    1691        39264 :                                 surface.Name);
    1692              :         }
    1693              : 
    1694        91250 :         SetupOutputVariable(state,
    1695              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
    1696              :                             Constant::Units::W,
    1697        45625 :                             state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
    1698              :                             OutputProcessor::TimeStepType::Zone,
    1699              :                             OutputProcessor::StoreType::Average,
    1700        45625 :                             surface.Name);
    1701        91250 :         SetupOutputVariable(state,
    1702              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
    1703              :                             Constant::Units::W_m2,
    1704        45625 :                             state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
    1705              :                             OutputProcessor::TimeStepType::Zone,
    1706              :                             OutputProcessor::StoreType::Average,
    1707        45625 :                             surface.Name);
    1708        91250 :         SetupOutputVariable(state,
    1709              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
    1710              :                             Constant::Units::J,
    1711        45625 :                             state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
    1712              :                             OutputProcessor::TimeStepType::Zone,
    1713              :                             OutputProcessor::StoreType::Sum,
    1714        45625 :                             surface.Name);
    1715              : 
    1716        91250 :         SetupOutputVariable(state,
    1717              :                             "Surface Inside Face System Radiation Heat Gain Rate",
    1718              :                             Constant::Units::W,
    1719        45625 :                             state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
    1720              :                             OutputProcessor::TimeStepType::Zone,
    1721              :                             OutputProcessor::StoreType::Average,
    1722        45625 :                             surface.Name);
    1723        91250 :         SetupOutputVariable(state,
    1724              :                             "Surface Inside Face System Radiation Heat Gain Rate per Area",
    1725              :                             Constant::Units::W_m2,
    1726        45625 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
    1727              :                             OutputProcessor::TimeStepType::Zone,
    1728              :                             OutputProcessor::StoreType::Average,
    1729        45625 :                             surface.Name);
    1730        91250 :         SetupOutputVariable(state,
    1731              :                             "Surface Inside Face System Radiation Heat Gain Energy",
    1732              :                             Constant::Units::J,
    1733        45625 :                             state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
    1734              :                             OutputProcessor::TimeStepType::Zone,
    1735              :                             OutputProcessor::StoreType::Sum,
    1736        45625 :                             surface.Name);
    1737              : 
    1738        45625 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
    1739        36912 :             SetupOutputVariable(state,
    1740              :                                 "Surface Outside Face Outdoor Air Drybulb Temperature",
    1741              :                                 Constant::Units::C,
    1742        18456 :                                 state.dataSurface->SurfOutDryBulbTemp(loop),
    1743              :                                 OutputProcessor::TimeStepType::Zone,
    1744              :                                 OutputProcessor::StoreType::Average,
    1745        18456 :                                 surface.Name);
    1746        36912 :             SetupOutputVariable(state,
    1747              :                                 "Surface Outside Face Outdoor Air Wetbulb Temperature",
    1748              :                                 Constant::Units::C,
    1749        18456 :                                 state.dataSurface->SurfOutWetBulbTemp(loop),
    1750              :                                 OutputProcessor::TimeStepType::Zone,
    1751              :                                 OutputProcessor::StoreType::Average,
    1752        18456 :                                 surface.Name);
    1753        36912 :             SetupOutputVariable(state,
    1754              :                                 "Surface Outside Face Outdoor Air Wind Speed",
    1755              :                                 Constant::Units::m_s,
    1756        18456 :                                 state.dataSurface->SurfOutWindSpeed(loop),
    1757              :                                 OutputProcessor::TimeStepType::Zone,
    1758              :                                 OutputProcessor::StoreType::Average,
    1759        18456 :                                 surface.Name);
    1760        36912 :             SetupOutputVariable(state,
    1761              :                                 "Surface Outside Face Outdoor Air Wind Direction",
    1762              :                                 Constant::Units::deg,
    1763        18456 :                                 state.dataSurface->SurfOutWindDir(loop),
    1764              :                                 OutputProcessor::TimeStepType::Zone,
    1765              :                                 OutputProcessor::StoreType::Average,
    1766        18456 :                                 surface.Name);
    1767        36912 :             SetupOutputVariable(state,
    1768              :                                 "Surface Outside Face Convection Heat Gain Rate",
    1769              :                                 Constant::Units::W,
    1770        18456 :                                 state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
    1771              :                                 OutputProcessor::TimeStepType::Zone,
    1772              :                                 OutputProcessor::StoreType::Average,
    1773        18456 :                                 surface.Name);
    1774        36912 :             SetupOutputVariable(state,
    1775              :                                 "Surface Outside Face Convection Heat Gain Rate per Area",
    1776              :                                 Constant::Units::W_m2,
    1777        18456 :                                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
    1778              :                                 OutputProcessor::TimeStepType::Zone,
    1779              :                                 OutputProcessor::StoreType::Average,
    1780        18456 :                                 surface.Name);
    1781        36912 :             SetupOutputVariable(state,
    1782              :                                 "Surface Outside Face Convection Heat Gain Energy",
    1783              :                                 Constant::Units::J,
    1784        18456 :                                 state.dataHeatBalSurf->SurfQConvOutReport(loop),
    1785              :                                 OutputProcessor::TimeStepType::Zone,
    1786              :                                 OutputProcessor::StoreType::Sum,
    1787        18456 :                                 surface.Name);
    1788        36912 :             SetupOutputVariable(state,
    1789              :                                 "Surface Outside Face Convection Heat Transfer Coefficient",
    1790              :                                 Constant::Units::W_m2K,
    1791        18456 :                                 state.dataHeatBalSurf->SurfHConvExt(loop),
    1792              :                                 OutputProcessor::TimeStepType::Zone,
    1793              :                                 OutputProcessor::StoreType::Average,
    1794        18456 :                                 surface.Name);
    1795        36912 :             SetupOutputVariable(state,
    1796              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
    1797              :                                 Constant::Units::W,
    1798        18456 :                                 state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
    1799              :                                 OutputProcessor::TimeStepType::Zone,
    1800              :                                 OutputProcessor::StoreType::Average,
    1801        18456 :                                 surface.Name);
    1802        36912 :             SetupOutputVariable(state,
    1803              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
    1804              :                                 Constant::Units::W_m2,
    1805        18456 :                                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
    1806              :                                 OutputProcessor::TimeStepType::Zone,
    1807              :                                 OutputProcessor::StoreType::Average,
    1808        18456 :                                 surface.Name);
    1809        36912 :             SetupOutputVariable(state,
    1810              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
    1811              :                                 Constant::Units::J,
    1812        18456 :                                 state.dataHeatBalSurf->SurfQRadOutReport(loop),
    1813              :                                 OutputProcessor::TimeStepType::Zone,
    1814              :                                 OutputProcessor::StoreType::Sum,
    1815        18456 :                                 surface.Name);
    1816        36912 :             SetupOutputVariable(state,
    1817              :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
    1818              :                                 Constant::Units::W_m2K,
    1819        18456 :                                 state.dataHeatBalSurf->SurfHAirExt(loop),
    1820              :                                 OutputProcessor::TimeStepType::Zone,
    1821              :                                 OutputProcessor::StoreType::Average,
    1822        18456 :                                 surface.Name);
    1823        36912 :             SetupOutputVariable(state,
    1824              :                                 "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
    1825              :                                 Constant::Units::W_m2K,
    1826        18456 :                                 state.dataHeatBalSurf->SurfHSkyExt(loop),
    1827              :                                 OutputProcessor::TimeStepType::Zone,
    1828              :                                 OutputProcessor::StoreType::Average,
    1829        18456 :                                 surface.Name);
    1830        36912 :             SetupOutputVariable(state,
    1831              :                                 "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
    1832              :                                 Constant::Units::W_m2K,
    1833        18456 :                                 state.dataHeatBalSurf->SurfHGrdExt(loop),
    1834              :                                 OutputProcessor::TimeStepType::Zone,
    1835              :                                 OutputProcessor::StoreType::Average,
    1836        18456 :                                 surface.Name);
    1837        36912 :             SetupOutputVariable(state,
    1838              :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
    1839              :                                 Constant::Units::W,
    1840        18456 :                                 state.dataHeatBalSurf->SurfQAirExtReport(loop),
    1841              :                                 OutputProcessor::TimeStepType::Zone,
    1842              :                                 OutputProcessor::StoreType::Average,
    1843        18456 :                                 surface.Name);
    1844        36912 :             SetupOutputVariable(state,
    1845              :                                 "Surface Outside Face Heat Emission to Air Rate",
    1846              :                                 Constant::Units::W,
    1847        18456 :                                 state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
    1848              :                                 OutputProcessor::TimeStepType::Zone,
    1849              :                                 OutputProcessor::StoreType::Average,
    1850        18456 :                                 surface.Name);
    1851              : 
    1852        18456 :             if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1853        24218 :                 SetupOutputVariable(state,
    1854              :                                     "Surface Outside Face Solar Radiation Heat Gain Rate",
    1855              :                                     Constant::Units::W,
    1856        12109 :                                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
    1857              :                                     OutputProcessor::TimeStepType::Zone,
    1858              :                                     OutputProcessor::StoreType::Average,
    1859        12109 :                                     surface.Name);
    1860        24218 :                 SetupOutputVariable(state,
    1861              :                                     "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
    1862              :                                     Constant::Units::W_m2,
    1863        12109 :                                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
    1864              :                                     OutputProcessor::TimeStepType::Zone,
    1865              :                                     OutputProcessor::StoreType::Average,
    1866        12109 :                                     surface.Name);
    1867        24218 :                 SetupOutputVariable(state,
    1868              :                                     "Surface Outside Face Solar Radiation Heat Gain Energy",
    1869              :                                     Constant::Units::J,
    1870        12109 :                                     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
    1871              :                                     OutputProcessor::TimeStepType::Zone,
    1872              :                                     OutputProcessor::StoreType::Sum,
    1873        12109 :                                     surface.Name);
    1874              :             }
    1875              :         }
    1876        45625 :         if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
    1877        15346 :             surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
    1878         6845 :             surface.Class == DataSurfaces::SurfaceClass::Door) {
    1879              :             //      IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    1880        78522 :             SetupOutputVariable(state,
    1881              :                                 "Surface Inside Face Conduction Heat Transfer Rate",
    1882              :                                 Constant::Units::W,
    1883        39261 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
    1884              :                                 OutputProcessor::TimeStepType::Zone,
    1885              :                                 OutputProcessor::StoreType::Average,
    1886        39261 :                                 surface.Name);
    1887        78522 :             SetupOutputVariable(state,
    1888              :                                 "Surface Inside Face Conduction Heat Gain Rate",
    1889              :                                 Constant::Units::W,
    1890        39261 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
    1891              :                                 OutputProcessor::TimeStepType::Zone,
    1892              :                                 OutputProcessor::StoreType::Average,
    1893        39261 :                                 surface.Name);
    1894        78522 :             SetupOutputVariable(state,
    1895              :                                 "Surface Inside Face Conduction Heat Loss Rate",
    1896              :                                 Constant::Units::W,
    1897        39261 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
    1898              :                                 OutputProcessor::TimeStepType::Zone,
    1899              :                                 OutputProcessor::StoreType::Average,
    1900        39261 :                                 surface.Name);
    1901        78522 :             SetupOutputVariable(state,
    1902              :                                 "Surface Inside Face Conduction Heat Transfer Rate per Area",
    1903              :                                 Constant::Units::W_m2,
    1904        39261 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
    1905              :                                 OutputProcessor::TimeStepType::Zone,
    1906              :                                 OutputProcessor::StoreType::Average,
    1907        39261 :                                 surface.Name);
    1908        78522 :             SetupOutputVariable(state,
    1909              :                                 "Surface Inside Face Conduction Heat Transfer Energy",
    1910              :                                 Constant::Units::J,
    1911        39261 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
    1912              :                                 OutputProcessor::TimeStepType::Zone,
    1913              :                                 OutputProcessor::StoreType::Sum,
    1914        39261 :                                 surface.Name);
    1915              : 
    1916        39261 :             if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1917        78442 :                 SetupOutputVariable(state,
    1918              :                                     "Surface Outside Face Conduction Heat Transfer Rate",
    1919              :                                     Constant::Units::W,
    1920        39221 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
    1921              :                                     OutputProcessor::TimeStepType::Zone,
    1922              :                                     OutputProcessor::StoreType::Average,
    1923        39221 :                                     surface.Name);
    1924        78442 :                 SetupOutputVariable(state,
    1925              :                                     "Surface Outside Face Conduction Heat Gain Rate",
    1926              :                                     Constant::Units::W,
    1927        39221 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
    1928              :                                     OutputProcessor::TimeStepType::Zone,
    1929              :                                     OutputProcessor::StoreType::Average,
    1930        39221 :                                     surface.Name);
    1931        78442 :                 SetupOutputVariable(state,
    1932              :                                     "Surface Outside Face Conduction Heat Loss Rate",
    1933              :                                     Constant::Units::W,
    1934        39221 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
    1935              :                                     OutputProcessor::TimeStepType::Zone,
    1936              :                                     OutputProcessor::StoreType::Average,
    1937        39221 :                                     surface.Name);
    1938        78442 :                 SetupOutputVariable(state,
    1939              :                                     "Surface Outside Face Conduction Heat Transfer Rate per Area",
    1940              :                                     Constant::Units::W_m2,
    1941        39221 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
    1942              :                                     OutputProcessor::TimeStepType::Zone,
    1943              :                                     OutputProcessor::StoreType::Average,
    1944        39221 :                                     surface.Name);
    1945        78442 :                 SetupOutputVariable(state,
    1946              :                                     "Surface Outside Face Conduction Heat Transfer Energy",
    1947              :                                     Constant::Units::J,
    1948        39221 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
    1949              :                                     OutputProcessor::TimeStepType::Zone,
    1950              :                                     OutputProcessor::StoreType::Sum,
    1951        39221 :                                     surface.Name);
    1952              : 
    1953        78442 :                 SetupOutputVariable(state,
    1954              :                                     "Surface Average Face Conduction Heat Transfer Rate",
    1955              :                                     Constant::Units::W,
    1956        39221 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
    1957              :                                     OutputProcessor::TimeStepType::Zone,
    1958              :                                     OutputProcessor::StoreType::Average,
    1959        39221 :                                     surface.Name);
    1960        78442 :                 SetupOutputVariable(state,
    1961              :                                     "Surface Average Face Conduction Heat Gain Rate",
    1962              :                                     Constant::Units::W,
    1963        39221 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
    1964              :                                     OutputProcessor::TimeStepType::Zone,
    1965              :                                     OutputProcessor::StoreType::Average,
    1966        39221 :                                     surface.Name);
    1967        78442 :                 SetupOutputVariable(state,
    1968              :                                     "Surface Average Face Conduction Heat Loss Rate",
    1969              :                                     Constant::Units::W,
    1970        39221 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
    1971              :                                     OutputProcessor::TimeStepType::Zone,
    1972              :                                     OutputProcessor::StoreType::Average,
    1973        39221 :                                     surface.Name);
    1974        78442 :                 SetupOutputVariable(state,
    1975              :                                     "Surface Average Face Conduction Heat Transfer Rate per Area",
    1976              :                                     Constant::Units::W_m2,
    1977        39221 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
    1978              :                                     OutputProcessor::TimeStepType::Zone,
    1979              :                                     OutputProcessor::StoreType::Average,
    1980        39221 :                                     surface.Name);
    1981        78442 :                 SetupOutputVariable(state,
    1982              :                                     "Surface Average Face Conduction Heat Transfer Energy",
    1983              :                                     Constant::Units::J,
    1984        39221 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
    1985              :                                     OutputProcessor::TimeStepType::Zone,
    1986              :                                     OutputProcessor::StoreType::Sum,
    1987        39221 :                                     surface.Name);
    1988              : 
    1989        78442 :                 SetupOutputVariable(state,
    1990              :                                     "Surface Heat Storage Rate",
    1991              :                                     Constant::Units::W,
    1992        39221 :                                     state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
    1993              :                                     OutputProcessor::TimeStepType::Zone,
    1994              :                                     OutputProcessor::StoreType::Average,
    1995        39221 :                                     surface.Name);
    1996        78442 :                 SetupOutputVariable(state,
    1997              :                                     "Surface Heat Storage Gain Rate",
    1998              :                                     Constant::Units::W,
    1999        39221 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
    2000              :                                     OutputProcessor::TimeStepType::Zone,
    2001              :                                     OutputProcessor::StoreType::Average,
    2002        39221 :                                     surface.Name);
    2003        78442 :                 SetupOutputVariable(state,
    2004              :                                     "Surface Heat Storage Loss Rate",
    2005              :                                     Constant::Units::W,
    2006        39221 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
    2007              :                                     OutputProcessor::TimeStepType::Zone,
    2008              :                                     OutputProcessor::StoreType::Average,
    2009        39221 :                                     surface.Name);
    2010        78442 :                 SetupOutputVariable(state,
    2011              :                                     "Surface Heat Storage Rate per Area",
    2012              :                                     Constant::Units::W_m2,
    2013        39221 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
    2014              :                                     OutputProcessor::TimeStepType::Zone,
    2015              :                                     OutputProcessor::StoreType::Average,
    2016        39221 :                                     surface.Name);
    2017        78442 :                 SetupOutputVariable(state,
    2018              :                                     "Surface Heat Storage Energy",
    2019              :                                     Constant::Units::J,
    2020        39221 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
    2021              :                                     OutputProcessor::TimeStepType::Zone,
    2022              :                                     OutputProcessor::StoreType::Sum,
    2023        39221 :                                     surface.Name);
    2024              :             }
    2025              : 
    2026              :             //      ENDIF
    2027              :             // CurrentModuleObject='Opaque Surfaces'
    2028              : 
    2029        78522 :             SetupOutputVariable(state,
    2030              :                                 "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
    2031              :                                 Constant::Units::W,
    2032        39261 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
    2033              :                                 OutputProcessor::TimeStepType::Zone,
    2034              :                                 OutputProcessor::StoreType::Average,
    2035        39261 :                                 surface.Name);
    2036              :         }
    2037        45625 :         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    2038          284 :             SetupOutputVariable(state,
    2039              :                                 "Surface Internal Source Location Temperature",
    2040              :                                 Constant::Units::C,
    2041          142 :                                 state.dataHeatBalSurf->SurfTempSource(loop),
    2042              :                                 OutputProcessor::TimeStepType::Zone,
    2043              :                                 OutputProcessor::StoreType::Average,
    2044          142 :                                 surface.Name);
    2045          284 :             SetupOutputVariable(state,
    2046              :                                 "Surface Internal User Specified Location Temperature",
    2047              :                                 Constant::Units::C,
    2048          142 :                                 state.dataHeatBalSurf->SurfTempUserLoc(loop),
    2049              :                                 OutputProcessor::TimeStepType::Zone,
    2050              :                                 OutputProcessor::StoreType::Average,
    2051          142 :                                 surface.Name);
    2052              :         }
    2053              : 
    2054        45625 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
    2055         6361 :             auto &surfShade = state.dataSurface->surfShades(loop);
    2056        12722 :             SetupOutputVariable(state,
    2057              :                                 "Surface Shading Device Is On Time Fraction",
    2058              :                                 Constant::Units::None,
    2059         6361 :                                 state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
    2060              :                                 OutputProcessor::TimeStepType::Zone,
    2061              :                                 OutputProcessor::StoreType::Average,
    2062         6361 :                                 surface.Name);
    2063         6361 :             SetupOutputVariable(state,
    2064              :                                 "Surface Storm Window On Off Status",
    2065              :                                 Constant::Units::None,
    2066         6361 :                                 state.dataSurface->SurfWinStormWinFlag(loop),
    2067              :                                 OutputProcessor::TimeStepType::Zone,
    2068              :                                 OutputProcessor::StoreType::Average,
    2069         6361 :                                 surface.Name);
    2070        12722 :             SetupOutputVariable(state,
    2071              :                                 "Surface Window Blind Slat Angle",
    2072              :                                 Constant::Units::deg,
    2073         6361 :                                 surfShade.blind.slatAngDeg,
    2074              :                                 OutputProcessor::TimeStepType::Zone,
    2075              :                                 OutputProcessor::StoreType::Average,
    2076         6361 :                                 surface.Name);
    2077              :         }
    2078              :         //    IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    2079        45625 :         SetupOutputVariable(state,
    2080              :                             "Surface Inside Face Convection Classification Index",
    2081              :                             Constant::Units::None,
    2082        45625 :                             state.dataSurface->surfIntConv(loop).convClassRpt,
    2083              :                             OutputProcessor::TimeStepType::Zone,
    2084              :                             OutputProcessor::StoreType::Average,
    2085        45625 :                             surface.Name);
    2086        45625 :         SetupOutputVariable(state,
    2087              :                             "Surface Inside Face Convection Model Equation Index",
    2088              :                             Constant::Units::None,
    2089        45625 :                             state.dataSurface->surfIntConv(loop).hcModelEqRpt,
    2090              :                             OutputProcessor::TimeStepType::Zone,
    2091              :                             OutputProcessor::StoreType::Average,
    2092        45625 :                             surface.Name);
    2093        45625 :         SetupOutputVariable(state,
    2094              :                             "Surface Inside Face Convection Reference Air Index",
    2095              :                             Constant::Units::None,
    2096        45625 :                             state.dataSurface->SurfTAirRefRpt(loop),
    2097              :                             OutputProcessor::TimeStepType::Zone,
    2098              :                             OutputProcessor::StoreType::Average,
    2099        45625 :                             surface.Name);
    2100        45625 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    2101        18196 :             SetupOutputVariable(state,
    2102              :                                 "Surface Outside Face Convection Classification Index",
    2103              :                                 Constant::Units::None,
    2104        18196 :                                 state.dataSurface->surfExtConv(loop).convClassRpt,
    2105              :                                 OutputProcessor::TimeStepType::Zone,
    2106              :                                 OutputProcessor::StoreType::Average,
    2107        18196 :                                 surface.Name);
    2108        18196 :             SetupOutputVariable(state,
    2109              :                                 "Surface Outside Face Forced Convection Model Equation Index",
    2110              :                                 Constant::Units::None,
    2111        18196 :                                 state.dataSurface->surfExtConv(loop).hfModelEqRpt,
    2112              :                                 OutputProcessor::TimeStepType::Zone,
    2113              :                                 OutputProcessor::StoreType::Average,
    2114        18196 :                                 surface.Name);
    2115        18196 :             SetupOutputVariable(state,
    2116              :                                 "Surface Outside Face Natural Convection Model Equation Index",
    2117              :                                 Constant::Units::None,
    2118        18196 :                                 state.dataSurface->surfExtConv(loop).hnModelEqRpt,
    2119              :                                 OutputProcessor::TimeStepType::Zone,
    2120              :                                 OutputProcessor::StoreType::Average,
    2121        18196 :                                 surface.Name);
    2122              :         }
    2123              : 
    2124        91250 :         SetupOutputVariable(state,
    2125              :                             "Surface Inside Face Heat Source Gain Rate per Area",
    2126              :                             Constant::Units::W_m2,
    2127        45625 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
    2128              :                             OutputProcessor::TimeStepType::Zone,
    2129              :                             OutputProcessor::StoreType::Average,
    2130        45625 :                             surface.Name);
    2131        91250 :         SetupOutputVariable(state,
    2132              :                             "Surface Outside Face Heat Source Gain Rate per Area",
    2133              :                             Constant::Units::W_m2,
    2134        45625 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
    2135              :                             OutputProcessor::TimeStepType::Zone,
    2136              :                             OutputProcessor::StoreType::Average,
    2137        45625 :                             surface.Name);
    2138              : 
    2139              :         //     ENDIF
    2140        45625 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    2141          596 :             SetupOutputVariable(state,
    2142              :                                 "Surface Construction Index",
    2143              :                                 Constant::Units::None,
    2144          596 :                                 surface.Construction,
    2145              :                                 OutputProcessor::TimeStepType::Zone,
    2146              :                                 OutputProcessor::StoreType::Average,
    2147          596 :                                 surface.Name);
    2148              :         }
    2149              :     }
    2150         3212 :     SetupOutputVariable(state,
    2151              :                         "Site Total Surface Heat Emission to Air",
    2152              :                         Constant::Units::J,
    2153          803 :                         state.dataHeatBalSurf->SumSurfaceHeatEmission,
    2154              :                         OutputProcessor::TimeStepType::Zone,
    2155              :                         OutputProcessor::StoreType::Sum,
    2156              :                         "Environment");
    2157          803 : }
    2158              : 
    2159         6396 : void InitThermalAndFluxHistories(EnergyPlusData &state)
    2160              : {
    2161              : 
    2162              :     // SUBROUTINE INFORMATION:
    2163              :     //       AUTHOR         George Walton
    2164              :     //       DATE WRITTEN   March 1978
    2165              :     //       RE-ENGINEERED  Feb98 (RKS)
    2166              : 
    2167              :     // PURPOSE OF THIS SUBROUTINE:
    2168              :     // This subroutine sets the initial temperature and flux histories
    2169              :     // needed for a stable and reasonable heat balance solution starting
    2170              :     // point.
    2171              : 
    2172              :     // METHODOLOGY EMPLOYED:
    2173              :     // This subroutine assumes that the simulation is at steady state at
    2174              :     // the beginning and then begins to vary.  Thus, the temperatures, the
    2175              :     // fluxes. and their histories can all be set to the same value.  Some
    2176              :     // of the initializations depend on the surface characteristics.  This
    2177              :     // requires a DO loop to perform the proper calculation.
    2178              : 
    2179              :     // REFERENCES:
    2180              :     // (I)BLAST legacy routine INITTH
    2181              : 
    2182              :     // First do the "bulk" initializations of arrays sized to NumOfZones
    2183        54578 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2184        48182 :         new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
    2185              :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2186        48182 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
    2187        48182 :         thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2188        48182 :         thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
    2189        48182 :         state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
    2190              :     }
    2191        54568 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    2192        48172 :         thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
    2193         6396 :     }
    2194              :     // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
    2195        54722 :     for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
    2196        48326 :         new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
    2197              :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2198        48326 :         thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2199        48326 :         thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
    2200         6396 :     }
    2201              : 
    2202              :     // "Bulk" initializations of arrays sized to TotSurfaces
    2203        54578 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2204        96508 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2205        48326 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2206        48326 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2207        48326 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2208       467845 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2209       419519 :                 state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2210       419519 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;        // module level array
    2211       419519 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp;     // module level array
    2212       419519 :                 state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
    2213       419519 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    2214       419519 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    2215       419519 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    2216       419519 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    2217       419519 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) = 0.0;
    2218       419519 :                 state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
    2219       419519 :                 state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
    2220       419519 :                 state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
    2221       419519 :                 state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
    2222       419519 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
    2223       419519 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
    2224       419519 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
    2225       419519 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
    2226       419519 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
    2227       419519 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
    2228       419519 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
    2229       419519 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
    2230       419519 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
    2231       419519 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
    2232       419519 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
    2233       419519 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
    2234       419519 :                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
    2235       419519 :                 state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
    2236       419519 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
    2237       419519 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
    2238       419519 :                 state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
    2239       419519 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
    2240       419519 :                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
    2241       419519 :                 state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
    2242       419519 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
    2243              :             } // end of  Surf array
    2244        48326 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2245        48326 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2246        48326 :             if (firstSurfOpaq >= 0) {
    2247       411048 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2248       362722 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
    2249       362722 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
    2250       362722 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
    2251       362722 :                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2252              :                 } // end of Zone Surf
    2253              :             }
    2254        48326 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2255        48326 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2256        48326 :             if (firstSurfWin >= 0) {
    2257       105113 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2258              :                     // Initialize window frame and divider temperatures
    2259        56787 :                     state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2260        56787 :                     state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2261        56787 :                     state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2262        56787 :                     state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2263        56787 :                     state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2264        56787 :                     state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2265              : 
    2266              :                     // Initialize previous-timestep shading indicators
    2267        56787 :                     state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2268        56787 :                     state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2269              :                 } // end of Zone Surf
    2270              :             }
    2271        48182 :         }
    2272              :     } // end of Zone
    2273              : 
    2274              :     // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
    2275        54578 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2276        96508 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2277        48326 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2278        48326 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2279        48326 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2280       966520 :             for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2281      8889055 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2282      7970861 :                     state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2283      7970861 :                     state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2284      7970861 :                     state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2285      7970861 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2286              :                 }
    2287              :             }
    2288        48182 :         }
    2289              :     }
    2290         6396 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2291        17040 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2292        31740 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2293        15918 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2294        15918 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2295        15918 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2296       162951 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2297       147033 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    2298              :                 }
    2299       318360 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2300      3096069 :                     for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2301      2793627 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2302      2793627 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2303      2793627 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2304      2793627 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2305              :                     }
    2306              :                 }
    2307        15822 :             }
    2308              :         }
    2309              :     }
    2310         6396 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    2311         1170 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2312         1770 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2313          885 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2314          885 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2315          885 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2316         7313 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2317       128560 :                     for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2318       122132 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2319       122132 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2320       122132 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2321       122132 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2322       122132 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
    2323       122132 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
    2324              :                     }
    2325              :                 }
    2326          885 :             }
    2327              :         }
    2328              :     }
    2329         6396 :     state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    2330              : 
    2331              :     // Perform other initializations that depend on the surface characteristics
    2332        71311 :     for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
    2333      4639732 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2334      4574817 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2335              :             // Reset outside boundary conditions if necessary
    2336      4574817 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2337      1725165 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2338      2849652 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2339       214317 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2340       214317 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2341      2635335 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2342        16720 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2343        16720 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2344              :             }
    2345              :             // Initialize the flux histories
    2346      4574817 :             state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
    2347      4574817 :                 state.dataConstruction->Construct(surface.Construction).UValue *
    2348      4574817 :                 (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
    2349      4574817 :             state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2350        64915 :         }
    2351              :     }
    2352       425920 :     for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2353       419524 :         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    2354           30 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
    2355           30 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
    2356              :         }
    2357         6396 :     }
    2358              :     // Initialize Kiva convection algorithms
    2359         6660 :     for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
    2360          264 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
    2361          264 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
    2362          264 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
    2363         6396 :     }
    2364         6396 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2365       148251 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2366       147033 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2367       147033 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2368      1061560 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2369      1008482 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2370              :                 }
    2371       147033 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2372        86160 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2373        81852 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2374        81852 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2375              :                 }
    2376        89647 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2377        36600 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2378        34770 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2379        34770 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2380              :                 }
    2381              :             }
    2382       916550 :             for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
    2383       769517 :                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2384       769517 :                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2385              :             }
    2386         1218 :         }
    2387              :     }
    2388              : 
    2389         6396 :     if (state.dataSurface->TotOSCM >= 1) {
    2390          292 :         for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
    2391          202 :             auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
    2392          202 :             thisOSC.TConv = 20.0;
    2393          202 :             thisOSC.HConv = 4.0;
    2394          202 :             thisOSC.TRad = 20.0;
    2395          202 :             thisOSC.HRad = 4.0;
    2396              :         }
    2397              :     }
    2398         6396 : }
    2399              : 
    2400        10122 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
    2401              : {
    2402              :     // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
    2403        10122 :     auto &s_mat = state.dataMaterial;
    2404        10122 :     auto &s_surf = state.dataSurface;
    2405              : 
    2406        14169 :     for (int SurfNum : s_surf->extMovInsulSurfNums) {
    2407         4047 :         auto &movInsul = s_surf->extMovInsuls(SurfNum);
    2408         4047 :         Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
    2409         4047 :         if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
    2410            0 :             movInsul.present = false;
    2411            0 :             int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
    2412            0 :             auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
    2413            0 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
    2414            0 :             state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
    2415            0 :             state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
    2416            0 :             continue;
    2417            0 :         }
    2418              : 
    2419         4047 :         auto const *mat = s_mat->materials(movInsul.matNum);
    2420         4047 :         movInsul.present = true;
    2421         4047 :         movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
    2422         4047 :         if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
    2423         2022 :             auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
    2424         2022 :             assert(matGlass != nullptr);
    2425         2022 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
    2426         2022 :         } else {
    2427         2025 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
    2428              :         }
    2429         4047 :         state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
    2430         4047 :         state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
    2431        10122 :     }
    2432        10122 : }
    2433              : 
    2434        10122 : void EvalInsideMovableInsulation(EnergyPlusData &state)
    2435              : {
    2436        10122 :     auto &s_mat = state.dataMaterial;
    2437        10122 :     auto &s_surf = state.dataSurface;
    2438              :     // This subroutine determines whether or not inside movable insulation is present at the current time.
    2439        16197 :     for (int SurfNum : s_surf->intMovInsulSurfNums) {
    2440         6075 :         auto &movInsul = s_surf->intMovInsuls(SurfNum);
    2441         6075 :         Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
    2442         6075 :         if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
    2443            0 :             movInsul.present = false;
    2444            0 :             int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
    2445            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    2446            0 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
    2447            0 :             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
    2448            0 :             continue;
    2449            0 :         }
    2450              : 
    2451         6075 :         auto const *mat = s_mat->materials(movInsul.matNum);
    2452              : 
    2453         6075 :         movInsul.present = true;
    2454         6075 :         movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
    2455         6075 :         if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
    2456            0 :             auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
    2457            0 :             assert(matGlass != nullptr);
    2458            0 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
    2459            0 :         } else {
    2460         6075 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
    2461              :         }
    2462         6075 :         state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
    2463        10122 :     }
    2464        10122 : }
    2465              : 
    2466      2800078 : void InitSolarHeatGains(EnergyPlusData &state)
    2467              : {
    2468              : 
    2469              :     // SUBROUTINE INFORMATION:
    2470              :     //       AUTHOR         Anonymous
    2471              :     //       DATE WRITTEN   July 1977
    2472              :     //       MODIFIED       Mar99 (FW): handle movable interior shades and
    2473              :     //                                  switchable glazing
    2474              :     //                      Oct99 (FW): account for Window5 glass calculation approach
    2475              :     //                      May01 (FW): handle interior and exterior blinds
    2476              :     //                      Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
    2477              :     //                      May06 (RR): handle exterior window screens
    2478              :     //       RE-ENGINEERED  Feb98 (RKS)
    2479              : 
    2480              :     // PURPOSE OF THIS SUBROUTINE:
    2481              :     // This subroutine initializes the arrays associated with solar heat
    2482              :     // gains for both individual surfaces and for zones.  As a result,
    2483              :     // this routine sets the following variable arrays:
    2484              :     // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
    2485              :     // SurfWinQRadSWwinAbs (for windows)
    2486              : 
    2487              :     // METHODOLOGY EMPLOYED:
    2488              :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    2489              :     // sun is up, various calculations are made.
    2490              : 
    2491              :     // REFERENCES:
    2492              :     // (I)BLAST legacy routine QSUN
    2493              : 
    2494      2800078 :     auto &s_mat = state.dataMaterial;
    2495      2800078 :     auto &Surface = state.dataSurface->Surface;
    2496              : 
    2497              :     // Using/Aliasing
    2498              :     using Dayltg::TransTDD;
    2499              :     using SolarShading::CalcInteriorSolarDistribution;
    2500              :     using namespace DataWindowEquivalentLayer;
    2501              :     using SolarShading::SurfaceScheduledSolarInc;
    2502              :     using SolarShading::WindowScheduledSolarAbs;
    2503              : 
    2504              :     // Why are these globals?
    2505      2800078 :     auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
    2506      2800078 :     auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
    2507      2800078 :     auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
    2508              : 
    2509     22623034 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2510     19822956 :         state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
    2511     19822956 :         state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
    2512     19822956 :         state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
    2513     19822956 :         state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
    2514     19822956 :         state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
    2515     19822956 :         state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
    2516              : 
    2517     19822956 :         state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
    2518     19822956 :         state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
    2519     19822956 :         state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
    2520     19822956 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
    2521     19822956 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
    2522     19822956 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
    2523     19822956 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
    2524     19822956 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
    2525     19822956 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
    2526              :     }
    2527     22618990 :     for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2528     19818912 :         state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
    2529              :     }
    2530     22623034 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2531     39694512 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2532     19871556 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2533     19871556 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2534     19871556 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2535    167531295 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2536    147659739 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
    2537    147659739 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
    2538    147659739 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
    2539    147659739 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
    2540    147659739 :                 state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
    2541    147659739 :                 state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
    2542    147659739 :                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2543    147659739 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
    2544    147659739 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
    2545              :             }
    2546              : 
    2547     19871556 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2548     19871556 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2549     42239844 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2550              :                 // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
    2551     22368288 :                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
    2552     22368288 :                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
    2553     22368288 :                 state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
    2554     22368288 :                 state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
    2555     22368288 :                 state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
    2556     22368288 :                 state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
    2557     22368288 :                 state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
    2558     22368288 :                 state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
    2559     22368288 :                 state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
    2560     22368288 :                 state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
    2561              :             }
    2562              : 
    2563     42239844 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2564     22368288 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
    2565     22368288 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
    2566     22368288 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
    2567     22368288 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
    2568     22368288 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
    2569     22368288 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
    2570     22368288 :                 state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
    2571     22368288 :                 state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
    2572     22368288 :                 state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
    2573              :             }
    2574     42239844 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2575     22368288 :                 state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
    2576     22368288 :                 state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
    2577     22368288 :                 state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
    2578     22368288 :                 state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
    2579     22368288 :                 state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
    2580     22368288 :                 state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
    2581     22368288 :                 state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
    2582              :             }
    2583    158972448 :             for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2584    295678908 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2585    156578016 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
    2586              :                 }
    2587              :             }
    2588     19822956 :         }
    2589              :     }
    2590      2800078 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    2591        48135 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2592        47332 :             state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2593        47332 :             state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2594              :         }
    2595              :     }
    2596              :     bool currSolRadPositive =
    2597      2800078 :         state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
    2598      2800078 :     bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
    2599      2800078 :     bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
    2600      2800078 :     bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
    2601      2800078 :                       sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
    2602      2800078 :     state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
    2603              : 
    2604      2800078 :     if (currSolRadPositive || resetSolar) {
    2605     90518687 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2606     89100243 :             state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2607     89100243 :             state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2608     89100243 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2609     89100243 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2610     89100243 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
    2611              : 
    2612     89100243 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
    2613     89100243 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
    2614     89100243 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
    2615     89100243 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
    2616              : 
    2617     89100243 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
    2618     89100243 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
    2619     89100243 :             state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
    2620     89100243 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
    2621     89100243 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
    2622              : 
    2623     89100243 :             state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
    2624     89100243 :             state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
    2625              :         }
    2626     11504192 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2627     10085748 :             state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
    2628     10085748 :             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
    2629     10085748 :             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
    2630     10085748 :             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
    2631     10085748 :             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
    2632     10085748 :             state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
    2633     10085748 :             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2634     10085748 :             state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2635     10085748 :             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2636     10085748 :             state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2637              :         }
    2638     11506260 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2639     20200472 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2640     10112656 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2641     10112656 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2642     10112656 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2643     21545846 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2644     11433190 :                     state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
    2645     11433190 :                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
    2646     11433190 :                     state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
    2647     11433190 :                     state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
    2648     11433190 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    2649     11433190 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
    2650     11433190 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
    2651     11433190 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
    2652     11433190 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
    2653     11433190 :                     state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
    2654              :                 }
    2655     21545846 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2656     11433190 :                     state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
    2657     11433190 :                     state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
    2658     11433190 :                     state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
    2659     11433190 :                     state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
    2660     11433190 :                     state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
    2661     11433190 :                     state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
    2662     11433190 :                     state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
    2663     11433190 :                     state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
    2664     11433190 :                     state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
    2665     11433190 :                     state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
    2666     11433190 :                     state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
    2667     11433190 :                     state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
    2668     11433190 :                     state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
    2669              :                 }
    2670     21545846 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2671     11433190 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
    2672     11433190 :                     state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
    2673     11433190 :                     state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
    2674     11433190 :                     state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
    2675     11433190 :                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2676     11433190 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2677     11433190 :                     state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
    2678     11433190 :                     state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
    2679     11433190 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
    2680              :                 }
    2681     21545846 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2682     11433190 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
    2683     11433190 :                     state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
    2684     11433190 :                     state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
    2685     11433190 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
    2686     11433190 :                     state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
    2687     11433190 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
    2688     11433190 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
    2689     11433190 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
    2690     11433190 :                     state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
    2691              :                 }
    2692              : 
    2693     21545846 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2694     11433190 :                     state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
    2695     11433190 :                     state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
    2696     11433190 :                     state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
    2697     11433190 :                     state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
    2698     11433190 :                     state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
    2699     11433190 :                     state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
    2700     11433190 :                     state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
    2701     11433190 :                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
    2702     11433190 :                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
    2703     11433190 :                     state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
    2704     11433190 :                     state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
    2705     11433190 :                     state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
    2706     11433190 :                     state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
    2707              :                 }
    2708     80943441 :                 for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
    2709    150940110 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2710     80109325 :                         state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
    2711              :                     }
    2712              :                 }
    2713     70788592 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
    2714    129275076 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2715     68599140 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
    2716              :                     }
    2717              :                 }
    2718     10087816 :             }
    2719              :         }
    2720              :     }
    2721      2800078 :     if (resetSolar) {
    2722      4220743 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2723      3719433 :             state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
    2724      3719433 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
    2725              :         }
    2726              : 
    2727              :         // TTD domes are currently not considered in the window list of a zone
    2728       501310 :         if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
    2729         1233 :             for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
    2730          822 :                 e.TransSolBeam = 0.0;
    2731          822 :                 e.TransSolDiff = 0.0;
    2732          822 :                 e.TransVisBeam = 0.0;
    2733          822 :                 e.TransVisDiff = 0.0;
    2734          822 :                 e.TransmittedSolar = 0.0;
    2735          822 :                 int SurfDome = e.Dome;
    2736          822 :                 state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
    2737          822 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
    2738          822 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
    2739         6576 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2740         5754 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
    2741              :                 }
    2742              :             }
    2743              :         }
    2744              : 
    2745       501310 :         if (state.dataSurface->CalcSolRefl) {
    2746        30175 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2747        27084 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
    2748        27084 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
    2749        27084 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
    2750              :             }
    2751              :         }
    2752     33493802 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2753     32992492 :             state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
    2754     32992492 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
    2755     32992492 :             state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
    2756     32992492 :             state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
    2757     32992492 :             state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
    2758     32992492 :             state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
    2759     32992492 :             state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
    2760              :         }
    2761              :     }
    2762      2800078 :     if (currSolRadPositive) { // Sun is up, calculate solar quantities
    2763       917134 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2764              :                                 state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
    2765       917134 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2766              :                                 state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
    2767       917134 :         Real64 GndReflSolarRad = 0.0;
    2768       917134 :         Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
    2769              : 
    2770     57024885 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2771     56107751 :             state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
    2772              :         }
    2773     57024885 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2774     56107751 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2775     56107751 :             state.dataSurface->SurfSkySolarInc(SurfNum) =
    2776     56107751 :                 state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2777     56107751 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2778         9408 :                 GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
    2779         4704 :                                   state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2780         4704 :                 Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
    2781              :             } else {
    2782     56103047 :                 GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    2783              :             }
    2784     56107751 :             state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
    2785     56107751 :             state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2786     56107751 :             state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
    2787              :         }
    2788       917134 :         if (state.dataSurface->CalcSolRefl) {
    2789              :             // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
    2790        22984 :             Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
    2791        22984 :             Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
    2792              :             // For Complex Fenestrations:
    2793       313999 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2794       291015 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2795              : 
    2796       291015 :                 Real64 GndSurfReflectance = 0.0;
    2797       291015 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2798            0 :                     GndSurfReflectance =
    2799            0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2800              :                 } else {
    2801       291015 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2802              :                 }
    2803       291015 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2804       291015 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2805       291015 :                 state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
    2806       291015 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2807       291015 :                 state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
    2808       291015 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2809       291015 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
    2810       291015 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
    2811       291015 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
    2812       291015 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
    2813       291015 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
    2814       291015 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
    2815       291015 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
    2816       291015 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
    2817       291015 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
    2818              :                 // TH2 CR 9056
    2819       291015 :                 state.dataSurface->SurfSkySolarInc(SurfNum) +=
    2820       291015 :                     currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
    2821       291015 :                     currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    2822       291015 :                 state.dataSurface->SurfGndSolarInc(SurfNum) =
    2823       291015 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
    2824       291015 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2825       291015 :                 state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2826              :             }
    2827              :         }
    2828              : 
    2829       917134 :         SolarShading::CalcWindowProfileAngles(state);
    2830              : 
    2831       917134 :         if (state.dataHeatBal->CalcWindowRevealReflection) {
    2832          826 :             SolarShading::CalcBeamSolarOnWinRevealSurface(state);
    2833              :         }
    2834              : 
    2835       917134 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2836          826 :             SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
    2837          826 :             if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2838          826 :                 SolarShading::CalcInteriorSolarDistributionWCESimple(state);
    2839              :             }
    2840              :         } else {
    2841       916308 :             SolarShading::CalcInteriorSolarDistribution(state);
    2842              :         }
    2843              : 
    2844      7283449 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2845              : 
    2846              :             // TH 3/24/2010 - QBV is not used!
    2847              :             // unused      QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
    2848              : 
    2849              :             // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
    2850              :             // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
    2851              :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2852              : 
    2853              :             // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
    2854              :             // QDforDaylight(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2855              :             //                          +EnclSolDS(ZoneNum)*DifSolarRad  &
    2856              :             //                          +EnclSolDG(ZoneNum)*GndSolarRad
    2857              : 
    2858              :             //  Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
    2859              :             //  EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
    2860              :             //  Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
    2861              :             //   diffuse solar rather than using weighted area*absorptance
    2862      6366315 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
    2863      6366315 :                 (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
    2864      6366315 :                 state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2865              : 
    2866              :             // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
    2867              :             // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
    2868              :             // and transmitted through interior windows
    2869              :             // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
    2870              :             // QD(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2871              :             //                +EnclSolDS(ZoneNum)*DifSolarRad  &
    2872              :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2873     12732630 :             state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
    2874      6366315 :                                                          state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
    2875      6366315 :                                                          state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2876              :         }
    2877              : 
    2878              :         // Flux of diffuse solar in each zone
    2879              : 
    2880      7283449 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2881      6366315 :             state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
    2882              :         }
    2883              : 
    2884       917134 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    2885        18955 :             for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2886        15164 :                 if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
    2887         7582 :                     Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
    2888         7582 :                     int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
    2889         7582 :                                                                                  1)); // Tuned Linear indexing
    2890        37910 :                     for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
    2891        30328 :                         if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
    2892         7582 :                             EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
    2893         7582 :                                                    state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
    2894              :                         }
    2895              :                     }
    2896         7582 :                     state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
    2897              :                 }
    2898              :             }
    2899              :         }
    2900              : 
    2901      7283449 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2902      6366315 :             if (state.dataHeatBalSurf->InterZoneWindow) {
    2903        15164 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
    2904        15164 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2905              :             } else {
    2906      6351151 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2907              :             }
    2908              :         }
    2909              : 
    2910              :         //    RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
    2911              :         //    DO SurfNum = 1, TotSurfaces
    2912              :         //      IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
    2913              :         //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    2914              :         //      IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
    2915              :         //      ZoneNum = Surface(SurfNum)%Zone
    2916              :         // Diffuse solar entering zone through exterior windows is assumed to be uniformly
    2917              :         // distributed on inside face of surfaces of zone
    2918              :         //      DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) /  &
    2919              :         //        Zone(ZoneNum)%TotalSurfArea
    2920              :         //      DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) *  &
    2921              :         //        DifIncInsSurfIntensRep(SurfNum)
    2922              :         //      DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
    2923              :         //    END DO
    2924              : 
    2925              :         // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
    2926       917134 :         if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
    2927      2084499 :             for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
    2928      1780334 :                 Real64 GndSurfReflectance = 0.0;
    2929      1780334 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2930            0 :                     GndSurfReflectance =
    2931            0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2932              :                 } else {
    2933      1780334 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2934              :                 }
    2935              :                 // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2936      1780334 :                 Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2937      1780334 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
    2938      1780334 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2939      1780334 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2940      1780334 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2941              :                 // Incident direct (unreflected) beam
    2942      1780334 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2943      1780334 :                     currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
    2944              :                 // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2945      1780334 :                 state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2946              :                 // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2947      1780334 :                 state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2948              :                 // Incident diffuse solar from beam-to-diffuse reflection from ground
    2949      1780334 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2950      1780334 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2951              :                 // Incident diffuse solar from sky diffuse reflection from ground
    2952      1780334 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2953      1780334 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2954              :                 // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2955              :                 // in SkySolarInc.
    2956      1780334 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2957      1780334 :                     state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2958      1780334 :                     state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    2959              :             }
    2960              :         }
    2961              : 
    2962       917134 :         Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
    2963              : 
    2964     23421354 :         for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
    2965     22504220 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2966              :             // Regular surface
    2967     22504220 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2968     22504220 :             Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2969              :             // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2970     22504220 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    2971     22504220 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2972              : 
    2973              :             // Report variables for various incident solar quantities
    2974              :             // Incident direct (unreflected) beam
    2975     22504220 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2976     22504220 :                 currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    2977     22504220 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
    2978              : 
    2979     22504220 :             Real64 GndSurfReflectance = 0.0;
    2980     22504220 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2981         3528 :                 GndSurfReflectance =
    2982         3528 :                     state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2983              :             } else {
    2984     22500692 :                 GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2985              :             }
    2986              :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2987     22504220 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2988              :             // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2989     22504220 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2990              :             // Incident diffuse solar from beam-to-diffuse reflection from ground
    2991     22504220 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2992     22504220 :                 currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2993              : 
    2994              :             // Incident diffuse solar from sky diffuse reflection from ground
    2995     22504220 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2996     22504220 :                 currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2997              :             // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2998              :             // in SkySolarInc.
    2999              :             // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
    3000              :             // TH2 CR 9056
    3001     22504220 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    3002     22504220 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    3003     22504220 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    3004              : 
    3005     22504220 :             if (state.dataSurface->CalcSolRefl) {
    3006              :                 // Incident beam solar from beam-to-beam (specular) reflection from obstructions
    3007       173799 :                 state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    3008              :                 // Incident diffuse solar from beam-to-diffuse reflection from obstructions
    3009       173799 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
    3010       173799 :                     state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    3011              :                 // Incident diffuse solar from sky diffuse reflection from obstructions
    3012       173799 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    3013              :                 // TH2 CR 9056: Add reflections from obstructions to the total incident
    3014       347598 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
    3015       173799 :                                                                      state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
    3016       173799 :                                                                      state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
    3017              :             }
    3018       917134 :         }
    3019       918366 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    3020         1232 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
    3021         1232 :             int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;    // TDD: DOME object number
    3022         1232 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3023         1232 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3024              : 
    3025              :             // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
    3026              :             // by dividing out diffuse solar transmittance of TDD:DIFFUSER
    3027         1232 :             Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    3028              : 
    3029         1232 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
    3030         1232 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3031         1232 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
    3032         1232 :                                      TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
    3033              : 
    3034         2464 :             state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
    3035         1232 :                                                           state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
    3036         1232 :                                                           TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
    3037              : 
    3038         2464 :             state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
    3039         1232 :                                                           state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
    3040              :             // Incident direct (unreflected) beam
    3041         2464 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
    3042         2464 :                                                                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
    3043         1232 :                                                                                                       state.dataGlobal->TimeStep,
    3044         1232 :                                                                                                       SurfNum2) *
    3045              :                                                                     ConInc; // NOTE: sunlit and coninc array set to SurfNum2
    3046              : 
    3047              :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    3048         1232 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
    3049         1232 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    3050         1232 :                 (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    3051         1232 :                  state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
    3052              :         }
    3053              : 
    3054       917750 :         for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
    3055          616 :             int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window;       // Daylighting shelf object number
    3056          616 :             int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
    3057          616 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    3058          616 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    3059          616 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3060          616 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3061              :             // Shelf diffuse solar radiation
    3062              :             Real64 ShelfSolarRad =
    3063          616 :                 (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
    3064          616 :                      state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
    3065          616 :                  state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
    3066          616 :                 state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
    3067              : 
    3068          616 :             GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    3069          616 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    3070            0 :                 GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
    3071              :             }
    3072              :             // Add all reflected solar from the outside shelf to the ground solar
    3073              :             // NOTE:  If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
    3074          616 :             state.dataSurface->SurfGndSolarInc(SurfNum) =
    3075          616 :                 GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
    3076              :         }
    3077              : 
    3078              :         // Calculate Exterior and Interior Absorbed Short Wave Radiation
    3079      7284688 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3080     12749976 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3081      6382422 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3082      6382422 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    3083      6382422 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    3084     53383723 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    3085     47001301 :                     int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    3086     47001301 :                     Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3087     47001301 :                     currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3088     47001301 :                     if (Surface(SurfNum).ExtSolar) {
    3089              :                         Real64 AbsExt =
    3090     13429814 :                             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
    3091     13429814 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3092     13429814 :                             state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
    3093     13429814 :                             AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
    3094              :                     }
    3095     47001301 :                     if (ConstrNum > 0) {
    3096     47001301 :                         int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
    3097     47001301 :                         if (SurfSolIncPtr == 0) {
    3098     47000713 :                             if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) {    // Opaque surface
    3099     47000713 :                                 int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
    3100     47000713 :                                 int InShelfSurf = 0;                                                // Inside daylighting shelf surface number
    3101     47000713 :                                 if (ShelfNum > 0) {
    3102            0 :                                     InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
    3103              :                                 }
    3104     47000713 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
    3105     47000713 :                                     state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
    3106     47000713 :                                 if (InShelfSurf > 0) { // Inside daylighting shelf
    3107              :                                     // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
    3108            0 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3109            0 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
    3110              :                                 } else { // Regular surface
    3111     47000713 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3112     47000713 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
    3113              :                                 }
    3114              :                             }
    3115              :                         } else {
    3116          588 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
    3117              :                         }
    3118              :                     }
    3119              :                 }
    3120      6382422 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3121      6382422 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3122     13685004 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    3123      7302582 :                     auto &surf = state.dataSurface->Surface(SurfNum);
    3124      7302582 :                     auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3125      7302582 :                     if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3126              :                         // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
    3127      7294072 :                         int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3128      7294072 :                         auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3129      7294072 :                         Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
    3130      7294072 :                         Real64 BeamSolar = currBeamSolar(SurfNum);                         // Local variable for BeamSolarRad
    3131      7294072 :                         Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum);  // Sky diffuse solar incident on a surface
    3132      7294072 :                         Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum);  // Ground diffuse solar incident on a surface
    3133              : 
    3134      7294072 :                         DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3135              : 
    3136     14573423 :                         if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
    3137      7279351 :                             !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3138      7278525 :                             int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3139     16644687 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3140      9366162 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3141              :                             }
    3142              : 
    3143      7278525 :                             if (IS_SHADED(ShadeFlag)) { // Shaded window
    3144              : 
    3145       184702 :                                 int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
    3146       184702 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3147              : 
    3148       184702 :                                 if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
    3149       116218 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3150        74732 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
    3151              :                                     }
    3152        41486 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
    3153              : 
    3154       143216 :                                 } else if (ANY_BLIND(ShadeFlag)) { // Blind on
    3155        71430 :                                     auto &surfShade = state.dataSurface->surfShades(SurfNum);
    3156        71430 :                                     int slatIdxLo = surfShade.blind.slatAngIdxLo;
    3157        71430 :                                     int slatIdxHi = surfShade.blind.slatAngIdxHi;
    3158        71430 :                                     Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3159              :                                     Real64 AbsDiffBlind;
    3160              : 
    3161              :                                     // For constructions, have to do interpolation whether we have movable slats or not
    3162       147298 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3163        75868 :                                         auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
    3164        75868 :                                         auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
    3165              : 
    3166        75868 :                                         AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
    3167        75868 :                                         AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3168        75868 :                                         AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3169              :                                     }
    3170              : 
    3171        71430 :                                     auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
    3172        71430 :                                     auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
    3173        71430 :                                     AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
    3174              : 
    3175        71430 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
    3176              : 
    3177        71430 :                                     auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
    3178        71430 :                                     if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
    3179        71430 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
    3180              : 
    3181              :                                         // Need to do these interpolations unless we want to cache this in surfShade.blind.
    3182        71430 :                                         Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3183        71430 :                                         Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3184              : 
    3185        71430 :                                         state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
    3186        71430 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
    3187        71430 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
    3188              :                                     }
    3189              :                                 }
    3190              : 
    3191              :                                 // Correct for shadowing of divider onto interior shading device (note that dividers are
    3192              :                                 // not allowed in windows with between-glass shade/blind)
    3193              : 
    3194       184702 :                                 if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    3195          742 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3196              :                                 }
    3197              : 
    3198       184702 :                                 if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {        // Switchable glazing
    3199        71786 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
    3200       215358 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3201       143572 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
    3202       143572 :                                             Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
    3203              :                                     }
    3204              :                                 }
    3205              : 
    3206              :                             } // End of check if window has shading device on
    3207              : 
    3208      7278525 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3209     16644687 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3210      9366162 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3211      9366162 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
    3212      9366162 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3213              :                                 // SurfWinA is from InteriorSolarDistribution
    3214      9366162 :                                 if (ANY_BLIND(ShadeFlag)) {
    3215        75868 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3216        75868 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3217        75868 :                                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3218        75868 :                                     auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
    3219        75868 :                                     if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
    3220              : 
    3221        75868 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
    3222              : 
    3223        75868 :                                         int slatIdxLo = surfShade.blind.slatAngIdxLo;
    3224        75868 :                                         int slatIdxHi = surfShade.blind.slatAngIdxLo;
    3225        75868 :                                         Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3226        75868 :                                         auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
    3227        75868 :                                         auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
    3228              : 
    3229        75868 :                                         Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3230        75868 :                                         Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3231              : 
    3232        75868 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3233        75868 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
    3234       151736 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
    3235        75868 :                                             state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3236              :                                     }
    3237              :                                 }
    3238              :                                 // Total solar absorbed in solid layer (W), for reporting
    3239      9366162 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3240      9366162 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3241              : 
    3242              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3243      9366162 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3244              :                             }
    3245      7278525 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3246      7278525 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3247              :                             // Need to do it this way for now because of scheduled surface gains. They do work only with
    3248              :                             // BSDF windows and overwriting absorbtances will work only for ordinary windows
    3249              :                             // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
    3250              :                             //   SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
    3251              :                             //   inExtWindowModel->isExternalLibraryModel() ) {
    3252              :                             //   TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
    3253              :                             //   for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
    3254              :                             //     SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
    3255              :                             //       ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
    3256              :                             //   }
    3257        15547 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    3258        12243 :                             int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
    3259              :                             // Number of solid layers in fenestration system (glass + shading)
    3260        12243 :                             int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
    3261              :                             // Current state for Complex Fenestration
    3262              :                             // Examine for schedule surface gain
    3263        12243 :                             Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
    3264              :                                 state,
    3265              :                                 SurfNum,
    3266        12243 :                                 ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
    3267              : 
    3268        46277 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3269        34034 :                                 if (SurfSolAbs != 0) {
    3270          294 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) =
    3271          294 :                                         state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
    3272              :                                     // ABWin(Lay) = SurfWinA(SurfNum,Lay)
    3273          294 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
    3274              :                                 } else {
    3275              :                                     // Several notes about this equation.  First part is accounting for diffuse solar radiation for the ground
    3276              :                                     // and from the sky.  Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
    3277              :                                     // radiation originating from beam on exterior side.  Third item (SurfWinACFOverlap(SurfNum,Lay)) is
    3278              :                                     // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
    3279              :                                     // windows
    3280        33740 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3281        33740 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
    3282        33740 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
    3283        33740 :                                         state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3284        33740 :                                         state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
    3285              :                                 }
    3286              :                                 // Total solar absorbed in solid layer (W), for reporting
    3287        34034 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3288        34034 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3289              : 
    3290              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3291        34034 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3292              :                             }
    3293        12243 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3294        12243 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3295              : 
    3296         3304 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    3297         2478 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3298              :                             // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
    3299              :                             int TotSolidLay =
    3300         2478 :                                 state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
    3301        11564 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3302              :                                 // Absorbed window components include:
    3303              :                                 // (1) beam solar radiation absorbed by all layers in the fenestration
    3304              :                                 // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
    3305              :                                 // (3) diffuse short wave incident on the inside face of the fenestration.  The short wave internal sources
    3306              :                                 //     include light, ...
    3307         9086 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
    3308         9086 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3309         9086 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3310         9086 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
    3311              : 
    3312              :                                 // Total solar absorbed in solid layer (W), for reporting
    3313         9086 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3314         9086 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3315              : 
    3316              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3317         9086 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3318              :                             }
    3319              : 
    3320         2478 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3321         2478 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3322          826 :                         } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3323          826 :                             int SurfNum2 = SurfNum;
    3324          826 :                             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3325            0 :                                 SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    3326              :                             }
    3327              : 
    3328              :                             std::pair<Real64, Real64> incomingAngle =
    3329          826 :                                 Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
    3330          826 :                             Real64 Theta = incomingAngle.first;
    3331          826 :                             Real64 Phi = incomingAngle.second;
    3332              : 
    3333              :                             std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
    3334          826 :                                 Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
    3335          826 :                                     state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
    3336              : 
    3337          826 :                             size_t totLayers = aLayer->getNumOfLayers();
    3338         1652 :                             for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
    3339          826 :                                 Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
    3340              :                                     Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
    3341              : 
    3342          826 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3343          826 :                                     AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3344              : 
    3345              :                                 // Total solar absorbed in solid layer (W), for reporting
    3346          826 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3347          826 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3348              : 
    3349              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3350          826 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3351              :                             }
    3352          826 :                         }
    3353              : 
    3354              :                         // Solar absorbed by window frame and dividers
    3355      7294072 :                         int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
    3356      7294072 :                         if (FrDivNum > 0) {
    3357       304322 :                             Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum);                    // Frame, divider area (m2)
    3358       304322 :                             Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
    3359       304322 :                             Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
    3360       304322 :                             Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
    3361       304322 :                             Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
    3362       304322 :                             Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
    3363       304322 :                             Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
    3364       304322 :                             Real64 CosIncAngHorProj = 0.0;  // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
    3365       304322 :                             Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
    3366       304322 :                             Real64 FracSunLit = 0.0;        // Fraction of window sunlit this time step
    3367              :                             Real64 BeamFaceInc;             // Beam solar incident window plane this time step (W/m2)
    3368              :                             Real64 DifSolarFaceInc;         // Diffuse solar incident on window plane this time step (W/m2)
    3369       304322 :                             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3370       304322 :                             Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3371       304322 :                             if (FrArea > 0.0 || DivArea > 0.0) {
    3372       185302 :                                 FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    3373       185302 :                                 BeamFaceInc = currBeamSolarRad *
    3374       185302 :                                               state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    3375              :                                               CosInc;
    3376       185302 :                                 DifSolarFaceInc = SkySolarInc + GndSolarInc;
    3377              :                             }
    3378       304322 :                             if (FracSunLit > 0.0) {
    3379       128315 :                                 if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
    3380        19572 :                                     (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
    3381              :                                     // Dot products used to calculate beam solar incident on faces of
    3382              :                                     // frame and divider perpendicular to the glass surface.
    3383              :                                     // Note that SOLCOS is the current timestep's solar direction cosines.
    3384              :                                     //                  PhiWin = ASIN(WALCOS(3,SurfNum))
    3385              :                                     Real64 PhiWin =
    3386       100049 :                                         std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
    3387       100049 :                                     Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
    3388       100049 :                                     Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
    3389       100049 :                                     Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
    3390       100049 :                                     Real64 const cos_PhiWin(std::cos(PhiWin));
    3391       100049 :                                     Real64 const cos_PhiSun(std::cos(PhiSun));
    3392              :                                     CosIncAngHorProj =
    3393       100049 :                                         std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
    3394       100049 :                                     CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
    3395              :                                 }
    3396              :                             }
    3397              :                             // Frame solar
    3398              :                             // (A window shade or blind, if present, is assumed to not shade the frame, so no special
    3399              :                             // treatment of frame solar needed if window has an exterior shade or blind.)
    3400       304322 :                             if (FrArea > 0.0) {
    3401       185302 :                                 Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
    3402       185302 :                                 Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
    3403       185302 :                                 Real64 TransDiffGl = 0.0;  // Diffuse solar transmittance
    3404       185302 :                                 if (FrProjOut > 0.0 || FrProjIn > 0.0) {
    3405              :                                     Real64 BeamFrHorFaceInc =
    3406       261364 :                                         currBeamSolarRad * CosIncAngHorProj *
    3407       130682 :                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
    3408       130682 :                                         FrArea;
    3409              :                                     Real64 BeamFrVertFaceInc =
    3410       261364 :                                         currBeamSolarRad * CosIncAngVertProj *
    3411       130682 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3412       130682 :                                         FrArea;
    3413              :                                     // Beam solar on outside of frame
    3414       130682 :                                     FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
    3415       130682 :                                     if (FrProjIn > 0.0) {
    3416       130682 :                                         Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3417       130682 :                                         TransDiffGl = thisConstruct.TransDiff;
    3418       130682 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3419        71044 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3420        71044 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3421        71044 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3422        71044 :                                             Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3423        71044 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3424        71044 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3425        71044 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3426              :                                         }
    3427              :                                         // Beam solar on inside of frame
    3428       130682 :                                         FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
    3429              :                                     }
    3430              :                                 }
    3431              :                                 // Beam plus diffuse solar on outside of frame
    3432       185302 :                                 FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
    3433       185302 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
    3434       185302 :                                     FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3435              :                                 // Add diffuse from beam reflected from window outside reveal surfaces
    3436       185302 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
    3437       185302 :                                                                                       state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
    3438       185302 :                                                                                       state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3439              : 
    3440              :                                 // Beam plus diffuse solar on inside of frame
    3441       185302 :                                 FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
    3442       185302 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3443              :                                 // Add diffuse from beam reflected from window inside reveal surfaces
    3444       185302 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
    3445       185302 :                                                                                      state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
    3446       185302 :                                                                                      state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3447              :                             }
    3448              : 
    3449              :                             // Divider solar
    3450              :                             // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
    3451              :                             // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
    3452              :                             // DivProjIn will be zero in this case.)
    3453       304322 :                             if (DivArea > 0.0) {                                                         // Solar absorbed by window divider
    3454       140236 :                                 Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3455       140236 :                                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    3456              :                                     // Suspended (between-glass) divider; account for effect glass on outside of divider
    3457              :                                     // (note that outside and inside projection for this type of divider are both zero)
    3458         8004 :                                     int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
    3459         8004 :                                     auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
    3460         8004 :                                     assert(thisMaterial != nullptr);
    3461         8004 :                                     Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
    3462         8004 :                                     Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
    3463         8004 :                                     Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3464         8004 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3465         8004 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3466         8004 :                                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3467            0 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3468            0 :                                         Real64 MatNumGlSh = constructionSh.LayerPoint(1);
    3469            0 :                                         auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
    3470            0 :                                         assert(thisMaterialSh != nullptr);
    3471            0 :                                         Real64 TransGlSh = thisMaterialSh->Trans;
    3472            0 :                                         Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
    3473            0 :                                         Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
    3474            0 :                                         TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3475            0 :                                         ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
    3476            0 :                                         AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
    3477              :                                     }
    3478         8004 :                                     Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
    3479         8004 :                                     DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    3480              :                                 }
    3481              : 
    3482       140236 :                                 Real64 BeamDivHorFaceInc = 0.0;  // Beam solar on divider's horizontal outside projection faces (W/m2)
    3483       140236 :                                 Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
    3484              :                                 // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
    3485       140236 :                                 if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3486        95784 :                                     BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
    3487        95784 :                                                         DivProjOut *
    3488        95784 :                                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3489              :                                                         FracSunLit / DivArea;
    3490        95784 :                                     BeamDivVertFaceInc =
    3491        95784 :                                         currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
    3492        95784 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3493              :                                         DivArea;
    3494              :                                 }
    3495       140236 :                                 Real64 DivIncSolarOutBm =
    3496              :                                     0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
    3497       140236 :                                 Real64 DivIncSolarOutDif =
    3498              :                                     0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
    3499       140236 :                                 Real64 DivIncSolarInBm =
    3500              :                                     0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
    3501       140236 :                                 Real64 DivIncSolarInDif =
    3502              :                                     0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
    3503       271912 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
    3504       131676 :                                     !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
    3505       131676 :                                     DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
    3506       131676 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3507       131676 :                                     if (DivProjIn > 0.0) {
    3508        95784 :                                         Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3509        95784 :                                         Real64 TransDiffGl = thisConstruct.TransDiff;                       // Diffuse solar transmittance
    3510        95784 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3511        71044 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3512        71044 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3513        71044 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3514              : 
    3515        71044 :                                             Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3516              :                                             // Outer glass solar trans, refl, absorptance if switched
    3517        71044 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3518        71044 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3519              :                                             // Diffuse solar transmittance, switched construction
    3520        71044 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3521              :                                         }
    3522              :                                         // Beam plus diffuse solar on inside of divider
    3523              :                                         // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
    3524              :                                         // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
    3525              :                                         Real64 BeamDivHorFaceIncIn =
    3526        95784 :                                             currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
    3527        95784 :                                             (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3528        95784 :                                             FracSunLit / DivArea;
    3529              :                                         Real64 BeamDivVertFaceIncIn =
    3530        95784 :                                             currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
    3531        95784 :                                             DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
    3532        95784 :                                             FracSunLit / DivArea;
    3533        95784 :                                         DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
    3534        95784 :                                         DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
    3535              :                                     }
    3536              :                                 } else { // Exterior shade, screen or blind present
    3537              : 
    3538         8560 :                                     DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3539         8560 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3540         8560 :                                     DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3541         8560 :                                     DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3542              :                                 }
    3543              : 
    3544       140236 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3545              :                                     // No exterior or between-glass shade, screen or blind
    3546       131676 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
    3547       131676 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
    3548              :                                     // Exterior shade, screen or blind
    3549              : 
    3550         8560 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
    3551            0 :                                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3552              : 
    3553            0 :                                     int profIdxLo = surfShade.blind.profAngIdxLo;
    3554            0 :                                     int profIdxHi = surfShade.blind.profAngIdxHi;
    3555            0 :                                     Real64 profInterpFac = surfShade.blind.profAngInterpFac;
    3556              : 
    3557            0 :                                     auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
    3558            0 :                                     auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
    3559              : 
    3560            0 :                                     Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
    3561            0 :                                     Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
    3562              : 
    3563              :                                     // TBlBmBm - Blind beam-beam solar transmittance
    3564            0 :                                     Real64 TBlBmBm = surfShade.blind.bmBmTrans;
    3565            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3566            0 :                                         DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
    3567            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3568            0 :                                         DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
    3569              : 
    3570         8560 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
    3571         8560 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3572         8560 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3573         8560 :                                     auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
    3574         8560 :                                     assert(matFen != nullptr);
    3575         8560 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3576         8560 :                                         DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
    3577         8560 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3578         8560 :                                         DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
    3579              : 
    3580            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
    3581            0 :                                     int screenNum = surfWin.screenNum;
    3582            0 :                                     auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
    3583            0 :                                     assert(screen != nullptr);
    3584              : 
    3585            0 :                                     auto &surf = state.dataSurface->Surface(SurfNum);
    3586              :                                     Real64 phi, theta;
    3587            0 :                                     Material::GetRelativePhiTheta(
    3588            0 :                                         surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
    3589              : #ifdef PRECALC_INTERP_SCREEN
    3590              :                                     int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
    3591              :                                     BilinearInterpCoeffs coeffs;
    3592            0 :                                     Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
    3593            0 :                                     GetBilinearInterpCoeffs(
    3594            0 :                                         phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
    3595            0 :                                     auto const &b11 = screen->btars[ip1][it1];
    3596            0 :                                     auto const &b12 = screen->btars[ip1][it2];
    3597            0 :                                     auto const &b21 = screen->btars[ip2][it1];
    3598            0 :                                     auto const &b22 = screen->btars[ip2][it2];
    3599            0 :                                     Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
    3600            0 :                                     Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
    3601              : 
    3602            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3603            0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3604            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3605            0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3606              : #else  // !PRECALC_INTERP_SCREEN
    3607              :                                     Material::ScreenBmTransAbsRef btar;
    3608              : 
    3609              :                                     Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
    3610              :                                     Real64 BmDfTrans = btar.DfTrans;
    3611              :                                     Real64 BmBmTrans = btar.BmTrans;
    3612              : 
    3613              :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3614              :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3615              :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3616              :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3617              : #endif // PRECALC_INTERP_SCREEN
    3618              :                                 }
    3619              :                             }
    3620              :                         }
    3621              :                     } // Surface(SurfNum)%ExtSolar
    3622              :                 } // end of surface window loop
    3623      6367554 :             } // end of space loop
    3624              :         } // end of zone loop
    3625       918366 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    3626         1232 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
    3627         1232 :             int const ConstrNum = Surface(SurfNum).Construction;
    3628         1232 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3629         1232 :             int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3630         1232 :             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3631         2464 :             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3632         1232 :                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3633         1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3634         1232 :                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
    3635         1232 :                         (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
    3636         1232 :                     state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
    3637         1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3638         1232 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3639         1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3640         1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3641         1232 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3642              :             }
    3643              :         }
    3644              : 
    3645              :         // Average absorbed solar for representative surfaces
    3646       917134 :         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    3647         4606 :             for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3648         9016 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3649         4508 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    3650         4508 :                     int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    3651         4508 :                     int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    3652        43806 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3653        39298 :                         auto &surface = state.dataSurface->Surface(surfNum);
    3654        39298 :                         if (surface.ConstituentSurfaceNums.size() > 1) {
    3655         1470 :                             Real64 QoutAtot = 0.0;
    3656         1470 :                             Real64 QinAtot = 0.0;
    3657         1470 :                             Real64 Atot = 0.0;
    3658         4606 :                             for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3659         3136 :                                 QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3660         3136 :                                 QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3661         3136 :                                 Atot += state.dataSurface->Surface(constSurfNum).Area;
    3662         1470 :                             }
    3663              : 
    3664         1470 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
    3665         1470 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
    3666              :                         }
    3667              :                     }
    3668         4508 :                     firstSurf = thisSpace.WindowSurfaceFirst;
    3669         4508 :                     lastSurf = thisSpace.WindowSurfaceLast;
    3670        21952 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3671        17444 :                         auto const &surface = state.dataSurface->Surface(surfNum);
    3672        17444 :                         if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
    3673              :                             // Absorbed in glazing
    3674              :                             int totalGlassLayers =
    3675         1862 :                                 state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
    3676         5586 :                             for (int layer = 1; layer <= totalGlassLayers; ++layer) {
    3677         3724 :                                 Real64 QAtot = 0.0;
    3678         3724 :                                 Real64 Atot = 0.0;
    3679        29792 :                                 for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3680        26068 :                                     QAtot +=
    3681        26068 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
    3682        26068 :                                     Atot += state.dataSurface->Surface(constSurfNum).Area;
    3683         3724 :                                 }
    3684              : 
    3685         3724 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
    3686              :                             }
    3687              : 
    3688              :                             // Absorbed by frame and dividers
    3689         1862 :                             if (surface.FrameDivider > 0) {
    3690          196 :                                 if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    3691            0 :                                     Real64 QoutAtot = 0.0;
    3692            0 :                                     Real64 QinAtot = 0.0;
    3693            0 :                                     Real64 Atot = 0.0;
    3694            0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3695            0 :                                         QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
    3696            0 :                                                     state.dataSurface->SurfWinFrameArea(constSurfNum);
    3697            0 :                                         QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
    3698            0 :                                                    state.dataSurface->SurfWinFrameArea(constSurfNum);
    3699            0 :                                         Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
    3700            0 :                                     }
    3701              : 
    3702            0 :                                     state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
    3703            0 :                                     state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
    3704              :                                 }
    3705          196 :                                 if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    3706            0 :                                     Real64 QoutAtot = 0.0;
    3707            0 :                                     Real64 QinAtot = 0.0;
    3708            0 :                                     Real64 Atot = 0.0;
    3709            0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3710            0 :                                         QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
    3711            0 :                                                     state.dataSurface->SurfWinDividerArea(constSurfNum);
    3712            0 :                                         QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
    3713            0 :                                                    state.dataSurface->SurfWinDividerArea(constSurfNum);
    3714            0 :                                         Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
    3715            0 :                                     }
    3716              : 
    3717            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
    3718            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
    3719              :                                 }
    3720              :                             }
    3721              :                         }
    3722              :                     }
    3723         4508 :                 }
    3724              :             }
    3725              :         }
    3726       917134 :     } // End of sun-up check
    3727      2800078 : }
    3728              : 
    3729      2800078 : void InitIntSolarDistribution(EnergyPlusData &state)
    3730              : {
    3731              : 
    3732              :     // SUBROUTINE INFORMATION:
    3733              :     //       AUTHOR         Anonymous
    3734              :     //       DATE WRITTEN   July 1977
    3735              :     //       MODIFIED       Oct 1999 (FW) to handle movable shades
    3736              :     //                      May 2000 (FW) to handle window frame and dividers
    3737              :     //                      May 2001 (FW) to handle window blinds
    3738              :     //                      Jan 2002 (FW) mods for between-glass shade/blind
    3739              :     //                      May 2006 (RR) to handle exterior window screens
    3740              :     //       RE-ENGINEERED  Mar98 (RKS)
    3741              : 
    3742              :     // PURPOSE OF THIS SUBROUTINE:
    3743              :     // This subroutine initializes the arrays associated with solar heat
    3744              :     // gains for both individual surfaces and for zones.
    3745              : 
    3746              :     // METHODOLOGY EMPLOYED:
    3747              :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    3748              :     // sun is up, various calculations are made.
    3749              : 
    3750              :     // REFERENCES:
    3751              :     // (I)BLAST legacy routine QSUN
    3752              : 
    3753              :     using Dayltg::DistributeTDDAbsorbedSolar;
    3754              :     using namespace DataWindowEquivalentLayer;
    3755              : 
    3756      2800078 :     auto &s_mat = state.dataMaterial;
    3757              :     // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
    3758              :     // Note: If sun is not up, QS is only internal gains
    3759     22618990 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3760     19818912 :         Real64 sumSpaceQLTSW = 0.0;
    3761     39690468 :         for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
    3762     19871556 :             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3763     19818912 :         }
    3764     19818912 :         state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
    3765     19818912 :         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
    3766              :     }
    3767              : 
    3768      2800078 :     if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
    3769              : 
    3770        60735 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3771              : 
    3772        48588 :             if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
    3773              : 
    3774       120960 :                 for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
    3775              : 
    3776        96768 :                     if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
    3777        24192 :                         Real64 sumSpaceQLTSW = 0.0;
    3778        48384 :                         for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
    3779        24192 :                             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3780        24192 :                         }
    3781        24192 :                         state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
    3782        24192 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3783        24192 :                             (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
    3784        24192 :                         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
    3785        24192 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
    3786        24192 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
    3787        24192 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3788        24192 :                             state.dataHeatBal->EnclSolQD(OtherenclosureNum);
    3789        24192 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
    3790        24192 :                             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
    3791              :                     }
    3792              :                 }
    3793              :             }
    3794              :         }
    3795              :     }
    3796              : 
    3797              :     // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
    3798              : 
    3799      2800078 :     if (state.dataEnvrn->SunIsUp) {
    3800     86680127 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    3801     85280782 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    3802              :             //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    3803     85280782 :             if (surface.Class == DataSurfaces::SurfaceClass::Shading) {
    3804         1129 :                 continue;
    3805              :             }
    3806     85279653 :             int const enclosureNum = surface.SolarEnclIndex;
    3807     85279653 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
    3808     85279653 :                 state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
    3809     85279653 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
    3810     85279653 :                 state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
    3811     85279653 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
    3812     85279653 :                 state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3813      1399345 :         }
    3814              :     }
    3815              : 
    3816              :     // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
    3817     22618990 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3818     19818912 :         auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
    3819     19818912 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    3820        48588 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
    3821        48588 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3822              :             // CR 8695, VMULT not based on visible
    3823        48588 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
    3824        48588 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3825              :         } else {
    3826     19770324 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
    3827     19770324 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
    3828              :         }
    3829              :     }
    3830              : 
    3831              :     // COMPUTE RADIANT GAINS ON SURFACES
    3832     22623034 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3833     39694512 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3834     19871556 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3835     19871556 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
    3836     19871556 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
    3837    167531295 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
    3838    147659739 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3839    147659739 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3840    147659739 :                 int const ConstrNum = surface.Construction;
    3841    147659739 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3842              : 
    3843    147659739 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
    3844              :                 // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
    3845    147659739 :                 Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
    3846              : 
    3847    147659739 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
    3848    147659739 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
    3849              : 
    3850              :                 // Calculate absorbed solar on outside if movable exterior insulation in place
    3851    147659739 :                 if (state.dataSurface->AnyMovableInsulation) {
    3852        60732 :                     auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
    3853        60732 :                     if (movInsul.present) {
    3854         4047 :                         Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
    3855         4047 :                         auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
    3856         4047 :                         state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
    3857         4047 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
    3858              :                         // For transparent insulation, allow some sunlight to get through the movable insulation.
    3859              :                         // The equation below is derived by taking what is transmitted through the layer and applying
    3860              :                         // the fraction that is absorbed plus the back reflected portion (first order reflection only)
    3861              :                         // to the plane between the transparent insulation and the exterior surface face.
    3862         4047 :                         auto const *matMovInsul = s_mat->materials(movInsul.matNum);
    3863         4047 :                         auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
    3864         4047 :                         Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
    3865              : 
    3866         4047 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3867         4047 :                             transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
    3868         4047 :                             ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
    3869              :                     }
    3870              :                 }
    3871              :                 // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
    3872              :                 // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
    3873    147659739 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
    3874              :             } // end of opaque
    3875              : 
    3876     19871556 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3877     19871556 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3878     42239844 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
    3879     22368288 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3880     22368288 :                 auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3881     22368288 :                 int const radEnclosureNum = surface.RadEnclIndex;
    3882     22368288 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3883     22368288 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3884     22368288 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3885              : 
    3886     22368288 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
    3887     22360179 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    3888              : 
    3889     22360179 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    3890     22360179 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3891              : 
    3892              :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    3893     22360179 :                     Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
    3894     22360179 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    3895     22359779 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3896     22359779 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3897     22359779 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3898              :                     } else {
    3899              :                         // radiant value prior to adjustment for pulse for load component report
    3900          400 :                         Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    3901              :                         // for the loads component report during the special sizing run increase the radiant portion
    3902              :                         // a small amount to create a "pulse" of heat that is used for the
    3903              :                         // radiant value including adjustment for pulse for load component report
    3904          400 :                         Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    3905              :                         // ITABSF is the Inside Thermal Absorptance
    3906              :                         // EnclRadThermAbsMult is a multiplier for each zone/enclosure
    3907              :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    3908          400 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3909          400 :                             adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    3910          400 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3911              :                     }
    3912              : 
    3913     22360179 :                     if (NOT_SHADED(ShadeFlag)) { // No window shading
    3914     50254476 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3915     28181098 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3916     28181098 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    3917              :                         }
    3918       286801 :                     } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    3919              :                         // Interior, exterior or between-glass shade, screen or blind in place
    3920       188978 :                         auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    3921       433866 :                         for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
    3922       244888 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3923        93965 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3924        93965 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
    3925       150923 :                             } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
    3926       129219 :                                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3927       129219 :                                 Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3928       129219 :                                 auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
    3929       129219 :                                 auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
    3930              :                                 // Glass layer back diffuse solar absorptance when blind in place
    3931       129219 :                                 Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
    3932              : 
    3933       129219 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3934       129219 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
    3935              :                             }
    3936              :                         }
    3937       188978 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    3938        44850 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3939        44850 :                                                                                  constrSh.ShadeAbsorpThermal *
    3940        22425 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3941       166553 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    3942       128113 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3943       128113 :                             Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
    3944       256226 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3945       128113 :                                                                                  EffBlEmiss *
    3946       128113 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3947              :                         }
    3948              : 
    3949       188978 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3950        50929 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
    3951        50929 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
    3952       138049 :                         } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    3953       138049 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3954       138049 :                             auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
    3955       138049 :                             auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
    3956       138049 :                             Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3957       138049 :                             Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
    3958              : 
    3959       138049 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
    3960              :                         }
    3961              :                         // Correct for divider shadowing
    3962       188978 :                         if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3963        21522 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3964              :                         }
    3965              : 
    3966       286801 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {       // Switchable glazing
    3967        71786 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
    3968       215358 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3969              : 
    3970       143572 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3971       143572 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    3972       143572 :                                 Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    3973       143572 :                                                  thisConstruct.AbsDiffBack(IGlass),
    3974       143572 :                                                  constructionSh.AbsDiffBack(IGlass));
    3975              :                         }
    3976              : 
    3977              :                     } // End of shading flag check
    3978              : 
    3979              :                     // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
    3980     22360179 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    3981       477684 :                         state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
    3982       477684 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
    3983       477684 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3984       477684 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    3985       477684 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    3986       477684 :                                  state.dataSurface->SurfWinFrameEmis(SurfNum)) *
    3987       477684 :                             (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame
    3988              :                     }
    3989     22360179 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {                     // Window has dividers
    3990       329931 :                         Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum);    // Window divider thermal absorptance
    3991       329931 :                         Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3992       329931 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) ==
    3993              :                             DataSurfaces::FrameDividerType::Suspended) {                         // Suspended divider; account for inside glass
    3994        29589 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
    3995        29589 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
    3996        29589 :                             assert(thisMaterial != nullptr);
    3997        29589 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
    3998        29589 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    3999        29589 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    4000        29589 :                             Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
    4001        29589 :                             DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
    4002        29589 :                             DividerThermAbs = thisMaterial->AbsorpThermalBack;
    4003              :                         }
    4004              :                         // Correct for interior shade transmittance
    4005       329931 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    4006          742 :                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4007          742 :                             int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
    4008          742 :                             auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
    4009          742 :                             assert(matSh != nullptr);
    4010          742 :                             DividerSolAbs *= matSh->Trans;
    4011          742 :                             DividerThermAbs *= matSh->TransThermal;
    4012              : 
    4013       329189 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    4014            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4015            0 :                             Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
    4016            0 :                             Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
    4017              : 
    4018            0 :                             DividerSolAbs *= SolBackDiffDiffTrans;
    4019            0 :                             DividerThermAbs *= IRBackTrans;
    4020              :                         }
    4021              :                         // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
    4022       329931 :                         state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
    4023       329931 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
    4024       329931 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    4025       329931 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    4026       329931 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    4027       329931 :                                  DividerThermAbs) *
    4028       329931 :                             (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
    4029              :                     }
    4030              :                 } else {
    4031              :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    4032         8109 :                     Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
    4033         8109 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    4034         8109 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    4035         8109 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    4036         8109 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4037              :                     } else {
    4038              :                         // radiant value prior to adjustment for pulse for load component report
    4039            0 :                         Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    4040              :                         // for the loads component report during the special sizing run increase the radiant portion
    4041              :                         // a small amount to create a "pulse" of heat that is used for the
    4042              :                         // radiant value including adjustment for pulse for load component report
    4043            0 :                         Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    4044              :                         // ITABSF is the Inside Thermal Absorptance
    4045              :                         // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
    4046              :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    4047            0 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    4048            0 :                             adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    4049            0 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4050              :                     }
    4051              :                     // Radiations absorbed by the window layers coming from zone side
    4052         8109 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4053        37842 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4054        29733 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
    4055        29733 :                             state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
    4056              :                     }
    4057              :                     // Window frame has not been included for equivalent layer model yet
    4058              : 
    4059              :                 } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
    4060              : 
    4061     22368288 :                 if (surface.ExtBoundCond > 0) { // Interzone surface
    4062              :                     // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
    4063        27192 :                     int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
    4064        27192 :                     if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
    4065        27192 :                         int TotGlassLayers = thisConstruct.TotGlassLayers;
    4066        54384 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4067        27192 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
    4068        27192 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    4069        27192 :                                 state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
    4070              :                             // Note that AbsDiff rather than AbsDiffBack is used in the above since the
    4071              :                             // radiation from the current zone is incident on the outside of the adjacent
    4072              :                             // zone's window.
    4073              :                         }
    4074              :                     } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
    4075            0 :                         int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
    4076            0 :                         int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
    4077            0 :                         for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4078            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
    4079            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
    4080              :                             // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
    4081              :                             // since the radiation from the current zone is incident on the outside of the
    4082              :                             // adjacent zone's window.
    4083              :                         }
    4084              :                     }
    4085              :                 }
    4086              : 
    4087     22368288 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
    4088     22320639 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4089     22320639 :                     int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    4090     22320639 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4091     22320639 :                     if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
    4092     50207892 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4093     28148017 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4094              :                         }
    4095       260764 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    4096       215358 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4097       143572 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4098              :                         }
    4099              :                     } else {
    4100       188978 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4101              :                         // Interior, exterior or between-glass shade, screen or blind in place
    4102       433866 :                         for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
    4103       244888 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4104              :                         }
    4105       188978 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4106       188978 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
    4107              :                         }
    4108              :                     } // End of shading flag check
    4109        47649 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    4110        39540 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    4111       119289 :                     for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4112        79749 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4113              :                     }
    4114         8109 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    4115              : 
    4116              :                     // ConstrNum   = Surface(SurfNum)%Construction
    4117         8109 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4118              : 
    4119        37842 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4120        29733 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
    4121              :                     }
    4122              :                 }
    4123              : 
    4124              :             } // End of window
    4125     19822956 :         }
    4126              :     }
    4127      2800078 :     Dayltg::DistributeTDDAbsorbedSolar(state);
    4128      2800078 : }
    4129              : 
    4130      2800078 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
    4131              : {
    4132              : 
    4133              :     // SUBROUTINE INFORMATION:
    4134              :     //       AUTHOR         Legacy Code (George Walton)
    4135              :     //       DATE WRITTEN   Legacy: Dec 1976
    4136              :     //       MODIFIED       Nov. 99, FCW: to take into account movable interior shades and switchable glazing
    4137              :     //                      June 01, FCW: to take into account interior blinds.
    4138              : 
    4139              :     // PURPOSE OF THIS SUBROUTINE:
    4140              :     // This routine computes the fractions of long-wave radiation from lights, equipment and people
    4141              :     // that is absorbed by each zone surface.
    4142              : 
    4143              :     // METHODOLOGY EMPLOYED:
    4144              :     // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
    4145              : 
    4146              :     // REFERENCES:
    4147              :     // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
    4148      2800078 :     auto &s_mat = state.dataMaterial;
    4149              : 
    4150     22618990 :     for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    4151     19818912 :         if (!thisEnclosure.radReCalc) {
    4152     19641879 :             continue;
    4153              :         }
    4154       354220 :         for (int spaceNum : thisEnclosure.spaceNums) {
    4155       177187 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4156       177187 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    4157       177187 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    4158       596634 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    4159       419447 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4160       419447 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4161        10800 :                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4162        10800 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
    4163              :                 } else {
    4164       408647 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4165       408647 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
    4166              :                 }
    4167              :             }
    4168       177033 :         }
    4169      2800078 :     }
    4170      2800078 :     if (state.dataSurface->AnyMovableSlat) {
    4171        12150 :         for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
    4172              :             // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
    4173         6075 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4174              :             // Not sure we need to do this anymore
    4175         6075 :             if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4176         2578 :                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4177         2578 :                 state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
    4178              :             }
    4179         6075 :         }
    4180              :     }
    4181              : 
    4182     22618990 :     for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
    4183     19818912 :         if (!thisRadEnclosure.radReCalc) {
    4184     19641879 :             continue;
    4185              :         }
    4186       177033 :         Real64 SUM1 = 0.0;
    4187      1903624 :         for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
    4188      1726591 :             auto &surf = state.dataSurface->Surface(SurfNum);
    4189      1726591 :             int const ConstrNum = surf.Construction;
    4190      1726591 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4191      1726591 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4192      1726591 :             if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    4193      1726591 :                 SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4194              :             } else { // Switchable glazing
    4195            0 :                 SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    4196            0 :                                                      thisConstruct.InsideAbsorpThermal,
    4197            0 :                                                      state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
    4198              :             }
    4199              : 
    4200              :             // Window frame and divider effects
    4201      1726591 :             if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    4202       122286 :                 SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
    4203       122286 :                         state.dataSurface->SurfWinFrameEmis(SurfNum);
    4204              :             }
    4205      1726591 :             if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4206       121637 :                 Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
    4207              :                 // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
    4208       121637 :                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    4209           95 :                     DividerThermAbs = thisConstruct.InsideAbsorpThermal;
    4210              :                 }
    4211       121637 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4212              :                     // Interior shade or blind in place
    4213           14 :                     int const ConstrNumSh = surf.activeShadedConstruction;
    4214           14 :                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4215              : 
    4216           14 :                     if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
    4217           14 :                         auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4218              :                         // Shade layer material number
    4219           14 :                         int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
    4220           14 :                         auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
    4221           14 :                         assert(matSh != nullptr);
    4222              :                         // Shade or blind IR transmittance
    4223           14 :                         Real64 TauShIR = matSh->TransThermal;
    4224              :                         // Effective emissivity of shade or blind
    4225           14 :                         Real64 EffShDevEmiss = surfShade.effShadeEmi;
    4226              : 
    4227           14 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    4228            0 :                             TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
    4229              :                         }
    4230           14 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
    4231              :                     } else {
    4232              :                         // this is for EMS activated shade/blind but the window construction has no shade/blind layer
    4233            0 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4234              :                                 DividerThermAbs;
    4235              :                     }
    4236              :                 } else {
    4237       121623 :                     SUM1 +=
    4238       121623 :                         state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
    4239              :                 }
    4240              :             }
    4241              : 
    4242              :         } // End of loop over surfaces in zone/enclosure
    4243       177033 :         thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
    4244              : 
    4245      2800078 :     } // End of loop over enclosures
    4246      2800078 : }
    4247              : 
    4248      2800078 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
    4249              : {
    4250              : 
    4251              :     // SUBROUTINE INFORMATION:
    4252              :     //       AUTHOR         Legacy (George Walton)
    4253              :     //       DATE WRITTEN   Legacy (December 1980)
    4254              :     //       MODIFIED       Nov. 99, FW; now called every time step to account for movable
    4255              :     //                      window shades and insulation
    4256              :     //                      Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
    4257              :     //                      to ComputeIntSWAbsorpFactors
    4258              :     //                      May 00, FW; add window frame and divider effects
    4259              :     //                      June 01, FW: account for window blinds
    4260              :     //                      Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
    4261              :     //                      Jan 03, FW: add between-glass shade/blind
    4262              :     //                      May 06, RR: account for exterior window screens
    4263              : 
    4264              :     // PURPOSE OF THIS SUBROUTINE:
    4265              :     // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
    4266              :     // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
    4267              :     // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
    4268              : 
    4269              :     // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
    4270              :     // radiation absorbed by interior window shades).
    4271              : 
    4272              :     // REFERENCES:
    4273              :     // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
    4274              :     //                         From Zone Lights And Diffuse Solar.
    4275              : 
    4276              :     // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
    4277      2800078 :     Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
    4278              : 
    4279      2800078 :     auto &s_mat = state.dataMaterial;
    4280              : 
    4281     22618990 :     for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
    4282     19818912 :         if (!thisSolEnclosure.radReCalc) {
    4283     19641879 :             continue;
    4284              :         }
    4285       177033 :         Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
    4286              : 
    4287      1904148 :         for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
    4288      1727115 :             auto &thisSurf = state.dataSurface->Surface(SurfNum);
    4289      1727115 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4290      1727115 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4291      1727115 :             if (thisConstruct.TransDiff <= 0.0) {
    4292              :                 // Opaque surface
    4293      1309773 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
    4294      1309773 :                 SUM1 += thisSurf.Area * AbsIntSurf;
    4295              : 
    4296              :             } else {
    4297              :                 // Window
    4298       417342 :                 if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
    4299       411348 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4300              : 
    4301       411348 :                     Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
    4302       411348 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4303       411348 :                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    4304              : 
    4305              :                     // Sum of absorptances of glass layers
    4306       984630 :                     for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
    4307       573282 :                         Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
    4308              : 
    4309              :                         // Window with shade, screen or blind
    4310       573282 :                         if (ConstrNumSh != 0) {
    4311       269488 :                             auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4312       269488 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    4313        13665 :                                 AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
    4314       255823 :                             } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4315         8643 :                                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4316         8643 :                                 auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
    4317         8643 :                                 auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
    4318         8643 :                                 Real64 interpFac = surfShade.blind.slatAngInterpFac;
    4319         8643 :                                 AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
    4320              :                             }
    4321              :                         }
    4322              : 
    4323              :                         // Switchable glazing
    4324       573282 :                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4325            0 :                             assert(ConstrNumSh > 0); // Should this be included in the if above
    4326            0 :                             auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4327            0 :                             AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
    4328              :                         }
    4329       573282 :                         AbsDiffTotWin += AbsDiffLayWin;
    4330              :                     }
    4331              : 
    4332       411348 :                     Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
    4333       411348 :                     Real64 DiffAbsShade = 0.0;                     // Diffuse short-wave shade or blind absorptance
    4334              : 
    4335              :                     // Window with shade, screen or blind
    4336              : 
    4337       411348 :                     if (ConstrNumSh != 0) {
    4338       143733 :                         auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4339       143733 :                         if (ANY_SHADE_SCREEN(ShadeFlag)) {
    4340         7679 :                             TransDiffWin = constrSh.TransDiff;
    4341         7679 :                             DiffAbsShade = constrSh.AbsDiffBackShade;
    4342       136054 :                         } else if (ANY_BLIND(ShadeFlag)) {
    4343         8605 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4344         8605 :                             auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
    4345         8605 :                             auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
    4346         8605 :                             Real64 interpFac = surfShade.blind.slatAngInterpFac;
    4347         8605 :                             TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
    4348         8605 :                             DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
    4349              :                         }
    4350              :                     }
    4351              : 
    4352              :                     // Switchable glazing
    4353              : 
    4354       411348 :                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4355            0 :                         assert(ConstrNumSh > 0);
    4356            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4357            0 :                         TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
    4358              :                     }
    4359              : 
    4360       411348 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
    4361              : 
    4362              :                     // Window frame and divider effects (shade area is glazed area plus divider area)
    4363              : 
    4364       411348 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    4365       122286 :                         SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
    4366       122286 :                                 (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
    4367              :                     }
    4368       411348 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4369       121637 :                         Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    4370       121637 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    4371              :                             // Suspended (between-glass) divider: account for glass on inside of divider
    4372           95 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
    4373           95 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
    4374           95 :                             assert(thisMaterial != nullptr);
    4375           95 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
    4376           95 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    4377           95 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    4378           95 :                             Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
    4379           95 :                             DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    4380              :                         }
    4381       121637 :                         if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4382           14 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
    4383              :                         } else {
    4384       121623 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4385              :                                     DividerAbs;
    4386              :                         }
    4387              :                     }
    4388              :                 } else { // equivalent layer window
    4389              :                     // In equivalent layer window solid layers (Glazing and shades) are treated equally
    4390              :                     // frames and dividers are not supported
    4391         5994 :                     Real64 AbsDiffTotWin = 0.0;
    4392         5994 :                     Real64 AbsDiffLayWin = 0.0;
    4393         5994 :                     Real64 TransDiffWin = thisConstruct.TransDiff;
    4394        28000 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
    4395        22006 :                         AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
    4396        22006 :                         AbsDiffTotWin += AbsDiffLayWin;
    4397              :                     }
    4398         5994 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
    4399              :                 }
    4400              :             } // End of check if opaque surface or window
    4401              :         } // End of loop over surfaces in zone
    4402              : 
    4403       177033 :         if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
    4404       177028 :             thisSolEnclosure.solVMULT = 1.0 / SUM1;
    4405              : 
    4406              :         } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
    4407              :             // or they really want to disallow any solar from being absorbed on the inside surfaces.  Fire off a
    4408              :             // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
    4409              :             // back out whatever window is there.  Note that this also assumes that the shade has no effect.
    4410              :             // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
    4411              :             // in the zone?
    4412            5 :             if (thisSolEnclosure.solAbsFirstCalc) {
    4413            2 :                 ShowWarningError(
    4414              :                     state,
    4415            2 :                     format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
    4416            1 :                            thisSolEnclosure.Name));
    4417            1 :                 thisSolEnclosure.solAbsFirstCalc = false;
    4418              :             }
    4419            5 :             thisSolEnclosure.solVMULT = 0.0;
    4420              :         }
    4421      2800078 :     } // End of enclosure loop
    4422      2800078 : }
    4423              : 
    4424        12147 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
    4425              : {
    4426              : 
    4427              :     // SUBROUTINE INFORMATION:
    4428              :     //       MODIFIED       Jun 2007 - Lawrie - Speed enhancements.
    4429              :     //       RE-ENGINEERED  Winkelmann, Lawrie
    4430              : 
    4431              :     // PURPOSE OF THIS SUBROUTINE:
    4432              :     // This subroutine computes the diffuse solar exchange factors between enclosures with
    4433              :     // interzone windows.
    4434              : 
    4435        12147 :     int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
    4436        12147 :     if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
    4437            6 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
    4438            6 :         state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
    4439            6 :         state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
    4440              :     }
    4441              : 
    4442        12147 :     state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
    4443        12147 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
    4444        12147 :     state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
    4445              : 
    4446              :     //      IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN  ! this caused massive diffs
    4447        12147 :     if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) {
    4448           51 :         return;
    4449              :     }
    4450              :     //            Compute fraction transmitted in one pass.
    4451              : 
    4452       101664 :     for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
    4453        89568 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4454        89568 :         if (surface.ExtBoundCond <= 0) {
    4455        62496 :             continue;
    4456              :         }
    4457        27072 :         if (surface.ExtBoundCond == SurfNum) {
    4458            0 :             continue;
    4459              :         }
    4460        27072 :         if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) {
    4461            0 :             continue;
    4462              :         }
    4463              : 
    4464        27072 :         int surfEnclNum = surface.SolarEnclIndex;
    4465        27072 :         if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) {
    4466            0 :             continue;
    4467              :         }
    4468        27072 :         int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
    4469        54144 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
    4470        27072 :                                                                          state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
    4471        27072 :         if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) {
    4472        27072 :             state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
    4473              :         }
    4474        12096 :     }
    4475              :     //          Compute fractions for multiple passes.
    4476              : 
    4477        12096 :     Array2D<Real64>::size_type l(0u), m(0u), d(0u);
    4478        60480 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
    4479        48384 :         m = NZ - 1;
    4480        48384 :         Real64 D_d(0.0); // Local accumulator
    4481       241920 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
    4482       193536 :             if (MZ == NZ) {
    4483        48384 :                 continue;
    4484              :             }
    4485       145152 :             state.dataHeatBalSurfMgr->DiffuseArray[l] =
    4486       145152 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
    4487       290304 :                 (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
    4488       145152 :                            state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
    4489       145152 :             D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
    4490              :         }
    4491        48384 :         state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
    4492              :     }
    4493              : 
    4494        12096 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
    4495              :     // added for CR 7999 & 7869
    4496        12096 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
    4497        12096 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
    4498        60480 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
    4499       197568 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4500       173376 :             if (MZ == NZ) {
    4501        36288 :                 continue;
    4502              :             }
    4503       137088 :             if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
    4504        24192 :                 state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
    4505        24192 :                 break;
    4506              :             }
    4507              :         }
    4508              :     }
    4509              : 
    4510              :     //           Compute fractions for multiple zones.
    4511              : 
    4512        60480 :     for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
    4513        48384 :         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) {
    4514        24192 :             continue;
    4515              :         }
    4516              : 
    4517       120960 :         for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
    4518        96768 :             if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) {
    4519        48384 :                 continue;
    4520              :             }
    4521        48384 :             if (IZ == JZ) {
    4522        24192 :                 continue;
    4523              :             }
    4524        24192 :             if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) {
    4525            0 :                 continue;
    4526              :             }
    4527              : 
    4528       120960 :             for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
    4529        96768 :                 if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) {
    4530        48384 :                     continue;
    4531              :                 }
    4532        48384 :                 if (IZ == KZ) {
    4533        24192 :                     continue;
    4534              :                 }
    4535        24192 :                 if (JZ == KZ) {
    4536        24192 :                     continue;
    4537              :                 }
    4538            0 :                 if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) {
    4539            0 :                     continue;
    4540              :                 }
    4541            0 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
    4542            0 :                     state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4543              : 
    4544            0 :                 for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
    4545            0 :                     if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) {
    4546            0 :                         continue;
    4547              :                     }
    4548            0 :                     if (IZ == LZ) {
    4549            0 :                         continue;
    4550              :                     }
    4551            0 :                     if (JZ == LZ) {
    4552            0 :                         continue;
    4553              :                     }
    4554            0 :                     if (KZ == LZ) {
    4555            0 :                         continue;
    4556              :                     }
    4557            0 :                     if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) {
    4558            0 :                         continue;
    4559              :                     }
    4560            0 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4561            0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
    4562            0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4563              : 
    4564            0 :                     for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4565            0 :                         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) {
    4566            0 :                             continue;
    4567              :                         }
    4568            0 :                         if (IZ == MZ) {
    4569            0 :                             continue;
    4570              :                         }
    4571            0 :                         if (JZ == MZ) {
    4572            0 :                             continue;
    4573              :                         }
    4574            0 :                         if (KZ == MZ) {
    4575            0 :                             continue;
    4576              :                         }
    4577            0 :                         if (LZ == MZ) {
    4578            0 :                             continue;
    4579              :                         }
    4580            0 :                         if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) {
    4581            0 :                             continue;
    4582              :                         }
    4583            0 :                         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
    4584            0 :                             state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4585            0 :                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4586              :                     } // MZ Loop
    4587              : 
    4588              :                 } // LZ Loop
    4589              : 
    4590              :             } // KZ Loop
    4591              : 
    4592              :         } // JZ Loop
    4593              : 
    4594              :     } // IZ Loop
    4595              : } // ComputeDifSolExcZoneWIZWindows()
    4596              : 
    4597       419548 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
    4598              : {
    4599              : 
    4600              :     // SUBROUTINE INFORMATION:
    4601              :     //       AUTHOR         B. Griffith
    4602              :     //       DATE WRITTEN   April 2011
    4603              : 
    4604              :     // PURPOSE OF THIS SUBROUTINE:
    4605              :     // initialize material and construction surface properties if being overridden by EMS
    4606              : 
    4607              :     // METHODOLOGY EMPLOYED:
    4608              :     // update solar, thermal and visible absorptance values when actuated by EMS
    4609              : 
    4610              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4611              :     int TotLayers;       // count of material layers in a construction
    4612              :     int InsideMaterNum;  // integer pointer for inside face's material layer
    4613              :     int OutsideMaterNum; // integer pointer for outside face's material layer
    4614              : 
    4615       419548 :     auto &s_mat = state.dataMaterial;
    4616              : 
    4617       419548 :     state.dataGlobal->AnySurfPropOverridesInModel = false;
    4618              :     // first determine if anything needs to be done, once yes, then always init
    4619      9337604 :     for (auto const *mat : s_mat->materials) {
    4620      8918056 :         if (mat->group != Material::Group::Regular) {
    4621      1221929 :             continue;
    4622              :         }
    4623              : 
    4624      7696127 :         if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
    4625            0 :             state.dataGlobal->AnySurfPropOverridesInModel = true;
    4626            0 :             break;
    4627              :         }
    4628              :     }
    4629              : 
    4630       419548 :     if (!state.dataGlobal->AnySurfPropOverridesInModel) {
    4631       419548 :         return; // quick return if nothing has ever needed to be done
    4632              :     }
    4633              : 
    4634              :     // first, loop over materials
    4635              :     // why is this a second loop?
    4636            0 :     for (auto *mat : s_mat->materials) {
    4637            0 :         if (mat->group != Material::Group::Regular) {
    4638            0 :             continue;
    4639              :         }
    4640              : 
    4641            0 :         mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
    4642            0 :         mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
    4643            0 :         mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
    4644              :     } // loop over materials
    4645              : 
    4646              :     // second, loop over constructions
    4647            0 :     for (auto &thisConstruct : state.dataConstruction->Construct) {
    4648            0 :         if (thisConstruct.TypeIsWindow) {
    4649            0 :             continue; // only override opaque constructions
    4650              :         }
    4651            0 :         TotLayers = thisConstruct.TotLayers;
    4652            0 :         if (TotLayers == 0) {
    4653            0 :             continue; // error condition
    4654              :         }
    4655            0 :         InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
    4656            0 :         if (InsideMaterNum != 0) {
    4657            0 :             auto const *mat = s_mat->materials(InsideMaterNum);
    4658            0 :             thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
    4659            0 :             thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
    4660            0 :             thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
    4661              :         }
    4662              : 
    4663            0 :         OutsideMaterNum = thisConstruct.LayerPoint(1);
    4664            0 :         if (OutsideMaterNum != 0) {
    4665            0 :             auto const *mat = s_mat->materials(OutsideMaterNum);
    4666            0 :             thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
    4667            0 :             thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
    4668            0 :             thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
    4669              :         }
    4670              :     } // for (ConstrNum)
    4671              : } // InitEMSControlledSurfaceProperties()
    4672              : 
    4673       419548 : void InitEMSControlledConstructions(EnergyPlusData &state)
    4674              : {
    4675              : 
    4676              :     // SUBROUTINE INFORMATION:
    4677              :     //       AUTHOR         B. Griffith
    4678              :     //       DATE WRITTEN   Jan 2012
    4679              : 
    4680              :     // PURPOSE OF THIS SUBROUTINE:
    4681              :     // change construction on surface if overridden by EMS
    4682              : 
    4683       419548 :     state.dataGlobal->AnyConstrOverridesInModel = false;
    4684     45096650 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4685     44683161 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
    4686         6059 :             state.dataGlobal->AnyConstrOverridesInModel = true;
    4687         6059 :             break;
    4688              :         }
    4689              :     }
    4690       419548 :     if (!state.dataGlobal->AnyConstrOverridesInModel) {
    4691       413489 :         return;
    4692              :     }
    4693              : 
    4694       424130 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4695       418071 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4696              : 
    4697       418071 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
    4698              : 
    4699         6059 :             if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4700         6059 :                     .TypeIsWindow) { // okay, always allow windows
    4701         6059 :                 state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4702         6059 :                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4703              :             }
    4704              : 
    4705        12118 :             if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
    4706         6059 :                 (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
    4707              : 
    4708         6059 :                 surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4709         6059 :                 state.dataConstruction->Construct(surface.Construction).IsUsed = true;
    4710         6059 :                 state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4711              : 
    4712              :             } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
    4713            0 :                 if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
    4714              :                     // check if constructions appear compatible
    4715              : 
    4716            0 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    4717            0 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    4718              :                         // compare old construction to new construction and see if terms match
    4719              :                         // set as okay and turn false if find a big problem
    4720            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4721              :                             true;
    4722            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4723              :                             true;
    4724            0 :                         if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
    4725            0 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
    4726              :                             // throw warning, but allow
    4727            0 :                             ShowWarningError(state,
    4728              :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4729              :                                              "CTF timescales are being used.");
    4730            0 :                             ShowContinueError(state,
    4731            0 :                                               format("Construction named = {} has CTF timesteps = {}",
    4732            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4733            0 :                                                      state.dataConstruction->Construct(surface.Construction).NumHistories));
    4734            0 :                             ShowContinueError(
    4735              :                                 state,
    4736            0 :                                 format("While construction named = {} has CTF timesteps = {}",
    4737            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4738            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
    4739            0 :                             ShowContinueError(
    4740              :                                 state,
    4741            0 :                                 format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
    4742            0 :                                        surface.Name));
    4743              :                         }
    4744            0 :                         if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
    4745            0 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
    4746              :                             // throw warning, but allow
    4747            0 :                             ShowWarningError(state,
    4748              :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4749              :                                              "CTF terms are being used.");
    4750            0 :                             ShowContinueError(state,
    4751            0 :                                               format("Construction named = {} has number of CTF terms = {}",
    4752            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4753            0 :                                                      state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
    4754            0 :                             ShowContinueError(
    4755              :                                 state,
    4756            0 :                                 format("While construction named = {} has number of CTF terms = {}",
    4757            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4758            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
    4759            0 :                             ShowContinueError(state,
    4760            0 :                                               format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
    4761              :                                                      "name = {}, and the simulation continues",
    4762            0 :                                                      surface.Name));
    4763              :                         }
    4764              : 
    4765            0 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4766            0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4767              :                                 // throw warning, and do not allow
    4768            0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4769            0 :                                 ShowContinueError(state,
    4770            0 :                                                   format("Construction named = {} has internal source/sink",
    4771            0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4772            0 :                                 ShowContinueError(
    4773              :                                     state,
    4774            0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4775            0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4776            0 :                                 ShowContinueError(
    4777              :                                     state,
    4778            0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4779            0 :                                            surface.Name));
    4780              : 
    4781            0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4782            0 :                                                                                   SurfNum) = false;
    4783              :                             }
    4784              :                         }
    4785              : 
    4786            0 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4787              :                                                                               SurfNum)) {
    4788            0 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4789              :                         }
    4790              : 
    4791            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    4792            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4793              :                             true;
    4794            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4795              :                             true;
    4796            0 :                         if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
    4797            0 :                             state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
    4798              :                             // throw warning, and do not allow
    4799            0 :                             ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4800            0 :                             ShowContinueError(state,
    4801            0 :                                               format("Construction named = {} has number of finite difference nodes ={}",
    4802            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4803            0 :                                                      state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
    4804            0 :                             ShowContinueError(
    4805              :                                 state,
    4806            0 :                                 format("While construction named = {}has number of finite difference nodes ={}",
    4807            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4808            0 :                                        state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4809            0 :                                            .TotNodes));
    4810            0 :                             ShowContinueError(
    4811              :                                 state,
    4812            0 :                                 format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4813            0 :                                        surface.Name));
    4814              : 
    4815            0 :                             state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4816              :                                 false;
    4817              :                         }
    4818              : 
    4819            0 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4820            0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4821              :                                 // throw warning, and do not allow
    4822            0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4823            0 :                                 ShowContinueError(state,
    4824            0 :                                                   format("Construction named = {} has internal source/sink",
    4825            0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4826            0 :                                 ShowContinueError(
    4827              :                                     state,
    4828            0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4829            0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4830            0 :                                 ShowContinueError(
    4831              :                                     state,
    4832            0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4833            0 :                                            surface.Name));
    4834              : 
    4835            0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4836            0 :                                                                                   SurfNum) = false;
    4837              :                             }
    4838              :                         }
    4839              : 
    4840            0 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4841              :                                                                               SurfNum)) {
    4842            0 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4843              :                         }
    4844              : 
    4845            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
    4846            0 :                         ShowSevereError(state,
    4847              :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
    4848              :                                         "algorithm CombinedHeatAndMoistureFiniteElement.");
    4849            0 :                         ShowContinueError(
    4850              :                             state,
    4851            0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4852            0 :                                    surface.Name));
    4853            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4854              :                             true;
    4855            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4856              :                             false;
    4857              : 
    4858            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
    4859            0 :                         ShowSevereError(state,
    4860              :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
    4861              :                                         "Foundation Outside Boundary Condition.");
    4862            0 :                         ShowContinueError(
    4863              :                             state,
    4864            0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4865            0 :                                    surface.Name));
    4866            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4867              :                             true;
    4868            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4869              :                             false;
    4870              :                     }
    4871              : 
    4872              :                 } else {
    4873              :                     // do nothing, has been checked and is not okay with single warning already issued.
    4874              :                 }
    4875              :             }
    4876              :         } else {
    4877       412012 :             surface.Construction = surface.ConstructionStoredInputValue;
    4878       412012 :             state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
    4879              :         }
    4880              :     } // for (SurfNum)
    4881              : } // InitEMSControlledConstructions()
    4882              : 
    4883              : // End Initialization Section of the Module
    4884              : //******************************************************************************
    4885              : 
    4886              : // Begin Algorithm Section of the Module
    4887              : //******************************************************************************
    4888              : 
    4889              : // Beginning of Record Keeping subroutines for the HB Module
    4890              : // *****************************************************************************
    4891              : 
    4892      3732214 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4893              : {
    4894      3732214 :     int firstZone = 1;
    4895      3732214 :     int lastZone = state.dataGlobal->NumOfZones;
    4896              : 
    4897      3732214 :     if (present(ZoneToResimulate)) {
    4898       796099 :         firstZone = ZoneToResimulate;
    4899       796099 :         lastZone = ZoneToResimulate;
    4900              :     }
    4901              : 
    4902     24954457 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4903     42493086 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4904     21270843 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4905     21270843 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    4906     21270843 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    4907     44623294 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4908     23352451 :                 if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
    4909     23321209 :                     state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
    4910              :                 }
    4911              :             }
    4912              :             // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
    4913     21270843 :             if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
    4914     12739695 :                 state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4915     12739695 :                 state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
    4916     12739695 :                     state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4917              :             } else {
    4918      8531148 :                 state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4919      8531148 :                 state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
    4920      8531148 :                     state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4921              :             }
    4922     21222243 :         }
    4923              :     }
    4924              : 
    4925      3732214 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    4926          342 :         UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
    4927              :     }
    4928              : 
    4929              :     // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
    4930     24954457 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4931     42493086 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4932     21270843 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4933     21270843 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    4934     21270843 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    4935    201679567 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4936    180408724 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
    4937    180408724 :                     -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4938    180408724 :                     (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4939              :             }
    4940     21222243 :         }
    4941              :     }
    4942              :     // Opaque surfaces
    4943     24954457 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4944     42493086 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4945     21270843 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4946     21270843 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    4947     21270843 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    4948    178327116 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4949    157056273 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
    4950    157056273 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
    4951              :             }
    4952     21222243 :         }
    4953              :     }
    4954              :     // Inside face conduction calculation for Kiva surfaces
    4955      3850474 :     for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
    4956       118260 :         state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
    4957       118260 :             -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    4958       118260 :               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    4959       118260 :               state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
    4960      3732214 :     }
    4961      3732214 : }
    4962              : 
    4963          342 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4964              : {
    4965          342 :     int firstZone = 1;
    4966          342 :     int lastZone = state.dataGlobal->NumOfZones;
    4967              : 
    4968          342 :     if (present(ZoneToResimulate)) {
    4969            0 :         firstZone = ZoneToResimulate;
    4970            0 :         lastZone = ZoneToResimulate;
    4971              :     }
    4972              : 
    4973        16074 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4974        31464 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4975        15732 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4976              :             // Heat transfer surfaces
    4977        15732 :             int firstSurf = thisSpace.HTSurfaceFirst;
    4978        15732 :             int lastSurf = thisSpace.HTSurfaceLast;
    4979       213750 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4980       198018 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    4981       198018 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    4982              : 
    4983       198018 :                 if (surfNum != repSurfNum) {
    4984              : #if 0
    4985              :                 // Check for divergence
    4986              :                 Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4987              :                                   (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4988              :                 Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
    4989              :                                      (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
    4990              :                 Real64 diff = surfConv - repSurfConv;
    4991              :                 if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
    4992              :                     ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
    4993              :                     ShowContinueErrorTimeStamp(state, "");
    4994              :                     ShowContinueError(state, format("  Original Surface: {}", surface.Name));
    4995              :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
    4996              :                     ShowContinueError(state,
    4997              :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    4998              :                     ShowContinueError(state,
    4999              :                                       format("    Sunlit fraction: {:.3R}",
    5000              :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
    5001              :                     ShowContinueError(state, format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
    5002              :                     ShowContinueError(state,
    5003              :                                       format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
    5004              :                     ShowContinueError(state, format("  Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
    5005              :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
    5006              :                     ShowContinueError(state,
    5007              :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
    5008              :                     ShowContinueError(state,
    5009              :                                       format("    Sunlit fraction: {:.3R}",
    5010              :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
    5011              :                     ShowContinueError(state,
    5012              :                                       format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
    5013              :                     ShowContinueError(
    5014              :                         state, format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
    5015              :                 }
    5016              : #endif
    5017              : 
    5018              :                     // Surface Heat Balance Arrays
    5019        44802 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
    5020        44802 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
    5021        44802 :                     state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
    5022        44802 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
    5023        44802 :                     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
    5024        44802 :                     state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
    5025        44802 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
    5026              : 
    5027        44802 :                     state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
    5028        44802 :                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
    5029        44802 :                     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
    5030        44802 :                     state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
    5031        44802 :                     state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
    5032        44802 :                     state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
    5033              : 
    5034        44802 :                     state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
    5035        44802 :                     if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
    5036            0 :                         state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
    5037              :                     }
    5038              : 
    5039        44802 :                     state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
    5040        44802 :                     state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
    5041              : 
    5042        44802 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    5043        44802 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
    5044        44802 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
    5045        44802 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
    5046              : 
    5047              :                     // Internal (non reporting variables)
    5048        44802 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
    5049        44802 :                     state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
    5050              :                 }
    5051              :             }
    5052              : 
    5053              :             // Opaque surfaces
    5054        15732 :             firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    5055        15732 :             lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    5056       152874 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    5057       137142 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    5058       137142 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    5059              : 
    5060       137142 :                 if (surfNum != repSurfNum) {
    5061              :                     // Surface Heat Balance Arrays
    5062         5814 :                     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
    5063         5814 :                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
    5064         5814 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
    5065              :                 }
    5066              :             }
    5067              : 
    5068              :             // Window surfaces
    5069        15732 :             firstSurf = thisSpace.WindowSurfaceFirst;
    5070        15732 :             lastSurf = thisSpace.WindowSurfaceLast;
    5071        76608 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    5072        60876 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    5073        60876 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    5074              : 
    5075        60876 :                 if (surfNum != repSurfNum) {
    5076        38988 :                     Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    5077              : 
    5078              :                     // Glazing
    5079        38988 :                     state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    5080        38988 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    5081        38988 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    5082              : 
    5083              :                     // Frame
    5084        38988 :                     Real64 frameHeatGain = 0.0;
    5085        38988 :                     if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    5086            0 :                         Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
    5087            0 :                         state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
    5088            0 :                         state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
    5089            0 :                         state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
    5090            0 :                         state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
    5091            0 :                         frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
    5092              :                     }
    5093              : 
    5094              :                     // Divider
    5095        38988 :                     Real64 dividerHeatGain = 0.0;
    5096        38988 :                     if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    5097            0 :                         Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
    5098            0 :                         state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
    5099            0 :                         state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
    5100            0 :                         state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
    5101            0 :                         state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
    5102            0 :                         dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
    5103              :                     }
    5104              : 
    5105        38988 :                     state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
    5106              : 
    5107              :                     // Whole window
    5108        77976 :                     state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
    5109        38988 :                                                                    state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
    5110        38988 :                                                                   state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
    5111              :                 }
    5112              :             }
    5113        15732 :         }
    5114              :     }
    5115          342 : }
    5116              : 
    5117      2799877 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
    5118              : {
    5119              : 
    5120              :     // SUBROUTINE INFORMATION:
    5121              :     //       AUTHOR         Rick Strand
    5122              :     //       DATE WRITTEN   December 2000
    5123              : 
    5124              :     // PURPOSE OF THIS SUBROUTINE:
    5125              :     // If a radiant system is present and was on for part of the time step,
    5126              :     // then we probably need to make yet another pass through the heat balance.
    5127              :     // This is necessary because the heat source/sink to the surface that is
    5128              :     // the radiant system may have varied during the system time steps.
    5129              : 
    5130              :     // METHODOLOGY EMPLOYED:
    5131              :     // First, determine whether or not the radiant system was running.  If
    5132              :     // any of the Qsource terms are non-zero, then it was running.  Then,
    5133              :     // update the current source terms with the "average" value calculated
    5134              :     // by the radiant system algorithm.  This requires the "USE" of the
    5135              :     // radiant algorithm module.  Finally, using this source value, redo
    5136              :     // the inside and outside heat balances.
    5137              : 
    5138              :     bool LowTempRadSysOn;     // .TRUE. if a low temperature radiant system is running
    5139              :     bool HighTempRadSysOn;    // .TRUE. if a high temperature radiant system is running
    5140              :     bool HWBaseboardSysOn;    // .TRUE. if a water baseboard heater is running
    5141              :     bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
    5142              :     bool ElecBaseboardSysOn;  // .TRUE. if a steam baseboard heater is running
    5143              :     bool CoolingPanelSysOn;   // true if a simple cooling panel is running
    5144              :     bool SwimmingPoolOn;      // true if a pool is present (running)
    5145              : 
    5146      2799877 :     LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
    5147      2799877 :     HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
    5148      2799877 :     HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
    5149      2799877 :     SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
    5150      2799877 :     ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
    5151      2799877 :     CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
    5152      2799877 :     SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
    5153              : 
    5154      2799877 :     if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
    5155              :         // Solve the zone heat balance 'Detailed' solution
    5156              :         // Call the outside and inside surface heat balances
    5157        82564 :         CalcHeatBalanceOutsideSurf(state);
    5158        82564 :         CalcHeatBalanceInsideSurf(state);
    5159              :     }
    5160      2799877 : }
    5161              : 
    5162      2624518 : void UpdateThermalHistories(EnergyPlusData &state)
    5163              : {
    5164              : 
    5165              :     // SUBROUTINE INFORMATION:
    5166              :     //       AUTHOR         Russ Taylor
    5167              :     //       DATE WRITTEN   June 1990
    5168              :     //       RE-ENGINEERED  Mar98 (RKS)
    5169              : 
    5170              :     // PURPOSE OF THIS SUBROUTINE:
    5171              :     // This subroutine updates and shifts the thermal and flux histories.
    5172              : 
    5173              :     // METHODOLOGY EMPLOYED:
    5174              :     // If a surface runs on the user selected subhourly time step, then the
    5175              :     // history terms for the temperatures and fluxes must simply be updated
    5176              :     // and shifted.  However, if the surface runs at a different (longer) time
    5177              :     // step, then the "master" history series is used for the interpolated
    5178              :     // update scheme.
    5179              : 
    5180              :     // REFERENCES:
    5181              :     // (I)BLAST legacy routine UTHRMH
    5182              :     // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
    5183              :     // Mechanical Systems in Heat Balance Based Energy Analysis Programs
    5184              :     // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
    5185              : 
    5186      2624518 :     if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
    5187          790 :         state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5188          790 :         state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5189          790 :         state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5190          790 :         state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5191          790 :         state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
    5192          790 :         if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5193           31 :             state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5194           31 :             state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5195           31 :             state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5196              :         }
    5197          790 :         state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
    5198              :     }
    5199              : 
    5200     22163257 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5201     39126078 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5202     19587339 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5203     19587339 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5204     19587339 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5205    165433320 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5206              :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5207    145845981 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5208              : 
    5209    145845981 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5210       288450 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5211       138432 :                     continue;
    5212              :                 }
    5213              : 
    5214    145707549 :                 int const ConstrNum = surface.Construction;
    5215    145707549 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5216              : 
    5217    145707549 :                 if (construct.NumCTFTerms == 0) {
    5218            0 :                     continue; // Skip surfaces with no history terms
    5219              :                 }
    5220              : 
    5221              :                 // Sign convention for the various terms in the following two equations
    5222              :                 // is based on the form of the Conduction Transfer Function equation
    5223              :                 // given by:
    5224              :                 // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
    5225              :                 // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
    5226              :                 // In both equations, flux is positive from outside to inside.  The V and W terms are for radiant systems only.
    5227              : 
    5228              :                 // Set current inside flux:
    5229    145707549 :                 Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5230    145707549 :                 Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
    5231    145707549 :                                                 state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
    5232    145707549 :                                                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
    5233              :                 // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
    5234              :                 // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
    5235              :                 // redundant.
    5236    145707549 :                 if (construct.SourceSinkPresent) {
    5237       397692 :                     SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
    5238              :                 }
    5239    145707549 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
    5240    145707549 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
    5241    145707549 :                 state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
    5242              : 
    5243              :                 // Update the temperature at the source/sink location (if one is present)
    5244    145707549 :                 if (construct.SourceSinkPresent) {
    5245       397692 :                     state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
    5246       397692 :                         SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
    5247       397692 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
    5248       397692 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    5249       397692 :                     state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
    5250       397692 :                         SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
    5251       397692 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
    5252       397692 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
    5253              :                 }
    5254              : 
    5255              :                 // Set current outside flux:
    5256    145707549 :                 if (construct.SourceSinkPresent) {
    5257       397692 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
    5258       397692 :                         SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5259       397692 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
    5260       397692 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
    5261              :                 } else {
    5262    290619714 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
    5263    145309857 :                                                                              state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5264    145309857 :                                                                              state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
    5265              :                 }
    5266              :                 // switch sign for balance at outside face
    5267    145707549 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5268    145707549 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
    5269              :             }
    5270     19538739 :         }
    5271              :     } // ...end of loop over all (heat transfer) surfaces...
    5272              : 
    5273      2624518 :     if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
    5274              :         // Temporarily save the rvalue references of the last term arrays
    5275      2161746 :         Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5276      2161746 :         Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5277      2161746 :         Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5278      2161746 :         Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5279              :         // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
    5280     19289358 :         for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
    5281     17127612 :             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
    5282     17127612 :             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
    5283     17127612 :             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
    5284     17127612 :             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
    5285              :         }
    5286              :         // Reuse the pointers of the last term arrays for the second term arrays
    5287      2161746 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
    5288      2161746 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
    5289      2161746 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
    5290      2161746 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
    5291              :         // 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)
    5292      2161746 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
    5293      2161746 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
    5294      2161746 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
    5295      2161746 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
    5296      2161746 :         return;
    5297      2161746 :     }
    5298              : 
    5299      3581182 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5300      6253020 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5301      3134610 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5302      3134610 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5303      3134610 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5304     26009661 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5305     22875051 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5306              :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5307     22875051 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5308            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5309            0 :                     continue;
    5310              :                 }
    5311     22875051 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5312     19144611 :                     state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5313     19144611 :                     state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    5314     19144611 :                     state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5315     19144611 :                     state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
    5316              :                 }
    5317              :             }
    5318      3118410 :         }
    5319              : 
    5320              :     } // ...end of loop over all (heat transfer) surfaces...
    5321       462772 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5322       431634 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5323       653526 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5324       326763 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5325       326763 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5326       326763 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5327      2540337 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5328      2213574 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5329              :                     // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5330      2213574 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5331            0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5332            0 :                         continue;
    5333              :                     }
    5334      2213574 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5335      2201448 :                         state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
    5336      2201448 :                         state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
    5337      2201448 :                         state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
    5338              :                     }
    5339              :                 }
    5340       326763 :             }
    5341              :         } // ...end of loop over all (heat transfer) surfaces...
    5342              :     }
    5343              : 
    5344              :     // SHIFT TEMPERATURE AND FLUX HISTORIES:
    5345              :     // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
    5346      3581182 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5347      6253020 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5348      3134610 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5349      3134610 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5350      3134610 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5351     26009661 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5352     22875051 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5353              : 
    5354     22875051 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5355            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5356            0 :                     continue;
    5357              :                 }
    5358              : 
    5359     22875051 :                 int const ConstrNum = surface.Construction;
    5360     22875051 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5361              : 
    5362     22875051 :                 ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
    5363     22875051 :                 state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
    5364              : 
    5365     22875051 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
    5366     19142399 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    5367              : 
    5368     19142399 :                     if (construct.NumCTFTerms > 1) {
    5369     18915644 :                         int const numCTFTerms(construct.NumCTFTerms);
    5370    150295692 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5371    131380048 :                             state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
    5372    131380048 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5373    131380048 :                             state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
    5374    131380048 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5375    131380048 :                             state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
    5376    131380048 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5377    131380048 :                             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
    5378    131380048 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5379    131380048 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
    5380    131380048 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5381    131380048 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
    5382    131380048 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5383    131380048 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
    5384    131380048 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5385    131380048 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
    5386    131380048 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5387              :                         }
    5388              :                     }
    5389              : 
    5390     19142399 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
    5391     19142399 :                     state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
    5392     19142399 :                     state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
    5393     19142399 :                     state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
    5394              : 
    5395     19142399 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
    5396     19142399 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
    5397     19142399 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
    5398     19142399 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
    5399              :                 } else {
    5400      3732652 :                     Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5401      3732652 :                     if (construct.NumCTFTerms > 1) {
    5402      3732652 :                         int const numCTFTerms(construct.NumCTFTerms);
    5403     53391610 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5404              :                             // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
    5405              :                             //                                 (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
    5406     49658958 :                             Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
    5407     49658958 :                             Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
    5408     49658958 :                             Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5409     49658958 :                             Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5410     49658958 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
    5411     49658958 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
    5412              : 
    5413     49658958 :                             Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
    5414     49658958 :                             Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
    5415     49658958 :                             Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5416     49658958 :                             Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5417     49658958 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
    5418     49658958 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
    5419              :                         }
    5420              :                     }
    5421              :                     // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
    5422      3732652 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
    5423      3732652 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
    5424      3732652 :                         (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
    5425      3732652 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
    5426      3732652 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
    5427      3732652 :                         (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
    5428      3732652 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
    5429      3732652 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
    5430      3732652 :                         (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
    5431      3732652 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
    5432      3732652 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
    5433      3732652 :                         (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
    5434              :                 }
    5435              :             }
    5436      3118410 :         }
    5437              :     } // ...end of loop over all (heat transfer) surfaces
    5438              : 
    5439       462772 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5440       431634 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5441       653526 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5442       326763 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5443       326763 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5444       326763 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5445      2540337 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5446      2213574 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5447      2213574 :                     int const ConstrNum = surface.Construction;
    5448      2213574 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5449      2213574 :                     if (!construct.SourceSinkPresent) {
    5450      1815882 :                         continue;
    5451              :                     }
    5452       397692 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5453            0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5454            0 :                         continue;
    5455              :                     }
    5456              : 
    5457       397692 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5458       385536 :                         if (construct.NumCTFTerms > 1) {
    5459       385536 :                             int const numCTFTerms = construct.NumCTFTerms;
    5460       385536 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5461       385536 :                             int m1 = m + 1;
    5462      3820314 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
    5463              :                                 // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
    5464              :                                 // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
    5465              :                                 // 1 );
    5466      3434778 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
    5467      3434778 :                                     state.dataHeatBalSurf->SurfTsrcHistM[m];
    5468      3434778 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
    5469      3434778 :                                     state.dataHeatBalSurf->SurfQsrcHistM[m];
    5470      3434778 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
    5471      3434778 :                                     state.dataHeatBalSurf->SurfTuserHistM[m];
    5472              :                             }
    5473              :                         }
    5474       385536 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
    5475       385536 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
    5476       385536 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
    5477       385536 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
    5478       385536 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
    5479       385536 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
    5480              :                     } else {
    5481        12156 :                         Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5482              : 
    5483        12156 :                         if (construct.NumCTFTerms > 1) {
    5484        12156 :                             int const numCTFTerms = construct.NumCTFTerms;
    5485        12156 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5486        12156 :                             int m1 = m + 1;
    5487       158028 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
    5488              :                                 // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
    5489              :                                 // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
    5490              :                                 // HistTermNum
    5491              :                                 // - 1 ) ) * sum_steps;  Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) );  SurfQsrcHist( SurfNum,
    5492              :                                 // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
    5493       145872 :                                 Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
    5494       145872 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] =
    5495       145872 :                                     TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
    5496       145872 :                                 Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
    5497       145872 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] =
    5498       145872 :                                     QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
    5499       145872 :                                 Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
    5500       145872 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] =
    5501       145872 :                                     TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
    5502              :                             }
    5503              :                         }
    5504              :                         // Tuned Linear indexing
    5505              :                         // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
    5506              :                         // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
    5507        12156 :                         int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
    5508        12156 :                         state.dataHeatBalSurf->SurfTsrcHist[l2] =
    5509        12156 :                             state.dataHeatBalSurf->SurfTsrcHistM[l2] -
    5510        12156 :                             (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
    5511        12156 :                         state.dataHeatBalSurf->SurfQsrcHist[l2] =
    5512        12156 :                             state.dataHeatBalSurf->SurfQsrcHistM[l2] -
    5513        12156 :                             (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
    5514        12156 :                         state.dataHeatBalSurf->SurfTuserHist[l2] =
    5515        12156 :                             state.dataHeatBalSurf->SurfTuserHistM[l2] -
    5516        12156 :                             (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
    5517              :                     }
    5518              :                 }
    5519       326763 :             }
    5520              :         } // ...end of loop over all (heat transfer) surfaces...
    5521              :     } // ...end of AnyInternalHeatSourceInInput
    5522              : }
    5523              : 
    5524      3732214 : void CalculateZoneMRT(EnergyPlusData &state,
    5525              :                       ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    5526              : {
    5527              : 
    5528              :     // SUBROUTINE INFORMATION:
    5529              :     //       AUTHOR         Rick Strand
    5530              :     //       DATE WRITTEN   November 2000
    5531              : 
    5532              :     // PURPOSE OF THIS SUBROUTINE:
    5533              :     // Calculates the current zone and enclosure MRT for thermal comfort and radiation
    5534              :     // calculation purposes.
    5535              : 
    5536      3732214 :     if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5537          803 :         state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
    5538          803 :         state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
    5539          803 :         state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
    5540          803 :         state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
    5541         6009 :         for (auto &encl : state.dataViewFactor->EnclRadInfo) {
    5542         5206 :             encl.sumAE = 0.0;
    5543          803 :         }
    5544        48135 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5545        47332 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    5546        47332 :             if (surface.HeatTransSurf) {
    5547        45625 :                 auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
    5548        45625 :                 thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
    5549        45625 :                 int ZoneNum = surface.Zone;
    5550        45625 :                 if (ZoneNum > 0) {
    5551        45624 :                     state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
    5552              :                 }
    5553        45625 :                 if (surface.RadEnclIndex > 0) {
    5554        45624 :                     state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
    5555              :                 }
    5556              :             }
    5557              :         }
    5558              :     }
    5559              : 
    5560              :     // Zero sumAET for applicable enclosures
    5561      3732214 :     if (present(ZoneToResimulate)) {
    5562      1592198 :         for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
    5563       796099 :             int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
    5564       796099 :             state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
    5565       796099 :             state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
    5566       796099 :         }
    5567              :     } else {
    5568     23358215 :         for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5569     20422100 :             thisEnclosure.reCalcMRT = true;
    5570      2936115 :         }
    5571              :     }
    5572     26930699 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5573     23198485 :         if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) {
    5574      1976242 :             continue;
    5575              :         }
    5576     21222243 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    5577     21222243 :         if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
    5578     21220218 :             Real64 zoneSumAET = 0.0;
    5579     42489036 :             for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
    5580     21268818 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5581    201669442 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    5582    180400624 :                     Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
    5583    180400624 :                     zoneSumAET += surfAET;
    5584    180400624 :                     state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
    5585              :                 }
    5586     21220218 :             }
    5587     21220218 :             thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
    5588              :         } else {
    5589         2025 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5590            2 :                 ShowWarningError(
    5591              :                     state,
    5592            2 :                     format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
    5593            3 :                 ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
    5594              :             }
    5595         2025 :             thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    5596              :         }
    5597              :     }
    5598              :     // Calculate MRT for applicable enclosures
    5599     26926655 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5600     23194441 :         if (!thisEnclosure.reCalcMRT) {
    5601            0 :             continue;
    5602              :         }
    5603     23194441 :         if (thisEnclosure.sumAE > 0.01) {
    5604     23192416 :             thisEnclosure.sumAET = 0.0;
    5605    218005217 :             for (int surfNum : thisEnclosure.SurfacePtr) {
    5606    194812801 :                 Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
    5607    194812801 :                 thisEnclosure.sumAET += surfAET;
    5608              :             }
    5609     23192416 :             thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
    5610              :         } else {
    5611         2025 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5612            2 :                 ShowWarningError(state,
    5613            2 :                                  format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
    5614            3 :                 ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
    5615              :             }
    5616         2025 :             Real64 sumMATVol = 0.0;
    5617         2025 :             Real64 sumVol = 0.0;
    5618         2025 :             Real64 sumMAT = 0.0;
    5619         4050 :             for (auto &spaceNum : thisEnclosure.spaceNums) {
    5620         2025 :                 Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
    5621         2025 :                 Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
    5622         2025 :                 sumVol += spaceVolume;
    5623         2025 :                 sumMATVol += spaceMAT * spaceVolume;
    5624         2025 :                 sumMAT += spaceMAT;
    5625         2025 :             }
    5626         2025 :             if (sumVol > 0.01) {
    5627         2025 :                 thisEnclosure.MRT = sumMATVol / sumVol;
    5628              :             } else {
    5629            0 :                 thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
    5630              :             }
    5631              :         }
    5632              :         // Set space MRTs
    5633     46441526 :         for (int spaceNum : thisEnclosure.spaceNums) {
    5634     23247085 :             state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
    5635     23194441 :         }
    5636      3732214 :     }
    5637              : 
    5638      3732214 :     state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
    5639      3732214 : }
    5640              : 
    5641              : // End of Record Keeping subroutines for the HB Module
    5642              : // *****************************************************************************
    5643              : 
    5644              : // Beginning of Reporting subroutines for the HB Module
    5645              : // *****************************************************************************
    5646              : 
    5647      2799877 : void CalcThermalResilience(EnergyPlusData &state)
    5648              : {
    5649              :     // This function calculate timestep-wise heat index and humidex.
    5650              : 
    5651              :     // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
    5652              :     // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
    5653              :     // Technical Attachment (SR 90-23).
    5654              :     // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
    5655              : 
    5656              :     // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
    5657              :     // Canada's Atmospheric Environment Service in 1979.
    5658              :     // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
    5659              :     // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
    5660              :     //        using OutputProcessor::ReqRepVars;
    5661      2799877 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
    5662         6010 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5663        10414 :             SetupOutputVariable(state,
    5664              :                                 "Zone Heat Index",
    5665              :                                 Constant::Units::C,
    5666         5207 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
    5667              :                                 OutputProcessor::TimeStepType::Zone,
    5668              :                                 OutputProcessor::StoreType::Average,
    5669         5207 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5670        10414 :             SetupOutputVariable(state,
    5671              :                                 "Zone Humidity Index",
    5672              :                                 Constant::Units::None,
    5673         5207 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
    5674              :                                 OutputProcessor::TimeStepType::Zone,
    5675              :                                 OutputProcessor::StoreType::Average,
    5676         5207 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5677              :         }
    5678        22660 :         for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
    5679        21857 :             if (reqVar->name == "Zone Heat Index") {
    5680            0 :                 state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
    5681        21857 :             } else if (reqVar->name == "Zone Humidity Index") {
    5682            0 :                 state.dataHeatBalSurfMgr->reportVarHumidex = true;
    5683              :             }
    5684          803 :         }
    5685              :     }
    5686              : 
    5687              :     // Calculate Heat Index and Humidex.
    5688              :     // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
    5689              :     // then heat index is calculated and converted back to C.
    5690      2799877 :     if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5691      6500454 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5692      5413755 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5693      5413755 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5694      5413755 :             Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
    5695      5413755 :             Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
    5696      5413755 :             if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
    5697      5413755 :                 Real64 constexpr c1 = -42.379;
    5698      5413755 :                 Real64 constexpr c2 = 2.04901523;
    5699      5413755 :                 Real64 constexpr c3 = 10.14333127;
    5700      5413755 :                 Real64 constexpr c4 = -.22475541;
    5701      5413755 :                 Real64 constexpr c5 = -.00683783;
    5702      5413755 :                 Real64 constexpr c6 = -.05481717;
    5703      5413755 :                 Real64 constexpr c7 = .00122874;
    5704      5413755 :                 Real64 constexpr c8 = .00085282;
    5705      5413755 :                 Real64 constexpr c9 = -.00000199;
    5706              :                 Real64 HI;
    5707              : 
    5708      5413755 :                 if (ZoneTF < 80) {
    5709      4680490 :                     HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
    5710              :                 } else {
    5711       733265 :                     HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
    5712       733265 :                          c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
    5713       733265 :                     if (ZoneRH < 13 && ZoneTF < 112) {
    5714        34760 :                         HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
    5715       698505 :                     } else if (ZoneRH > 85 && ZoneTF < 87) {
    5716        15013 :                         HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
    5717              :                     }
    5718              :                 }
    5719      5413755 :                 HI = (HI - 32.0) * (5.0 / 9.0);
    5720      5413755 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
    5721              :             } else {
    5722              :                 // calculate extended heat index
    5723            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
    5724            0 :                     ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
    5725              :             }
    5726              :         }
    5727              :     }
    5728      2799877 :     if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5729      6500454 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5730      5413755 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5731      5413755 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5732      5413755 :             Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
    5733      5413755 :             Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
    5734      5413755 :             Real64 const h = 5.0 / 9.0 * (e - 10.0);
    5735      5413755 :             Real64 const Humidex = ZoneT + h;
    5736      5413755 :             state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
    5737              :         }
    5738              :     }
    5739      2799877 : }
    5740              : 
    5741      1086699 : void ReportThermalResilience(EnergyPlusData &state)
    5742              : {
    5743              : 
    5744      1086699 :     Array1D_bool reportPeriodFlags;
    5745      1086699 :     if (state.dataWeather->TotReportPers > 0) {
    5746         5376 :         reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
    5747         5376 :         General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
    5748              :     }
    5749              : 
    5750      1086699 :     auto &ort = state.dataOutRptTab;
    5751      1093611 :     for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5752         6912 :         if (reportPeriodFlags(i)) {
    5753            0 :             int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    5754            0 :             state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    5755              :         }
    5756              :     }
    5757              : 
    5758      1086699 :     if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
    5759          672 :         int constexpr HINoBins = 5;                     // Heat Index range - number of bins
    5760          672 :         int constexpr HumidexNoBins = 5;                // Humidex range - number of bins
    5761          672 :         int constexpr SETNoBins = 5;                    // SET report column numbers
    5762          672 :         int constexpr ColdHourOfSafetyNoBins = 5;       // Cold Stress Hour of Safety number of columns
    5763          672 :         int constexpr HeatHourOfSafetyNoBins = 5;       // Heat Stress Hour of Safety number of columns
    5764          672 :         int constexpr UnmetDegreeHourNoBins = 6;        // Unmet Degree Hour number of columns
    5765          672 :         int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
    5766              : 
    5767          672 :         if (state.dataHeatBal->TotPeople == 0) {
    5768          103 :             state.dataHeatBalSurfMgr->hasPierceSET = false;
    5769              :         }
    5770         3619 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5771         2947 :             if (!state.dataHeatBal->People(iPeople).Pierce) {
    5772         2936 :                 state.dataHeatBalSurfMgr->hasPierceSET = false;
    5773              :             }
    5774              :         }
    5775         4271 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5776              :             // the whole period
    5777              :             // user specified reporting period
    5778         3604 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5779            5 :                 state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5780            5 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5781            5 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5782            5 :                 state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5783            5 :                 state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5784            5 :                 state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5785            5 :                 if (state.dataHeatBalSurfMgr->hasPierceSET) {
    5786            5 :                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5787            5 :                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5788              :                 }
    5789            5 :                 state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
    5790            5 :                 state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
    5791            5 :                 state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
    5792            5 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5793            5 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5794              :             }
    5795         3599 :             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
    5796         3599 :             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
    5797         3599 :             state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
    5798         3599 :             state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
    5799              :         }
    5800          672 :         state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5801          672 :         state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5802          672 :         state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5803          672 :         state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5804          672 :         state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
    5805              :     }
    5806              : 
    5807              :     // Count hours only during weather simulation periods
    5808      1086699 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    5809              :         // use default value if there are no user inputs
    5810       219096 :         Real64 ColdTempThresh = 15.56;
    5811       219096 :         Real64 HeatTempThresh = 30.0;
    5812              :         // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
    5813              :         // Record last time step SET to trace SET unmet duration;
    5814              : 
    5815       219096 :         Real64 valueNotInit = -999.0;
    5816       219096 :         Real64 nearThreshold = 1.0;
    5817      1192032 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5818       972936 :             state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
    5819       972936 :             state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
    5820              :         }
    5821      1069296 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5822       850200 :             int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
    5823       850200 :             state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
    5824       850200 :                 state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
    5825       850200 :             state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5826       850200 :             if (state.dataHeatBal->People(iPeople).Pierce) {
    5827            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
    5828              :             } else {
    5829       850200 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
    5830              :             }
    5831              : 
    5832       850200 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    5833       850200 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5834       850200 :             ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5835       850200 :             bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
    5836       850200 :             if (Temperature > ColdTempThresh) { // safe
    5837       781208 :                 if (!CrossedColdThresh) {
    5838              :                     // compute the number of hours before threshold is reached
    5839       396296 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5840              :                 }
    5841              :             } else { // danger
    5842              :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5843        68992 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5844        68992 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5845        68992 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5846              :                 // first time crossing threshold
    5847        68992 :                 if (!CrossedColdThresh) {
    5848              :                     // compute the time when the zone crosses the threshold temperature
    5849              :                     int encodedMonDayHrMin;
    5850           10 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5851           10 :                                                state.dataEnvrn->Month,
    5852           10 :                                                state.dataEnvrn->DayOfMonth,
    5853           10 :                                                state.dataGlobal->HourOfDay,
    5854           10 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5855              :                     // fixme: not sure how to aggregate by zone
    5856           10 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
    5857           10 :                     CrossedColdThresh = true;
    5858              :                 }
    5859              :             }
    5860       850200 :             HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5861       850200 :             bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
    5862       850200 :             if (Temperature < HeatTempThresh) { // safe
    5863       845039 :                 if (!CrossedHeatThresh) {
    5864              :                     // compute the number of hours before threshold is reached
    5865       460217 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5866              :                 }
    5867              :             } else { // danger
    5868              :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5869         5161 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5870         5161 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5871         5161 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5872              :                 // first time crossing threshold
    5873         5161 :                 if (!CrossedHeatThresh) {
    5874              :                     // compute the time when the zone crosses the threshold temperature
    5875              :                     int encodedMonDayHrMin;
    5876           13 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5877           13 :                                                state.dataEnvrn->Month,
    5878           13 :                                                state.dataEnvrn->DayOfMonth,
    5879           13 :                                                state.dataGlobal->HourOfDay,
    5880           13 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5881           13 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
    5882           13 :                     CrossedHeatThresh = true;
    5883              :                 }
    5884              :             }
    5885              : 
    5886       850200 :             Real64 VeryHotPMVThresh = 3.0;
    5887       850200 :             Real64 WarmPMVThresh = 0.7;
    5888       850200 :             Real64 CoolPMVThresh = -0.7;
    5889       850200 :             Real64 VeryColdPMVThresh = -3.0;
    5890       850200 :             Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
    5891       850200 :             if (PMV < VeryColdPMVThresh) {
    5892            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
    5893            0 :                     (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5894            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
    5895            0 :                     (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5896              :             }
    5897       850200 :             if (PMV < CoolPMVThresh) {
    5898        91082 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
    5899        91082 :                     (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5900        91082 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
    5901        91082 :                     (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5902              :             }
    5903       850200 :             if (PMV > WarmPMVThresh) {
    5904        94796 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
    5905        94796 :                     (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5906        94796 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
    5907        94796 :                     (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5908              :             }
    5909       850200 :             if (PMV > VeryHotPMVThresh) {
    5910          402 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
    5911          402 :                     (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5912          402 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
    5913          402 :                     (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5914              :             }
    5915              : 
    5916              :             // check whether PierceSET changed for people in a zone
    5917       850200 :             if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
    5918       850200 :                 state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5919              :             } else {
    5920            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
    5921            0 :                     ShowRecurringWarningErrorAtEnd(state,
    5922            0 :                                                    fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
    5923            0 :                                                    state.dataHeatBalFanSys->PierceSETerrorIndex);
    5924              :                 }
    5925              :             }
    5926              : 
    5927              :             // check whether PierceSET, PMV, etc. changed for different people in a zone
    5928       850200 :             if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
    5929       850200 :                 state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
    5930              :             } else {
    5931            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
    5932            0 :                     ShowRecurringWarningErrorAtEnd(state,
    5933            0 :                                                    fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
    5934            0 :                                                    state.dataHeatBalFanSys->PMVerrorIndex);
    5935              :                 }
    5936              :             }
    5937              : 
    5938       850200 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5939            0 :                 if (reportPeriodFlags(i)) {
    5940            0 :                     int ReportPeriodIdx = i;
    5941            0 :                     ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5942            0 :                     bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5943            0 :                     if (Temperature > ColdTempThresh) { // safe
    5944            0 :                         if (!CrossedColdThreshRepPeriod) {
    5945              :                             // compute the number of hours before threshold is reached
    5946            0 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5947              :                         }
    5948              :                     } else { // danger
    5949              :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5950            0 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5951            0 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5952            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5953            0 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5954            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5955              :                         // first time crossing threshold
    5956            0 :                         if (!CrossedColdThreshRepPeriod) {
    5957              :                             // compute the time when the zone crosses the threshold temperature
    5958              :                             int encodedMonDayHrMin;
    5959            0 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5960            0 :                                                        state.dataEnvrn->Month,
    5961            0 :                                                        state.dataEnvrn->DayOfMonth,
    5962            0 :                                                        state.dataGlobal->HourOfDay,
    5963            0 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5964              :                             // fixme: not sure how to aggregate by zone
    5965            0 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5966            0 :                             CrossedColdThreshRepPeriod = true;
    5967              :                         }
    5968              :                     }
    5969            0 :                     HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5970            0 :                     bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5971            0 :                     if (Temperature < HeatTempThresh) { // safe
    5972            0 :                         if (!CrossedHeatThreshRepPeriod) {
    5973              :                             // compute the number of hours before threshold is reached
    5974            0 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5975              :                         }
    5976              :                     } else { // danger
    5977              :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5978            0 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5979            0 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5980            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5981            0 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5982            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5983              :                         // first time crossing threshold
    5984            0 :                         if (!CrossedHeatThreshRepPeriod) {
    5985              :                             // compute the time when the zone crosses the threshold temperature
    5986              :                             int encodedMonDayHrMin;
    5987            0 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5988            0 :                                                        state.dataEnvrn->Month,
    5989            0 :                                                        state.dataEnvrn->DayOfMonth,
    5990            0 :                                                        state.dataGlobal->HourOfDay,
    5991            0 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5992            0 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5993            0 :                             CrossedHeatThreshRepPeriod = true;
    5994              :                         }
    5995              :                     }
    5996              : 
    5997            0 :                     if (PMV < VeryColdPMVThresh) {
    5998            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5999            0 :                             (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    6000            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6001            0 :                             (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6002              :                     }
    6003            0 :                     if (PMV < CoolPMVThresh) {
    6004            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6005            0 :                             (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    6006            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6007            0 :                             (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6008              :                     }
    6009            0 :                     if (PMV > WarmPMVThresh) {
    6010            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6011            0 :                             (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    6012            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6013            0 :                             (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6014              :                     }
    6015            0 :                     if (PMV > VeryHotPMVThresh) {
    6016            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6017            0 :                             (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    6018            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6019            0 :                             (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6020              :                     }
    6021              :                 }
    6022              :             }
    6023              :         }
    6024      1192032 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6025       972936 :             Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
    6026       972936 :             Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
    6027              : 
    6028       972936 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6029       972936 :             if (HI <= 26.7) {
    6030       921157 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
    6031       921157 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6032       921157 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6033        51779 :             } else if (HI > 26.7 && HI <= 32.2) {
    6034        41483 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
    6035        41483 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6036        41483 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6037        10296 :             } else if (HI > 32.2 && HI <= 39.4) {
    6038         4776 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
    6039         4776 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6040         4776 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6041         5520 :             } else if (HI > 39.4 && HI <= 51.7) {
    6042         3610 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
    6043         3610 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6044         3610 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6045              :             } else {
    6046         1910 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
    6047         1910 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    6048         1910 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6049              :             }
    6050              : 
    6051       972936 :             if (Humidex <= 29) {
    6052       884184 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
    6053       884184 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6054       884184 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6055        88752 :             } else if (Humidex > 29 && Humidex <= 40) {
    6056        78160 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
    6057        78160 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6058        78160 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6059        10592 :             } else if (Humidex > 40 && Humidex <= 45) {
    6060         4801 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
    6061         4801 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6062         4801 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6063         5791 :             } else if (Humidex > 45 && Humidex <= 50) {
    6064         3093 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
    6065         3093 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6066         3093 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6067              :             } else {
    6068         2698 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
    6069         2698 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    6070         2698 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6071              :             }
    6072              : 
    6073       972936 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    6074       972936 :             auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    6075       972936 :             Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
    6076       972936 :             Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
    6077              : 
    6078       972936 :             if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6079        42672 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6080        42672 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
    6081        42672 :                     NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6082        42672 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
    6083        42672 :                     (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6084              :             }
    6085       972936 :             if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6086        65815 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6087        65815 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
    6088        65815 :                     NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6089        65815 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
    6090        65815 :                     (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6091              :             }
    6092              : 
    6093       972936 :             if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6094              :                 int encodedMonDayHrMin;
    6095            0 :                 Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6096            0 :                 Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6097              : 
    6098            0 :                 if (PierceSET <= 12.2) {
    6099            0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6100            0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6101            0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6102              :                     // Reset duration when last step is out of range.
    6103            0 :                     if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6104            0 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6105            0 :                                                    state.dataEnvrn->Month,
    6106            0 :                                                    state.dataEnvrn->DayOfMonth,
    6107            0 :                                                    state.dataGlobal->HourOfDay,
    6108            0 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6109            0 :                         state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    6110            0 :                         state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    6111              :                     }
    6112              :                     // Keep the longest duration record.
    6113            0 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    6114            0 :                     if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
    6115            0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6116            0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
    6117            0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
    6118              :                     }
    6119            0 :                 } else if (PierceSET > 30) {
    6120            0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6121            0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6122            0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6123            0 :                     if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6124            0 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6125            0 :                                                    state.dataEnvrn->Month,
    6126            0 :                                                    state.dataEnvrn->DayOfMonth,
    6127            0 :                                                    state.dataGlobal->HourOfDay,
    6128            0 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6129            0 :                         state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    6130            0 :                         state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    6131              :                     }
    6132            0 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    6133            0 :                     if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
    6134            0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6135            0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
    6136            0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
    6137              :                     }
    6138              :                 }
    6139              : 
    6140            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6141            0 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    6142            0 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    6143              :                 }
    6144              :             }
    6145              : 
    6146       972936 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    6147            0 :                 if (reportPeriodFlags(i)) {
    6148            0 :                     int ReportPeriodIdx = i;
    6149              : 
    6150            0 :                     if (HI <= 26.7) {
    6151            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6152            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6153            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6154            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6155            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6156            0 :                     } else if (HI > 26.7 && HI <= 32.2) {
    6157            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6158            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6159            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6160            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6161            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6162            0 :                     } else if (HI > 32.2 && HI <= 39.4) {
    6163            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6164            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6165            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6166            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6167            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6168            0 :                     } else if (HI > 39.4 && HI <= 51.7) {
    6169            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6170            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6171            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6172            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6173            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6174              :                     } else {
    6175            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6176            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6177            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6178            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6179            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6180              :                     }
    6181              : 
    6182            0 :                     if (Humidex <= 29) {
    6183            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6184            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6185            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6186            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6187            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6188            0 :                     } else if (Humidex > 29 && Humidex <= 40) {
    6189            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6190            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6191            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6192            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6193            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6194            0 :                     } else if (Humidex > 40 && Humidex <= 45) {
    6195            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6196            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6197            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6198            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6199            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6200            0 :                     } else if (Humidex > 45 && Humidex <= 50) {
    6201            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6202            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6203            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6204            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6205            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6206              :                     } else {
    6207            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6208            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6209            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6210            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6211            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6212              :                     }
    6213              : 
    6214            0 :                     if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6215              :                         int encodedMonDayHrMin;
    6216            0 :                         Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6217            0 :                         Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6218            0 :                         if (PierceSET <= 12.2) {
    6219            0 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6220            0 :                                 (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6221            0 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6222            0 :                                 (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6223            0 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6224            0 :                                 (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6225              :                             // Reset duration when last step is out of range
    6226            0 :                             if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6227            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6228            0 :                                                            state.dataEnvrn->Month,
    6229            0 :                                                            state.dataEnvrn->DayOfMonth,
    6230            0 :                                                            state.dataGlobal->HourOfDay,
    6231            0 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6232            0 :                                 state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6233            0 :                                 state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6234            0 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6235            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6236            0 :                                                            state.dataEnvrn->Month,
    6237            0 :                                                            state.dataEnvrn->DayOfMonth,
    6238            0 :                                                            state.dataGlobal->HourOfDay,
    6239            0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6240            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6241            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6242              :                             }
    6243              :                             // Keep the longest duration record.
    6244            0 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6245            0 :                             if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6246            0 :                                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6247            0 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6248            0 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6249            0 :                                     state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6250            0 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6251            0 :                                     state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6252              :                             }
    6253            0 :                         } else if (PierceSET > 30) {
    6254            0 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6255            0 :                                 (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6256            0 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6257            0 :                                 (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6258            0 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6259            0 :                                 (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6260              :                             // Reset duration when last step is out of range.
    6261            0 :                             if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6262            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6263            0 :                                                            state.dataEnvrn->Month,
    6264            0 :                                                            state.dataEnvrn->DayOfMonth,
    6265            0 :                                                            state.dataGlobal->HourOfDay,
    6266            0 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6267            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6268            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6269            0 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6270            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6271            0 :                                                            state.dataEnvrn->Month,
    6272            0 :                                                            state.dataEnvrn->DayOfMonth,
    6273            0 :                                                            state.dataGlobal->HourOfDay,
    6274            0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6275            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6276            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6277              :                             }
    6278            0 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6279            0 :                             if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6280            0 :                                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6281            0 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6282            0 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6283            0 :                                     state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6284            0 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6285            0 :                                     state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6286              :                             }
    6287              :                         }
    6288            0 :                         if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6289            0 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6290            0 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6291              :                         }
    6292              :                     }
    6293              : 
    6294            0 :                     if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6295            0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6296            0 :                             (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6297            0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6298            0 :                             NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6299            0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6300            0 :                             (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6301              :                     }
    6302            0 :                     if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6303            0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6304            0 :                             (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6305            0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6306            0 :                             NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6307            0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
    6308            0 :                             (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6309              :                     }
    6310              :                 }
    6311              :             }
    6312              :         } // loop over zones
    6313              :     }
    6314      1086699 : }
    6315              : 
    6316        19089 : void ReportCO2Resilience(EnergyPlusData &state)
    6317              : {
    6318        19089 :     if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
    6319          672 :         int NoBins = 3;
    6320         4271 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6321         3602 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6322            3 :                 state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6323            3 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6324            3 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6325              :             }
    6326              :         }
    6327          672 :         state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
    6328          672 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    6329          657 :             if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
    6330            0 :                 ShowWarningError(state,
    6331              :                                  "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
    6332              :                                  "Zone Air CO2 Concentration output is required, "
    6333              :                                  "but no ZoneAirContaminantBalance object is defined.");
    6334              :             }
    6335          657 :             state.dataOutRptTab->displayCO2ResilienceSummary = false;
    6336          657 :             return;
    6337              :         }
    6338              :     }
    6339              : 
    6340        18432 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6341            0 :         for (auto const &people : state.dataHeatBal->People) {
    6342            0 :             state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
    6343            0 :         }
    6344              : 
    6345            0 :         Array1D_bool reportPeriodFlags;
    6346            0 :         if (state.dataWeather->TotReportPers > 0) {
    6347            0 :             reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
    6348            0 :             General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
    6349              :         }
    6350              : 
    6351            0 :         auto &ort = state.dataOutRptTab;
    6352            0 :         for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6353            0 :             if (reportPeriodFlags(i)) {
    6354            0 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6355            0 :                 state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6356              :             }
    6357              :         }
    6358              : 
    6359            0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6360            0 :             Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
    6361              : 
    6362            0 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6363            0 :             if (ZoneAirCO2 <= 1000) {
    6364            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6365            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6366            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6367            0 :             } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6368            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6369            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6370            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6371              :             } else {
    6372            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6373            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6374            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6375              :             }
    6376            0 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6377            0 :                 if (reportPeriodFlags(i)) {
    6378            0 :                     int ReportPeriodIdx = i;
    6379            0 :                     if (ZoneAirCO2 <= 1000) {
    6380            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6381            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6382            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6383            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6384            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6385            0 :                     } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6386            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6387            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6388            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6389            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6390            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6391              :                     } else {
    6392            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6393            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6394            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6395            0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6396            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6397              :                     }
    6398              :                 }
    6399              :             }
    6400              :         }
    6401            0 :     } // loop over zones
    6402              : }
    6403              : 
    6404        92393 : void ReportVisualResilience(EnergyPlusData &state)
    6405              : {
    6406        92393 :     if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
    6407          672 :         int NoBins = 4;
    6408         4271 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6409         3602 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6410            3 :                 state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6411            3 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6412            3 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6413              :             }
    6414              :         }
    6415          672 :         state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
    6416          672 :         if ((int)state.dataDayltg->daylightControl.size() == 0) {
    6417          617 :             if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
    6418            0 :                 ShowWarningError(state,
    6419              :                                  "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
    6420              :                                  "Zone Average Daylighting Reference Point Illuminance output is required, "
    6421              :                                  "but no Daylighting Control Object is defined.");
    6422              :             }
    6423          617 :             state.dataOutRptTab->displayVisualResilienceSummary = false;
    6424          617 :             return;
    6425              :         }
    6426              :     }
    6427              : 
    6428        91776 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6429            0 :         for (auto const &people : state.dataHeatBal->People) {
    6430            0 :             state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
    6431            0 :         }
    6432              :         // Accumulate across daylighting controls first
    6433            0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6434            0 :             state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
    6435              :         }
    6436            0 :         for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
    6437            0 :             auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
    6438            0 :             if (thisDaylightControl.PowerReductionFactor > 0) {
    6439            0 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6440            0 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
    6441              :                 }
    6442              :             } else {
    6443            0 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6444            0 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
    6445            0 :                         thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
    6446              :                 }
    6447              :             }
    6448              :         }
    6449              : 
    6450            0 :         Array1D_bool reportPeriodFlags;
    6451            0 :         if (state.dataWeather->TotReportPers > 0) {
    6452            0 :             reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
    6453            0 :             General::findReportPeriodIdx(
    6454            0 :                 state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
    6455              :         }
    6456              : 
    6457            0 :         auto &ort = state.dataOutRptTab;
    6458            0 :         for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6459            0 :             if (reportPeriodFlags(i)) {
    6460            0 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6461            0 :                 state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6462              :             }
    6463              :         }
    6464              : 
    6465            0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6466            0 :             if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) {
    6467            0 :                 continue;
    6468              :             }
    6469              :             // Now divide by total reference points to get average
    6470            0 :             Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
    6471              : 
    6472            0 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6473            0 :             if (avgZoneIllum <= 100) {
    6474            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6475            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6476            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6477            0 :             } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6478            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6479            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6480            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6481            0 :             } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6482            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6483            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6484            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6485              :             } else {
    6486            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
    6487            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6488            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6489              :             }
    6490            0 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6491            0 :                 if (reportPeriodFlags(i)) {
    6492            0 :                     int ReportPeriodIdx = i;
    6493            0 :                     if (avgZoneIllum <= 100) {
    6494            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6495            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6496            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6497            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6498            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6499            0 :                     } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6500            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6501            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6502            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6503            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6504            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6505            0 :                     } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6506            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6507            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6508            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6509            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6510            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6511              :                     } else {
    6512            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6513            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6514            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6515            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6516            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6517              :                     }
    6518              :                 }
    6519              :             }
    6520              :         }
    6521            0 :     } // loop over zones
    6522              : }
    6523              : 
    6524      2799877 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
    6525              : {
    6526              : 
    6527              :     // SUBROUTINE INFORMATION:
    6528              :     //       AUTHOR         Linda Lawrie
    6529              :     //       DATE WRITTEN   Oct 2000
    6530              : 
    6531              :     // PURPOSE OF THIS SUBROUTINE:
    6532              :     // This subroutine puts the reporting part of the HBSurface Module in one area.
    6533              : 
    6534      2799877 :     SolarShading::ReportSurfaceShading(state);
    6535              : 
    6536      2799877 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    6537          342 :         ReportNonRepresentativeSurfaceResults(state);
    6538              :     }
    6539              : 
    6540              :     // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
    6541              : 
    6542              :     // Opaque or window surfaces
    6543     22621627 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6544     39692100 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6545     19870350 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6546     19870350 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6547     19870350 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6548    189889131 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6549    170018781 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6550              :                 // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
    6551    170018781 :                 state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
    6552    170018781 :                 state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
    6553    170018781 :                     state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6554              : 
    6555    170018781 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6556    170018781 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
    6557    170018781 :                     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6558              : 
    6559    170018781 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
    6560    170018781 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
    6561    170018781 :                     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6562              : 
    6563    170018781 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
    6564    170018781 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
    6565    170018781 :                     state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6566              : 
    6567    170018781 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
    6568              : 
    6569    170018781 :                 state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
    6570    170018781 :                     state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6571              : 
    6572    170018781 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
    6573    170018781 :                 state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
    6574    170018781 :                     state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6575              : 
    6576              :                 // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
    6577    170018781 :                 state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
    6578    170018781 :                     surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
    6579    170018781 :                     (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
    6580              : 
    6581              :                 // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
    6582    170018781 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
    6583    170018781 :                     state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
    6584              :             }
    6585     19821750 :         }
    6586              :     }
    6587              : 
    6588      2799877 :     if (state.dataOutRptTab->displayHeatEmissionsSummary) {
    6589      1081995 :         state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
    6590     47580495 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6591     46498500 :             if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    6592     21434877 :                 state.dataHeatBalSurf->SumSurfaceHeatEmission +=
    6593     21434877 :                     state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    6594              :             }
    6595              :         }
    6596              :     }
    6597              : 
    6598              :     // Window surfaces
    6599     22621627 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6600     39692100 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6601     19870350 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6602     19870350 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    6603     19870350 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    6604     42237432 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6605     22367082 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6606     22367082 :                 state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
    6607     22367082 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
    6608              : 
    6609              :                 // Absorbed short wave radiation
    6610              :                 int TotGlassLayers;
    6611     22367082 :                 int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    6612     22367082 :                 auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
    6613     22367082 :                 int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
    6614     22367082 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
    6615     22367082 :                 if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
    6616         8109 :                     TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
    6617     22358973 :                 } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
    6618        39540 :                     TotGlassLayers = thisConstruct.TotSolidLayers;
    6619     22319433 :                 } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    6620     22130455 :                     TotGlassLayers = thisConstruct.TotGlassLayers;
    6621              :                 } else {
    6622              :                     // Interior, exterior or between-glass shade, screen or blind in place
    6623       188978 :                     TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
    6624              :                 }
    6625     22367082 :                 state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
    6626     22367082 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
    6627     22367082 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
    6628     51041118 :                 for (int lay = 1; lay <= TotGlassLayers; ++lay) {
    6629              :                     // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6630     28674036 :                     state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
    6631     28674036 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
    6632              :                     // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6633     28674036 :                     state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6634              :                     // Total Shortwave Absorbed:All solid Layers[W]
    6635     28674036 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6636              :                 }
    6637              : 
    6638              :                 // Window heat gain/loss
    6639     22367082 :                 if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
    6640      7744835 :                     state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
    6641      7744835 :                     state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
    6642      7744835 :                         state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6643              :                 } else {
    6644     14622247 :                     state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
    6645     14622247 :                     state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
    6646     14622247 :                         state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6647              :                 }
    6648     22367082 :                 state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
    6649     22367082 :                     state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6650     22367082 :                 if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    6651         4050 :                     int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    6652         4050 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
    6653         4050 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
    6654              :                 }
    6655              :             }
    6656     19821750 :         }
    6657              :     }
    6658              : 
    6659      2799877 :     if (state.dataSurface->AnyMovableInsulation) {
    6660        10122 :         ReportIntMovInsInsideSurfTemp(state);
    6661              :     }
    6662              : 
    6663              :     // Opaque heat transfer surfaces
    6664     22621627 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6665     39692100 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6666     19870350 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6667     19870350 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6668     19870350 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6669    167522049 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6670    147651699 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6671              : 
    6672    147651699 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
    6673    147651699 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
    6674    147651699 :                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6675              : 
    6676    147651699 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
    6677    147651699 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
    6678    147651699 :                     state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6679              : 
    6680    147651699 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
    6681    147651699 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
    6682    147651699 :                     state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6683              : 
    6684              :                 // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6685    147651699 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
    6686              :                 // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6687    147651699 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
    6688              : 
    6689              :                 // inside face conduction updates
    6690    147651699 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
    6691    147651699 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
    6692    147651699 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6693    147651699 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
    6694    147651699 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
    6695    147651699 :                 if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
    6696     71781074 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6697              :                 } else {
    6698     75870625 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6699              :                 }
    6700              : 
    6701              :                 // outside face conduction updates
    6702    147651699 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
    6703    147651699 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
    6704    147651699 :                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6705    147651699 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
    6706    147651699 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
    6707    147651699 :                 if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
    6708     90935375 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6709              :                 } else {
    6710     56716324 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6711              :                 }
    6712              :             }
    6713    167522049 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6714              :                 // do average surface conduction updates
    6715              : 
    6716    147651699 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
    6717    147651699 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
    6718    147651699 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
    6719    147651699 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
    6720    147651699 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
    6721    147651699 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6722    147651699 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
    6723    147651699 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
    6724    147651699 :                 if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
    6725     64681931 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6726              :                 } else {
    6727     82969768 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6728              :                 }
    6729              : 
    6730              :                 // do surface storage rate updates
    6731    147651699 :                 state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
    6732    147651699 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
    6733    147651699 :                 state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
    6734    147651699 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
    6735    147651699 :                 state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
    6736    147651699 :                     state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6737    147651699 :                 state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
    6738    147651699 :                 state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
    6739    147651699 :                 if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
    6740     63507931 :                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6741              :                 } else {
    6742     84143768 :                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6743              :                 }
    6744              :             }
    6745     19821750 :         }
    6746              :     }
    6747              : 
    6748      2799877 :     if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
    6749              :         // This is by surface, so it works for both space and zone component loads
    6750        73122 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
    6751        73122 :         auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
    6752       674988 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6753      1236060 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6754       634194 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6755       634194 :                 int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6756       634194 :                 int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6757      5032314 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6758      4398120 :                     surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
    6759      4398120 :                     surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
    6760              :                 }
    6761       634194 :                 firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6762       634194 :                 lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6763      5588010 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6764      4953816 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6765      4953816 :                     if (!state.dataGlobal->WarmupFlag) {
    6766       677376 :                         if (state.dataGlobal->isPulseZoneSizing) {
    6767       338688 :                             surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6768              :                         } else {
    6769       338688 :                             surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6770       338688 :                             surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6771              :                         }
    6772              :                     }
    6773              :                 }
    6774       601866 :             }
    6775              :         }
    6776              :     }
    6777              : 
    6778      2799877 :     if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6779       514302 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6780       777210 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6781       388605 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6782       388605 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6783       388605 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6784      3186792 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6785      2798187 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6786      2798187 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6787              :                 }
    6788       388605 :                 if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
    6789       177218 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6790       177218 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
    6791       177218 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6792              :                 } else {
    6793       211387 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6794       211387 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
    6795       211387 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6796              :                 }
    6797              : 
    6798       388605 :                 if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
    6799       256629 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6800       256629 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
    6801       256629 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6802              :                 } else {
    6803       131976 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6804       131976 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
    6805       131976 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6806              :                 }
    6807       388605 :             }
    6808              :         }
    6809              :     }
    6810      2799877 : }
    6811              : 
    6812          342 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
    6813              : {
    6814        16074 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6815        31464 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6816        15732 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6817              :             // Heat transfer surfaces
    6818        15732 :             int firstSurf = thisSpace.HTSurfaceFirst;
    6819        15732 :             int lastSurf = thisSpace.HTSurfaceLast;
    6820       213750 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6821       198018 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6822       198018 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    6823       198018 :                 if (surfNum != repSurfNum) {
    6824        44802 :                     state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
    6825        44802 :                     state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
    6826              :                 }
    6827              :             }
    6828              : 
    6829              :             // Windows
    6830        15732 :             if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6831            0 :                 firstSurf = thisSpace.WindowSurfaceFirst;
    6832            0 :                 lastSurf = thisSpace.WindowSurfaceLast;
    6833            0 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6834            0 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6835            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    6836            0 :                     if (surfNum != repSurfNum) {
    6837            0 :                         Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    6838            0 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    6839            0 :                             state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    6840            0 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    6841            0 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    6842            0 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    6843            0 :                             state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
    6844              :                     }
    6845              :                 }
    6846              :             }
    6847        15732 :         }
    6848              :     }
    6849          342 : }
    6850              : 
    6851        10122 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
    6852              : {
    6853        10122 :     state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
    6854        16197 :     for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
    6855         6075 :         if (state.dataSurface->intMovInsuls(SurfNum).present) {
    6856         6075 :             state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    6857              :         }
    6858        10122 :     }
    6859        10122 : }
    6860              : // End of Reporting subroutines for the HB Module
    6861              : // *****************************************************************************
    6862              : 
    6863              : // *****************************************************************************
    6864              : // *****************************************************************************
    6865              : // *****************************************************************************
    6866              : // *****************************************************************************
    6867              : 
    6868              : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
    6869              : 
    6870      3699480 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
    6871              :                                 ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    6872              : {
    6873              : 
    6874              :     // SUBROUTINE INFORMATION:
    6875              :     //       AUTHOR         George Walton
    6876              :     //       DATE WRITTEN   December 1979
    6877              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays);
    6878              :     //                      Aug 2000 (RJL for MTF moisture calculations)
    6879              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    6880              :     //                      Dec 2000 (RKS for radiant system model addition)
    6881              :     //                      Apr 2002 (COP removed denominator from OSC calculation
    6882              :     //                      Jul 2008 (P.Biddulph include calls to HAMT)
    6883              :     //                      Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
    6884              :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    6885              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    6886              : 
    6887              :     // PURPOSE OF THIS SUBROUTINE:
    6888              :     // This subroutine performs a heat balance on the outside face of each
    6889              :     // surface in the building.
    6890              : 
    6891              :     // METHODOLOGY EMPLOYED:
    6892              :     // Various boundary conditions are set and additional parameters are set-
    6893              :     // up.  Then, the proper heat balance equation is selected based on the
    6894              :     // presence of movable insulation, thermal mass of the surface construction,
    6895              :     // and convection model being used.
    6896              : 
    6897              :     // REFERENCES:
    6898              :     // (I)BLAST legacy routine HBOUT
    6899              :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    6900              : 
    6901              :     //    // Using/Aliasing
    6902              :     //    using namespace DataEnvironment;
    6903              :     //    using namespace DataHeatBalance;
    6904              :     //    using namespace DataHeatBalSurface;
    6905              :     //    using namespace DataSurfaces;
    6906              :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
    6907              :     //    using namespace Psychrometrics;
    6908              :     //    using EcoRoofManager::CalcEcoRoof;
    6909              :     //
    6910              :     //    // Locals
    6911              :     //    // SUBROUTINE ARGUMENT DEFINITIONS:
    6912              :     //
    6913              :     //>>>>>>> origin/develop
    6914              :     // SUBROUTINE PARAMETER DEFINITIONS:
    6915      3699480 :     constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
    6916      3699480 :     constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
    6917      3699480 :     constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
    6918      3699480 :     constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
    6919      3699480 :     constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
    6920      3699480 :     constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
    6921      3699480 :     constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
    6922      3699480 :     constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
    6923      3699480 :     constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
    6924      3699480 :     constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
    6925      3699480 :     constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
    6926      3699480 :     constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
    6927      3699480 :     constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
    6928      3699480 :     constexpr std::string_view Outside("Outside");
    6929              : 
    6930      3699480 :     auto &s_mat = state.dataMaterial;
    6931              : 
    6932      3699480 :     bool MovInsulErrorFlag = false; // Movable Insulation error flag
    6933              : 
    6934              :     // set ground surfaces average temperature
    6935      3699480 :     GetGroundSurfacesTemperatureAverage(state);
    6936              : 
    6937              :     // set surrounding surfaces average temperature
    6938      3699480 :     GetSurroundingSurfacesTemperatureAverage(state);
    6939              : 
    6940      3699480 :     auto &Surface = state.dataSurface->Surface;
    6941              : 
    6942      3699480 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    6943     23750256 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6944              :             // Need to transfer any source/sink for a surface to the local array.  Note that
    6945              :             // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
    6946              :             // This must be done at this location so that this is always updated correctly.
    6947     22781150 :             if (Surface(SurfNum).Area > 0.0) {
    6948     22781150 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
    6949     22781150 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6950              :             }
    6951              : 
    6952              :             // next we add source (actually a sink) from any integrated PV
    6953     22781150 :             if (Surface(SurfNum).Area > 0.0) {
    6954     22781150 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
    6955     22781150 :                     state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6956              :             }
    6957              :         }
    6958              :     }
    6959              : 
    6960      3699480 :     if (present(ZoneToResimulate)) {
    6961      1592198 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6962       796099 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
    6963              :     } else {
    6964      5806762 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6965      2903381 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
    6966              :     }
    6967              : 
    6968              :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    6969      3712053 :     for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
    6970        12573 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
    6971      3699480 :     }
    6972     26701561 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
    6973     46052762 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6974     23050681 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    6975    216414670 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    6976    193363989 :                 if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) {
    6977     24258476 :                     continue;
    6978              :                 }
    6979    169105513 :                 if (present(ZoneToResimulate)) {
    6980     18716444 :                     if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
    6981     11506789 :                         continue; // skip surfaces that are not associated with this zone
    6982              :                     }
    6983              :                 }
    6984              :                 // Interior windows in partitions use "normal" heat balance calculations
    6985              :                 // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
    6986              :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
    6987              : 
    6988              :                 // Initializations for this surface
    6989    157598724 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    6990    157598724 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    6991    157598724 :                 Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
    6992    157598724 :                 Real64 HSky = 0.0;      // "Convection" coefficient from sky to surface
    6993    157598724 :                 Real64 HGround = 0.0;   // "Convection" coefficient from ground to surface
    6994    157598724 :                 Real64 HAir = 0.0;      // "Convection" coefficient from air to surface (radiation)
    6995    157598724 :                 Real64 HSurrr = 0.0;    // "Linearized radiation" coefficient from surrounding surfaces to surface
    6996    157598724 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    6997    157598724 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    6998    157598724 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    6999    157598724 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    7000    157598724 :                 state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
    7001    157598724 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) = 0.0;
    7002              : 
    7003              :                 // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
    7004              :                 // various different boundary conditions
    7005    157598724 :                 switch (Surface(SurfNum).ExtBoundCond) {
    7006      9641561 :                 case DataSurfaces::Ground: { // Surface in contact with ground
    7007      9641561 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7008      9641561 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    7009              : 
    7010              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7011      9641561 :                     if (thisConstruct.SourceSinkPresent) {
    7012      1374580 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7013              :                     }
    7014              : 
    7015              :                     // start HAMT
    7016      9641561 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7017              :                         // Set variables used in the HAMT moisture balance
    7018        26913 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7019        26913 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    7020        26913 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    7021        26913 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
    7022        26913 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7023              : 
    7024        26913 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7025        26913 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7026        80739 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7027              :                                   state,
    7028        26913 :                                   state.dataEnvrn->OutBaroPress,
    7029        26913 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7030              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7031        26913 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7032              :                                                                 1.0,
    7033        26913 :                                                                 state.dataEnvrn->OutBaroPress,
    7034        26913 :                                                                 RoutineNameGroundTemp)) +
    7035        53826 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7036        26913 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7037              : 
    7038        26913 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7039        26913 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7040        26913 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7041              :                     }
    7042              :                     // end HAMT
    7043              : 
    7044      9641561 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7045              :                         // Set variables used in the FD moisture balance
    7046       415748 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7047       415748 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    7048       415748 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    7049       415748 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
    7050       415748 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7051       415748 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7052       415748 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7053      1247244 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7054              :                                   state,
    7055       415748 :                                   state.dataEnvrn->OutBaroPress,
    7056       415748 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7057              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7058       415748 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7059              :                                                                 1.0,
    7060       415748 :                                                                 state.dataEnvrn->OutBaroPress,
    7061       415748 :                                                                 RoutineNameGroundTemp)) +
    7062       831496 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7063       415748 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7064       415748 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7065       415748 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7066       415748 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7067              :                     }
    7068              :                     // Added for FCfactor grounds
    7069      9641561 :                 } break;
    7070       554427 :                 case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
    7071       554427 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7072       554427 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7073              : 
    7074              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7075       554427 :                     if (thisConstruct.SourceSinkPresent) {
    7076            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7077              :                     }
    7078              : 
    7079       554427 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7080              :                         // Set variables used in the HAMT moisture balance
    7081            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7082            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7083            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    7084            0 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
    7085            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7086              : 
    7087            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7088            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7089            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7090              :                                   state,
    7091            0 :                                   state.dataEnvrn->OutBaroPress,
    7092            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7093              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7094            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7095              :                                                                 1.0,
    7096            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7097            0 :                                                                 RoutineNameGroundTempFC)) +
    7098            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7099            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7100              : 
    7101            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7102            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7103            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7104              :                     }
    7105              : 
    7106       554427 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7107              :                         // Set variables used in the FD moisture balance
    7108            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7109            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7110            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    7111            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
    7112            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7113            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7114            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7115            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7116              :                                   state,
    7117            0 :                                   state.dataEnvrn->OutBaroPress,
    7118            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7119              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7120            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7121              :                                                                 1.0,
    7122            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7123            0 :                                                                 RoutineNameGroundTempFC)) +
    7124            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7125            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7126            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7127            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7128            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7129              :                     }
    7130       554427 :                 } break;
    7131        74661 :                 case DataSurfaces::OtherSideCoefNoCalcExt: {
    7132              :                     // Use Other Side Coefficients to determine the surface film coefficient and
    7133              :                     // the exterior boundary condition temperature
    7134              : 
    7135        74661 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7136              :                     // Set surface temp from previous timestep
    7137        74661 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7138        74423 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7139              :                     }
    7140              : 
    7141        74661 :                     if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
    7142        67137 :                         state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
    7143              :                     }
    7144              : 
    7145              :                     //  Allow for modification of TemperatureCoefficient with unitary sine wave.
    7146              :                     Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
    7147        74661 :                     if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
    7148         3465 :                         ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
    7149              :                     } else {
    7150        71196 :                         ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
    7151              :                     }
    7152              : 
    7153        74661 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7154        74661 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7155        74661 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7156        74661 :                          ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7157        74661 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7158        74661 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7159        74661 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7160        74661 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7161        74661 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7162              : 
    7163              :                     // Enforce max/min limits if applicable
    7164        74661 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
    7165        33255 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7166        33255 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7167              :                     }
    7168        74661 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
    7169        33255 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7170        33255 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7171              :                     }
    7172              : 
    7173        74661 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7174              : 
    7175              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7176        74661 :                     if (thisConstruct.SourceSinkPresent) {
    7177            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7178              :                     }
    7179              : 
    7180       149322 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7181        74661 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7182              :                         // Set variables used in the FD moisture balance and HAMT
    7183            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7184            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7185            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7186            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7187            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7188            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7189            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7190            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7191            0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7192              :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7193            0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7194              :                                                                                               1.0,
    7195            0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7196            0 :                                                                                               RoutineNameOtherSideCoefNoCalcExt)) +
    7197            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7198            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7199            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7200            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7201            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7202              :                     }
    7203              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7204        74661 :                 } break;
    7205         1353 :                 case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
    7206              :                     // First, set up the outside convection coefficient and the exterior temperature
    7207              :                     // boundary condition for the surface
    7208         1353 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7209              :                     // Set surface temp from previous timestep
    7210         1353 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7211         1347 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7212              :                     }
    7213              : 
    7214         1353 :                     if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
    7215            0 :                         state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
    7216              :                     }
    7217              : 
    7218         1353 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
    7219              : 
    7220         1353 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7221         1353 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7222         1353 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7223         1353 :                          state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7224         1353 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7225         1353 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7226         1353 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7227         1353 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7228         1353 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7229              : 
    7230              :                     // Enforce max/min limits if applicable
    7231         1353 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
    7232            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7233            0 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7234              :                     }
    7235         1353 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
    7236            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7237            0 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7238              :                     }
    7239              : 
    7240         1353 :                     Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7241              : 
    7242              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7243         1353 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
    7244            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7245              :                     }
    7246              : 
    7247         2706 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7248         1353 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7249              :                         // Set variables used in the FD moisture balance and HAMT
    7250            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7251            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7252            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7253            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7254            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7255            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7256            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7257            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7258            0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7259              :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7260            0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7261              :                                                                                               1.0,
    7262            0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7263            0 :                                                                                               RoutineNameOtherSideCoefCalcExt)) +
    7264            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7265            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7266            0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7267            0 :                         state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7268            0 :                         state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7269              :                     }
    7270              : 
    7271              :                     // Call the outside surface temp calculation and pass the necessary terms
    7272         1353 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7273            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7274         1353 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7275         1353 :                         if (MovInsulErrorFlag) {
    7276            0 :                             ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7277              :                         }
    7278              :                     }
    7279              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7280         1353 :                 } break;
    7281       211815 :                 case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
    7282              :                     // modeling that defines the "outside environment"
    7283              :                     // First, set up the outside convection coefficient and the exterior temperature
    7284              :                     // boundary condition for the surface
    7285       211815 :                     int OPtr = Surface(SurfNum).OSCMPtr;
    7286              :                     // EMS overrides
    7287       211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) {
    7288            0 :                         state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
    7289              :                     }
    7290       211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) {
    7291            0 :                         state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
    7292              :                     }
    7293       211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) {
    7294            0 :                         state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
    7295              :                     }
    7296       211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) {
    7297            0 :                         state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
    7298              :                     }
    7299       211815 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
    7300              : 
    7301       211815 :                     Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
    7302              : 
    7303              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7304       211815 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
    7305            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7306              :                     }
    7307              : 
    7308       423630 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7309       211815 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7310              :                         // Set variables used in the FD moisture balance and HAMT
    7311            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7312            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7313            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7314            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7315            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7316            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7317            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7318              :                                   state,
    7319            0 :                                   state.dataEnvrn->OutBaroPress,
    7320            0 :                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7321              :                                   Psychrometrics::PsyWFnTdbRhPb(
    7322            0 :                                       state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
    7323            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7324            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7325            0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
    7326            0 :                         state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
    7327            0 :                         state.dataMstBal->HAirFD(SurfNum) = 0.0;  // CR 8046, null out and use only sky term for surface to baffle IR
    7328              :                     }
    7329              : 
    7330              :                     // Call the outside surface temp calculation and pass the necessary terms
    7331       211815 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7332            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7333              : 
    7334       211815 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7335         8124 :                             CalcExteriorVentedCavity(state, SurfNum);
    7336              :                         }
    7337              : 
    7338       211815 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7339       211815 :                         if (MovInsulErrorFlag) {
    7340            0 :                             ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7341              :                         }
    7342              : 
    7343            0 :                     } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7344            0 :                                Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7345            0 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7346            0 :                             CalcExteriorVentedCavity(state, SurfNum);
    7347              :                         }
    7348              :                     }
    7349              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7350       211815 :                 } break;
    7351     45311249 :                 case DataSurfaces::ExternalEnvironment: {
    7352              :                     // checking the EcoRoof presented in the external environment
    7353              :                     // recompute each load by calling ecoroof
    7354              : 
    7355              :                     Real64 TempExt;
    7356              : 
    7357     45311249 :                     if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
    7358       443820 :                         EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
    7359       443820 :                         continue;
    7360              :                     }
    7361              :                     // Roughness index of the exterior surface
    7362     44867429 :                     Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
    7363              :                     // Thermal absorptance of the exterior surface
    7364     44867429 :                     Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
    7365     44867429 :                     HMovInsul = 0;
    7366              :                     // Check for outside movable insulation
    7367     44867429 :                     if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
    7368         4047 :                         HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
    7369              :                     }
    7370              : 
    7371              :                     // Check for exposure to wind (exterior environment)
    7372     44867429 :                     if (Surface(SurfNum).ExtWind) {
    7373              : 
    7374              :                         // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
    7375     44690612 :                         Convect::InitExtConvCoeff(state,
    7376              :                                                   SurfNum,
    7377              :                                                   HMovInsul,
    7378              :                                                   RoughSurf,
    7379              :                                                   AbsThermSurf,
    7380     44690612 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7381     44690612 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7382     44690612 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7383     44690612 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7384     44690612 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7385     44690612 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7386              : 
    7387     44690612 :                         if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
    7388              : 
    7389        11907 :                             if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
    7390        11907 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
    7391              :                             } else { // User set
    7392            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    7393              :                             }
    7394              : 
    7395        11907 :                             TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
    7396              : 
    7397              :                             // start HAMT
    7398        11907 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7399              :                                 // Set variables used in the HAMT moisture balance
    7400            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7401            0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7402            0 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
    7403            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7404            0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7405            0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7406            0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7407            0 :                                                                         state.dataEnvrn->OutBaroPress,
    7408            0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7409              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7410            0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7411              :                                                                                                       1.0,
    7412            0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7413            0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7414            0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7415            0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7416            0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7417            0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7418            0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7419              :                             }
    7420              :                             // end HAMT
    7421        11907 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7422              :                                 // Set variables used in the FD moisture balance
    7423            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7424            0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7425            0 :                                     Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
    7426            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7427            0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7428            0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7429            0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7430            0 :                                                                         state.dataEnvrn->OutBaroPress,
    7431            0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7432              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7433            0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7434              :                                                                                                       1.0,
    7435            0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7436            0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7437            0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7438            0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7439            0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7440            0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7441            0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7442            0 :                                 state.dataMstBal->HSurrFD(SurfNum) = state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum);
    7443              :                             }
    7444              : 
    7445              :                         } else { // Surface is dry, use the normal correlation
    7446              : 
    7447     44678705 :                             TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7448              : 
    7449     87469528 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7450     42790823 :                                 Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7451              :                                 // Set variables used in the FD moisture balance and HAMT
    7452      2032533 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7453      2032533 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7454      2032533 :                                     state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7455      2032533 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7456      2032533 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7457      2032533 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7458      4065066 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7459      2032533 :                                                                         state.dataEnvrn->OutBaroPress,
    7460      2032533 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7461              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7462      2032533 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7463              :                                                                                                       1.0,
    7464      2032533 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7465      2032533 :                                                                                                       RoutineNameExtEnvDrySurf)) +
    7466      4065066 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7467      2032533 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7468              :                                 //  check for saturation conditions of air
    7469              :                                 // Local temporary saturated vapor density for checking
    7470              :                                 Real64 RhoVaporSat =
    7471      2032533 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
    7472      2032533 :                                 if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) {
    7473      1103097 :                                     state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
    7474              :                                 }
    7475      2032533 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7476      2032533 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7477      2032533 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7478      2032533 :                                 state.dataMstBal->HSurrFD(SurfNum) = state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum);
    7479              :                             }
    7480              :                         }
    7481              : 
    7482              :                     } else { // No wind
    7483              : 
    7484              :                         // Calculate exterior heat transfer coefficients for windspeed = 0
    7485       176817 :                         Convect::InitExtConvCoeff(state,
    7486              :                                                   SurfNum,
    7487              :                                                   HMovInsul,
    7488              :                                                   RoughSurf,
    7489              :                                                   AbsThermSurf,
    7490       176817 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7491       176817 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7492       176817 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7493       176817 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7494       176817 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7495       176817 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7496              : 
    7497       176817 :                         TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7498              : 
    7499       346908 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7500       170091 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7501              :                             // Set variables used in the FD moisture balance and HAMT
    7502         6726 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7503         6726 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7504         6726 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7505         6726 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7506         6726 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7507         6726 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7508        13452 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7509         6726 :                                                                     state.dataEnvrn->OutBaroPress,
    7510         6726 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7511              :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7512         6726 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7513              :                                                                                                   1.0,
    7514         6726 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7515         6726 :                                                                                                   RoutineNameNoWind)) +
    7516        13452 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7517         6726 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7518         6726 :                             state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7519         6726 :                             state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7520         6726 :                             state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7521         6726 :                             state.dataMstBal->HSurrFD(SurfNum) = state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum);
    7522              :                         }
    7523              :                     }
    7524              :                     // Calculate LWR from surrounding surfaces if defined for an exterior surface
    7525     44867429 :                     if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
    7526         5412 :                         int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
    7527              :                         // Absolute temperature of the outside surface of an exterior surface
    7528         5412 :                         Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
    7529        13530 :                         for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
    7530              :                              SrdSurfNum++) {
    7531              :                             // View factor of a surrounding surface
    7532         8118 :                             Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
    7533              :                             // Absolute temperature of a surrounding surface
    7534              :                             Real64 SrdSurfTempAbs =
    7535         8118 :                                 state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
    7536         8118 :                                 Constant::Kelvin;
    7537         8118 :                             state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
    7538         8118 :                                 Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
    7539              :                         }
    7540              :                     }
    7541              : 
    7542     44867429 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7543     46910738 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
    7544      2043309 :                         Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7545     42828170 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7546     42828170 :                         if (MovInsulErrorFlag) {
    7547            0 :                             ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7548              :                         }
    7549              :                     }
    7550     44867429 :                 } break;
    7551              : 
    7552       118260 :                 case DataSurfaces::KivaFoundation: {
    7553       118260 :                     auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
    7554       118260 :                     Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
    7555       118260 :                     Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
    7556              : 
    7557              :                     // Set Kiva exterior convection algorithms
    7558       118260 :                     Convect::InitExtConvCoeff(state,
    7559              :                                               SurfNum,
    7560              :                                               HMovInsul,
    7561              :                                               RoughSurf,
    7562              :                                               AbsThermSurf,
    7563       118260 :                                               state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7564       118260 :                                               state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7565       118260 :                                               state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7566       118260 :                                               state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7567       118260 :                                               state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7568       118260 :                                               state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7569       118260 :                 } break;
    7570              : 
    7571    101685398 :                 default: { // for interior or other zone surfaces
    7572              : 
    7573    101685398 :                     if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
    7574              : 
    7575     31831518 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7576              : 
    7577              :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7578              : 
    7579     63517968 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7580     31686450 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7581              :                             // Set variables used in the FD moisture balance HAMT
    7582       145068 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7583       145068 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
    7584       145068 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7585       145068 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7586       145068 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7587       290136 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7588              :                                       state,
    7589       145068 :                                       state.dataEnvrn->OutBaroPress,
    7590       145068 :                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7591              :                                       Psychrometrics::PsyWFnTdbRhPb(
    7592       145068 :                                           state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
    7593       290136 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7594       145068 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7595       145068 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7596       145068 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7597       145068 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7598       145068 :                             state.dataMstBal->HSurrFD(SurfNum) = 0.0;
    7599              :                         }
    7600              : 
    7601              :                     } else { // Interzone partition
    7602              : 
    7603     69853880 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7604     69853880 :                             state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7605              : 
    7606              :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7607              : 
    7608    138564488 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7609     68710608 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7610              :                             // Set variables used in the FD moisture balance and HAMT
    7611      1143272 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7612      1143272 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
    7613      1143272 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
    7614      1143272 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7615      1143272 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7616      2286544 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7617      1143272 :                                                                     state.dataEnvrn->OutBaroPress,
    7618      1143272 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7619              :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7620      1143272 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7621              :                                                                                                   1.0,
    7622      1143272 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7623      1143272 :                                                                                                   RoutineNameIZPart)) +
    7624      2286544 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7625      1143272 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7626      1143272 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7627      1143272 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7628      1143272 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7629      1143272 :                             state.dataMstBal->HSurrFD(SurfNum) = 0.0;
    7630              :                         }
    7631              :                     }
    7632              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7633    101685398 :                 } break;
    7634              :                 }
    7635              : 
    7636    157154904 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
    7637              :             }
    7638     23002081 :         }
    7639              :     } // ...end of DO loop over all surface (actually heat transfer surfaces)
    7640      3699480 : }
    7641              : 
    7642    157154904 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
    7643              : {
    7644    157154904 :     auto const &surface = state.dataSurface->Surface(SurfNum);
    7645    157154904 :     int OPtr = surface.OSCMPtr;
    7646    157154904 :     if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
    7647       211815 :         return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
    7648              :     } else {
    7649    156943089 :         if (state.dataEnvrn->IsRain) {
    7650        43093 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7651        43093 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
    7652              :         } else {
    7653    156899996 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7654    156899996 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
    7655              :         }
    7656              :     }
    7657              : }
    7658              : 
    7659      3732214 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
    7660              :                                ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    7661              : {
    7662      3732214 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
    7663          803 :         if (state.dataHeatBal->AnyEMPD) {
    7664            2 :             state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
    7665              :         }
    7666          803 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    7667           66 :             SetupOutputVariable(state,
    7668              :                                 "Surface Inside Face Heat Balance Calculation Iteration Count",
    7669              :                                 Constant::Units::None,
    7670           22 :                                 state.dataHeatBal->InsideSurfIterations,
    7671              :                                 OutputProcessor::TimeStepType::Zone,
    7672              :                                 OutputProcessor::StoreType::Sum,
    7673              :                                 "Simulation");
    7674              :         }
    7675              :         // Precompute whether CTF temperature limits will be needed
    7676          803 :         state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
    7677         6010 :         for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
    7678        10426 :             for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
    7679         5219 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    7680        50533 :                 for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
    7681        45362 :                     DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
    7682        45362 :                     if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
    7683              :                         (alg == DataSurfaces::HeatTransferModel::Kiva)) {
    7684           48 :                         state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
    7685           48 :                         break;
    7686              :                     }
    7687              :                 }
    7688         5207 :             }
    7689              :         }
    7690          803 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
    7691              :     }
    7692              : 
    7693      3732214 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
    7694         6396 :         state.dataHeatBalSurf->SurfTempInsOld = 23.0;
    7695         6396 :         state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
    7696         6396 :         state.dataHeatBal->SurfTempEffBulkAir = 23.0;
    7697         6396 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
    7698         6396 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
    7699              : 
    7700              :         // Initialize Kiva instances ground temperatures
    7701         6396 :         if (state.dataHeatBal->AnyKiva) {
    7702           63 :             state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
    7703              :         }
    7704              :     }
    7705      3732214 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    7706      3723319 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
    7707              :     }
    7708              : 
    7709      3732214 :     sumSurfQdotRadHVAC(state);
    7710              : 
    7711              :     // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
    7712      3732214 :     bool const PartialResimulate(present(ZoneToResimulate));
    7713              : 
    7714      3732214 :     if (!PartialResimulate) {
    7715      2936115 :         if (state.dataHeatBal->AllCTF) {
    7716      2693116 :             CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
    7717              :         } else {
    7718       485998 :             CalcHeatBalanceInsideSurf2(state,
    7719       242999 :                                        state.dataSurface->AllHTSurfaceList,
    7720       242999 :                                        state.dataSurface->AllIZSurfaceList,
    7721       242999 :                                        state.dataSurface->AllHTNonWindowSurfaceList,
    7722       242999 :                                        state.dataSurface->AllHTWindowSurfaceList);
    7723              :         }
    7724              :     } else {
    7725       796099 :         auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
    7726       796099 :         auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
    7727       796099 :         auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
    7728       796099 :         auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
    7729              :         // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
    7730       796099 :         CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
    7731              :     }
    7732      3732214 :     CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
    7733      3732214 :     UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
    7734      3732214 : }
    7735              : 
    7736      1039098 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
    7737              :                                 const std::vector<int> &HTSurfs,          // Heat transfer surfaces to simulate (opaque and windows)
    7738              :                                 const std::vector<int> &IZSurfs,          // Interzone heat transfer surfaces to simulate
    7739              :                                 const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
    7740              :                                 const std::vector<int> &HTWindowSurfs,    // Window heat transfer surfaces to simulate
    7741              :                                 ObjexxFCL::Optional_int_const ZoneToResimulate)
    7742              : {
    7743              :     // SUBROUTINE INFORMATION:
    7744              :     //       AUTHOR         George Walton
    7745              :     //       DATE WRITTEN   December 1979
    7746              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    7747              :     //                      Dec 1999 (FCW for window calculation)
    7748              :     //                      May 2000 (FCW for window frame and dividers)
    7749              :     //                      Aug 2000 (RJL for MTF moisture calculations)
    7750              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    7751              :     //                      Dec 2000 (RKS for radiant system model addition)
    7752              :     //                      Jul 2003 (CC) set the reference temperatures for inside surface heat balance
    7753              :     //                                    depending on convection algorithms and/or air models used
    7754              :     //                      May 2006 (RR  account for exterior window screen)
    7755              :     //                      Jul 2008 (P. Biddulph include calls to HAMT)
    7756              :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    7757              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    7758              : 
    7759              :     // PURPOSE OF THIS SUBROUTINE:
    7760              :     // This subroutine performs a heat balance on the inside face of each
    7761              :     // surface in the building.
    7762              : 
    7763              :     // METHODOLOGY EMPLOYED:
    7764              :     // Various boundary conditions are set and additional parameters are set-
    7765              :     // up.  Then, the proper heat balance equation is selected based on whether
    7766              :     // the surface is a partition or not and on whether or not movable
    7767              :     // insulation is present on the inside face.
    7768              : 
    7769              :     // REFERENCES:
    7770              :     // (I)BLAST legacy routine HBSRF
    7771              : 
    7772      1039098 :     constexpr std::string_view rhoAirZone("RhoAirZone");
    7773      1039098 :     constexpr std::string_view wsurf("Wsurf");
    7774      1039098 :     constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
    7775      1039098 :     constexpr std::string_view Inside("Inside");
    7776              : 
    7777              :     Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
    7778              :     Real64 SurfTempInSat;  // Local temporary surface dew point temperature
    7779              : 
    7780              :     Real64 Wsurf;         // Moisture ratio for HAMT
    7781              :     Real64 RhoAirZone;    // Zone moisture density for HAMT
    7782              :     int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
    7783              : 
    7784      1039098 :     auto &s_mat = state.dataMaterial;
    7785              :     // determine reference air temperatures
    7786     13649562 :     for (int SurfNum : HTSurfs) {
    7787              : 
    7788              :         // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
    7789     12610464 :         if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7790            0 :             continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7791              :         }
    7792     12610464 :         Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
    7793     12610464 :         state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
    7794     12610464 :         state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
    7795      1039098 :     }
    7796              : 
    7797              :     // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    7798              :     // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    7799              :     // CalcWindowHeatBalance.
    7800              :     // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    7801      1963423 :     for (int surfNum : HTWindowSurfs) {
    7802       924325 :         state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    7803       924325 :         state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    7804       924325 :         state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    7805       924325 :         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    7806       924325 :         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    7807       924325 :         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    7808       924325 :         state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    7809       924325 :         state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    7810       924325 :         state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    7811       924325 :         state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    7812       924325 :         state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    7813       924325 :         state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    7814       924325 :         state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    7815      1039098 :     }
    7816              : 
    7817      1039098 :     state.dataHeatBal->InsideSurfIterations = 0;
    7818              : 
    7819              :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    7820      1039098 :     for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    7821            0 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    7822            0 :             state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
    7823      1039098 :     }
    7824              : 
    7825              :     // Calculate Kiva instances
    7826      1039098 :     if (state.dataHeatBal->AnyKiva) {
    7827        30738 :         if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
    7828        21897 :               state.dataGlobal->TimeStep == 1) ||
    7829        61476 :              state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
    7830        13063 :             !state.dataGlobal->WarmupFlag) {
    7831         9336 :             state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
    7832              :         }
    7833              :     }
    7834              : 
    7835      1039098 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    7836      4133103 :     while (!Converged) {    // Start of main inside heat balance DO loop...
    7837              : 
    7838      3094005 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    7839              : 
    7840      3094005 :         if (state.dataHeatBal->AnyKiva) {
    7841       865799 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7842       663220 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
    7843       202579 :             }
    7844              :         }
    7845              : 
    7846      6188010 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    7847      3094005 :                                                            state.dataHeatBalSurf->SurfTempIn,
    7848      3094005 :                                                            state.dataHeatBal->InsideSurfIterations,
    7849      3094005 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    7850              :                                                            ZoneToResimulate,
    7851              :                                                            Inside); // Update the radiation balance
    7852              : 
    7853      3094005 :         if (state.dataHeatBal->AnyKiva) {
    7854       865799 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7855       663220 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
    7856       202579 :             }
    7857              :         }
    7858              : 
    7859              :         // Every 30 iterations, recalculate the inside convection coefficients in case
    7860              :         // there has been a significant drift in the surface temperatures predicted.
    7861              :         // This is not fool-proof and it basically means that the outside surface
    7862              :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    7863              :         // The choice of 30 is not significant--just want to do this a couple of
    7864              :         // times before the iteration limit is hit.
    7865      5148912 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    7866      2054907 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    7867           67 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    7868              :         }
    7869              : 
    7870      3094005 :         if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    7871      1437866 :             for (int SurfNum : HTSurfs) {
    7872      1330236 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    7873      1330236 :                 if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7874            0 :                     continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7875              :                 }
    7876              : 
    7877              :                 // Calculate the inside surface moisture quantities
    7878              :                 // calculate the inside surface moisture transfer conditions
    7879              :                 // check for saturation conditions of air
    7880      1330236 :                 if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
    7881       626657 :                     (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
    7882      1056940 :                     int ZoneNum = surface.Zone;
    7883      1056940 :                     Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    7884      1056940 :                     Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
    7885      1056940 :                     Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    7886              : 
    7887      1056940 :                     state.dataMstBal->RhoVaporAirIn(SurfNum) =
    7888      1056940 :                         min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
    7889              :                             Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
    7890      1056940 :                     state.dataMstBal->HMassConvInFD(SurfNum) =
    7891      2113880 :                         HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
    7892      1056940 :                                         Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
    7893              :                 }
    7894       107630 :             }
    7895              :         }
    7896              : 
    7897     43739600 :         for (int SurfNum : HTNonWindowSurfs) {
    7898              :             // Perform heat balance on the inside face of the surface ...
    7899              :             // The following are possibilities here:
    7900              :             //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    7901              :             //   (b) the surface is a partition, in which case the temperature of both sides are the same
    7902              :             //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    7903              :             //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    7904              :             //   (e) standard opaque surface with movable insulation, special two-part equation
    7905              :             // In the surface calculation there are the following Algorithm types for opaque surfaces that
    7906              :             // do not have movable insulation:
    7907              :             //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    7908              :             //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    7909              :             //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    7910              :             //   (d) the HAMT calc (solutionalgo = UseHAMT).
    7911              : 
    7912     40645595 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    7913     40645595 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    7914            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    7915            0 :                 if (SurfNum != repSurfNum) {
    7916            0 :                     continue;
    7917              :                 }
    7918              :             }
    7919     40645595 :             int const ZoneNum = surface.Zone;
    7920     40645595 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7921     40645595 :             int const ConstrNum = surface.Construction;
    7922     40645595 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    7923     40645595 :             Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    7924     40645595 :             Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7925              : 
    7926     40645595 :             if (surface.ExtBoundCond == SurfNum) {
    7927              :                 // CR6869 -- let Window HB take care of it      IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
    7928              :                 // Surface is adiabatic
    7929      2270634 :                 if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7930       295824 :                     surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    7931              : 
    7932      1974810 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7933            0 :                         MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    7934            0 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    7935              :                     }
    7936              :                     // Pre-calculate a few terms
    7937              :                     Real64 const TempTerm(
    7938      1974810 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    7939      1974810 :                         state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    7940      1974810 :                         HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    7941      1974810 :                         state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    7942      1974810 :                         (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    7943      1974810 :                     Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    7944              :                     // Calculate the current inside surface temperature
    7945      1974810 :                     if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    7946            0 :                         ((state.dataSurface->SurfIsPool(SurfNum)) &&
    7947            0 :                          (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    7948            0 :                          (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    7949      1974810 :                         if (construct.SourceSinkPresent) {
    7950            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7951            0 :                                 (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    7952            0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7953              :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7954              :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7955              :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7956              :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7957              :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7958              :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7959              :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7960              :                         } else {
    7961      1974810 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7962      1974810 :                                 (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7963              :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7964              :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7965              :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7966              :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7967              :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7968              :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7969              :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7970              :                         }
    7971              :                     } else { // this is a pool and it has been simulated this time step
    7972            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7973            0 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    7974            0 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
    7975            0 :                             (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    7976              :                              DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
    7977              :                         // non-pool equation for details) | Iterative damping term (for stability) |
    7978              :                         // Conduction term (both partition sides same temp) | Pool and damping term
    7979              :                     }
    7980      1974810 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7981            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    7982            0 :                             state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
    7983              :                         // Conduction term (both partition sides same temp) |
    7984              :                         // Convection and damping term
    7985            0 :                         if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    7986            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    7987              :                         }
    7988              :                     }
    7989              :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    7990      1974810 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
    7991       766517 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7992       766517 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    7993       766517 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    7994       766517 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    7995              :                     }
    7996              : 
    7997      1974810 :                     if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    7998              : 
    7999              :                         // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
    8000            0 :                         Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
    8001            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    8002            0 :                             TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
    8003              :                         // radiation from internal sources | Convection from surface to zone air | Radiant flux from
    8004              :                         // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
    8005              :                         // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
    8006              :                         // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
    8007              :                         // term (both partition sides same temp) | Convection and damping term
    8008            0 :                         state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    8009              :                             0.0; // The outside temp is assumed to be equal to the inside temp for a partition
    8010            0 :                         state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    8011            0 :                             construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
    8012              :                         // term (both partition sides same temp) | Convection and damping term
    8013              :                     }
    8014              : 
    8015      2270634 :                 } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    8016            0 :                            surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8017              : 
    8018       295824 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8019            0 :                         HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
    8020              :                                                                   SurfNum,
    8021            0 :                                                                   state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
    8022              :                                                                   TempSurfOutTmp); // HAMT
    8023              :                     }
    8024              : 
    8025       295824 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8026       591648 :                         HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    8027       295824 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8028              :                     }
    8029              : 
    8030       295824 :                     TH11 = TempSurfOutTmp;
    8031              :                 }
    8032              : 
    8033      2270634 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8034              : 
    8035              :             } else { // Standard surface or interzone surface
    8036     38374961 :                 bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
    8037     38374961 :                 if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
    8038              : 
    8039     38374961 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    8040     11664367 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    8041              : 
    8042     27414173 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8043       703579 :                             MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    8044       703579 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    8045              :                         }
    8046              :                         // Pre-calculate a few terms
    8047              :                         Real64 const TempTerm(
    8048     27414173 :                             state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    8049     27414173 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    8050     27414173 :                             HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    8051     27414173 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    8052     27414173 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    8053     27414173 :                         Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    8054              :                         // Calculate the current inside surface temperature
    8055     27414173 :                         if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    8056            0 :                             ((state.dataSurface->SurfIsPool(SurfNum)) &&
    8057            0 :                              (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    8058            0 :                              (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    8059     27414173 :                             if (construct.SourceSinkPresent) {
    8060      1678300 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8061      1678300 :                                     (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    8062      1678300 :                                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8063      1678300 :                                      construct.CTFCross[0] * TH11) *
    8064              :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8065              :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    8066              :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    8067              :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    8068              :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    8069              :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    8070              :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    8071              :                                 // Radiation from AFN ducts
    8072              :                             } else {
    8073     25735873 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8074     25735873 :                                     (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8075     25735873 :                                      construct.CTFCross[0] * TH11) *
    8076              :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8077              :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    8078              :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    8079              :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    8080              :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    8081              :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    8082              :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    8083              :                                 // Radiation from AFN ducts
    8084              :                             }
    8085              :                         } else { // surface is a pool and the pool has been simulated this time step
    8086            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8087            0 :                                 (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    8088            0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
    8089            0 :                                 (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    8090              :                                  DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
    8091              :                             // (see non-pool equation for details) | Iterative damping term (for
    8092              :                             // stability) | Current conduction from | the outside surface |
    8093              :                             // Coefficient for conduction (current time) | Pool and damping term
    8094              :                         }
    8095     27414173 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8096       703579 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    8097       703579 :                                 state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
    8098              :                                 TempDiv; // Coefficient for conduction (current time) | Convection and damping term
    8099       703579 :                             if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    8100            0 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    8101              :                             }
    8102              :                         }
    8103              :                         // if any mixed heat transfer models in zone, apply limits to CTF result
    8104     27414173 :                         if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
    8105      3648198 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
    8106              :                                 DataHeatBalSurface::MinSurfaceTempLimit,
    8107      3648198 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8108      3648198 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8109              :                         }
    8110              : 
    8111     27414173 :                         if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    8112              : 
    8113              :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8114      1678300 :                             Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
    8115      1678300 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    8116      1678300 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8117              :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8118              :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8119              :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8120              :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8121              :                             // sides same temp) | Convection and damping term
    8122      1678300 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    8123      1678300 :                                 construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
    8124              :                             // Cond term (both partition sides same temp) |
    8125              :                             // Convection and damping term
    8126      1678300 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    8127      1678300 :                                 construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
    8128              :                             // partition sides same temp) | Convection and
    8129              :                             // damping term
    8130              : 
    8131      1678300 :                             if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8132              :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8133              :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8134              :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8135              :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8136       270256 :                                 if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
    8137       135128 :                                     int OtherSideSurfNum = surface.ExtBoundCond;
    8138       135128 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8139       135128 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    8140       135128 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8141       135128 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    8142       135128 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8143       135128 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    8144       135128 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    8145       135128 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8146       135128 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
    8147       135128 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8148       135128 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
    8149       135128 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8150              :                                 }
    8151              :                             }
    8152              :                         }
    8153              : 
    8154     38374961 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    8155      1016581 :                                surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8156              : 
    8157     10297568 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8158       353361 :                             if (surface.ExtBoundCond > 0) {
    8159              :                                 // HAMT get the correct other side zone zone air temperature --
    8160            0 :                                 int OtherSideSurfNum = surface.ExtBoundCond;
    8161              :                                 // ZoneNum = surface.Zone;
    8162            0 :                                 OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
    8163            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) =
    8164            0 :                                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
    8165              :                             }
    8166       353361 :                             HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8167              :                         }
    8168              : 
    8169     10297568 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8170     19888414 :                             HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    8171      9944207 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8172              :                         }
    8173              : 
    8174     10297568 :                         TH11 = TempSurfOutTmp;
    8175              : 
    8176     10960788 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
    8177              :                         // Read Kiva results for each surface
    8178       663220 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8179       663220 :                             state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
    8180              : 
    8181       663220 :                         TH11 = 0.0;
    8182              :                     }
    8183              : 
    8184     38374961 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8185              : 
    8186              :                 } else { // Movable insulation present
    8187            0 :                     Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
    8188            0 :                     if (construct.SourceSinkPresent) {
    8189              : 
    8190            0 :                         ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
    8191            0 :                         ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    8192            0 :                         ShowContinueError(state,
    8193            0 :                                           format("interior movable insulation {} for a surface with that construction.",
    8194            0 :                                                  s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
    8195            0 :                         ShowContinueError(state,
    8196              :                                           "This is not currently allowed because the heat balance equations do not currently accommodate "
    8197              :                                           "this combination.");
    8198            0 :                         ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    8199              :                     }
    8200              : 
    8201            0 :                     Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
    8202              : 
    8203            0 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) =
    8204            0 :                         (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    8205            0 :                          construct.CTFCross[0] * TH11 +
    8206            0 :                          F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    8207            0 :                                HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8208            0 :                                state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    8209            0 :                                state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    8210            0 :                                DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
    8211            0 :                         (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8212              : 
    8213            0 :                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8214            0 :                         (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    8215            0 :                          HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
    8216            0 :                          state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
    8217              :                         (HMovInsul);
    8218              :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    8219            0 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
    8220            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8221            0 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    8222            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8223            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8224              :                     }
    8225              :                 }
    8226              :             }
    8227      3094005 :         }
    8228      6456894 :         for (int SurfNum : HTWindowSurfs) {
    8229      3362889 :             auto &surface = state.dataSurface->Surface(SurfNum);
    8230      3362889 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8231            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    8232            0 :                 if (SurfNum != repSurfNum) {
    8233            0 :                     continue;
    8234              :                 }
    8235              :             }
    8236      3362889 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8237      3362889 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
    8238      3362889 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8239      3362889 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8240              :                 // Lookup up the TDD:DOME object
    8241            0 :                 int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8242            0 :                 int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8243              :                 // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8244            0 :                 Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8245              : 
    8246              :                 // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8247              :                 // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8248              :                 //   = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
    8249            0 :                 Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    8250            0 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8251            0 :                     (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    8252            0 :                      state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8253            0 :                      state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    8254            0 :                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8255            0 :                      Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8256            0 :                     (Ueff + HConvIn_surf +
    8257              :                      DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8258              :                                                          // solar | Convection from surface to zone air | Net radiant exchange with
    8259              :                                                          // other zone surfaces | Iterative damping term (for stability) | Current
    8260              :                                                          // conduction from the outside surface | Coefficient for conduction (current
    8261              :                                                          // time) | Convection and damping term
    8262            0 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8263              : 
    8264            0 :                 Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
    8265              : 
    8266              :                 // fill out report vars for components of Window Heat Gain
    8267            0 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
    8268            0 :                     HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
    8269            0 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
    8270            0 :                     state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8271            0 :                     (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
    8272            0 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
    8273            0 :                     state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8274            0 :                         (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8275            0 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
    8276              : 
    8277              :                 // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8278            0 :                 state.dataSurface->SurfWinHeatGain(SurfNum) =
    8279            0 :                     state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
    8280            0 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
    8281            0 :                     surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
    8282              :                 // Net transmitted solar | Convection | IR exchange | IR
    8283              :                 // Zone diffuse interior shortwave reflected back into the TDD
    8284              : 
    8285              :             } else {                                                // Regular window
    8286      3362889 :                 if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8287              :                     // Get outside convection coeff for exterior window here to avoid calling
    8288              :                     // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8289              :                     // (HeatBalanceSurfaceManager USEing and WindowManager and
    8290              :                     // WindowManager USEing HeatBalanceSurfaceManager)
    8291       924325 :                     if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8292       924325 :                         auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
    8293       924325 :                         Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8294       924325 :                         Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8295       924325 :                         DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
    8296       924325 :                         if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8297              :                             // Exterior shade in place
    8298            0 :                             int const ConstrNumSh = surface.activeShadedConstruction;
    8299            0 :                             if (ConstrNumSh != 0) {
    8300            0 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    8301            0 :                                 auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
    8302            0 :                                 assert(thisMaterial2 != nullptr);
    8303            0 :                                 RoughSurf = thisMaterial2->Roughness;
    8304            0 :                                 EmisOut = thisMaterial2->AbsorpThermal;
    8305              :                             }
    8306              :                         }
    8307              : 
    8308              :                         // Get the outside effective emissivity for Equivalent layer model
    8309       924325 :                         if (construct.WindowTypeEQL) {
    8310            0 :                             EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    8311              :                         }
    8312              :                         // Set Exterior Convection Coefficient...
    8313       924325 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8314              : 
    8315            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8316              : 
    8317       924325 :                         } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    8318              : 
    8319              :                             // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    8320              :                             // subroutine)
    8321       924325 :                             Convect::InitExtConvCoeff(state,
    8322              :                                                       SurfNum,
    8323              :                                                       0.0,
    8324              :                                                       RoughSurf,
    8325              :                                                       EmisOut,
    8326              :                                                       TH11,
    8327       924325 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8328       924325 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8329       924325 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8330       924325 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8331       924325 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8332              : 
    8333       924325 :                             if (state.dataEnvrn->IsRain) {                             // Raining: since wind exposed, outside window surface gets wet
    8334            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
    8335              :                             }
    8336              : 
    8337              :                         } else { // Not Wind exposed
    8338              : 
    8339              :                             // Calculate exterior heat transfer coefficients for windspeed = 0
    8340            0 :                             Convect::InitExtConvCoeff(state,
    8341              :                                                       SurfNum,
    8342              :                                                       0.0,
    8343              :                                                       RoughSurf,
    8344              :                                                       EmisOut,
    8345              :                                                       TH11,
    8346            0 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8347            0 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8348            0 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8349            0 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8350            0 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8351              :                         }
    8352              :                     } else { // Interior Surface
    8353              : 
    8354            0 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8355            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8356              :                         } else {
    8357              :                             // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    8358              :                             // same
    8359            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    8360              :                         }
    8361              :                     }
    8362              : 
    8363              :                     // Following call determines inside surface temperature of glazing, and of
    8364              :                     // frame and/or divider, if present
    8365       924325 :                     Window::CalcWindowHeatBalance(
    8366       924325 :                         state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
    8367       924325 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8368              :                 }
    8369              :             }
    8370      3094005 :         } // ...end of inside surface heat balance equation selection
    8371              : 
    8372     47102489 :         for (int SurfNum : HTSurfs) {
    8373     44008484 :             int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
    8374     44008484 :             auto &zone = state.dataHeatBal->Zone(ZoneNum);
    8375     44008484 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8376     44008484 :             Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    8377     44008484 :             TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8378     44008484 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
    8379     44008484 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) {
    8380            0 :                 continue;
    8381              :             }
    8382     44008484 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8383              :                 // Tubular daylighting devices are treated as one big object with an effective R value.
    8384              :                 // The outside face temperature of the TDD:DOME and the inside face temperature of the
    8385              :                 // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    8386              :                 // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    8387              :                 // and the outside face of the TDD:DIFFUSER for reporting.
    8388              : 
    8389              :                 // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    8390            0 :                 int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    8391            0 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    8392            0 :                     state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8393              : 
    8394              :                 // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    8395              :                 // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    8396            0 :                 TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    8397            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    8398              :             }
    8399              : 
    8400     44008484 :             if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8401            0 :                 TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    8402              :             }
    8403              : 
    8404      3094005 :         } // ...end of main loops over all surfaces for inside heat balances
    8405              : 
    8406              :         // Interzone surface updating: interzone surfaces have other side temperatures
    8407              :         // which can vary as the simulation iterates through the inside heat
    8408              :         // balance.  This block is intended to "lock" the opposite side (outside)
    8409              :         // temperatures to the correct value, namely the value calculated by the
    8410              :         // inside surface heat balance for the other side.
    8411              :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    8412              :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    8413     22234717 :         for (int SurfNum : IZSurfs) {
    8414     19140712 :             int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
    8415              :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    8416              :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    8417              :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    8418              :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    8419     19140712 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    8420     19140712 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    8421      3094005 :         }
    8422              : 
    8423      3094005 :         ++state.dataHeatBal->InsideSurfIterations;
    8424              : 
    8425              :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    8426      3094005 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    8427     43739600 :         for (int SurfNum : HTNonWindowSurfs) {
    8428     40645595 :             MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
    8429     40645595 :             if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8430              :                 // also check all internal nodes as well as surface faces
    8431     10240031 :                 MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
    8432              :             }
    8433      3094005 :         } // ...end of loop to check for convergence
    8434              : 
    8435      3094005 :         if (!state.dataHeatBal->AnyCondFD) {
    8436      2082927 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
    8437       688318 :                 Converged = true;
    8438              :             }
    8439              :         } else {
    8440      1011078 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) {
    8441       369583 :                 Converged = true;
    8442              :             }
    8443              : 
    8444              :             // resets relaxation factor to speed up iterations when under-relaxation is not needed.
    8445      1011078 :             if (state.dataHeatBal->InsideSurfIterations <= 1) {
    8446       351700 :                 state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    8447              :             }
    8448      1011078 :             if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
    8449              :                 // adjust relaxation factor down, assume large number of iterations is result of instability
    8450         1739 :                 state.dataHeatBal->CondFDRelaxFactor *= 0.9;
    8451         1739 :                 if (state.dataHeatBal->CondFDRelaxFactor < 0.1) {
    8452         1277 :                     state.dataHeatBal->CondFDRelaxFactor = 0.1;
    8453              :                 }
    8454              :             }
    8455              :         }
    8456              : 
    8457              : #ifdef EP_Count_Calls
    8458              :         state.dataTimingsData->NumMaxInsideSurfIterations =
    8459              :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    8460              : #endif
    8461              : 
    8462      3094005 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
    8463        39240 :             Converged = false;
    8464              :         }
    8465              : 
    8466      3094005 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    8467            0 :             if (!state.dataGlobal->WarmupFlag) {
    8468            0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    8469            0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    8470            0 :                     if (!state.dataHeatBal->AnyCondFD) {
    8471            0 :                         ShowWarningError(state,
    8472            0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8473              :                                                 "Allowed Temp Diff [C] ={:.3R}",
    8474              :                                                 MaxDelTemp,
    8475            0 :                                                 state.dataHeatBal->MaxAllowedDelTemp));
    8476            0 :                         ShowContinueErrorTimeStamp(state, "");
    8477              :                     } else {
    8478            0 :                         ShowWarningError(state,
    8479            0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8480              :                                                 "Allowed Temp Diff [C] ={:.6R}",
    8481              :                                                 MaxDelTemp,
    8482            0 :                                                 state.dataHeatBal->MaxAllowedDelTempCondFD));
    8483            0 :                         ShowContinueErrorTimeStamp(state, "");
    8484              :                     }
    8485              :                 } else {
    8486            0 :                     ShowRecurringWarningErrorAtEnd(state,
    8487              :                                                    "Inside surface heat balance convergence problem continues",
    8488            0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    8489              :                                                    MaxDelTemp,
    8490              :                                                    MaxDelTemp,
    8491              :                                                    _,
    8492              :                                                    "[C]",
    8493              :                                                    "[C]");
    8494              :                 }
    8495              :             }
    8496            0 :             break; // iteration loop
    8497              :         }
    8498              : 
    8499              :     } // ...end of main inside heat balance DO loop (ends when Converged)
    8500              : 
    8501              :     // Update SumHmXXXX for non-window EMPD or HAMT surfaces
    8502      1039098 :     if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    8503              : 
    8504              :         // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
    8505        94956 :         for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
    8506        54963 :             thisZoneHB.SumHmAW = 0.0;
    8507        54963 :             thisZoneHB.SumHmARa = 0.0;
    8508        54963 :             thisZoneHB.SumHmARaW = 0.0;
    8509        39993 :         }
    8510              : 
    8511       381747 :         for (int SurfNum : HTNonWindowSurfs) {
    8512       341754 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    8513       341754 :             int ZoneNum = surface.Zone;
    8514       341754 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    8515              : 
    8516       341754 :             if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8517       171564 :                 HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
    8518              : 
    8519       171564 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8520              : 
    8521       171564 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8522              : 
    8523       171564 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
    8524       514692 :                 RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
    8525              :                     state,
    8526       171564 :                     state.dataEnvrn->OutBaroPress,
    8527              :                     MAT_zone,
    8528       171564 :                     Psychrometrics::PsyWFnTdbRhPb(
    8529              :                         state,
    8530              :                         MAT_zone,
    8531       171564 :                         Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
    8532       171564 :                         state.dataEnvrn->OutBaroPress));
    8533              : 
    8534       171564 :                 Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
    8535              :                 Wsurf =
    8536       343128 :                     Psychrometrics::PsyWFnTdbRhPb(state,
    8537              :                                                   surfInTemp,
    8538       171564 :                                                   Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
    8539       171564 :                                                   state.dataEnvrn->OutBaroPress);
    8540              : 
    8541       171564 :                 thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
    8542              : 
    8543       171564 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
    8544              : 
    8545       170190 :             } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8546              :                 // need to calculate the amount of moisture that is entering or
    8547              :                 // leaving the zone  Qm [kg/sec] = hmi * Area * (Del Rhov)
    8548              :                 // {Hmi [m/sec];     Area [m2];    Rhov [kg moist/m3]  }
    8549              :                 // Positive values are into the zone and negative values are
    8550              :                 // leaving the zone.  SumHmAw is the sum of the moisture entering or
    8551              :                 // leaving the zone from all of the surfaces and is a rate.  Multiply
    8552              :                 // by time to get the actual amount affecting the zone volume of air.
    8553              : 
    8554       150018 :                 MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
    8555       150018 :                 state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
    8556       150018 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8557       150018 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8558       150018 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    8559       150018 :                 thisZoneHB.SumHmARa +=
    8560       150018 :                     FD_Area_fac *
    8561       450054 :                     Psychrometrics::PsyRhoAirFnPbTdbW(
    8562              :                         state,
    8563       150018 :                         state.dataEnvrn->OutBaroPress,
    8564              :                         MAT_zone,
    8565       150018 :                         Psychrometrics::PsyWFnTdbRhPb(state,
    8566              :                                                       MAT_zone,
    8567       150018 :                                                       Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
    8568       150018 :                                                       state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
    8569              :                 // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
    8570       150018 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
    8571              :             }
    8572        39993 :         }
    8573              :     }
    8574      1039098 : }
    8575              : 
    8576      2693116 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
    8577              :                                        const int FirstZone,             // First zone to simulate
    8578              :                                        const int LastZone,              // Last zone to simulate
    8579              :                                        const std::vector<int> &IZSurfs, // Last zone to simulate
    8580              :                                        ObjexxFCL::Optional_int_const ZoneToResimulate)
    8581              : {
    8582              : 
    8583              :     // This function performs a heat balance on the inside face of each
    8584              :     // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
    8585              :     // simplified for CTF surfaces only.
    8586              : 
    8587              :     // REFERENCES:
    8588              :     // (I)BLAST legacy routine HBSRF
    8589              : 
    8590      2693116 :     auto &s_mat = state.dataMaterial;
    8591      2693116 :     auto &Surface = state.dataSurface->Surface;
    8592              : 
    8593      2693116 :     constexpr std::string_view Inside("Inside");
    8594              : 
    8595      2693116 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
    8596              :         // Set up coefficient arrays that never change - loop over non-window HT surfaces
    8597         5897 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8598        10250 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8599         5131 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8600         5131 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8601         5131 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8602        43725 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8603        38594 :                     int const ConstrNum = Surface(surfNum).Construction;
    8604        38594 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8605        38594 :                     if (Surface(surfNum).ExtBoundCond == surfNum) {
    8606         6944 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
    8607              :                     } else {
    8608        31650 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
    8609              :                     }
    8610        38594 :                     if (construct.SourceSinkPresent) {
    8611          127 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
    8612              :                     } else {
    8613        38467 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
    8614              :                     }
    8615              :                 }
    8616         5119 :             }
    8617              :         }
    8618              : 
    8619          778 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
    8620              :     }
    8621              : 
    8622     22496124 :     for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8623     39654616 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8624     19851608 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8625              :             // loop over all heat transfer surface except TDD Dome.
    8626     19851608 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    8627     19851608 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    8628              :             // determine reference air temperatures and other variable terms - loop over all surfaces
    8629    189497629 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8630    169646021 :                 auto const &surface = Surface(surfNum);
    8631    169646021 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8632       198018 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8633       198018 :                     if (surfNum != repSurfNum) {
    8634        44802 :                         continue;
    8635              :                     }
    8636              :                 }
    8637              : 
    8638    169601219 :                 int const ConstrNum = Surface(surfNum).Construction;
    8639    169601219 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8640    169601219 :                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
    8641    169601219 :                 state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
    8642    169601219 :                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
    8643    169601219 :                 state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    8644    169601219 :                 if (construct.SourceSinkPresent) {
    8645       791424 :                     state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
    8646              :                 }
    8647              : 
    8648              :                 // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
    8649    169601219 :                 if (state.dataSurface->SurfIsPool(surfNum)) {
    8650        51624 :                     if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
    8651         8092 :                         (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
    8652        35440 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
    8653              :                     } else {
    8654         8092 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
    8655              :                     }
    8656              :                 }
    8657    169601219 :                 Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
    8658    169601219 :                 state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
    8659    169601219 :                 state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
    8660              :             }
    8661              : 
    8662              :             // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    8663              :             // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    8664              :             // CalcWindowHeatBalance.
    8665              :             // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    8666     19851608 :             int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8667     19851608 :             int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8668     42279734 :             for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8669     22428126 :                 state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    8670     22428126 :                 state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    8671     22428126 :                 state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    8672     22428126 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    8673     22428126 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    8674     22428126 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    8675     22428126 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    8676     22428126 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    8677     22428126 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    8678     22428126 :                 state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    8679     22428126 :                 state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    8680     22428126 :                 state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    8681     22428126 :                 state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    8682              :             }
    8683              : 
    8684              :             // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    8685     19876754 :             for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    8686        25146 :                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    8687        25146 :                     state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
    8688     19851608 :             }
    8689              : 
    8690              :             // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
    8691     19851608 :             int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8692     19851608 :             int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8693     19851608 :             Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8694     19851608 :             Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8695              :             // this loop auto-vectorizes
    8696    167069503 :             for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8697    147217895 :                 auto const &surface = Surface(surfNum);
    8698    147217895 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8699       137142 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8700       137142 :                     if (surfNum != repSurfNum) {
    8701         5814 :                         continue;
    8702              :                     }
    8703              :                 }
    8704              : 
    8705              :                 // Pre-calculate a few terms before the iteration loop
    8706    147212081 :                 state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8707    147212081 :                     state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8708    147212081 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8709    147212081 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8710    147212081 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8711    147212081 :                     (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8712    147212081 :                 state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8713    147212081 :                     1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8714    147212081 :                            state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8715    147212081 :                            state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8716    147212081 :                            (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
    8717              :             }
    8718     19803008 :         }
    8719              :     }
    8720              : 
    8721      2693116 :     state.dataHeatBal->InsideSurfIterations = 0;
    8722      2693116 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    8723     13605689 :     while (!Converged) {    // Start of main inside heat balance iteration loop...
    8724              : 
    8725     10912573 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    8726              : 
    8727     21825146 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    8728     10912573 :                                                            state.dataHeatBalSurf->SurfTempIn,
    8729     10912573 :                                                            state.dataHeatBal->InsideSurfIterations,
    8730     10912573 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    8731              :                                                            ZoneToResimulate,
    8732              :                                                            Inside); // Update the radiation balance
    8733              : 
    8734              :         // Every 30 iterations, recalculate the inside convection coefficients in case
    8735              :         // there has been a significant drift in the surface temperatures predicted.
    8736              :         // This is not fool-proof and it basically means that the outside surface
    8737              :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    8738              :         // The choice of 30 is not significant--just want to do this a couple of
    8739              :         // times before the iteration limit is hit.
    8740     19132030 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    8741      8219457 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    8742         1759 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    8743              :             // Since HConvIn has changed re-calculate a few terms - non-window surfaces
    8744        12364 :             for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8745        21210 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8746        10605 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8747        10605 :                     int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8748        10605 :                     int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8749              : 
    8750        10605 :                     Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8751        10605 :                     Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8752              :                     // this loop auto-vectorizes
    8753        91810 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8754        81205 :                         auto const &surface = Surface(surfNum);
    8755        81205 :                         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8756            0 :                             int repSurfNum = surface.RepresentativeCalcSurfNum;
    8757            0 :                             if (surfNum != repSurfNum) {
    8758            0 :                                 continue;
    8759              :                             }
    8760              :                         }
    8761              : 
    8762        81205 :                         state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8763        81205 :                             state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8764        81205 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8765        81205 :                             state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8766        81205 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8767        81205 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8768        81205 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8769        81205 :                             1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8770        81205 :                                    state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8771        81205 :                                    state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8772        81205 :                                    (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
    8773              :                                    iterDampConstant);
    8774              :                     }
    8775        10605 :                 }
    8776              :             }
    8777              :         }
    8778              : 
    8779              :         // Loop over non-window surfaces
    8780    102553364 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8781    183507802 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8782     91867011 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8783     91867011 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8784     91867011 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8785     91867011 :                 Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
    8786              :                 // this loop auto-vectorizes
    8787    778404749 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8788              :                     // Perform heat balance on the inside face of the surface ...
    8789              :                     // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
    8790              :                     //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    8791              :                     //   (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
    8792              :                     //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    8793              :                     //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    8794              :                     //   (e) standard opaque surface with movable insulation, special two-part equation
    8795              :                     // In the surface calculation there are the following Algorithm types for opaque surfaces that
    8796              :                     // do not have movable insulation:
    8797              :                     //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    8798              :                     //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    8799              :                     //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    8800              :                     //   (d) the HAMT calc (solutionalgo = UseHAMT).
    8801              : 
    8802              :                     // For adiabatic surface:
    8803              :                     // Adiabatic:   TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
    8804              :                     // Adiabatic:   SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8805              :                     // Ad+Source:   SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
    8806              :                     // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool:     TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
    8807              :                     // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool:     SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
    8808              :                     // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8809              : 
    8810              :                     // For standard or interzone surface:
    8811              :                     // Standard:    TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
    8812              :                     // Standard:    SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
    8813              :                     // TempDiv; Std+Source:  SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
    8814              :                     // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool:    TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
    8815              :                     // IterDampConst); Std+Pool:    SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
    8816              :                     // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
    8817              : 
    8818              :                     // Composite with Adiabatic/Source/Pool flags:
    8819              :                     //              TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
    8820              :                     //              SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
    8821              :                     //              SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
    8822              :                     //              SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
    8823              :                     //                                        + IterDampConst * SurfTempInsOld(SurfNum)+
    8824              :                     //                                        IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
    8825              :                     //                                        * TH11) * TempDiv;
    8826              : 
    8827              :                     // Calculate the current inside surface temperature
    8828    686537738 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8829    686537738 :                         ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
    8830    686537738 :                              (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
    8831    686537738 :                          state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
    8832    686537738 :                              state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
    8833    686537738 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
    8834    686537738 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
    8835    686537738 :                          iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8836    686537738 :                          (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
    8837    686537738 :                              state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
    8838    686537738 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum);
    8839              :                     // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8840              :                     // radiation from internal sources | Convection from surface to zone air | Net radiant
    8841              :                     // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
    8842              :                     // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
    8843              :                     // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
    8844              :                     // an electric baseboard heater | Iterative damping term (for stability) | Current
    8845              :                     // conduction from | the outside surface | Coefficient for conduction (current time) |
    8846              :                     // Convection and damping term | Radiation from AFN ducts
    8847              : 
    8848    686537738 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8849              :                 }
    8850              : 
    8851              :                 // Loop over non-window surfaces (includes TubularDaylightingDomes)
    8852    778404749 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8853    686537738 :                     auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
    8854              : 
    8855    686537738 :                     bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
    8856    686537738 :                     if (movableInsulPresent) { // Movable insulation present, recalc surface temps
    8857        16981 :                         Real64 HMovInsul = movInsul.H;
    8858        16981 :                         Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
    8859        16981 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) =
    8860        16981 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8861        16981 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
    8862        16981 :                              F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8863        16981 :                                    state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8864        16981 :                                    state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8865        16981 :                                    state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8866        16981 :                                    state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8867        16981 :                                    DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
    8868        16981 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8869              : 
    8870        16981 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8871        16981 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
    8872        16981 :                              HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
    8873        16981 :                              state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
    8874        16981 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
    8875              :                             (HMovInsul);
    8876              :                     }
    8877              : 
    8878    686537738 :                     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    8879     12269820 :                         if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
    8880              :                             // Set the appropriate parameters for the radiant system
    8881              :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8882              :                             Real64 const RadSysDiv(1.0 /
    8883      2445348 :                                                    (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    8884              :                             Real64 const TempTerm(
    8885      2445348 :                                 state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8886      2445348 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8887      2445348 :                                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8888      2445348 :                                 state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8889      2445348 :                                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8890      2445348 :                                 (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
    8891      2445348 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
    8892      2445348 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8893              :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8894              :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8895              :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8896              :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8897              :                             // sides same temp) | Convection and damping term
    8898      2445348 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
    8899      2445348 :                                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
    8900              :                             // Cond term (both partition sides same temp) |
    8901              :                             // Convection and damping term
    8902      2445348 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
    8903      2445348 :                                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
    8904              :                             // partition sides same temp) | Convection and
    8905              :                             // damping term
    8906              : 
    8907      2445348 :                             if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8908              :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8909              :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8910              :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8911              :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8912       968842 :                                 if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
    8913       484421 :                                     int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
    8914       484421 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8915       484421 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
    8916       484421 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8917       484421 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
    8918       484421 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8919       484421 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
    8920       484421 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
    8921       484421 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8922       484421 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
    8923       484421 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8924       484421 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
    8925       484421 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8926              :                                 }
    8927              :                             }
    8928              :                         }
    8929              :                     }
    8930              :                 }
    8931              : 
    8932              :                 // Loop over window surfaces
    8933     91867011 :                 int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8934     91867011 :                 int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8935    193638700 :                 for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8936    101771689 :                     auto &surface = state.dataSurface->Surface(surfNum);
    8937    101771689 :                     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8938       166430 :                         int repSurfNum = surface.RepresentativeCalcSurfNum;
    8939       166430 :                         if (surfNum != repSurfNum) {
    8940       106590 :                             continue;
    8941              :                         }
    8942              :                     }
    8943    101665099 :                     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
    8944    101665099 :                     int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    8945    101665099 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8946    101665099 :                     if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8947              :                         // Lookup up the TDD:DOME object
    8948        20832 :                         int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    8949        20832 :                         int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8950              :                         // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8951        20832 :                         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8952              : 
    8953              :                         // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8954              :                         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8955              :                         //   = SurfWinQRadSWwinAbs(surfNum,1)/2.0
    8956        20832 :                         Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
    8957        20832 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8958        20832 :                             (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
    8959        20832 :                              state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8960        20832 :                              HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8961        20832 :                              state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8962        20832 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8963        20832 :                              Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8964        20832 :                             (Ueff + HConvIn_surf +
    8965              :                              DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8966              :                                                                  // solar | Convection from surface to zone air | Net radiant exchange with
    8967              :                                                                  // other zone surfaces | Iterative damping term (for stability) | Current
    8968              :                                                                  // conduction from the outside surface | Coefficient for conduction (current
    8969              :                                                                  // time) | Convection and damping term
    8970        20832 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8971        20832 :                         Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
    8972              : 
    8973              :                         // fill out report vars for components of Window Heat Gain
    8974        20832 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    8975        41664 :                             HConvIn_surf * surface.Area *
    8976        20832 :                             (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    8977        20832 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    8978        20832 :                             state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8979        20832 :                             (Sigma_Temp_4 -
    8980        20832 :                              (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
    8981        20832 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    8982        20832 :                             state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8983        20832 :                                 (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8984        20832 :                             state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
    8985              : 
    8986              :                         // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8987        20832 :                         state.dataSurface->SurfWinHeatGain(surfNum) =
    8988        20832 :                             state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
    8989        20832 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
    8990        20832 :                             surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
    8991              :                         // Net transmitted solar | Convection | IR exchange | IR
    8992              :                         // Zone diffuse interior shortwave reflected back into the TDD
    8993              :                     } else {                                                // Regular window
    8994    101644267 :                         if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8995              :                             // Get outside convection coeff for exterior window here to avoid calling
    8996              :                             // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8997              :                             // (HeatBalanceSurfaceManager USEing and WindowManager and
    8998              :                             // WindowManager USEing HeatBalanceSurfaceManager)
    8999     22385088 :                             if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    9000     22357896 :                                 auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
    9001     22357896 :                                 assert(thisMaterial != nullptr);
    9002     22357896 :                                 Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    9003     22357896 :                                 Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    9004     22357896 :                                 DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
    9005     22357896 :                                 if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    9006              :                                     // Exterior shade in place
    9007        31665 :                                     int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
    9008        31665 :                                     if (ConstrNumSh != 0) {
    9009        21522 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    9010        21522 :                                         auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
    9011        21522 :                                         RoughSurf = thisMaterial2->Roughness;
    9012        21522 :                                         EmisOut = thisMaterial2->AbsorpThermal;
    9013              :                                     }
    9014              :                                 }
    9015              : 
    9016              :                                 // Get the outside effective emissivity for Equivalent layer model
    9017     22357896 :                                 if (construct.WindowTypeEQL) {
    9018         8109 :                                     EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    9019              :                                 }
    9020              :                                 // Set Exterior Convection Coefficient...
    9021     22357896 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    9022              : 
    9023            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    9024              : 
    9025     22357896 :                                 } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    9026              : 
    9027              :                                     // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    9028              :                                     // subroutine)
    9029     22357896 :                                     Convect::InitExtConvCoeff(state,
    9030              :                                                               surfNum,
    9031              :                                                               0.0,
    9032              :                                                               RoughSurf,
    9033              :                                                               EmisOut,
    9034              :                                                               TH11,
    9035     22357896 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    9036     22357896 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    9037     22357896 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    9038     22357896 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    9039     22357896 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    9040              : 
    9041     22357896 :                                     if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    9042         5882 :                                         state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
    9043              :                                     }
    9044              : 
    9045              :                                 } else { // Not Wind exposed
    9046              : 
    9047              :                                     // Calculate exterior heat transfer coefficients for windspeed = 0
    9048            0 :                                     Convect::InitExtConvCoeff(state,
    9049              :                                                               surfNum,
    9050              :                                                               0.0,
    9051              :                                                               RoughSurf,
    9052              :                                                               EmisOut,
    9053              :                                                               TH11,
    9054            0 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    9055            0 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    9056            0 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    9057            0 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    9058            0 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    9059              :                                 }
    9060              : 
    9061              :                             } else { // Interior Surface
    9062              : 
    9063        27192 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    9064            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    9065              :                                 } else {
    9066              :                                     // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    9067              :                                     // same
    9068        27192 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    9069              :                                 }
    9070              :                             }
    9071              : 
    9072              :                             // Following call determines inside surface temperature of glazing, and of
    9073              :                             // frame and/or divider, if present
    9074     22385088 :                             Window::CalcWindowHeatBalance(
    9075     22385088 :                                 state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
    9076     22385088 :                             state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    9077              :                         }
    9078              :                     }
    9079              :                 }
    9080              : 
    9081     91867011 :                 int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    9082     91867011 :                 int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    9083    880176438 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    9084    788309427 :                     auto &zone = state.dataHeatBal->Zone(zoneNum);
    9085              : 
    9086    788309427 :                     Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    9087    788309427 :                     Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
    9088    788309427 :                     TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
    9089    788309427 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11;                                                  // For reporting
    9090    788309427 :                     if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    9091              :                         // Tubular daylighting devices are treated as one big object with an effective R value.
    9092              :                         // The outside face temperature of the TDD:DOME and the inside face temperature of the
    9093              :                         // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    9094              :                         // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    9095              :                         // and the outside face of the TDD:DIFFUSER for reporting.
    9096              : 
    9097              :                         // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    9098        20832 :                         int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
    9099        20832 :                         state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    9100        20832 :                             state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
    9101              : 
    9102              :                         // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    9103              :                         // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    9104        20832 :                         TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    9105        20832 :                             state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    9106              :                     }
    9107              : 
    9108    788309427 :                     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    9109            0 :                         TestSurfTempCalcHeatBalanceInsideSurf(
    9110            0 :                             state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    9111              :                     }
    9112              :                 }
    9113     91640791 :             }
    9114              :         } // ...end of main loops over all surfaces for inside heat balances
    9115              : 
    9116              :         // Interzone surface updating: interzone surfaces have other side temperatures
    9117              :         // which can vary as the simulation iterates through the inside heat
    9118              :         // balance.  This block is intended to "lock" the opposite side (outside)
    9119              :         // temperatures to the correct value, namely the value calculated by the
    9120              :         // inside surface heat balance for the other side.
    9121              :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    9122              :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    9123    326734571 :         for (int SurfNum : IZSurfs) {
    9124    315821998 :             int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
    9125              :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    9126              :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    9127              :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    9128              :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    9129    315821998 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    9130    315821998 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    9131    315821998 :             state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
    9132     10912573 :         }
    9133              : 
    9134     10912573 :         ++state.dataHeatBal->InsideSurfIterations;
    9135              : 
    9136              :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    9137     10912573 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    9138    102553364 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    9139    183507802 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    9140     91867011 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    9141     91867011 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    9142     91867011 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    9143    778404749 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    9144    686537738 :                     Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
    9145    686537738 :                     Real64 absDif = std::abs(delta);
    9146    686537738 :                     MaxDelTemp = std::max(absDif, MaxDelTemp);
    9147              :                 }
    9148     91640791 :             }
    9149              :         } // ...end of loop to check for convergence
    9150              : 
    9151     10912573 :         if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
    9152      2693116 :             Converged = true;
    9153              :         }
    9154              : 
    9155              : #ifdef EP_Count_Calls
    9156              :         state.dataTimingsData->NumMaxInsideSurfIterations =
    9157              :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    9158              : #endif
    9159              : 
    9160     10912573 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
    9161            0 :             Converged = false;
    9162              :         }
    9163              : 
    9164     10912573 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    9165            0 :             if (!state.dataGlobal->WarmupFlag) {
    9166            0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    9167            0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    9168            0 :                     ShowWarningError(state,
    9169            0 :                                      format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
    9170              :                                             "Temp Diff [C] ={:.6R}",
    9171              :                                             MaxDelTemp,
    9172            0 :                                             state.dataHeatBal->MaxAllowedDelTempCondFD));
    9173            0 :                     ShowContinueErrorTimeStamp(state, "");
    9174              :                 } else {
    9175            0 :                     ShowRecurringWarningErrorAtEnd(state,
    9176              :                                                    "Inside surface heat balance convergence problem continues",
    9177            0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    9178              :                                                    MaxDelTemp,
    9179              :                                                    MaxDelTemp,
    9180              :                                                    _,
    9181              :                                                    "[C]",
    9182              :                                                    "[C]");
    9183              :                 }
    9184              :             }
    9185            0 :             break; // iteration loop
    9186              :         }
    9187              : 
    9188              :     } // ...end of main inside heat balance iteration loop (ends when Converged)
    9189      2693116 : }
    9190              : 
    9191      3732214 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
    9192              : {
    9193      6873660 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
    9194      3141446 :         auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
    9195      3141446 :         state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
    9196      3141446 :                                                                    thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
    9197      3141446 :                                                                    thisSurfQRadFromHVAC.CoolingPanel;
    9198      3732214 :     }
    9199      3732214 : }
    9200              : 
    9201            0 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
    9202              : {
    9203            0 :     std::string surfName = state.dataSurface->Surface(SurfNum).Name;
    9204              : 
    9205            0 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    9206            0 :         if (state.dataGlobal->WarmupFlag) {
    9207            0 :             ++WarmupSurfTemp;
    9208              :         }
    9209            0 :         if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
    9210            0 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
    9211            0 :                 if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
    9212            0 :                     ShowSevereMessage(
    9213            0 :                         state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9214            0 :                     ShowContinueErrorTimeStamp(state, "");
    9215            0 :                     if (!zone.TempOutOfBoundsReported) {
    9216            0 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9217            0 :                         if (zone.FloorArea > 0.0) {
    9218            0 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9219              :                         } else {
    9220            0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9221              :                         }
    9222            0 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9223            0 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9224            0 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9225              :                         } else {
    9226            0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9227              :                         }
    9228            0 :                         if (zone.IsControlled) {
    9229            0 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9230              :                         } else {
    9231            0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9232              :                         }
    9233            0 :                         zone.TempOutOfBoundsReported = true;
    9234              :                     }
    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              :                 } else {
    9244            0 :                     ShowRecurringSevereErrorAtEnd(state,
    9245            0 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9246            0 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9247              :                                                   TH12,
    9248              :                                                   TH12,
    9249              :                                                   _,
    9250              :                                                   "C",
    9251              :                                                   "C");
    9252              :                 }
    9253              :             } else {
    9254            0 :                 if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
    9255            0 :                     ShowSevereMessage(
    9256            0 :                         state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9257            0 :                     ShowContinueErrorTimeStamp(state, "");
    9258            0 :                     if (!zone.TempOutOfBoundsReported) {
    9259            0 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9260            0 :                         if (zone.FloorArea > 0.0) {
    9261            0 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9262              :                         } else {
    9263            0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9264              :                         }
    9265            0 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9266            0 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9267            0 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9268              :                         } else {
    9269            0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9270              :                         }
    9271            0 :                         if (zone.IsControlled) {
    9272            0 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9273              :                         } else {
    9274            0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9275              :                         }
    9276            0 :                         zone.TempOutOfBoundsReported = true;
    9277              :                     }
    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              :                 } else {
    9287            0 :                     ShowRecurringSevereErrorAtEnd(state,
    9288            0 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9289            0 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9290              :                                                   TH12,
    9291              :                                                   TH12,
    9292              :                                                   _,
    9293              :                                                   "C",
    9294              :                                                   "C");
    9295              :                 }
    9296              :             }
    9297            0 :             if (zone.EnforcedReciprocity) {
    9298            0 :                 if (WarmupSurfTemp > 3) {
    9299            0 :                     ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
    9300            0 :                     ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
    9301            0 :                     ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9302              :                 }
    9303            0 :             } else if (WarmupSurfTemp > 10) {
    9304            0 :                 ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9305              :             }
    9306              :         }
    9307              :     }
    9308            0 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
    9309            0 :         if (!state.dataGlobal->WarmupFlag) {
    9310            0 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
    9311            0 :                 ShowSevereError(state,
    9312            0 :                                 format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9313            0 :                 ShowContinueErrorTimeStamp(state, "");
    9314            0 :                 if (!zone.TempOutOfBoundsReported) {
    9315            0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9316            0 :                     if (zone.FloorArea > 0.0) {
    9317            0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9318              :                     } else {
    9319            0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9320              :                     }
    9321            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9322            0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9323            0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9324              :                     } else {
    9325            0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9326              :                     }
    9327            0 :                     if (zone.IsControlled) {
    9328            0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9329              :                     } else {
    9330            0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9331              :                     }
    9332            0 :                     zone.TempOutOfBoundsReported = true;
    9333              :                 }
    9334            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9335              :             } else {
    9336            0 :                 ShowSevereError(state,
    9337            0 :                                 format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9338            0 :                 ShowContinueErrorTimeStamp(state, "");
    9339            0 :                 if (!zone.TempOutOfBoundsReported) {
    9340            0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9341            0 :                     if (zone.FloorArea > 0.0) {
    9342            0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9343              :                     } else {
    9344            0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9345              :                     }
    9346            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9347            0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9348            0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9349              :                     } else {
    9350            0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9351              :                     }
    9352            0 :                     if (zone.IsControlled) {
    9353            0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9354              :                     } else {
    9355            0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9356              :                     }
    9357            0 :                     zone.TempOutOfBoundsReported = true;
    9358              :                 }
    9359            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9360              :             }
    9361              :         } else {
    9362            0 :             if (TH12 < -10000. || TH12 > 10000.) {
    9363            0 :                 ShowSevereError(
    9364              :                     state,
    9365            0 :                     format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9366            0 :                 ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
    9367            0 :                 ShowContinueErrorTimeStamp(state, "");
    9368            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9369              :             }
    9370              :         }
    9371              :     }
    9372            0 : }
    9373              : 
    9374     43041338 : void CalcOutsideSurfTemp(EnergyPlusData &state,
    9375              :                          int const SurfNum,      // Surface number DO loop counter
    9376              :                          int const spaceNum,     // Space number the current surface is attached to
    9377              :                          int const ConstrNum,    // Construction index for the current surface
    9378              :                          Real64 const HMovInsul, // "Convection" coefficient of movable insulation
    9379              :                          Real64 const TempExt,   // Exterior temperature boundary condition
    9380              :                          bool &ErrorFlag         // Error flag for movable insulation problem
    9381              : )
    9382              : {
    9383              : 
    9384              :     // SUBROUTINE INFORMATION:
    9385              :     //       AUTHOR         George Walton
    9386              :     //       DATE WRITTEN   December 1979
    9387              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    9388              :     //                      Jul 2000 (RJL for Moisture algorithms)
    9389              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    9390              :     //                      Dec 2000 (RKS for radiant system model addition)
    9391              :     //                      Aug 2010 (BG added radiant heat flow rate reporting)
    9392              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    9393              : 
    9394              :     // PURPOSE OF THIS SUBROUTINE:
    9395              :     // This subroutine performs a heat balance on the outside face of each
    9396              :     // surface in the building.  NOTE that this also sets some coefficients
    9397              :     // that are needed for radiant system modeling.  Thus, it is extremely
    9398              :     // important that if someone makes changes to the heat balance equations
    9399              :     // at a later date that they must also make changes to the coefficient
    9400              :     // setting portion of this subroutine as well.
    9401              : 
    9402              :     // METHODOLOGY EMPLOYED:
    9403              :     // Various boundary conditions are set and additional parameters are set-
    9404              :     // up.  Then, the proper heat balance equation is selected based on the
    9405              :     // presence of movable insulation, thermal mass of the surface construction,
    9406              :     // and convection model being used.
    9407              : 
    9408              :     // REFERENCES:
    9409              :     // (I)BLAST legacy routine HBOUT
    9410              :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    9411              : 
    9412              :     // Determine whether or not movable insulation is present
    9413     43041338 :     bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
    9414              :     bool QuickConductionSurf;                 // .TRUE. if the cross CTF term is relatively large
    9415              :     Real64 F1;                                // Intermediate calculation variable
    9416              :     Real64 F2;                                // Intermediate calculation variable
    9417              :     // Determine whether this surface is a "slow conductive" or "quick conductive"
    9418              :     // surface.  Designates are inherited from BLAST.  Basically, a "quick" surface
    9419              :     // requires the inside heat balance to be accounted for in the heat balance
    9420              :     // while a "slow" surface can used the last time step's value for inside
    9421              :     // surface temperature.
    9422     43041338 :     auto &s_mat = state.dataMaterial;
    9423              : 
    9424     43041338 :     auto &surface = state.dataSurface->Surface(SurfNum);
    9425     43041338 :     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    9426     43041338 :     if (construct.CTFCross[0] > 0.01) {
    9427      4728312 :         QuickConductionSurf = true;
    9428      4728312 :         F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    9429              :     } else {
    9430     38313026 :         QuickConductionSurf = false;
    9431              :     }
    9432              : 
    9433     43041338 :     Real64 TSky = state.dataEnvrn->SkyTemp;
    9434     43041338 :     Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
    9435     43041338 :     Real64 TSrdSurfs = 0.0;
    9436              : 
    9437     43041338 :     if (surface.SurfHasSurroundingSurfProperty) {
    9438         5412 :         int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
    9439         5412 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
    9440            0 :             TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
    9441              :         }
    9442         5412 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
    9443            0 :             TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
    9444              :         }
    9445         5412 :         TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
    9446              :     }
    9447     43041338 :     if (surface.UseSurfPropertyGndSurfTemp) {
    9448         8118 :         TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
    9449              :     }
    9450              : 
    9451              :     // Now, calculate the outside surface temperature using the proper heat balance equation.
    9452              :     // Each case has been separated out into its own IF-THEN block for clarity.  Additional
    9453              :     // cases can simply be added anywhere in the following section.  This is the last step
    9454              :     // in the main loop.  Once the proper heat balance is done, the simulation goes on to
    9455              :     // the next SurfNum.
    9456              : 
    9457              :     // Outside heat balance case: Tubular daylighting device
    9458     43041338 :     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
    9459     43041338 :     if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    9460              : 
    9461              :         // Lookup up the TDD:DIFFUSER object
    9462         4050 :         int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    9463         4050 :         int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
    9464         4050 :         int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
    9465         4050 :         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    9466         4050 :         F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
    9467              : 
    9468              :         // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
    9469              :         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    9470              :         //   SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
    9471              :         //+Construct(ConstrNum)%CTFSourceOut[0]     &   TDDs cannot be radiant systems
    9472              :         // *SurfQsrcHist(1,SurfNum)                     &
    9473              :         //+Construct(ConstrNum)%CTFSourceIn[0] &   TDDs cannot be radiant systems
    9474              :         // *SurfQsrcHist(1,SurfNum)                &
    9475         4050 :         TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    9476         4050 :                 (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9477         4050 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
    9478         4050 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9479         4050 :                 F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
    9480         4050 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
    9481         4050 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
    9482         4050 :                (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9483         4050 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9484         4050 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9485         4050 :                 F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
    9486              :                             // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
    9487              : 
    9488              :         // Outside heat balance case: No movable insulation, slow conduction
    9489     43037288 :     } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
    9490              :         // Add LWR from surrounding surfaces
    9491     38304929 :         if (surface.OSCMPtr == 0) {
    9492     38163314 :             if (construct.SourceSinkPresent) {
    9493        83175 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9494        83175 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9495        83175 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9496        83175 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9497        83175 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9498        83175 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9499        83175 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9500        83175 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9501        83175 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9502              :             } else {
    9503     38080139 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9504     38080139 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9505     38080139 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9506     38080139 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9507     38080139 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9508     38080139 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9509     38080139 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9510     38080139 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9511              :             }
    9512              :             // Outside Heat Balance case: Other Side Conditions Model
    9513              :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9514              :             // local copies of variables for clarity in radiation terms
    9515              :             // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
    9516              :             Real64 RadTemp =
    9517       141615 :                 state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
    9518       141615 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
    9519              : 
    9520              :             // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
    9521       141615 :             if (construct.SourceSinkPresent) {
    9522            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9523            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9524            0 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9525            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9526            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9527              :             } else {
    9528       141615 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9529       141615 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9530       141615 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9531       141615 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9532              :             }
    9533              :         }
    9534              :         // Outside heat balance case: No movable insulation, quick conduction
    9535     43037288 :     } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
    9536      4728312 :         if (surface.OSCMPtr == 0) {
    9537      4658112 :             if (construct.SourceSinkPresent) {
    9538        24140 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9539        24140 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9540        24140 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9541        24140 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9542        24140 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9543        24140 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9544        24140 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9545        24140 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9546        24140 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9547        24140 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9548        24140 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9549        24140 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9550        24140 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9551        24140 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9552              :             } else {
    9553      4633972 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9554      4633972 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9555      4633972 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9556      4633972 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9557      4633972 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9558      4633972 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9559      4633972 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9560      4633972 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9561      4633972 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9562      4633972 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9563      4633972 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9564      4633972 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9565      4633972 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9566              :             }
    9567              :             // Outside Heat Balance case: Other Side Conditions Model
    9568              :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9569              :             // local copies of variables for clarity in radiation terms
    9570        70200 :             Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
    9571        70200 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
    9572              :             // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
    9573        70200 :             if (construct.SourceSinkPresent) {
    9574            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9575            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9576            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9577            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9578            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9579            0 :                               construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    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              :             } else {
    9585        70200 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9586        70200 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9587        70200 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9588        70200 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9589        70200 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9590        70200 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9591        70200 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9592        70200 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9593              :             }
    9594              :         }
    9595              :         // Outside heat balance case: Movable insulation, slow conduction
    9596      4732359 :     } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
    9597              : 
    9598         4047 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9599         4047 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9600         4047 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9601              : 
    9602         4047 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9603         4047 :                 construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9604         4047 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9605         4047 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9606         4047 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9607         4047 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9608         4047 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
    9609              : 
    9610              :         // Outside heat balance case: Movable insulation, quick conduction
    9611            0 :     } else if ((MovInsulPresent) && (QuickConductionSurf)) {
    9612              : 
    9613            0 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9614            0 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9615            0 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9616              : 
    9617            0 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9618            0 :                 F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9619            0 :                       state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9620            0 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9621            0 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
    9622            0 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9623            0 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9624            0 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9625            0 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9626            0 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
    9627              : 
    9628              :     } // ...end of outside heat balance cases IF-THEN block
    9629              : 
    9630              :     // multiply out linearized radiation coeffs for reporting
    9631              :     Real64 const HExtSurf_fac(
    9632     43041338 :         -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
    9633     43041338 :           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
    9634     43041338 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
    9635              : 
    9636              :     // Set the radiant system heat balance coefficients if this surface is also a radiant system
    9637     43041338 :     if (construct.SourceSinkPresent) {
    9638              : 
    9639       107315 :         if (MovInsulPresent) {
    9640              :             // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
    9641            0 :             ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
    9642            0 :             ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    9643            0 :             ShowContinueError(state,
    9644            0 :                               format("exterior movable insulation {} for a surface with that construction.",
    9645            0 :                                      s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
    9646            0 :             ShowContinueError(state,
    9647              :                               "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
    9648            0 :             ErrorFlag = true;
    9649            0 :             return;
    9650              : 
    9651              :         } else {
    9652       107315 :             Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
    9653       107315 :                                           state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
    9654       107315 :                                           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
    9655       107315 :                                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
    9656              : 
    9657       107315 :             state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    9658       107315 :                 (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9659       107315 :                  state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9660       107315 :                  (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9661       107315 :                  state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
    9662              :                 RadSysDiv; // ODB used to approx ground surface temp
    9663              : 
    9664       107315 :             state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
    9665              : 
    9666       107315 :             state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
    9667              :         }
    9668              :     }
    9669              : }
    9670              : 
    9671         8124 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
    9672              : {
    9673              : 
    9674              :     // SUBROUTINE INFORMATION:
    9675              :     //       AUTHOR         B Griffith
    9676              :     //       DATE WRITTEN   January 2005
    9677              : 
    9678              :     // PURPOSE OF THIS SUBROUTINE:
    9679              :     // manages calculating the temperatures of baffle and air cavity for
    9680              :     // multi-skin configuration.
    9681              : 
    9682              :     // METHODOLOGY EMPLOYED:
    9683              :     // derived from CalcPassiveTranspiredCollector
    9684              : 
    9685              :     // local working variables
    9686              :     Real64 HrPlen;
    9687              :     Real64 HcPlen;
    9688              :     Real64 Isc;
    9689              :     Real64 MdotVent;
    9690              :     Real64 VdotWind;
    9691              :     Real64 VdotThermal;
    9692              : 
    9693         8124 :     int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
    9694         8124 :     Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    9695         8124 :     Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
    9696         8124 :         state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
    9697         8124 :     Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
    9698         8124 :     Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
    9699              :     // Aspect Ratio of gap
    9700         8124 :     Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
    9701         8124 :     Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
    9702         8124 :     Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
    9703              : 
    9704              :     // all the work is done in this routine located in GeneralRoutines.cc
    9705              : 
    9706        32496 :     for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
    9707              : 
    9708        48744 :         TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
    9709        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
    9710              :                                                           holeArea,
    9711        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
    9712        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
    9713        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
    9714        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
    9715        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
    9716        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
    9717              :                                                           AspRat,
    9718        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
    9719        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
    9720        24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
    9721              :                                                           TmpTscoll,
    9722              :                                                           TmpTaPlen,
    9723              :                                                           HcPlen,
    9724              :                                                           HrPlen,
    9725              :                                                           Isc,
    9726              :                                                           MdotVent,
    9727              :                                                           VdotWind,
    9728              :                                                           VdotThermal);
    9729              : 
    9730              :     } // sequential solution
    9731              :     // now fill results into derived types
    9732         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
    9733         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
    9734         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
    9735         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
    9736         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
    9737         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
    9738        16248 :         (MdotVent / RhoAir) *
    9739         8124 :         (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
    9740              :         Constant::rSecsInHour;
    9741         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
    9742         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
    9743         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
    9744              : 
    9745              :     // now do some updates
    9746         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9747         8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9748              : 
    9749              :     // update the OtherSideConditionsModel coefficients.
    9750         8124 :     int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
    9751              : 
    9752         8124 :     state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9753         8124 :     state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
    9754         8124 :     state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9755         8124 :     state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
    9756         8124 : }
    9757              : 
    9758       834366 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
    9759              : {
    9760              :     // SUBROUTINE INFORMATION:
    9761              :     //       AUTHOR         Jason Glazer
    9762              :     //       DATE WRITTEN   September 2012
    9763              : 
    9764              :     // PURPOSE OF THIS SUBROUTINE:
    9765              :     //   Gather values during sizing used for surface absorption factors
    9766              : 
    9767              :     // METHODOLOGY EMPLOYED:
    9768              :     //   Save sequence of values for report during sizing.
    9769              : 
    9770              :     // This is by surface, so it works for both space and zone component loads
    9771       834366 :     if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
    9772        36642 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
    9773        36642 :         auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
    9774      2683542 :         for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
    9775      2646900 :             auto const &surface = state.dataSurface->Surface(jSurf);
    9776      2646900 :             if (!surface.HeatTransSurf || surface.Zone == 0) {
    9777       164700 :                 continue; // Skip non-heat transfer surfaces
    9778              :             }
    9779      2482200 :             if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    9780            0 :                 continue; // Skip tubular daylighting device domes
    9781              :             }
    9782      2482200 :             surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
    9783      2482200 :             surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
    9784              :         }
    9785              :     }
    9786       834366 : }
    9787              : 
    9788     56107751 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
    9789              : {
    9790     56107751 :     if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
    9791     56087909 :         return 1.0;
    9792        19842 :     } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
    9793        19842 :         return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9794              :     } else {
    9795            0 :         return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9796              :     }
    9797              : }
    9798              : 
    9799          803 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
    9800              : {
    9801              : 
    9802              :     // purpose:
    9803              :     //   Initializes sky and ground surfaces view factors of exterior surfaces
    9804              :     //   used by SurfaceProperty:LocalEnvironment
    9805              :     //   view factors are constant hence should be set only once
    9806              : 
    9807          803 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9808          799 :         return;
    9809              :     }
    9810            4 :     if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    9811            0 :         return;
    9812              :     }
    9813              : 
    9814          414 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9815          410 :         auto &Surface = state.dataSurface->Surface(SurfNum);
    9816          410 :         if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
    9817              : 
    9818           18 :             int GndSurfsNum = 0;
    9819           18 :             int SrdSurfsNum = 0;
    9820           18 :             Real64 SrdSurfsViewFactor = 0.0;
    9821           18 :             Real64 SurfsSkyViewFactor = 0.0;
    9822           18 :             Real64 GroundSurfsViewFactor = 0.0;
    9823           18 :             bool IsSkyViewFactorSet = false;
    9824           18 :             bool IsGroundViewFactorSet = false;
    9825           18 :             bool SetGroundViewFactorObject = false;
    9826           18 :             if (Surface.SurfHasSurroundingSurfProperty) {
    9827            6 :                 SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
    9828            6 :                 auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
    9829            6 :                 SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
    9830            6 :                 IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
    9831            6 :                 if (SurfsSkyViewFactor > 0.0) {
    9832            4 :                     SrdSurfsViewFactor += SurfsSkyViewFactor;
    9833              :                 }
    9834            6 :                 if (!Surface.IsSurfPropertyGndSurfacesDefined) {
    9835            5 :                     SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
    9836            5 :                     IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
    9837            5 :                     GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
    9838              :                 }
    9839           14 :                 for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    9840            8 :                     SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
    9841              :                 }
    9842              :             }
    9843           18 :             if (Surface.IsSurfPropertyGndSurfacesDefined) {
    9844           13 :                 GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
    9845           13 :                 IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
    9846           13 :                 GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
    9847           13 :                 SrdSurfsViewFactor += GroundSurfsViewFactor;
    9848              :             }
    9849              : 
    9850              :             // Check if the sum of all defined view factors > 1.0
    9851           18 :             if (SrdSurfsViewFactor > 1.0) {
    9852            0 :                 ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
    9853            0 :                 ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
    9854              :             }
    9855           18 :             if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9856              :                 // If both surface sky and ground view factor defined, overwrite with the defined value
    9857            4 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9858            4 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9859           14 :             } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
    9860              :                 // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
    9861            2 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9862            2 :                 Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
    9863            2 :                 if (GndSurfsNum > 0) {
    9864            0 :                     SetGroundViewFactorObject = true;
    9865            0 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9866              :                 } else {
    9867            2 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9868              :                 }
    9869           12 :             } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9870              :                 // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
    9871           12 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9872           12 :                 Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
    9873           12 :                 if (SrdSurfsNum > 0) {
    9874            0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9875            0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9876              :                 }
    9877              :             } else {
    9878              :                 // If neither ground nor sky view factor specified, continue to use the original proportion.
    9879            0 :                 Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
    9880            0 :                 Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
    9881            0 :                 if (SrdSurfsNum > 0) {
    9882            0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9883            0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9884            0 :                     if (GndSurfsNum == 0) {
    9885            0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9886            0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
    9887              :                     }
    9888              :                 }
    9889            0 :                 if (GndSurfsNum > 0) {
    9890            0 :                     SetGroundViewFactorObject = true;
    9891            0 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9892              :                 }
    9893              :             }
    9894           18 :             if (SetGroundViewFactorObject) {
    9895            0 :                 ReSetGroundSurfacesViewFactor(state, SurfNum);
    9896              :             }
    9897              :         }
    9898              :     }
    9899              : }
    9900              : 
    9901      3699480 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
    9902              : {
    9903              :     //  returns ground surfaces average temperature (deg C)
    9904              :     //  ground surfaces viewed by a building exterior surface
    9905              :     //  ground surfaces temperature weighed using view factors
    9906              : 
    9907      3699480 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9908      3692044 :         return;
    9909              :     }
    9910              : 
    9911       620862 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9912       613426 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
    9913       595837 :             continue;
    9914              :         }
    9915        17589 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9916        17589 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9917            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9918            0 :             continue;
    9919              :         }
    9920        17589 :         Real64 GndSurfaceTemp = 0.0;
    9921        17589 :         Real64 GndSurfViewFactor = 0.0;
    9922        17589 :         Real64 GndSurfaceTempSum = 0.0;
    9923        59532 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9924        41943 :             GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
    9925        41943 :             if (GndSurfViewFactor == 0.0) {
    9926            0 :                 continue;
    9927              :             }
    9928        41943 :             if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) {
    9929         1353 :                 continue;
    9930              :             }
    9931        40590 :             GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
    9932        40590 :             GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
    9933              :         }
    9934        17589 :         if (GndSurfaceTempSum == 0.0) {
    9935         1353 :             GndSurfsProperty.SurfsTempAvg = 0.0;
    9936         1353 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9937         1353 :             continue;
    9938              :         }
    9939        16236 :         GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
    9940              :     }
    9941              : }
    9942              : 
    9943      2800078 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
    9944              : {
    9945              :     //  returns ground surfaces average reflectance (dimensionless)
    9946              :     //  ground reflectance viewed by a building exterior surface
    9947              :     //  ground surfaces reflectance weighed using view factors
    9948              : 
    9949      2800078 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9950      2792642 :         return;
    9951              :     }
    9952       620862 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9953              : 
    9954       613426 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
    9955       595837 :             continue;
    9956              :         }
    9957        17589 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9958        17589 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9959            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9960            0 :             continue;
    9961              :         }
    9962        17589 :         Real64 GndSurfRefl = 0.0;
    9963        17589 :         Real64 GndSurfsReflSum = 0.0;
    9964        59532 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9965        41943 :             if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) {
    9966         1353 :                 continue;
    9967              :             }
    9968        40590 :             GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
    9969        40590 :             GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
    9970              :         }
    9971        17589 :         if (GndSurfsReflSum == 0.0) {
    9972         1353 :             GndSurfsProperty.SurfsReflAvg = 0.0;
    9973         1353 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9974         1353 :             continue;
    9975              :         }
    9976        16236 :         GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
    9977              :     }
    9978              : }
    9979              : 
    9980            0 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
    9981              : {
    9982              :     //  resets ground view factors based on view factors identity
    9983              :     //  the ground view factor value is set to the first element
    9984              :     //  when the ground view factor input field is blank
    9985              : 
    9986            0 :     if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
    9987            0 :         return;
    9988              :     }
    9989            0 :     auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9990            0 :     GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
    9991              : 
    9992            0 :     if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9993            0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9994            0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9995            0 :         return;
    9996              :     }
    9997            0 :     GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
    9998              : }
    9999              : 
   10000      3699480 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
   10001              : {
   10002              :     //  returns surrounding surfaces average temperature (deg C)
   10003              :     //  surrounding surfaces viewed by an exterior surface
   10004              :     //  surrounding surfaces temperature weighed using view factors
   10005              : 
   10006      3699480 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
   10007      3692044 :         return;
   10008              :     }
   10009              : 
   10010       620862 :     for (auto &surface : state.dataSurface->Surface) {
   10011       613426 :         if (!surface.SurfHasSurroundingSurfProperty) {
   10012       605308 :             continue;
   10013              :         }
   10014              :         // local vars
   10015         8118 :         Real64 SrdSurfaceTemp = 0.0;
   10016         8118 :         Real64 SrdSurfaceTempSum = 0.0;
   10017         8118 :         auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
   10018        18942 :         for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
   10019        10824 :             SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
   10020        10824 :             SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
   10021              :         }
   10022         8118 :         surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
   10023         7436 :     }
   10024              : }
   10025              : } // namespace EnergyPlus::HeatBalanceSurfaceManager
        

Generated by: LCOV version 2.0-1