LCOV - code coverage report
Current view: top level - EnergyPlus - HeatBalanceSurfaceManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 62.6 % 5698 3566
Test Date: 2025-05-22 16:09:37 Functions: 87.2 % 47 41

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <algorithm>
      50              : #include <cassert>
      51              : #include <cmath>
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : #include <ObjexxFCL/Array1D.hh>
      55              : #include <ObjexxFCL/Array2D.hh>
      56              : #include <ObjexxFCL/Fmath.hh>
      57              : #include <ObjexxFCL/string.functions.hh>
      58              : 
      59              : // EnergyPlus Headers
      60              : #include <AirflowNetwork/Solver.hpp>
      61              : #include <EnergyPlus/ChilledCeilingPanelSimple.hh>
      62              : #include <EnergyPlus/Construction.hh>
      63              : #include <EnergyPlus/ConvectionCoefficients.hh>
      64              : #include <EnergyPlus/CurveManager.hh>
      65              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      66              : #include <EnergyPlus/DataContaminantBalance.hh>
      67              : #include <EnergyPlus/DataDaylighting.hh>
      68              : #include <EnergyPlus/DataDaylightingDevices.hh>
      69              : #include <EnergyPlus/DataEnvironment.hh>
      70              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      71              : #include <EnergyPlus/DataHeatBalSurface.hh>
      72              : #include <EnergyPlus/DataHeatBalance.hh>
      73              : #include <EnergyPlus/DataLoopNode.hh>
      74              : #include <EnergyPlus/DataMoistureBalance.hh>
      75              : #include <EnergyPlus/DataMoistureBalanceEMPD.hh>
      76              : #include <EnergyPlus/DataRoomAirModel.hh>
      77              : #include <EnergyPlus/DataRuntimeLanguage.hh>
      78              : #include <EnergyPlus/DataSizing.hh>
      79              : #include <EnergyPlus/DataSurfaces.hh>
      80              : #include <EnergyPlus/DataSystemVariables.hh>
      81              : #include <EnergyPlus/DataViewFactorInformation.hh>
      82              : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
      83              : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      84              : #include <EnergyPlus/DataZoneEquipment.hh>
      85              : #include <EnergyPlus/DaylightingDevices.hh>
      86              : #include <EnergyPlus/DaylightingManager.hh>
      87              : #include <EnergyPlus/DisplayRoutines.hh>
      88              : #include <EnergyPlus/EcoRoofManager.hh>
      89              : #include <EnergyPlus/ElectricBaseboardRadiator.hh>
      90              : #include <EnergyPlus/ExtendedHeatIndex.hh>
      91              : #include <EnergyPlus/FileSystem.hh>
      92              : #include <EnergyPlus/HWBaseboardRadiator.hh>
      93              : #include <EnergyPlus/HeatBalFiniteDiffManager.hh>
      94              : #include <EnergyPlus/HeatBalanceAirManager.hh>
      95              : #include <EnergyPlus/HeatBalanceHAMTManager.hh>
      96              : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
      97              : #include <EnergyPlus/HeatBalanceKivaManager.hh>
      98              : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      99              : #include <EnergyPlus/HighTempRadiantSystem.hh>
     100              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
     101              : #include <EnergyPlus/InternalHeatGains.hh>
     102              : #include <EnergyPlus/LowTempRadiantSystem.hh>
     103              : #include <EnergyPlus/MoistureBalanceEMPDManager.hh>
     104              : #include <EnergyPlus/OutputProcessor.hh>
     105              : #include <EnergyPlus/OutputReportPredefined.hh>
     106              : #include <EnergyPlus/OutputReportTabular.hh>
     107              : #include <EnergyPlus/Psychrometrics.hh>
     108              : #include <EnergyPlus/ScheduleManager.hh>
     109              : #include <EnergyPlus/SolarShading.hh>
     110              : #include <EnergyPlus/SteamBaseboardRadiator.hh>
     111              : #include <EnergyPlus/SurfaceGeometry.hh>
     112              : #include <EnergyPlus/SwimmingPool.hh>
     113              : #include <EnergyPlus/ThermalComfort.hh>
     114              : #include <EnergyPlus/TranspiredCollector.hh>
     115              : #include <EnergyPlus/UtilityRoutines.hh>
     116              : #include <EnergyPlus/WindowComplexManager.hh>
     117              : #include <EnergyPlus/WindowEquivalentLayer.hh>
     118              : #include <EnergyPlus/WindowManager.hh>
     119              : #include <EnergyPlus/WindowManagerExteriorData.hh>
     120              : #include <EnergyPlus/WindowManagerExteriorThermal.hh>
     121              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
     122              : #include <WCECommon.hpp>
     123              : #include <WCEMultiLayerOptics.hpp>
     124              : #include <WCESingleLayerOptics.hpp>
     125              : #include <WCETarcog.hpp>
     126              : 
     127              : namespace EnergyPlus::HeatBalanceSurfaceManager {
     128              : 
     129              : // Module containing the routines dealing with the Heat Balance of the surfaces
     130              : 
     131              : // MODULE INFORMATION:
     132              : //       MODIFIED       DJS (PSU Dec 2006) to add ecoroof
     133              : 
     134              : // PURPOSE OF THIS MODULE:
     135              : // To encapsulate the data and algorithms required to
     136              : // manage the simulation of the surface heat balance for the building.
     137              : 
     138              : // REFERENCES:
     139              : // The heat balance method is outlined in the "TARP Reference Manual", NIST, NBSIR 83-2655, Feb 1983.
     140              : // The methods are also summarized in many BSO Theses and papers.
     141              : 
     142              : // OTHER NOTES:
     143              : // This module was created from IBLAST subroutines
     144              : 
     145       249946 : void ManageSurfaceHeatBalance(EnergyPlusData &state)
     146              : {
     147              : 
     148              :     // SUBROUTINE INFORMATION:
     149              :     //       AUTHOR         Richard Liesen
     150              :     //       DATE WRITTEN   January 1998
     151              : 
     152              :     // PURPOSE OF THIS SUBROUTINE:
     153              :     // This subroutine manages the heat surface balance method of calculating
     154              :     // building thermal loads.  It is called from the HeatBalanceManager
     155              :     // at the time step level.  This driver manages the calls to all of
     156              :     // the other drivers and simulation algorithms.
     157              : 
     158       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Surfaces");
     159       249946 :     InitSurfaceHeatBalance(state); // Initialize all heat balance related parameters
     160              : 
     161              :     // Solve the zone heat balance 'Detailed' solution
     162              :     // Call the outside and inside surface heat balances
     163       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Outside Surface Heat Balance");
     164       249946 :     CalcHeatBalanceOutsideSurf(state);
     165       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Inside Surface Heat Balance");
     166       249946 :     CalcHeatBalanceInsideSurf(state);
     167              : 
     168              :     // The air heat balance must be called before the temperature history
     169              :     // updates because there may be a radiant system in the building
     170       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Air Heat Balance");
     171       249946 :     HeatBalanceAirManager::ManageAirHeatBalance(state);
     172              : 
     173              :     // IF NECESSARY, do one final "average" heat balance pass.  This is only
     174              :     // necessary if a radiant system is present and it was actually on for
     175              :     // part or all of the time step.
     176       249945 :     UpdateFinalSurfaceHeatBalance(state);
     177              : 
     178              :     // Before we leave the Surface Manager the thermal histories need to be updated
     179       249945 :     if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
     180       200973 :         UpdateThermalHistories(state); // Update the thermal histories
     181              :     }
     182              : 
     183       249945 :     if (state.dataHeatBal->AnyCondFD) {
     184       342804 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     185       293832 :             auto const &surface = state.dataSurface->Surface(SurfNum);
     186       293832 :             int const ConstrNum = surface.Construction;
     187       293832 :             if (ConstrNum <= 0) continue;                                            // Shading surface, not really a heat transfer surface
     188       293832 :             if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) continue; //  Windows simulated in Window module
     189       293832 :             if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) continue;
     190       293832 :             state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
     191              :         }
     192              :     }
     193              : 
     194       249945 :     ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
     195              : 
     196       249945 :     ReportSurfaceHeatBalance(state);
     197       249945 :     if (state.dataGlobal->ZoneSizingCalc) OutputReportTabular::GatherComponentLoadsSurface(state);
     198              : 
     199       249945 :     CalcThermalResilience(state);
     200              : 
     201       249945 :     if (state.dataOutRptTab->displayThermalResilienceSummary) {
     202        69935 :         ReportThermalResilience(state);
     203              :     }
     204              : 
     205       249945 :     if (state.dataOutRptTab->displayCO2ResilienceSummary) {
     206           38 :         ReportCO2Resilience(state);
     207              :     }
     208              : 
     209       249945 :     if (state.dataOutRptTab->displayVisualResilienceSummary) {
     210           38 :         ReportVisualResilience(state);
     211              :     }
     212              : 
     213       249945 :     state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
     214       249945 : }
     215              : 
     216              : // Beginning Initialization Section of the Module
     217              : //******************************************************************************
     218              : 
     219       249957 : void UpdateVariableAbsorptances(EnergyPlusData &state)
     220              : {
     221       249957 :     auto &s_mat = state.dataMaterial;
     222       249960 :     for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
     223            3 :         auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
     224            3 :         auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
     225            3 :         assert(thisMaterial != nullptr);
     226            3 :         if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
     227            1 :             if (thisMaterial->absorpThermalVarSched != nullptr) {
     228            1 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
     229              :             }
     230            1 :             if (thisMaterial->absorpSolarVarSched != nullptr) {
     231            0 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
     232              :             }
     233              :         } else {
     234              :             Real64 triggerValue;
     235            2 :             if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
     236            2 :                 triggerValue = state.dataHeatBalSurf->SurfTempOut(surfNum);
     237            0 :             } else if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceReceivedSolarRadiation) {
     238            0 :                 triggerValue = state.dataHeatBal->SurfQRadSWOutIncident(surfNum);
     239              :             } else { // controlled by heating cooling mode
     240            0 :                 int zoneNum = state.dataSurface->Surface(surfNum).Zone;
     241            0 :                 bool isCooling = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).TotalOutputRequired < 0);
     242            0 :                 triggerValue = static_cast<Real64>(isCooling);
     243              :             }
     244            2 :             if (thisMaterial->absorpThermalVarCurve != nullptr) {
     245            2 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
     246            2 :                     max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
     247              :             }
     248            2 :             if (thisMaterial->absorpSolarVarCurve != nullptr) {
     249            2 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
     250            2 :                     max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
     251              :             }
     252              :         }
     253              :     }
     254       249957 : }
     255              : 
     256       249956 : void InitSurfaceHeatBalance(EnergyPlusData &state)
     257              : {
     258              : 
     259              :     // SUBROUTINE INFORMATION:
     260              :     //       AUTHOR         Richard J. Liesen
     261              :     //       DATE WRITTEN   January 1998
     262              :     //       MODIFIED       Nov. 1999, FCW,
     263              :     //                      Move ComputeIntThermalAbsorpFactors
     264              :     //                      so called every timestep
     265              :     //       MODIFIED       Aug. 2017
     266              :     //                      Add initializations of surface data to linked air node value if defined
     267              : 
     268              :     // PURPOSE OF THIS SUBROUTINE:
     269              :     // This subroutine is for surface initializations within the
     270              :     // heat balance.
     271              : 
     272              :     // METHODOLOGY EMPLOYED:
     273              :     // Uses the status flags to trigger record keeping events.
     274              : 
     275              :     //    // Using/Aliasing
     276              :     //    using namespace SolarShading;
     277              :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
     278              :     //    using HeatBalFiniteDiffManager::InitHeatBalFiniteDiff;
     279              :     //    using InternalHeatGains::ManageInternalHeatGains;
     280              :     //
     281              :     //    auto &Surface = state.dataSurface->Surface;
     282              :     //
     283       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Outdoor environment for Surfaces");
     284              : 
     285              :     // set zone level wind dir to global value
     286              :     // Initialize zone outdoor environmental variables
     287              :     // Bulk Initialization for Temperatures & WindSpeed
     288              :     // using the zone, modify the zone  Dry/Wet BulbTemps
     289              : 
     290              :     // Initialize surface outdoor environmental variables
     291              :     // Bulk Initialization for Temperatures & WindSpeed
     292              :     // using the surface centroids, modify the surface Dry/Wet BulbTemps
     293       249956 :     DataSurfaces::SetSurfaceOutBulbTempAt(state);
     294       249956 :     DataSurfaces::CheckSurfaceOutBulbTempAt(state);
     295              : 
     296       249956 :     DataSurfaces::SetSurfaceWindSpeedAt(state);
     297       249956 :     DataSurfaces::SetSurfaceWindDirAt(state);
     298       249956 :     if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
     299           21 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     300           18 :             if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
     301            1 :                 auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
     302            1 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
     303            1 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
     304            1 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
     305            1 :                 state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
     306              :             }
     307              :         }
     308              :     }
     309              :     // Overwriting surface and zone level environmental data with EMS override value
     310       249956 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     311       867072 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     312       750999 :             if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
     313            0 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
     314              :             }
     315       750999 :             if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
     316            0 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
     317              :             }
     318       750999 :             if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
     319            0 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
     320              :             }
     321       750999 :             if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
     322            0 :                 state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
     323              :             }
     324       750999 :             if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
     325         1354 :                 state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
     326              :             }
     327              :         }
     328              :     }
     329              : 
     330              :     // Do the Begin Simulation initializations
     331       249956 :     if (state.dataGlobal->BeginSimFlag) {
     332          112 :         AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
     333          112 :         state.dataHeatBalSurf->InterZoneWindow =
     334          112 :             std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
     335          112 :                         state.dataViewFactor->EnclSolInfo.end(),
     336          141 :                         [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
     337              :     }
     338       249956 :     if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
     339          244 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     340          282 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     341          150 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     342          150 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
     343          150 :                 int const lastSurf = thisSpace.HTSurfaceLast;
     344          944 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     345          794 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
     346          794 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
     347          794 :                     state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
     348          794 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
     349          794 :                     state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
     350          794 :                     state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
     351          794 :                     state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
     352              :                 }
     353              :             }
     354              :         }
     355              :     }
     356              : 
     357              :     // variable thermal solar absorptance overrides
     358       249956 :     UpdateVariableAbsorptances(state);
     359              : 
     360              :     // Do the Begin Environment initializations
     361       249956 :     if (state.dataGlobal->BeginEnvrnFlag) {
     362          483 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Temperature and Flux Histories");
     363          483 :         InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
     364              :     }
     365              : 
     366              :     // Calc movable insulation properties
     367       249956 :     if (state.dataSurface->AnyMovableInsulation) {
     368            0 :         EvalOutsideMovableInsulation(state);
     369            0 :         EvalInsideMovableInsulation(state);
     370              :     }
     371              : 
     372              :     // There are no daily initializations done in this portion of the surface heat balance
     373              :     // There are no hourly initializations done in this portion of the surface heat balance
     374              : 
     375       249956 :     GetGroundSurfacesReflectanceAverage(state);
     376              : 
     377              :     // Need to be called each timestep in order to check if surface points to new construction (EMS) and if does then
     378              :     // complex fenestration needs to be initialized for additional states
     379       249956 :     SolarShading::TimestepInitComplexFenestration(state);
     380              : 
     381              :     // Calculate exterior-surface multipliers that account for anisotropy of
     382              :     // sky radiance
     383       249956 :     if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
     384        71212 :         SolarShading::AnisoSkyViewFactors(state);
     385              :     } else {
     386       178744 :         state.dataSolarShading->SurfAnisoSkyMult = 0.0;
     387              :     }
     388              : 
     389              :     // Set shading flag for exterior windows (except flags related to daylighting) and
     390              :     // window construction (unshaded or shaded) to be used in heat balance calculation
     391       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Window Shading");
     392              : 
     393       249956 :     SolarShading::WindowShadingManager(state);
     394              : 
     395       249956 :     SolarShading::CheckGlazingShadingStatusChange(state);
     396              : 
     397              :     // Calculate factors that are used to determine how much long-wave radiation from internal
     398              :     // gains is absorbed by interior surfaces
     399       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Computing Interior Absorption Factors");
     400       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
     401       249956 :     ComputeIntThermalAbsorpFactors(state);
     402              : 
     403              :     // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
     404       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
     405       249956 :     ComputeIntSWAbsorpFactors(state);
     406              : 
     407       249956 :     if (state.dataHeatBalSurf->InterZoneWindow) {
     408            1 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     409            0 :             DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
     410              :         }
     411            1 :         ComputeDifSolExcZonesWIZWindows(state);
     412              :     }
     413              : 
     414       249956 :     Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
     415              : 
     416       499912 :     HeatBalanceIntRadExchange::CalcInteriorRadExchange(
     417       249956 :         state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
     418              : 
     419       249956 :     if (state.dataSurface->AirflowWindows) SolarShading::WindowGapAirflowControl(state);
     420              : 
     421              :     // The order of these initializations is important currently.  Over time we hope to
     422              :     //  take the appropriate parts of these inits to the other heat balance managers
     423       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Solar Heat Gains");
     424              : 
     425       249956 :     InitSolarHeatGains(state);
     426              : 
     427       249956 :     Dayltg::manageDaylighting(state);
     428              : 
     429       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Internal Heat Gains");
     430       249956 :     InternalHeatGains::ManageInternalHeatGains(state, false);
     431       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Interior Solar Distribution");
     432       249956 :     InitIntSolarDistribution(state);
     433              : 
     434       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Interior Convection Coefficients");
     435       249956 :     Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
     436              : 
     437       249956 :     if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
     438              :         //    if (firstTime) CALL DisplayString('Reporting Surfaces')
     439              :         //    CALL ReportSurfaces
     440          112 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Gathering Information for Predefined Reporting");
     441          112 :         GatherForPredefinedReport(state);
     442              :     }
     443              : 
     444              :     // Initialize the temperature history terms for conduction through the surfaces
     445       249956 :     if (state.dataHeatBal->AnyCondFD) {
     446        48972 :         HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
     447              :     }
     448              : 
     449       586606 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     450       709603 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     451       372953 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     452       372953 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     453       372953 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     454      2358705 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     455      1985752 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
     456      1985752 :                 if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     457       293832 :                     surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)
     458       293832 :                     continue;
     459              :                 // Outside surface temp of "normal" windows not needed in Window5 calculation approach
     460              :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
     461              : 
     462      1691920 :                 int const ConstrNum = surface.Construction;
     463      1691920 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
     464      1691920 :                 state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
     465      1691920 :                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
     466      1691920 :                 if (construct.NumCTFTerms <= 1) continue;
     467              : 
     468      7614410 :                 for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     469              :                     // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum )
     470              : 
     471              :                     // Sign convention for the various terms in the following two equations
     472              :                     // is based on the form of the Conduction Transfer Function equation
     473              :                     // given by:
     474              :                     // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old)
     475              :                     // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old)
     476              :                     // In both equations, flux is positive from outside to inside.
     477              : 
     478              :                     // Tuned Aliases and linear indexing
     479      6552068 :                     Real64 const ctf_cross(construct.CTFCross[Term]);
     480              : 
     481      6552068 :                     Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     482      6552068 :                     Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     483      6552068 :                     Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
     484      6552068 :                     Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
     485      6552068 :                     state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
     486      6552068 :                         ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
     487              : 
     488      6552068 :                     state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
     489      6552068 :                         construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
     490              :                 }
     491              :             }
     492              :         }
     493              :     }
     494       249956 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
     495            0 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     496            0 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     497            0 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     498            0 :                 int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     499            0 :                 int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     500            0 :                 for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     501            0 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
     502            0 :                     int const ConstrNum = surface.Construction;
     503            0 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
     504            0 :                     if (!construct.SourceSinkPresent) continue;
     505            0 :                     if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     506            0 :                         surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)
     507            0 :                         continue;
     508            0 :                     state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
     509            0 :                     state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
     510            0 :                     if (construct.NumCTFTerms <= 1) continue;
     511            0 :                     for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     512            0 :                         Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     513            0 :                         Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     514            0 :                         Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
     515              : 
     516            0 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
     517              : 
     518            0 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
     519              : 
     520            0 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
     521            0 :                             construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
     522            0 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
     523              : 
     524            0 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
     525            0 :                             construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
     526            0 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
     527              :                     }
     528              :                 }
     529              :             } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances
     530              :         }
     531              :     }
     532              : 
     533              :     // Zero out all of the radiant system heat balance coefficient arrays
     534       586606 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     535       709603 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     536       372953 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     537       372953 :             int const firstSurf = thisSpace.HTSurfaceFirst;
     538       372953 :             int const lastSurf = thisSpace.HTSurfaceLast;
     539      2447269 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     540      2074316 :                 state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
     541      2074316 :                 state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
     542      2074316 :                 state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
     543      2074316 :                 state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
     544      2074316 :                 state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
     545      2074316 :                 state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
     546              : 
     547      2074316 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
     548      2074316 :                 state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
     549      2074316 :                 state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
     550      2074316 :                 state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
     551              : 
     552              :             } // ...end of Zone Surf loop
     553              :         }
     554              :     } // ...end of Zone loop
     555              : 
     556       249980 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
     557           24 :         auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
     558           24 :         thisSurfQRadFromHVAC.HTRadSys = 0.0;
     559           24 :         thisSurfQRadFromHVAC.HWBaseboard = 0.0;
     560           24 :         thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
     561           24 :         thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
     562           24 :         thisSurfQRadFromHVAC.CoolingPanel = 0.0;
     563              :     }
     564              : 
     565       249956 :     if (state.dataGlobal->ZoneSizingCalc) GatherComponentLoadsSurfAbsFact(state);
     566              : 
     567       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     568          112 :         DisplayString(state, "Completed Initializing Surface Heat Balance");
     569              :     }
     570       249956 :     state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
     571       249956 : }
     572              : 
     573          114 : void GatherForPredefinedReport(EnergyPlusData &state)
     574              : {
     575              : 
     576              :     // SUBROUTINE INFORMATION:
     577              :     //       AUTHOR         Jason Glazer
     578              :     //       DATE WRITTEN   August 2006
     579              : 
     580              :     // PURPOSE OF THIS SUBROUTINE:
     581              :     // This subroutine reports the information for the predefined reports
     582              :     // related to envelope components.
     583              : 
     584              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     585          114 :     std::string surfName;
     586              :     Real64 mult;
     587              :     Real64 curAzimuth;
     588              :     Real64 curTilt;
     589              :     Real64 windowArea;
     590              :     Real64 frameWidth;
     591              :     Real64 frameArea;
     592              :     Real64 dividerArea;
     593              :     // counts for object count report
     594          114 :     int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
     595          114 :     Array1D_int numSurfaces(SurfaceClassCount);
     596          114 :     Array1D_int numExtSurfaces(SurfaceClassCount);
     597              :     int frameDivNum;
     598              :     bool isExterior;
     599          114 :     Array1D<Real64> computedNetArea; // holds the gross wall area minus the window and door areas
     600              : 
     601              :     // the following variables are for the CalcNominalWindowCond call but only SHGCSummer is needed
     602              :     Real64 nomCond;
     603              :     Real64 SHGCSummer;
     604              :     Real64 TransSolNorm;
     605              :     Real64 TransVisNorm;
     606              :     Real64 nomUfact;
     607              :     int errFlag;
     608              :     int curWSC;
     609              :     // following variables are totals for fenestration table
     610          114 :     Real64 windowAreaWMult(0.0);
     611          114 :     Real64 fenTotArea(0.0);
     612          114 :     Real64 fenTotAreaNorth(0.0);
     613          114 :     Real64 fenTotAreaNonNorth(0.0);
     614          114 :     Real64 ufactArea(0.0);
     615          114 :     Real64 ufactAreaNorth(0.0);
     616          114 :     Real64 ufactAreaNonNorth(0.0);
     617          114 :     Real64 shgcArea(0.0);
     618          114 :     Real64 shgcAreaNorth(0.0);
     619          114 :     Real64 shgcAreaNonNorth(0.0);
     620          114 :     Real64 vistranArea(0.0);
     621          114 :     Real64 vistranAreaNorth(0.0);
     622          114 :     Real64 vistranAreaNonNorth(0.0);
     623          114 :     Real64 intFenTotArea(0.0);
     624          114 :     Real64 intUfactArea(0.0);
     625          114 :     Real64 intShgcArea(0.0);
     626          114 :     Real64 intVistranArea(0.0);
     627              :     bool isNorth;
     628              : 
     629          114 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WinShadingType::Num)> WindowShadingTypeNames = {
     630              :         "No Shade",  // 0
     631              :         "Shade Off", // 1
     632              :         "Interior Shade",
     633              :         "Switchable Glazing",
     634              :         "Exterior Shade",
     635              :         "Exterior Screen",
     636              :         "Interior Blind",
     637              :         "Exterior Blind",
     638              :         "Between Glass Shade",
     639              :         "Between Glass Blind",
     640              :     };
     641              : 
     642          114 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WindowShadingControlType::Num)> WindowShadingControlTypeNames = {
     643              :         "Uncontrolled",
     644              :         "AlwaysOn",
     645              :         "AlwaysOff",
     646              :         "OnIfScheduleAllows",
     647              :         "OnIfHighSolarOnWindow",
     648              :         "OnIfHighHorizontalSolar",
     649              :         "OnIfHighOutdoorAirTemperature",
     650              :         "OnIfHighZoneAirTemperature",
     651              :         "OnIfHighZoneCooling",
     652              :         "OnIfHighGlare",
     653              :         "MeetDaylightIlluminanceSetpoint",
     654              :         "OnNightIfLowOutdoorTempAndOffDay",
     655              :         "OnNightIfLowInsideTempAndOffDay",
     656              :         "OnNightIfHeatingAndOffDay",
     657              :         "OnNightIfLowOutdoorTempAndOnDayIfCooling",
     658              :         "OnNightIfHeatingAndOnDayIfCooling",
     659              :         "OffNightAndOnDayIfCoolingAndHighSolarOnWindow",
     660              :         "OnNightAndOnDayIfCoolingAndHighSolarOnWindow",
     661              :         "OnIfHighOutdoorAirTempAndHighSolarOnWindow",
     662              :         "OnIfHighOutdoorAirTempAndHighHorizontalSolar",
     663              :         "OnIfHighZoneAirTempAndHighSolarOnWindow",
     664              :         "OnIfHighZoneAirTempAndHighHorizontalSolar"};
     665              : 
     666          114 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNames = {
     667              :         "CasementDouble", "CasementSingle",   "DualAction",
     668              :         "Fixed",          "Garage",           "Greenhouse",
     669              :         "HingedEscape",   "HorizontalSlider", "Jal",
     670              :         "Pivoted",        "ProjectingSingle", "ProjectingDual",
     671              :         "DoorSidelite",   "Skylight",         "SlidingPatioDoor",
     672              :         "CurtainWall",    "SpandrelPanel",    "SideHingedDoor",
     673              :         "DoorTransom",    "TropicalAwning",   "TubularDaylightingDevice",
     674              :         "VerticalSlider"};
     675              : 
     676          114 :     constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcWidth = {
     677              :         // width in meters from Table 4-3 of NFRC 100-2020
     678              :         1.200, 0.600, 1.200, //  CasementDouble,  CasementSingle,    DualAction,
     679              :         1.200, 2.134, 1.500, //  Fixed,           Garage,            Greenhouse,
     680              :         1.500, 1.500, 1.200, //  HingedEscape,    HorizontalSlider,  Jal,
     681              :         1.200, 1.500, 1.500, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     682              :         0.600, 1.200, 2.000, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     683              :         2.000, 2.000, 1.920, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     684              :         2.000, 1.500, 0.350, //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     685              :         1.200                //  VerticalSlider,
     686              :     };
     687              : 
     688          114 :     constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcHeight = {
     689              :         // height in meters from Table 4-3 of NFRC 100-2020
     690              :         1.500, 1.500, 1.500, //  CasementDouble,  CasementSingle,    DualAction,
     691              :         1.500, 2.134, 1.200, //  Fixed,           Garage,            Greenhouse,
     692              :         1.200, 1.200, 1.500, //  HingedEscape,    HorizontalSlider,  Jal,
     693              :         1.500, 1.200, 0.600, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     694              :         2.090, 1.200, 2.000, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     695              :         2.000, 1.200, 2.090, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     696              :         0.600, 1.200, 0.350, //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     697              :         1.500                //  VerticalSlider,
     698              :     };
     699              : 
     700          114 :     constexpr std::array<DataSurfaces::NfrcVisionType, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcVision = {
     701              :         DataSurfaces::NfrcVisionType::DualHorizontal, DataSurfaces::NfrcVisionType::Single,
     702              :         DataSurfaces::NfrcVisionType::DualVertical, //  CasementDouble,  CasementSingle,    DualAction,
     703              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     704              :         DataSurfaces::NfrcVisionType::Single, //  Fixed,           Garage,            Greenhouse,
     705              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::DualHorizontal,
     706              :         DataSurfaces::NfrcVisionType::Single, //  HingedEscape,    HorizontalSlider,  Jal,
     707              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     708              :         DataSurfaces::NfrcVisionType::DualHorizontal, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     709              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     710              :         DataSurfaces::NfrcVisionType::DualHorizontal, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     711              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     712              :         DataSurfaces::NfrcVisionType::Single, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     713              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     714              :         DataSurfaces::NfrcVisionType::Single,      //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     715              :         DataSurfaces::NfrcVisionType::DualVertical //  VerticalSlider
     716              :     };
     717              : 
     718          114 :     numSurfaces = 0;
     719          114 :     numExtSurfaces = 0;
     720              : 
     721          114 :     computedNetArea.allocate(state.dataSurface->TotSurfaces);
     722          114 :     computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
     723              : 
     724              :     // set up for EIO <FenestrationAssembly> output
     725          114 :     if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
     726            0 :         print(state.files.eio,
     727              :               "{}\n",
     728              :               "! <FenestrationAssembly>,Construction Name,Frame and Divider Name,NFRC Product Type,"
     729              :               "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
     730              :     }
     731              :     static constexpr std::string_view FenestrationAssemblyFormat("FenestrationAssembly,{},{},{},{:.3R},{:.3R},{:.3R}\n");
     732          114 :     std::vector<std::pair<int, int>> uniqConsFrame;
     733          114 :     std::pair<int, int> consAndFrame;
     734              : 
     735              :     // set up for EIO <FenestrationShadedState> output
     736          114 :     bool fenestrationShadedStateHeaderShown(false);
     737              :     static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
     738          114 :     std::vector<std::pair<int, int>> uniqShdConsFrame;
     739          114 :     std::pair<int, int> shdConsAndFrame;
     740              : 
     741          950 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
     742          836 :         auto &surface = state.dataSurface->Surface(iSurf);
     743          836 :         surfName = surface.Name;
     744              :         // only exterior surfaces including underground
     745          836 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
     746          216 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
     747          620 :             isExterior = true;
     748          620 :             switch (surface.Class) {
     749          545 :             case DataSurfaces::SurfaceClass::Wall:
     750              :             case DataSurfaces::SurfaceClass::Floor:
     751              :             case DataSurfaces::SurfaceClass::Roof: {
     752          545 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
     753          545 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     754          545 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
     755          545 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
     756          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
     757          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
     758          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
     759          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
     760          545 :                 OutputReportPredefined::PreDefTableEntry(
     761          545 :                     state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
     762          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
     763          545 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
     764          545 :                 curAzimuth = surface.Azimuth;
     765              :                 // Round to two decimals, like the display in tables
     766              :                 // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
     767          545 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     768          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
     769          545 :                 curTilt = surface.Tilt;
     770          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
     771          545 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     772          362 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     773           80 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
     774          282 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     775           82 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
     776          200 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     777          121 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
     778           79 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     779           79 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
     780              :                     }
     781              :                 }
     782          545 :             } break;
     783           58 :             case DataSurfaces::SurfaceClass::Window:
     784              :             case DataSurfaces::SurfaceClass::TDD_Dome: {
     785           58 :                 auto &construct = state.dataConstruction->Construct(surface.Construction);
     786           58 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     787           58 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
     788           58 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
     789           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
     790           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
     791           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
     792              :                 // if the construction report is requested the SummerSHGC is already calculated
     793           58 :                 if (construct.SummerSHGC != 0) {
     794           39 :                     SHGCSummer = construct.SummerSHGC;
     795           39 :                     TransVisNorm = construct.VisTransNorm;
     796              :                 } else {
     797              :                     // must calculate Summer SHGC
     798           19 :                     if (!construct.WindowTypeEQL) {
     799           19 :                         Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
     800           19 :                         construct.SummerSHGC = SHGCSummer;
     801           19 :                         construct.VisTransNorm = TransVisNorm;
     802           19 :                         construct.SolTransNorm = TransSolNorm;
     803              :                     }
     804              :                 }
     805              :                 // include the frame area if present
     806           58 :                 windowArea = surface.GrossArea;
     807           58 :                 frameArea = 0.0;
     808           58 :                 dividerArea = 0.0;
     809           58 :                 frameDivNum = surface.FrameDivider;
     810           58 :                 if (frameDivNum != 0) {
     811            3 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     812            3 :                     frameWidth = frameDivider.FrameWidth;
     813            3 :                     frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
     814            3 :                     windowArea += frameArea;
     815            3 :                     dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
     816            3 :                                                                frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
     817            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
     818            3 :                     OutputReportPredefined::PreDefTableEntry(
     819            3 :                         state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
     820            3 :                     OutputReportPredefined::PreDefTableEntry(
     821            3 :                         state, state.dataOutRptPredefined->pdchFenDividerConductance, surfName, frameDivider.DividerConductance, 3);
     822              : 
     823              :                     // report the selected NRFC product type (specific sizes) and the NFRC rating for the assembly (glass + frame + divider)
     824            3 :                     std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     825            3 :                     const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     826            3 :                     const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     827            3 :                     const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     828              : 
     829            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
     830              : 
     831            3 :                     Real64 uValueAssembly = 0.0;
     832            3 :                     Real64 shgcAssembly = 0.0;
     833            3 :                     Real64 vtAssembly = 0.0;
     834              : 
     835            3 :                     Window::GetWindowAssemblyNfrcForReport(
     836              :                         state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
     837            3 :                     if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
     838            0 :                         state.dataHeatBal->NominalU(surface.Construction) =
     839            0 :                             Window::GetIGUUValueForNFRCReport(state, iSurf, surface.Construction, windowWidth, windowHeight);
     840            0 :                         SHGCSummer = Window::GetSHGCValueForNFRCReporting(state, iSurf, surface.Construction, windowWidth, windowHeight);
     841              :                     }
     842            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
     843            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
     844            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
     845              : 
     846              :                     // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
     847            3 :                     if (state.dataGeneral->Constructions) {
     848            0 :                         consAndFrame = std::make_pair(surface.Construction, frameDivNum);
     849            0 :                         if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
     850            0 :                             uniqConsFrame.push_back(consAndFrame);
     851            0 :                             print(state.files.eio,
     852              :                                   FenestrationAssemblyFormat,
     853            0 :                                   construct.Name,
     854            0 :                                   frameDivider.Name,
     855              :                                   NFRCname,
     856              :                                   uValueAssembly,
     857              :                                   shgcAssembly,
     858              :                                   vtAssembly);
     859              :                         }
     860              :                     }
     861              :                 }
     862           58 :                 windowAreaWMult = windowArea * mult;
     863           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
     864           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
     865           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
     866          116 :                 OutputReportPredefined::PreDefTableEntry(
     867           58 :                     state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
     868           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
     869           58 :                 computedNetArea(surface.BaseSurf) -= windowAreaWMult;
     870           58 :                 nomUfact = state.dataHeatBal->NominalU(surface.Construction);
     871           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
     872              : 
     873           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
     874           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
     875           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
     876           58 :                 curAzimuth = surface.Azimuth;
     877              :                 // Round to two decimals, like the display in tables
     878           58 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     879           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
     880           58 :                 isNorth = false;
     881           58 :                 curTilt = surface.Tilt;
     882           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
     883           58 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     884           55 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     885           11 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
     886           11 :                         isNorth = true;
     887           44 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     888            9 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
     889           35 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     890           29 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
     891            6 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     892            6 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
     893              :                     }
     894              :                 }
     895              : 
     896              :                 // Report table for every shading control state
     897           58 :                 const unsigned int totalStates = surface.windowShadingControlList.size();
     898           58 :                 if (frameDivNum != 0) {
     899            3 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     900            3 :                     for (unsigned int i = 0; i < totalStates; ++i) {
     901            0 :                         const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     902            0 :                         const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     903            0 :                         const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     904              : 
     905            0 :                         const int stateConstrNum = surface.shadedConstructionList[i];
     906            0 :                         const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     907            0 :                         const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     908            0 :                         std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
     909              : 
     910            0 :                         OutputReportPredefined::PreDefTableEntry(
     911            0 :                             state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
     912            0 :                         OutputReportPredefined::PreDefTableEntry(
     913            0 :                             state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
     914            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
     915            0 :                         OutputReportPredefined::PreDefTableEntry(state,
     916            0 :                                                                  state.dataOutRptPredefined->pdchFenShdVisTr,
     917              :                                                                  constructionName,
     918            0 :                                                                  state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
     919            0 :                                                                  3);
     920              : 
     921            0 :                         Real64 stateAssemblyUValue{0.0};
     922            0 :                         Real64 stateAssemblySHGC{0.0};
     923            0 :                         Real64 stateAssemblyVT{0.0};
     924              : 
     925            0 :                         Window::GetWindowAssemblyNfrcForReport(
     926              :                             state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
     927              : 
     928            0 :                         std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     929            0 :                         OutputReportPredefined::PreDefTableEntry(
     930            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
     931              : 
     932            0 :                         OutputReportPredefined::PreDefTableEntry(
     933            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
     934            0 :                         OutputReportPredefined::PreDefTableEntry(
     935            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
     936            0 :                         OutputReportPredefined::PreDefTableEntry(
     937            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
     938              : 
     939            0 :                         if (state.dataGeneral->Constructions) {
     940            0 :                             if (!fenestrationShadedStateHeaderShown) {
     941            0 :                                 print(state.files.eio,
     942              :                                       "{}\n",
     943              :                                       "! <FenestrationShadedState>,Construction Name,Glass U-Factor {W/m2-K},"
     944              :                                       "Glass SHGC, Glass Visible Transmittance, Frame and Divider Name,NFRC Product Type,"
     945              :                                       "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
     946            0 :                                 fenestrationShadedStateHeaderShown = true;
     947              :                             }
     948              : 
     949            0 :                             shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
     950            0 :                             if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
     951            0 :                                 uniqShdConsFrame.push_back(shdConsAndFrame);
     952            0 :                                 print(state.files.eio,
     953              :                                       FenestrationShadedStateFormat,
     954              :                                       constructionName,
     955              :                                       stateUValue,
     956              :                                       stateSHGC,
     957            0 :                                       state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
     958            0 :                                       frameDivider.Name,
     959              :                                       NFRCname,
     960              :                                       stateAssemblyUValue,
     961              :                                       stateAssemblySHGC,
     962              :                                       stateAssemblyVT);
     963              :                             }
     964              :                         }
     965              :                     }
     966              :                 }
     967              : 
     968           58 :                 curWSC = surface.activeWindowShadingControl;
     969              :                 // compute totals for area weighted averages
     970           58 :                 fenTotArea += windowAreaWMult;
     971           58 :                 ufactArea += nomUfact * windowAreaWMult;
     972           58 :                 shgcArea += SHGCSummer * windowAreaWMult;
     973           58 :                 vistranArea += TransVisNorm * windowAreaWMult;
     974           58 :                 if (isNorth) {
     975           11 :                     fenTotAreaNorth += windowAreaWMult;
     976           11 :                     ufactAreaNorth += nomUfact * windowAreaWMult;
     977           11 :                     shgcAreaNorth += SHGCSummer * windowAreaWMult;
     978           11 :                     vistranAreaNorth += TransVisNorm * windowAreaWMult;
     979              :                 } else {
     980           47 :                     fenTotAreaNonNorth += windowAreaWMult;
     981           47 :                     ufactAreaNonNorth += nomUfact * windowAreaWMult;
     982           47 :                     shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
     983           47 :                     vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
     984              :                 }
     985              :                 // shading
     986           58 :                 if (surface.HasShadeControl) {
     987            8 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
     988           16 :                     OutputReportPredefined::PreDefTableEntry(
     989           16 :                         state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
     990              :                     // shading report
     991           16 :                     OutputReportPredefined::PreDefTableEntry(
     992              :                         state,
     993            8 :                         state.dataOutRptPredefined->pdchWscShading,
     994              :                         surfName,
     995            8 :                         WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
     996           16 :                     OutputReportPredefined::PreDefTableEntry(
     997              :                         state,
     998            8 :                         state.dataOutRptPredefined->pdchWscControl,
     999              :                         surfName,
    1000            8 :                         WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
    1001              : 
    1002              :                     // output list of all possible shading constructions for shaded windows including those with storms
    1003            8 :                     std::string names;
    1004           16 :                     for (int construction : surface.shadedConstructionList) {
    1005            8 :                         if (!names.empty()) names.append("; ");
    1006            8 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1007              :                     }
    1008            8 :                     for (int construction : surface.shadedStormWinConstructionList) {
    1009            0 :                         if (!names.empty()) names.append("; ");
    1010            0 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1011              :                     }
    1012            8 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
    1013              : 
    1014            8 :                     if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
    1015            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
    1016              :                     } else {
    1017            8 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
    1018              :                     }
    1019            8 :                 } else {
    1020           50 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
    1021              :                 }
    1022           58 :             } break;
    1023            1 :             case DataSurfaces::SurfaceClass::Door: {
    1024            1 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1025            1 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1026            1 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1027            2 :                 OutputReportPredefined::PreDefTableEntry(
    1028            2 :                     state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
    1029            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
    1030            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
    1031            1 :                 OutputReportPredefined::PreDefTableEntry(
    1032            1 :                     state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1033            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
    1034            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
    1035            1 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1036            1 :             } break;
    1037           16 :             default:
    1038           16 :                 break;
    1039              :             }
    1040          620 :         } else {
    1041              :             // interior surfaces
    1042          216 :             isExterior = false;
    1043          216 :             if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
    1044           18 :                 (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
    1045          214 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1046          214 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1047          214 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1048          214 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1049          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
    1050          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
    1051          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
    1052          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
    1053          428 :                 OutputReportPredefined::PreDefTableEntry(
    1054          214 :                     state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
    1055          214 :                 OutputReportPredefined::PreDefTableEntry(
    1056          214 :                     state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1057          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
    1058          214 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
    1059          214 :                 curAzimuth = surface.Azimuth;
    1060              :                 // Round to two decimals, like the display in tables
    1061              :                 // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
    1062          214 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
    1063          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
    1064          214 :                 curTilt = surface.Tilt;
    1065          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
    1066          214 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
    1067          126 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
    1068           67 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
    1069           59 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
    1070           36 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
    1071           23 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
    1072           13 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
    1073           10 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
    1074           10 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
    1075              :                     }
    1076              :                 }
    1077              :                 // interior window report
    1078          216 :             } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
    1079            0 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1080            0 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1081            0 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
    1082            0 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1083            0 :                 if (!has_prefix(surface.Name,
    1084              :                                 "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
    1085            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
    1086            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
    1087            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
    1088              :                     // include the frame area if present
    1089            0 :                     windowArea = surface.GrossArea;
    1090            0 :                     if (surface.FrameDivider != 0) {
    1091            0 :                         frameWidth = state.dataSurface->FrameDivider(surface.FrameDivider).FrameWidth;
    1092            0 :                         frameArea = (surface.Height + 2 * frameWidth) * (surface.Width + 2 * frameWidth) - (surface.Height * surface.Width);
    1093            0 :                         windowArea += frameArea;
    1094              :                     }
    1095            0 :                     windowAreaWMult = windowArea * mult;
    1096            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
    1097            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
    1098            0 :                     computedNetArea(surface.BaseSurf) -= windowAreaWMult;
    1099            0 :                     nomUfact = state.dataHeatBal->NominalU(surface.Construction);
    1100            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
    1101            0 :                     if (!construct.TypeIsAirBoundary) {
    1102              :                         // Solar properties not applicable for air boundary surfaces
    1103              :                         // if the construction report is requested the SummerSHGC is already calculated
    1104            0 :                         if (construct.SummerSHGC != 0) {
    1105            0 :                             SHGCSummer = construct.SummerSHGC;
    1106            0 :                             TransVisNorm = construct.VisTransNorm;
    1107              :                         } else {
    1108              :                             // must calculate Summer SHGC
    1109            0 :                             if (!construct.WindowTypeEQL) {
    1110            0 :                                 Window::CalcNominalWindowCond(
    1111              :                                     state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
    1112              :                             }
    1113              :                         }
    1114            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
    1115            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
    1116              :                         // compute totals for area weighted averages
    1117            0 :                         intShgcArea += SHGCSummer * windowAreaWMult;
    1118            0 :                         intVistranArea += TransVisNorm * windowAreaWMult;
    1119              :                     }
    1120            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
    1121              :                     // compute totals for area weighted averages
    1122            0 :                     intFenTotArea += windowAreaWMult;
    1123            0 :                     intUfactArea += nomUfact * windowAreaWMult;
    1124              :                 }
    1125            2 :             } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
    1126            2 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1127            2 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1128            2 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1129            2 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1130            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
    1131            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
    1132            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
    1133            2 :                 OutputReportPredefined::PreDefTableEntry(
    1134            2 :                     state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1135            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
    1136            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
    1137            2 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1138              :             }
    1139              :         }
    1140          836 :         int currSurfaceClass = int(surface.Class);
    1141          836 :         assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
    1142          836 :         assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
    1143          836 :         ++numSurfaces(currSurfaceClass);
    1144          836 :         if (isExterior) {
    1145          620 :             ++numExtSurfaces(currSurfaceClass);
    1146              :         }
    1147          836 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) {
    1148           58 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    1149            4 :                 ++numSurfaces((int)surface.OriginalClass);
    1150            4 :                 if (isExterior) {
    1151            4 :                     ++numExtSurfaces((int)surface.OriginalClass);
    1152              :                 }
    1153              :             }
    1154              :         }
    1155              :     }
    1156              :     // for fins and overhangs just add them explicitly since not otherwise classified
    1157          114 :     int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
    1158          114 :                        state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
    1159          114 :     numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1160          114 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1161          114 :     int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
    1162          114 :                   state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
    1163          114 :     numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1164          114 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1165              :     // go through all the surfaces again and this time insert the net area results
    1166          950 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
    1167          836 :         auto const &surface = state.dataSurface->Surface(iSurf);
    1168          836 :         DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
    1169              :         // exterior surfaces including underground
    1170          836 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
    1171          216 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
    1172          620 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1173              :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1174          545 :                 surfName = surface.Name;
    1175          545 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
    1176              :             }
    1177              :         } else {
    1178          216 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1179              :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1180          211 :                 surfName = surface.Name;
    1181          211 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
    1182              :             }
    1183              :         } // interior surfaces
    1184              :     }
    1185              :     // total
    1186          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
    1187          114 :     if (fenTotArea > 0.0) {
    1188           24 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
    1189           24 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
    1190           24 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
    1191              :     } else {
    1192           90 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
    1193           90 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
    1194           90 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
    1195              :     }
    1196              :     // north
    1197          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
    1198          114 :     if (fenTotAreaNorth > 0.0) {
    1199           12 :         OutputReportPredefined::PreDefTableEntry(
    1200           12 :             state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
    1201           12 :         OutputReportPredefined::PreDefTableEntry(
    1202           12 :             state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
    1203           12 :         OutputReportPredefined::PreDefTableEntry(
    1204           18 :             state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
    1205              :     } else {
    1206          108 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
    1207          108 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
    1208          108 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
    1209              :     }
    1210              :     // non-north
    1211          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
    1212          114 :     if (fenTotAreaNonNorth > 0.0) {
    1213           46 :         OutputReportPredefined::PreDefTableEntry(
    1214           46 :             state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
    1215           46 :         OutputReportPredefined::PreDefTableEntry(
    1216           46 :             state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
    1217           46 :         OutputReportPredefined::PreDefTableEntry(
    1218           69 :             state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
    1219              :     } else {
    1220           91 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
    1221           91 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
    1222           91 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
    1223              :     }
    1224              :     // interior fenestration totals
    1225          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
    1226          114 :     if (intFenTotArea > 0.0) {
    1227            0 :         OutputReportPredefined::PreDefTableEntry(
    1228            0 :             state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
    1229            0 :         OutputReportPredefined::PreDefTableEntry(
    1230            0 :             state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
    1231            0 :         OutputReportPredefined::PreDefTableEntry(
    1232            0 :             state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
    1233              :     } else {
    1234          114 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
    1235          114 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
    1236          114 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
    1237              :     }
    1238              :     // counts
    1239          114 :     OutputReportPredefined::PreDefTableEntry(
    1240          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1241          114 :     OutputReportPredefined::PreDefTableEntry(
    1242          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1243          114 :     OutputReportPredefined::PreDefTableEntry(
    1244          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1245          114 :     OutputReportPredefined::PreDefTableEntry(
    1246          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1247          114 :     OutputReportPredefined::PreDefTableEntry(
    1248          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1249          114 :     OutputReportPredefined::PreDefTableEntry(
    1250          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1251          114 :     OutputReportPredefined::PreDefTableEntry(
    1252          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1253          114 :     OutputReportPredefined::PreDefTableEntry(
    1254          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1255          114 :     OutputReportPredefined::PreDefTableEntry(
    1256          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1257          114 :     OutputReportPredefined::PreDefTableEntry(
    1258          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1259          114 :     OutputReportPredefined::PreDefTableEntry(
    1260          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1261          114 :     OutputReportPredefined::PreDefTableEntry(
    1262          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1263          114 :     OutputReportPredefined::PreDefTableEntry(
    1264          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1265          114 :     OutputReportPredefined::PreDefTableEntry(
    1266          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1267          114 :     OutputReportPredefined::PreDefTableEntry(
    1268          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1269          114 :     OutputReportPredefined::PreDefTableEntry(
    1270          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1271          114 :     OutputReportPredefined::PreDefTableEntry(
    1272          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1273          114 :     OutputReportPredefined::PreDefTableEntry(
    1274          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1275          114 :     OutputReportPredefined::PreDefTableEntry(
    1276          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1277          114 :     OutputReportPredefined::PreDefTableEntry(
    1278          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1279          114 :     OutputReportPredefined::PreDefTableEntry(
    1280          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1281          114 :     OutputReportPredefined::PreDefTableEntry(
    1282          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1283          114 :     OutputReportPredefined::PreDefTableEntry(
    1284          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1285          114 :     OutputReportPredefined::PreDefTableEntry(
    1286          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1287          114 :     OutputReportPredefined::PreDefTableEntry(
    1288          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1289          114 :     OutputReportPredefined::PreDefTableEntry(state,
    1290          114 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1291              :                                              "Tubular Daylighting Device Dome",
    1292          114 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1293          114 :     OutputReportPredefined::PreDefTableEntry(state,
    1294          114 :                                              state.dataOutRptPredefined->pdchSurfCntTot,
    1295              :                                              "Tubular Daylighting Device Diffuser",
    1296          114 :                                              numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1297          114 :     OutputReportPredefined::PreDefTableEntry(state,
    1298          114 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1299              :                                              "Tubular Daylighting Device Diffuser",
    1300          114 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1301          114 : }
    1302              : 
    1303          145 : void AllocateSurfaceHeatBalArrays(EnergyPlusData &state)
    1304              : {
    1305              : 
    1306              :     // SUBROUTINE INFORMATION:
    1307              :     //       AUTHOR         Richard Liesen
    1308              :     //       DATE WRITTEN   February 1998
    1309              : 
    1310              :     // METHODOLOGY EMPLOYED:
    1311              :     // Uses the status flags to trigger variable allocation.
    1312              : 
    1313              :     // Use the total number of surfaces to allocate variables to avoid a surface number limit
    1314          145 :     state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1315          145 :     state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1316          145 :     state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1317          145 :     state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1318          145 :     state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1319          145 :     state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1320          145 :     state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1321          145 :     state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
    1322          145 :     state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
    1323          145 :     state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
    1324          145 :     state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
    1325          145 :     state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
    1326          145 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1327            2 :         state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1328            2 :         state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1329              :     }
    1330              : 
    1331          145 :     state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
    1332          145 :     state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1333          145 :     state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1334          145 :     state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1335          145 :     state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1336          145 :     state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1337          145 :     state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1338              : 
    1339          145 :     state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1340          145 :     state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
    1341          145 :     state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1342          145 :     state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1343          145 :     state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1344              : 
    1345          145 :     state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
    1346          145 :     state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
    1347          145 :     state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
    1348          145 :     state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1349          145 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1350          145 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1351              : 
    1352          145 :     state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
    1353          145 :     state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
    1354          145 :     state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
    1355          145 :     state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
    1356         2900 :     for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1357         2755 :         state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1358         2755 :         state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1359         2755 :         state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1360         2755 :         state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1361              :     }
    1362              : 
    1363          145 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1364           26 :         state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
    1365              : 
    1366           26 :         state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1367           26 :         state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1368           26 :         state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1369           26 :         state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1370              : 
    1371          520 :         for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1372          494 :             state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1373          494 :             state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1374          494 :             state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1375          494 :             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1376              :         }
    1377              :     }
    1378              : 
    1379          145 :     state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1380          145 :     state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1381          145 :     state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1382          145 :     state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1383          145 :     state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1384              : 
    1385          145 :     state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1386          145 :     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1387              : 
    1388          145 :     state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1389          145 :     state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1390          145 :     state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1391              : 
    1392          145 :     state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1393          145 :     state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1394              : 
    1395          145 :     state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1396          145 :     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1397              : 
    1398          145 :     state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1399          145 :     state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1400          145 :     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1401              : 
    1402          145 :     state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1403          145 :     state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1404          145 :     state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1405              : 
    1406          145 :     state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1407          145 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1408          145 :     state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1409              : 
    1410          145 :     state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1411          145 :     state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1412              : 
    1413          145 :     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1414          145 :     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1415              : 
    1416          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1417          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1418          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1419          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1420          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1421              : 
    1422          145 :     state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1423          145 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1424          145 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1425          145 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1426          145 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1427              : 
    1428          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1429          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1430          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1431          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1432          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1433              : 
    1434          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1435          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1436          145 :     state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1437          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1438          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1439              : 
    1440          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
    1441              : 
    1442          145 :     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1443          145 :     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1444              : 
    1445          145 :     state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1446          145 :     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1447          145 :     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1448              : 
    1449          145 :     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1450          145 :     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1451              : 
    1452          145 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1453            2 :         state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1454            2 :         state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
    1455            2 :         state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1456            2 :         state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1457            2 :         state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1458            2 :         state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1459            2 :         state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1460            2 :         state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1461              :     }
    1462              : 
    1463          145 :     state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1464          145 :     state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1465          145 :     state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1466          145 :     state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1467          145 :     state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1468          145 :     state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1469          145 :     state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1470          145 :     state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
    1471          145 :     state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
    1472          145 :     state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
    1473              : 
    1474              :     // allocate terms used for pool surface heat balance
    1475          145 :     state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
    1476          145 :     state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1477              : 
    1478              :     // allocate term used as sink for PV electricity
    1479          145 :     state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1480              : 
    1481              :     // Allocate the moisture balance arrays
    1482          145 :     state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1483          145 :     state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1484          145 :     state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1485          145 :     state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1486          145 :     state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1487          145 :     state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1488          145 :     state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1489          145 :     state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1490          145 :     state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1491          145 :     state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1492          145 :     state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1493              : 
    1494          145 :     state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1495          145 :     state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1496              : 
    1497          145 :     state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1498          145 :     state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1499          145 :     state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
    1500          145 :     state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1501          145 :     state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1502              : 
    1503          145 :     DisplayString(state, "Setting up Surface Reporting Variables");
    1504              :     // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
    1505         1166 :     for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
    1506         1021 :         auto &surface = state.dataSurface->Surface(loop);
    1507         1021 :         if (!surface.HeatTransSurf) continue;
    1508         1994 :         SetupOutputVariable(state,
    1509              :                             "Surface Inside Face Temperature",
    1510              :                             Constant::Units::C,
    1511          997 :                             state.dataHeatBalSurf->SurfTempIn(loop),
    1512              :                             OutputProcessor::TimeStepType::Zone,
    1513              :                             OutputProcessor::StoreType::Average,
    1514          997 :                             surface.Name);
    1515         1994 :         SetupOutputVariable(state,
    1516              :                             "Surface Inside Face Interior Movable Insulation Temperature",
    1517              :                             Constant::Units::C,
    1518          997 :                             state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
    1519              :                             OutputProcessor::TimeStepType::Zone,
    1520              :                             OutputProcessor::StoreType::Average,
    1521          997 :                             surface.Name);
    1522              : 
    1523          997 :         if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1524         1994 :             SetupOutputVariable(state,
    1525              :                                 "Surface Outside Face Temperature",
    1526              :                                 Constant::Units::C,
    1527          997 :                                 state.dataHeatBalSurf->SurfTempOut(loop),
    1528              :                                 OutputProcessor::TimeStepType::Zone,
    1529              :                                 OutputProcessor::StoreType::Average,
    1530          997 :                                 surface.Name);
    1531              :         }
    1532              : 
    1533         1994 :         SetupOutputVariable(state,
    1534              :                             "Surface Inside Face Adjacent Air Temperature",
    1535              :                             Constant::Units::C,
    1536          997 :                             state.dataHeatBal->SurfTempEffBulkAir(loop),
    1537              :                             OutputProcessor::TimeStepType::Zone,
    1538              :                             OutputProcessor::StoreType::Average,
    1539          997 :                             surface.Name);
    1540         1994 :         SetupOutputVariable(state,
    1541              :                             "Surface Inside Face Convection Heat Transfer Coefficient",
    1542              :                             Constant::Units::W_m2K,
    1543          997 :                             state.dataHeatBalSurf->SurfHConvInt(loop),
    1544              :                             OutputProcessor::TimeStepType::Zone,
    1545              :                             OutputProcessor::StoreType::Average,
    1546          997 :                             surface.Name);
    1547         1994 :         SetupOutputVariable(state,
    1548              :                             "Surface Inside Face Convection Heat Gain Rate",
    1549              :                             Constant::Units::W,
    1550          997 :                             state.dataHeatBalSurf->SurfQdotConvInRep(loop),
    1551              :                             OutputProcessor::TimeStepType::Zone,
    1552              :                             OutputProcessor::StoreType::Average,
    1553          997 :                             surface.Name);
    1554         1994 :         SetupOutputVariable(state,
    1555              :                             "Surface Inside Face Convection Heat Gain Rate per Area",
    1556              :                             Constant::Units::W_m2,
    1557          997 :                             state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
    1558              :                             OutputProcessor::TimeStepType::Zone,
    1559              :                             OutputProcessor::StoreType::Average,
    1560          997 :                             surface.Name);
    1561         1994 :         SetupOutputVariable(state,
    1562              :                             "Surface Inside Face Convection Heat Gain Energy",
    1563              :                             Constant::Units::J,
    1564          997 :                             state.dataHeatBalSurf->SurfQConvInRep(loop),
    1565              :                             OutputProcessor::TimeStepType::Zone,
    1566              :                             OutputProcessor::StoreType::Sum,
    1567          997 :                             surface.Name);
    1568              : 
    1569         1994 :         SetupOutputVariable(state,
    1570              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
    1571              :                             Constant::Units::W,
    1572          997 :                             state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
    1573              :                             OutputProcessor::TimeStepType::Zone,
    1574              :                             OutputProcessor::StoreType::Average,
    1575          997 :                             surface.Name);
    1576         1994 :         SetupOutputVariable(state,
    1577              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
    1578              :                             Constant::Units::W_m2,
    1579          997 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
    1580              :                             OutputProcessor::TimeStepType::Zone,
    1581              :                             OutputProcessor::StoreType::Average,
    1582          997 :                             surface.Name);
    1583         1994 :         SetupOutputVariable(state,
    1584              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
    1585              :                             Constant::Units::J,
    1586          997 :                             state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
    1587              :                             OutputProcessor::TimeStepType::Zone,
    1588              :                             OutputProcessor::StoreType::Sum,
    1589          997 :                             surface.Name);
    1590              : 
    1591          997 :         if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1592         1884 :             SetupOutputVariable(state,
    1593              :                                 "Surface Inside Face Solar Radiation Heat Gain Rate",
    1594              :                                 Constant::Units::W,
    1595          942 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
    1596              :                                 OutputProcessor::TimeStepType::Zone,
    1597              :                                 OutputProcessor::StoreType::Average,
    1598          942 :                                 surface.Name);
    1599         1884 :             SetupOutputVariable(state,
    1600              :                                 "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
    1601              :                                 Constant::Units::W_m2,
    1602          942 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
    1603              :                                 OutputProcessor::TimeStepType::Zone,
    1604              :                                 OutputProcessor::StoreType::Average,
    1605          942 :                                 surface.Name);
    1606         1884 :             SetupOutputVariable(state,
    1607              :                                 "Surface Inside Face Solar Radiation Heat Gain Energy",
    1608              :                                 Constant::Units::J,
    1609          942 :                                 state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
    1610              :                                 OutputProcessor::TimeStepType::Zone,
    1611              :                                 OutputProcessor::StoreType::Sum,
    1612          942 :                                 surface.Name);
    1613              : 
    1614         1884 :             SetupOutputVariable(state,
    1615              :                                 "Surface Inside Face Lights Radiation Heat Gain Rate",
    1616              :                                 Constant::Units::W,
    1617          942 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
    1618              :                                 OutputProcessor::TimeStepType::Zone,
    1619              :                                 OutputProcessor::StoreType::Average,
    1620          942 :                                 surface.Name);
    1621         1884 :             SetupOutputVariable(state,
    1622              :                                 "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
    1623              :                                 Constant::Units::W_m2,
    1624          942 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
    1625              :                                 OutputProcessor::TimeStepType::Zone,
    1626              :                                 OutputProcessor::StoreType::Average,
    1627          942 :                                 surface.Name);
    1628         1884 :             SetupOutputVariable(state,
    1629              :                                 "Surface Inside Face Lights Radiation Heat Gain Energy",
    1630              :                                 Constant::Units::J,
    1631          942 :                                 state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
    1632              :                                 OutputProcessor::TimeStepType::Zone,
    1633              :                                 OutputProcessor::StoreType::Sum,
    1634          942 :                                 surface.Name);
    1635              :         }
    1636              : 
    1637         1994 :         SetupOutputVariable(state,
    1638              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
    1639              :                             Constant::Units::W,
    1640          997 :                             state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
    1641              :                             OutputProcessor::TimeStepType::Zone,
    1642              :                             OutputProcessor::StoreType::Average,
    1643          997 :                             surface.Name);
    1644         1994 :         SetupOutputVariable(state,
    1645              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
    1646              :                             Constant::Units::W_m2,
    1647          997 :                             state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
    1648              :                             OutputProcessor::TimeStepType::Zone,
    1649              :                             OutputProcessor::StoreType::Average,
    1650          997 :                             surface.Name);
    1651         1994 :         SetupOutputVariable(state,
    1652              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
    1653              :                             Constant::Units::J,
    1654          997 :                             state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
    1655              :                             OutputProcessor::TimeStepType::Zone,
    1656              :                             OutputProcessor::StoreType::Sum,
    1657          997 :                             surface.Name);
    1658              : 
    1659         1994 :         SetupOutputVariable(state,
    1660              :                             "Surface Inside Face System Radiation Heat Gain Rate",
    1661              :                             Constant::Units::W,
    1662          997 :                             state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
    1663              :                             OutputProcessor::TimeStepType::Zone,
    1664              :                             OutputProcessor::StoreType::Average,
    1665          997 :                             surface.Name);
    1666         1994 :         SetupOutputVariable(state,
    1667              :                             "Surface Inside Face System Radiation Heat Gain Rate per Area",
    1668              :                             Constant::Units::W_m2,
    1669          997 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
    1670              :                             OutputProcessor::TimeStepType::Zone,
    1671              :                             OutputProcessor::StoreType::Average,
    1672          997 :                             surface.Name);
    1673         1994 :         SetupOutputVariable(state,
    1674              :                             "Surface Inside Face System Radiation Heat Gain Energy",
    1675              :                             Constant::Units::J,
    1676          997 :                             state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
    1677              :                             OutputProcessor::TimeStepType::Zone,
    1678              :                             OutputProcessor::StoreType::Sum,
    1679          997 :                             surface.Name);
    1680              : 
    1681          997 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
    1682         1434 :             SetupOutputVariable(state,
    1683              :                                 "Surface Outside Face Outdoor Air Drybulb Temperature",
    1684              :                                 Constant::Units::C,
    1685          717 :                                 state.dataSurface->SurfOutDryBulbTemp(loop),
    1686              :                                 OutputProcessor::TimeStepType::Zone,
    1687              :                                 OutputProcessor::StoreType::Average,
    1688          717 :                                 surface.Name);
    1689         1434 :             SetupOutputVariable(state,
    1690              :                                 "Surface Outside Face Outdoor Air Wetbulb Temperature",
    1691              :                                 Constant::Units::C,
    1692          717 :                                 state.dataSurface->SurfOutWetBulbTemp(loop),
    1693              :                                 OutputProcessor::TimeStepType::Zone,
    1694              :                                 OutputProcessor::StoreType::Average,
    1695          717 :                                 surface.Name);
    1696         1434 :             SetupOutputVariable(state,
    1697              :                                 "Surface Outside Face Outdoor Air Wind Speed",
    1698              :                                 Constant::Units::m_s,
    1699          717 :                                 state.dataSurface->SurfOutWindSpeed(loop),
    1700              :                                 OutputProcessor::TimeStepType::Zone,
    1701              :                                 OutputProcessor::StoreType::Average,
    1702          717 :                                 surface.Name);
    1703         1434 :             SetupOutputVariable(state,
    1704              :                                 "Surface Outside Face Outdoor Air Wind Direction",
    1705              :                                 Constant::Units::deg,
    1706          717 :                                 state.dataSurface->SurfOutWindDir(loop),
    1707              :                                 OutputProcessor::TimeStepType::Zone,
    1708              :                                 OutputProcessor::StoreType::Average,
    1709          717 :                                 surface.Name);
    1710         1434 :             SetupOutputVariable(state,
    1711              :                                 "Surface Outside Face Convection Heat Gain Rate",
    1712              :                                 Constant::Units::W,
    1713          717 :                                 state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
    1714              :                                 OutputProcessor::TimeStepType::Zone,
    1715              :                                 OutputProcessor::StoreType::Average,
    1716          717 :                                 surface.Name);
    1717         1434 :             SetupOutputVariable(state,
    1718              :                                 "Surface Outside Face Convection Heat Gain Rate per Area",
    1719              :                                 Constant::Units::W_m2,
    1720          717 :                                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
    1721              :                                 OutputProcessor::TimeStepType::Zone,
    1722              :                                 OutputProcessor::StoreType::Average,
    1723          717 :                                 surface.Name);
    1724         1434 :             SetupOutputVariable(state,
    1725              :                                 "Surface Outside Face Convection Heat Gain Energy",
    1726              :                                 Constant::Units::J,
    1727          717 :                                 state.dataHeatBalSurf->SurfQConvOutReport(loop),
    1728              :                                 OutputProcessor::TimeStepType::Zone,
    1729              :                                 OutputProcessor::StoreType::Sum,
    1730          717 :                                 surface.Name);
    1731         1434 :             SetupOutputVariable(state,
    1732              :                                 "Surface Outside Face Convection Heat Transfer Coefficient",
    1733              :                                 Constant::Units::W_m2K,
    1734          717 :                                 state.dataHeatBalSurf->SurfHConvExt(loop),
    1735              :                                 OutputProcessor::TimeStepType::Zone,
    1736              :                                 OutputProcessor::StoreType::Average,
    1737          717 :                                 surface.Name);
    1738         1434 :             SetupOutputVariable(state,
    1739              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
    1740              :                                 Constant::Units::W,
    1741          717 :                                 state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
    1742              :                                 OutputProcessor::TimeStepType::Zone,
    1743              :                                 OutputProcessor::StoreType::Average,
    1744          717 :                                 surface.Name);
    1745         1434 :             SetupOutputVariable(state,
    1746              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
    1747              :                                 Constant::Units::W_m2,
    1748          717 :                                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
    1749              :                                 OutputProcessor::TimeStepType::Zone,
    1750              :                                 OutputProcessor::StoreType::Average,
    1751          717 :                                 surface.Name);
    1752         1434 :             SetupOutputVariable(state,
    1753              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
    1754              :                                 Constant::Units::J,
    1755          717 :                                 state.dataHeatBalSurf->SurfQRadOutReport(loop),
    1756              :                                 OutputProcessor::TimeStepType::Zone,
    1757              :                                 OutputProcessor::StoreType::Sum,
    1758          717 :                                 surface.Name);
    1759         1434 :             SetupOutputVariable(state,
    1760              :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
    1761              :                                 Constant::Units::W_m2K,
    1762          717 :                                 state.dataHeatBalSurf->SurfHAirExt(loop),
    1763              :                                 OutputProcessor::TimeStepType::Zone,
    1764              :                                 OutputProcessor::StoreType::Average,
    1765          717 :                                 surface.Name);
    1766         1434 :             SetupOutputVariable(state,
    1767              :                                 "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
    1768              :                                 Constant::Units::W_m2K,
    1769          717 :                                 state.dataHeatBalSurf->SurfHSkyExt(loop),
    1770              :                                 OutputProcessor::TimeStepType::Zone,
    1771              :                                 OutputProcessor::StoreType::Average,
    1772          717 :                                 surface.Name);
    1773         1434 :             SetupOutputVariable(state,
    1774              :                                 "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
    1775              :                                 Constant::Units::W_m2K,
    1776          717 :                                 state.dataHeatBalSurf->SurfHGrdExt(loop),
    1777              :                                 OutputProcessor::TimeStepType::Zone,
    1778              :                                 OutputProcessor::StoreType::Average,
    1779          717 :                                 surface.Name);
    1780         1434 :             SetupOutputVariable(state,
    1781              :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
    1782              :                                 Constant::Units::W,
    1783          717 :                                 state.dataHeatBalSurf->SurfQAirExtReport(loop),
    1784              :                                 OutputProcessor::TimeStepType::Zone,
    1785              :                                 OutputProcessor::StoreType::Average,
    1786          717 :                                 surface.Name);
    1787         1434 :             SetupOutputVariable(state,
    1788              :                                 "Surface Outside Face Heat Emission to Air Rate",
    1789              :                                 Constant::Units::W,
    1790          717 :                                 state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
    1791              :                                 OutputProcessor::TimeStepType::Zone,
    1792              :                                 OutputProcessor::StoreType::Average,
    1793          717 :                                 surface.Name);
    1794              : 
    1795          717 :             if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1796         1324 :                 SetupOutputVariable(state,
    1797              :                                     "Surface Outside Face Solar Radiation Heat Gain Rate",
    1798              :                                     Constant::Units::W,
    1799          662 :                                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
    1800              :                                     OutputProcessor::TimeStepType::Zone,
    1801              :                                     OutputProcessor::StoreType::Average,
    1802          662 :                                     surface.Name);
    1803         1324 :                 SetupOutputVariable(state,
    1804              :                                     "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
    1805              :                                     Constant::Units::W_m2,
    1806          662 :                                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
    1807              :                                     OutputProcessor::TimeStepType::Zone,
    1808              :                                     OutputProcessor::StoreType::Average,
    1809          662 :                                     surface.Name);
    1810         1324 :                 SetupOutputVariable(state,
    1811              :                                     "Surface Outside Face Solar Radiation Heat Gain Energy",
    1812              :                                     Constant::Units::J,
    1813          662 :                                     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
    1814              :                                     OutputProcessor::TimeStepType::Zone,
    1815              :                                     OutputProcessor::StoreType::Sum,
    1816          662 :                                     surface.Name);
    1817              :             }
    1818              :         }
    1819          997 :         if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
    1820          224 :             surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
    1821           58 :             surface.Class == DataSurfaces::SurfaceClass::Door) {
    1822              :             //      IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    1823         1880 :             SetupOutputVariable(state,
    1824              :                                 "Surface Inside Face Conduction Heat Transfer Rate",
    1825              :                                 Constant::Units::W,
    1826          940 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
    1827              :                                 OutputProcessor::TimeStepType::Zone,
    1828              :                                 OutputProcessor::StoreType::Average,
    1829          940 :                                 surface.Name);
    1830         1880 :             SetupOutputVariable(state,
    1831              :                                 "Surface Inside Face Conduction Heat Gain Rate",
    1832              :                                 Constant::Units::W,
    1833          940 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
    1834              :                                 OutputProcessor::TimeStepType::Zone,
    1835              :                                 OutputProcessor::StoreType::Average,
    1836          940 :                                 surface.Name);
    1837         1880 :             SetupOutputVariable(state,
    1838              :                                 "Surface Inside Face Conduction Heat Loss Rate",
    1839              :                                 Constant::Units::W,
    1840          940 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
    1841              :                                 OutputProcessor::TimeStepType::Zone,
    1842              :                                 OutputProcessor::StoreType::Average,
    1843          940 :                                 surface.Name);
    1844         1880 :             SetupOutputVariable(state,
    1845              :                                 "Surface Inside Face Conduction Heat Transfer Rate per Area",
    1846              :                                 Constant::Units::W_m2,
    1847          940 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
    1848              :                                 OutputProcessor::TimeStepType::Zone,
    1849              :                                 OutputProcessor::StoreType::Average,
    1850          940 :                                 surface.Name);
    1851         1880 :             SetupOutputVariable(state,
    1852              :                                 "Surface Inside Face Conduction Heat Transfer Energy",
    1853              :                                 Constant::Units::J,
    1854          940 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
    1855              :                                 OutputProcessor::TimeStepType::Zone,
    1856              :                                 OutputProcessor::StoreType::Sum,
    1857          940 :                                 surface.Name);
    1858              : 
    1859          940 :             if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1860         1880 :                 SetupOutputVariable(state,
    1861              :                                     "Surface Outside Face Conduction Heat Transfer Rate",
    1862              :                                     Constant::Units::W,
    1863          940 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
    1864              :                                     OutputProcessor::TimeStepType::Zone,
    1865              :                                     OutputProcessor::StoreType::Average,
    1866          940 :                                     surface.Name);
    1867         1880 :                 SetupOutputVariable(state,
    1868              :                                     "Surface Outside Face Conduction Heat Gain Rate",
    1869              :                                     Constant::Units::W,
    1870          940 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
    1871              :                                     OutputProcessor::TimeStepType::Zone,
    1872              :                                     OutputProcessor::StoreType::Average,
    1873          940 :                                     surface.Name);
    1874         1880 :                 SetupOutputVariable(state,
    1875              :                                     "Surface Outside Face Conduction Heat Loss Rate",
    1876              :                                     Constant::Units::W,
    1877          940 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
    1878              :                                     OutputProcessor::TimeStepType::Zone,
    1879              :                                     OutputProcessor::StoreType::Average,
    1880          940 :                                     surface.Name);
    1881         1880 :                 SetupOutputVariable(state,
    1882              :                                     "Surface Outside Face Conduction Heat Transfer Rate per Area",
    1883              :                                     Constant::Units::W_m2,
    1884          940 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
    1885              :                                     OutputProcessor::TimeStepType::Zone,
    1886              :                                     OutputProcessor::StoreType::Average,
    1887          940 :                                     surface.Name);
    1888         1880 :                 SetupOutputVariable(state,
    1889              :                                     "Surface Outside Face Conduction Heat Transfer Energy",
    1890              :                                     Constant::Units::J,
    1891          940 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
    1892              :                                     OutputProcessor::TimeStepType::Zone,
    1893              :                                     OutputProcessor::StoreType::Sum,
    1894          940 :                                     surface.Name);
    1895              : 
    1896         1880 :                 SetupOutputVariable(state,
    1897              :                                     "Surface Average Face Conduction Heat Transfer Rate",
    1898              :                                     Constant::Units::W,
    1899          940 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
    1900              :                                     OutputProcessor::TimeStepType::Zone,
    1901              :                                     OutputProcessor::StoreType::Average,
    1902          940 :                                     surface.Name);
    1903         1880 :                 SetupOutputVariable(state,
    1904              :                                     "Surface Average Face Conduction Heat Gain Rate",
    1905              :                                     Constant::Units::W,
    1906          940 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
    1907              :                                     OutputProcessor::TimeStepType::Zone,
    1908              :                                     OutputProcessor::StoreType::Average,
    1909          940 :                                     surface.Name);
    1910         1880 :                 SetupOutputVariable(state,
    1911              :                                     "Surface Average Face Conduction Heat Loss Rate",
    1912              :                                     Constant::Units::W,
    1913          940 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
    1914              :                                     OutputProcessor::TimeStepType::Zone,
    1915              :                                     OutputProcessor::StoreType::Average,
    1916          940 :                                     surface.Name);
    1917         1880 :                 SetupOutputVariable(state,
    1918              :                                     "Surface Average Face Conduction Heat Transfer Rate per Area",
    1919              :                                     Constant::Units::W_m2,
    1920          940 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
    1921              :                                     OutputProcessor::TimeStepType::Zone,
    1922              :                                     OutputProcessor::StoreType::Average,
    1923          940 :                                     surface.Name);
    1924         1880 :                 SetupOutputVariable(state,
    1925              :                                     "Surface Average Face Conduction Heat Transfer Energy",
    1926              :                                     Constant::Units::J,
    1927          940 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
    1928              :                                     OutputProcessor::TimeStepType::Zone,
    1929              :                                     OutputProcessor::StoreType::Sum,
    1930          940 :                                     surface.Name);
    1931              : 
    1932         1880 :                 SetupOutputVariable(state,
    1933              :                                     "Surface Heat Storage Rate",
    1934              :                                     Constant::Units::W,
    1935          940 :                                     state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
    1936              :                                     OutputProcessor::TimeStepType::Zone,
    1937              :                                     OutputProcessor::StoreType::Average,
    1938          940 :                                     surface.Name);
    1939         1880 :                 SetupOutputVariable(state,
    1940              :                                     "Surface Heat Storage Gain Rate",
    1941              :                                     Constant::Units::W,
    1942          940 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
    1943              :                                     OutputProcessor::TimeStepType::Zone,
    1944              :                                     OutputProcessor::StoreType::Average,
    1945          940 :                                     surface.Name);
    1946         1880 :                 SetupOutputVariable(state,
    1947              :                                     "Surface Heat Storage Loss Rate",
    1948              :                                     Constant::Units::W,
    1949          940 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
    1950              :                                     OutputProcessor::TimeStepType::Zone,
    1951              :                                     OutputProcessor::StoreType::Average,
    1952          940 :                                     surface.Name);
    1953         1880 :                 SetupOutputVariable(state,
    1954              :                                     "Surface Heat Storage Rate per Area",
    1955              :                                     Constant::Units::W_m2,
    1956          940 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
    1957              :                                     OutputProcessor::TimeStepType::Zone,
    1958              :                                     OutputProcessor::StoreType::Average,
    1959          940 :                                     surface.Name);
    1960         1880 :                 SetupOutputVariable(state,
    1961              :                                     "Surface Heat Storage Energy",
    1962              :                                     Constant::Units::J,
    1963          940 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
    1964              :                                     OutputProcessor::TimeStepType::Zone,
    1965              :                                     OutputProcessor::StoreType::Sum,
    1966          940 :                                     surface.Name);
    1967              :             }
    1968              : 
    1969              :             //      ENDIF
    1970              :             // CurrentModuleObject='Opaque Surfaces'
    1971              : 
    1972         1880 :             SetupOutputVariable(state,
    1973              :                                 "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
    1974              :                                 Constant::Units::W,
    1975          940 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
    1976              :                                 OutputProcessor::TimeStepType::Zone,
    1977              :                                 OutputProcessor::StoreType::Average,
    1978          940 :                                 surface.Name);
    1979              :         }
    1980          997 :         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    1981            2 :             SetupOutputVariable(state,
    1982              :                                 "Surface Internal Source Location Temperature",
    1983              :                                 Constant::Units::C,
    1984            1 :                                 state.dataHeatBalSurf->SurfTempSource(loop),
    1985              :                                 OutputProcessor::TimeStepType::Zone,
    1986              :                                 OutputProcessor::StoreType::Average,
    1987            1 :                                 surface.Name);
    1988            2 :             SetupOutputVariable(state,
    1989              :                                 "Surface Internal User Specified Location Temperature",
    1990              :                                 Constant::Units::C,
    1991            1 :                                 state.dataHeatBalSurf->SurfTempUserLoc(loop),
    1992              :                                 OutputProcessor::TimeStepType::Zone,
    1993              :                                 OutputProcessor::StoreType::Average,
    1994            1 :                                 surface.Name);
    1995              :         }
    1996              : 
    1997          997 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
    1998           55 :             auto &surfShade = state.dataSurface->surfShades(loop);
    1999          110 :             SetupOutputVariable(state,
    2000              :                                 "Surface Shading Device Is On Time Fraction",
    2001              :                                 Constant::Units::None,
    2002           55 :                                 state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
    2003              :                                 OutputProcessor::TimeStepType::Zone,
    2004              :                                 OutputProcessor::StoreType::Average,
    2005           55 :                                 surface.Name);
    2006           55 :             SetupOutputVariable(state,
    2007              :                                 "Surface Storm Window On Off Status",
    2008              :                                 Constant::Units::None,
    2009           55 :                                 state.dataSurface->SurfWinStormWinFlag(loop),
    2010              :                                 OutputProcessor::TimeStepType::Zone,
    2011              :                                 OutputProcessor::StoreType::Average,
    2012           55 :                                 surface.Name);
    2013          110 :             SetupOutputVariable(state,
    2014              :                                 "Surface Window Blind Slat Angle",
    2015              :                                 Constant::Units::deg,
    2016           55 :                                 surfShade.blind.slatAngDeg,
    2017              :                                 OutputProcessor::TimeStepType::Zone,
    2018              :                                 OutputProcessor::StoreType::Average,
    2019           55 :                                 surface.Name);
    2020              :         }
    2021              :         //    IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    2022          997 :         SetupOutputVariable(state,
    2023              :                             "Surface Inside Face Convection Classification Index",
    2024              :                             Constant::Units::None,
    2025          997 :                             state.dataSurface->surfIntConv(loop).convClassRpt,
    2026              :                             OutputProcessor::TimeStepType::Zone,
    2027              :                             OutputProcessor::StoreType::Average,
    2028          997 :                             surface.Name);
    2029          997 :         SetupOutputVariable(state,
    2030              :                             "Surface Inside Face Convection Model Equation Index",
    2031              :                             Constant::Units::None,
    2032          997 :                             state.dataSurface->surfIntConv(loop).hcModelEqRpt,
    2033              :                             OutputProcessor::TimeStepType::Zone,
    2034              :                             OutputProcessor::StoreType::Average,
    2035          997 :                             surface.Name);
    2036          997 :         SetupOutputVariable(state,
    2037              :                             "Surface Inside Face Convection Reference Air Index",
    2038              :                             Constant::Units::None,
    2039          997 :                             state.dataSurface->SurfTAirRefRpt(loop),
    2040              :                             OutputProcessor::TimeStepType::Zone,
    2041              :                             OutputProcessor::StoreType::Average,
    2042          997 :                             surface.Name);
    2043          997 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    2044          716 :             SetupOutputVariable(state,
    2045              :                                 "Surface Outside Face Convection Classification Index",
    2046              :                                 Constant::Units::None,
    2047          716 :                                 state.dataSurface->surfExtConv(loop).convClassRpt,
    2048              :                                 OutputProcessor::TimeStepType::Zone,
    2049              :                                 OutputProcessor::StoreType::Average,
    2050          716 :                                 surface.Name);
    2051          716 :             SetupOutputVariable(state,
    2052              :                                 "Surface Outside Face Forced Convection Model Equation Index",
    2053              :                                 Constant::Units::None,
    2054          716 :                                 state.dataSurface->surfExtConv(loop).hfModelEqRpt,
    2055              :                                 OutputProcessor::TimeStepType::Zone,
    2056              :                                 OutputProcessor::StoreType::Average,
    2057          716 :                                 surface.Name);
    2058          716 :             SetupOutputVariable(state,
    2059              :                                 "Surface Outside Face Natural Convection Model Equation Index",
    2060              :                                 Constant::Units::None,
    2061          716 :                                 state.dataSurface->surfExtConv(loop).hnModelEqRpt,
    2062              :                                 OutputProcessor::TimeStepType::Zone,
    2063              :                                 OutputProcessor::StoreType::Average,
    2064          716 :                                 surface.Name);
    2065              :         }
    2066              : 
    2067         1994 :         SetupOutputVariable(state,
    2068              :                             "Surface Inside Face Heat Source Gain Rate per Area",
    2069              :                             Constant::Units::W_m2,
    2070          997 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
    2071              :                             OutputProcessor::TimeStepType::Zone,
    2072              :                             OutputProcessor::StoreType::Average,
    2073          997 :                             surface.Name);
    2074         1994 :         SetupOutputVariable(state,
    2075              :                             "Surface Outside Face Heat Source Gain Rate per Area",
    2076              :                             Constant::Units::W_m2,
    2077          997 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
    2078              :                             OutputProcessor::TimeStepType::Zone,
    2079              :                             OutputProcessor::StoreType::Average,
    2080          997 :                             surface.Name);
    2081              : 
    2082              :         //     ENDIF
    2083          997 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    2084            1 :             SetupOutputVariable(state,
    2085              :                                 "Surface Construction Index",
    2086              :                                 Constant::Units::None,
    2087            1 :                                 surface.Construction,
    2088              :                                 OutputProcessor::TimeStepType::Zone,
    2089              :                                 OutputProcessor::StoreType::Average,
    2090            1 :                                 surface.Name);
    2091              :         }
    2092              :     }
    2093          580 :     SetupOutputVariable(state,
    2094              :                         "Site Total Surface Heat Emission to Air",
    2095              :                         Constant::Units::J,
    2096          145 :                         state.dataHeatBalSurf->SumSurfaceHeatEmission,
    2097              :                         OutputProcessor::TimeStepType::Zone,
    2098              :                         OutputProcessor::StoreType::Sum,
    2099              :                         "Environment");
    2100          145 : }
    2101              : 
    2102          483 : void InitThermalAndFluxHistories(EnergyPlusData &state)
    2103              : {
    2104              : 
    2105              :     // SUBROUTINE INFORMATION:
    2106              :     //       AUTHOR         George Walton
    2107              :     //       DATE WRITTEN   March 1978
    2108              :     //       RE-ENGINEERED  Feb98 (RKS)
    2109              : 
    2110              :     // PURPOSE OF THIS SUBROUTINE:
    2111              :     // This subroutine sets the initial temperature and flux histories
    2112              :     // needed for a stable and reasonable heat balance solution starting
    2113              :     // point.
    2114              : 
    2115              :     // METHODOLOGY EMPLOYED:
    2116              :     // This subroutine assumes that the simulation is at steady state at
    2117              :     // the beginning and then begins to vary.  Thus, the temperatures, the
    2118              :     // fluxes. and their histories can all be set to the same value.  Some
    2119              :     // of the initializations depend on the surface characteristics.  This
    2120              :     // requires a DO loop to perform the proper calculation.
    2121              : 
    2122              :     // REFERENCES:
    2123              :     // (I)BLAST legacy routine INITTH
    2124              : 
    2125              :     // First do the "bulk" initializations of arrays sized to NumOfZones
    2126         1157 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2127          674 :         new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
    2128              :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2129          674 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
    2130          674 :         thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2131          674 :         thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
    2132          674 :         state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
    2133              :     }
    2134         1213 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    2135          730 :         thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
    2136              :     }
    2137              :     // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
    2138         1263 :     for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
    2139          780 :         new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
    2140              :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2141          780 :         thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2142          780 :         thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
    2143              :     }
    2144              : 
    2145              :     // "Bulk" initializations of arrays sized to TotSurfaces
    2146         1157 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2147         1454 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2148          780 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2149          780 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2150          780 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2151         4918 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2152         4138 :                 state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2153         4138 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;        // module level array
    2154         4138 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp;     // module level array
    2155         4138 :                 state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
    2156         4138 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    2157         4138 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    2158         4138 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    2159         4138 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    2160         4138 :                 state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
    2161         4138 :                 state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
    2162         4138 :                 state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
    2163         4138 :                 state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
    2164         4138 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
    2165         4138 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
    2166         4138 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
    2167         4138 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
    2168         4138 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
    2169         4138 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
    2170         4138 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
    2171         4138 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
    2172         4138 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
    2173         4138 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
    2174         4138 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
    2175         4138 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
    2176         4138 :                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
    2177         4138 :                 state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
    2178         4138 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
    2179         4138 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
    2180         4138 :                 state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
    2181         4138 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
    2182         4138 :                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
    2183         4138 :                 state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
    2184         4138 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
    2185              :             } // end of  Surf array
    2186          780 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2187          780 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2188          780 :             if (firstSurfOpaq >= 0) {
    2189         4692 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2190         3912 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
    2191         3912 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
    2192         3912 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
    2193         3912 :                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2194              :                 } // end of Zone Surf
    2195              :             }
    2196          780 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2197          780 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2198          780 :             if (firstSurfWin >= 0) {
    2199         1006 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2200              :                     // Initialize window frame and divider temperatures
    2201          226 :                     state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2202          226 :                     state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2203          226 :                     state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2204          226 :                     state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2205          226 :                     state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2206          226 :                     state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2207              : 
    2208              :                     // Initialize previous-timestep shading indicators
    2209          226 :                     state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2210          226 :                     state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2211              :                 } // end of Zone Surf
    2212              :             }
    2213              :         }
    2214              :     } // end of Zone
    2215              : 
    2216              :     // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
    2217         1157 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2218         1454 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2219          780 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2220          780 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2221          780 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2222        15600 :             for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2223        93442 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2224        78622 :                     state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2225        78622 :                     state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2226        78622 :                     state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2227        78622 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2228              :                 }
    2229              :             }
    2230              :         }
    2231              :     }
    2232          483 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2233          236 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2234          252 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2235          126 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2236          126 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2237          126 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2238          888 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2239          762 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    2240              :                 }
    2241         2520 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2242        16872 :                     for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2243        14478 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2244        14478 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2245        14478 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2246        14478 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2247              :                     }
    2248              :                 }
    2249              :             }
    2250              :         }
    2251              :     }
    2252          483 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    2253            0 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2254            0 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2255            0 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2256            0 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2257            0 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2258            0 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2259            0 :                     for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2260            0 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2261            0 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2262            0 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2263            0 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2264            0 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
    2265            0 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
    2266              :                     }
    2267              :                 }
    2268              :             }
    2269              :         }
    2270              :     }
    2271          483 :     state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    2272              : 
    2273              :     // Perform other initializations that depend on the surface characteristics
    2274         4190 :     for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
    2275        38343 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2276        34636 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2277              :             // Reset outside boundary conditions if necessary
    2278        34636 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2279        21427 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2280        13209 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2281         2753 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2282         2753 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2283        10456 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2284            0 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2285            0 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2286              :             }
    2287              :             // Initialize the flux histories
    2288        34636 :             state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
    2289        34636 :                 state.dataConstruction->Construct(surface.Construction).UValue *
    2290        34636 :                 (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
    2291        34636 :             state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2292              :         }
    2293              :     }
    2294         4621 :     for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2295         4138 :         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    2296            0 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
    2297            0 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
    2298              :         }
    2299              :     }
    2300              :     // Initialize Kiva convection algorithms
    2301          483 :     for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
    2302            0 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
    2303            0 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
    2304            0 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
    2305              :     }
    2306          483 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2307          872 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2308          762 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2309          762 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2310        11880 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2311        11286 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2312              :                 }
    2313          762 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2314            0 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2315            0 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2316            0 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2317              :                 }
    2318          168 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2319            0 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2320            0 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2321            0 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2322              :                 }
    2323              :             }
    2324         3046 :             for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
    2325         2284 :                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2326         2284 :                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2327              :             }
    2328              :         }
    2329              :     }
    2330              : 
    2331          483 :     if (state.dataSurface->TotOSCM >= 1) {
    2332            2 :         for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
    2333            1 :             auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
    2334            1 :             thisOSC.TConv = 20.0;
    2335            1 :             thisOSC.HConv = 4.0;
    2336            1 :             thisOSC.TRad = 20.0;
    2337            1 :             thisOSC.HRad = 4.0;
    2338              :         }
    2339              :     }
    2340          483 : }
    2341              : 
    2342            3 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
    2343              : {
    2344              :     // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
    2345            3 :     auto &s_mat = state.dataMaterial;
    2346            3 :     auto &s_surf = state.dataSurface;
    2347              : 
    2348            6 :     for (int SurfNum : s_surf->extMovInsulSurfNums) {
    2349            3 :         auto &movInsul = s_surf->extMovInsuls(SurfNum);
    2350            3 :         Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
    2351            3 :         if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
    2352            0 :             movInsul.present = false;
    2353            0 :             int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
    2354            0 :             auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
    2355            0 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
    2356            0 :             state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
    2357            0 :             state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
    2358            0 :             continue;
    2359            0 :         }
    2360              : 
    2361            3 :         auto const *mat = s_mat->materials(movInsul.matNum);
    2362            3 :         movInsul.present = true;
    2363            3 :         movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
    2364            3 :         if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
    2365            2 :             auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
    2366            2 :             assert(matGlass != nullptr);
    2367            2 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
    2368            2 :         } else {
    2369            1 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
    2370              :         }
    2371            3 :         state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
    2372            3 :         state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
    2373              :     }
    2374            3 : }
    2375              : 
    2376            3 : void EvalInsideMovableInsulation(EnergyPlusData &state)
    2377              : {
    2378            3 :     auto &s_mat = state.dataMaterial;
    2379            3 :     auto &s_surf = state.dataSurface;
    2380              :     // This subroutine determines whether or not inside movable insulation is present at the current time.
    2381            6 :     for (int SurfNum : s_surf->intMovInsulSurfNums) {
    2382            3 :         auto &movInsul = s_surf->intMovInsuls(SurfNum);
    2383            3 :         Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
    2384            3 :         if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
    2385            0 :             movInsul.present = false;
    2386            0 :             int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
    2387            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    2388            0 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
    2389            0 :             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
    2390            0 :             continue;
    2391            0 :         }
    2392              : 
    2393            3 :         auto const *mat = s_mat->materials(movInsul.matNum);
    2394              : 
    2395            3 :         movInsul.present = true;
    2396            3 :         movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
    2397            3 :         if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
    2398            2 :             auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
    2399            2 :             assert(matGlass != nullptr);
    2400            2 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
    2401            2 :         } else {
    2402            1 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
    2403              :         }
    2404            3 :         state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
    2405              :     }
    2406            3 : }
    2407              : 
    2408       249960 : void InitSolarHeatGains(EnergyPlusData &state)
    2409              : {
    2410              : 
    2411              :     // SUBROUTINE INFORMATION:
    2412              :     //       AUTHOR         Anonymous
    2413              :     //       DATE WRITTEN   July 1977
    2414              :     //       MODIFIED       Mar99 (FW): handle movable interior shades and
    2415              :     //                                  switchable glazing
    2416              :     //                      Oct99 (FW): account for Window5 glass calculation approach
    2417              :     //                      May01 (FW): handle interior and exterior blinds
    2418              :     //                      Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
    2419              :     //                      May06 (RR): handle exterior window screens
    2420              :     //       RE-ENGINEERED  Feb98 (RKS)
    2421              : 
    2422              :     // PURPOSE OF THIS SUBROUTINE:
    2423              :     // This subroutine initializes the arrays associated with solar heat
    2424              :     // gains for both individual surfaces and for zones.  As a result,
    2425              :     // this routine sets the following variable arrays:
    2426              :     // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
    2427              :     // SurfWinQRadSWwinAbs (for windows)
    2428              : 
    2429              :     // METHODOLOGY EMPLOYED:
    2430              :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    2431              :     // sun is up, various calculations are made.
    2432              : 
    2433              :     // REFERENCES:
    2434              :     // (I)BLAST legacy routine QSUN
    2435              : 
    2436       249960 :     auto &s_mat = state.dataMaterial;
    2437       249960 :     auto &Surface = state.dataSurface->Surface;
    2438              : 
    2439              :     // Using/Aliasing
    2440              :     using Dayltg::TransTDD;
    2441              :     using SolarShading::CalcInteriorSolarDistribution;
    2442              :     using namespace DataWindowEquivalentLayer;
    2443              :     using SolarShading::SurfaceScheduledSolarInc;
    2444              :     using SolarShading::WindowScheduledSolarAbs;
    2445              : 
    2446              :     // Why are these globals?
    2447       249960 :     auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
    2448       249960 :     auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
    2449       249960 :     auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
    2450              : 
    2451       586612 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2452       336652 :         state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
    2453       336652 :         state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
    2454       336652 :         state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
    2455       336652 :         state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
    2456       336652 :         state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
    2457       336652 :         state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
    2458              : 
    2459       336652 :         state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
    2460       336652 :         state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
    2461       336652 :         state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
    2462       336652 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
    2463       336652 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
    2464       336652 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
    2465       336652 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
    2466       336652 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
    2467       336652 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
    2468              :     }
    2469       605538 :     for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2470       355578 :         state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
    2471              :     }
    2472       586612 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2473       709607 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2474       372955 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2475       372955 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2476       372955 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2477      2358715 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2478      1985760 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
    2479      1985760 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
    2480      1985760 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
    2481      1985760 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
    2482      1985760 :                 state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
    2483      1985760 :                 state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
    2484      1985760 :                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2485      1985760 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
    2486      1985760 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
    2487              :             }
    2488              : 
    2489       372955 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2490       372955 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2491       461525 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2492              :                 // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
    2493        88570 :                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
    2494        88570 :                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
    2495        88570 :                 state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
    2496        88570 :                 state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
    2497        88570 :                 state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
    2498        88570 :                 state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
    2499        88570 :                 state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
    2500        88570 :                 state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
    2501        88570 :                 state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
    2502        88570 :                 state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
    2503              :             }
    2504              : 
    2505       461525 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2506        88570 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
    2507        88570 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
    2508        88570 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
    2509        88570 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
    2510        88570 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
    2511        88570 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
    2512        88570 :                 state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
    2513        88570 :                 state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
    2514        88570 :                 state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
    2515              :             }
    2516       461525 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2517        88570 :                 state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
    2518        88570 :                 state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
    2519        88570 :                 state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
    2520        88570 :                 state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
    2521        88570 :                 state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
    2522        88570 :                 state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
    2523        88570 :                 state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
    2524              :             }
    2525      2983640 :             for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2526      3230675 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2527       619990 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
    2528              :                 }
    2529              :             }
    2530              :         }
    2531              :     }
    2532       249960 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    2533          926 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2534          812 :             state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2535          812 :             state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2536              :         }
    2537              :     }
    2538              :     bool currSolRadPositive =
    2539       249960 :         state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
    2540       249960 :     bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
    2541       249960 :     bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
    2542       249960 :     bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
    2543       249960 :                       sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
    2544       249960 :     state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
    2545              : 
    2546       249960 :     if (currSolRadPositive || resetSolar) {
    2547      1169133 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2548      1046167 :             state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2549      1046167 :             state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2550      1046167 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2551      1046167 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2552      1046167 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
    2553              : 
    2554      1046167 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
    2555      1046167 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
    2556      1046167 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
    2557      1046167 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
    2558              : 
    2559      1046167 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
    2560      1046167 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
    2561      1046167 :             state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
    2562      1046167 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
    2563      1046167 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
    2564              : 
    2565      1046167 :             state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
    2566      1046167 :             state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
    2567              :         }
    2568       299934 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2569       176968 :             state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
    2570       176968 :             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
    2571       176968 :             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
    2572       176968 :             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
    2573       176968 :             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
    2574       176968 :             state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
    2575       176968 :             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2576       176968 :             state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2577       176968 :             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2578       176968 :             state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2579              :         }
    2580       290055 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2581       353288 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2582       186199 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2583       186199 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2584       186199 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2585       231264 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2586        45065 :                     state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
    2587        45065 :                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
    2588        45065 :                     state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
    2589        45065 :                     state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
    2590        45065 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    2591        45065 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
    2592        45065 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
    2593        45065 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
    2594        45065 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
    2595        45065 :                     state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
    2596              :                 }
    2597       231264 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2598        45065 :                     state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
    2599        45065 :                     state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
    2600        45065 :                     state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
    2601        45065 :                     state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
    2602        45065 :                     state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
    2603        45065 :                     state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
    2604        45065 :                     state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
    2605        45065 :                     state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
    2606        45065 :                     state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
    2607        45065 :                     state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
    2608        45065 :                     state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
    2609        45065 :                     state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
    2610        45065 :                     state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
    2611              :                 }
    2612       231264 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2613        45065 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
    2614        45065 :                     state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
    2615        45065 :                     state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
    2616        45065 :                     state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
    2617        45065 :                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2618        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2619        45065 :                     state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
    2620        45065 :                     state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
    2621        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
    2622              :                 }
    2623       231264 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2624        45065 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
    2625        45065 :                     state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
    2626        45065 :                     state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
    2627        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
    2628        45065 :                     state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
    2629        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
    2630        45065 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
    2631        45065 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
    2632        45065 :                     state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
    2633              :                 }
    2634              : 
    2635       231264 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2636        45065 :                     state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
    2637        45065 :                     state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
    2638        45065 :                     state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
    2639        45065 :                     state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
    2640        45065 :                     state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
    2641        45065 :                     state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
    2642        45065 :                     state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
    2643        45065 :                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
    2644        45065 :                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
    2645        45065 :                     state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
    2646        45065 :                     state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
    2647        45065 :                     state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
    2648        45065 :                     state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
    2649              :                 }
    2650      1478034 :                 for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
    2651      1607320 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2652       315485 :                         state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
    2653              :                     }
    2654              :                 }
    2655      1303393 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
    2656      1387584 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2657       270390 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
    2658              :                     }
    2659              :                 }
    2660              :             }
    2661              :         }
    2662              :     }
    2663       249960 :     if (resetSolar) {
    2664       122672 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2665        70921 :             state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
    2666        70921 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
    2667              :         }
    2668              : 
    2669              :         // TTD domes are currently not considered in the window list of a zone
    2670        51751 :         if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
    2671            0 :             for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
    2672            0 :                 e.TransSolBeam = 0.0;
    2673            0 :                 e.TransSolDiff = 0.0;
    2674            0 :                 e.TransVisBeam = 0.0;
    2675            0 :                 e.TransVisDiff = 0.0;
    2676            0 :                 e.TransmittedSolar = 0.0;
    2677            0 :                 int SurfDome = e.Dome;
    2678            0 :                 state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
    2679            0 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
    2680            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
    2681            0 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2682            0 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
    2683              :                 }
    2684              :             }
    2685              :         }
    2686              : 
    2687        51751 :         if (state.dataSurface->CalcSolRefl) {
    2688            0 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2689            0 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
    2690            0 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
    2691            0 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
    2692              :             }
    2693              :         }
    2694       472795 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2695       421044 :             state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
    2696       421044 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
    2697       421044 :             state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
    2698       421044 :             state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
    2699       421044 :             state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
    2700       421044 :             state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
    2701       421044 :             state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
    2702              :         }
    2703              :     }
    2704       249960 :     if (currSolRadPositive) { // Sun is up, calculate solar quantities
    2705        71216 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2706              :                                 state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
    2707        71216 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2708              :                                 state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
    2709        71216 :         Real64 GndReflSolarRad = 0.0;
    2710        71216 :         Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
    2711              : 
    2712       696350 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2713       625134 :             state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
    2714              :         }
    2715       696350 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2716       625134 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2717       625134 :             state.dataSurface->SurfSkySolarInc(SurfNum) =
    2718       625134 :                 state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2719       625134 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2720            0 :                 GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
    2721            0 :                                   state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2722            0 :                 Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
    2723              :             } else {
    2724       625134 :                 GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    2725              :             }
    2726       625134 :             state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
    2727       625134 :             state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2728       625134 :             state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
    2729              :         }
    2730        71216 :         if (state.dataSurface->CalcSolRefl) {
    2731              :             // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
    2732            0 :             Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
    2733            0 :             Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
    2734              :             // For Complex Fenestrations:
    2735            0 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2736            0 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2737              : 
    2738            0 :                 Real64 GndSurfReflectance = 0.0;
    2739            0 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2740            0 :                     GndSurfReflectance =
    2741            0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2742              :                 } else {
    2743            0 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2744              :                 }
    2745            0 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2746            0 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2747            0 :                 state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
    2748            0 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2749            0 :                 state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
    2750            0 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2751            0 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
    2752            0 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
    2753            0 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
    2754            0 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
    2755            0 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
    2756            0 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
    2757            0 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
    2758            0 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
    2759            0 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
    2760              :                 // TH2 CR 9056
    2761            0 :                 state.dataSurface->SurfSkySolarInc(SurfNum) +=
    2762            0 :                     currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
    2763            0 :                     currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    2764            0 :                 state.dataSurface->SurfGndSolarInc(SurfNum) =
    2765            0 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
    2766            0 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2767            0 :                 state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2768              :             }
    2769              :         }
    2770              : 
    2771        71216 :         SolarShading::CalcWindowProfileAngles(state);
    2772              : 
    2773        71216 :         if (state.dataHeatBal->CalcWindowRevealReflection) SolarShading::CalcBeamSolarOnWinRevealSurface(state);
    2774              : 
    2775        71216 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2776            0 :             SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
    2777            0 :             if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2778            0 :                 SolarShading::CalcInteriorSolarDistributionWCESimple(state);
    2779              :             }
    2780              :         } else {
    2781        71216 :             SolarShading::CalcInteriorSolarDistribution(state);
    2782              :         }
    2783              : 
    2784       177264 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2785              : 
    2786              :             // TH 3/24/2010 - QBV is not used!
    2787              :             // unused      QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
    2788              : 
    2789              :             // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
    2790              :             // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
    2791              :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2792              : 
    2793              :             // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
    2794              :             // QDforDaylight(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2795              :             //                          +EnclSolDS(ZoneNum)*DifSolarRad  &
    2796              :             //                          +EnclSolDG(ZoneNum)*GndSolarRad
    2797              : 
    2798              :             //  Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
    2799              :             //  EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
    2800              :             //  Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
    2801              :             //   diffuse solar rather than using weighted area*absorptance
    2802       106048 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
    2803       106048 :                 (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
    2804       106048 :                 state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2805              : 
    2806              :             // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
    2807              :             // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
    2808              :             // and transmitted through interior windows
    2809              :             // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
    2810              :             // QD(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2811              :             //                +EnclSolDS(ZoneNum)*DifSolarRad  &
    2812              :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2813       212096 :             state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
    2814       106048 :                                                          state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
    2815       106048 :                                                          state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2816              :         }
    2817              : 
    2818              :         // Flux of diffuse solar in each zone
    2819              : 
    2820       177264 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2821       106048 :             state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
    2822              :         }
    2823              : 
    2824        71216 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    2825            0 :             for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2826            0 :                 if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
    2827            0 :                     Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
    2828            0 :                     int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
    2829            0 :                                                                                  1)); // Tuned Linear indexing
    2830            0 :                     for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
    2831            0 :                         if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
    2832            0 :                             EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
    2833            0 :                                                    state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
    2834              :                         }
    2835              :                     }
    2836            0 :                     state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
    2837              :                 }
    2838              :             }
    2839              :         }
    2840              : 
    2841       177264 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2842       106048 :             if (state.dataHeatBalSurf->InterZoneWindow)
    2843            0 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
    2844            0 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2845              :             else
    2846       106048 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2847              :         }
    2848              : 
    2849              :         //    RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
    2850              :         //    DO SurfNum = 1, TotSurfaces
    2851              :         //      IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
    2852              :         //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    2853              :         //      IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
    2854              :         //      ZoneNum = Surface(SurfNum)%Zone
    2855              :         // Diffuse solar entering zone through exterior windows is assumed to be uniformly
    2856              :         // distributed on inside face of surfaces of zone
    2857              :         //      DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) /  &
    2858              :         //        Zone(ZoneNum)%TotalSurfArea
    2859              :         //      DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) *  &
    2860              :         //        DifIncInsSurfIntensRep(SurfNum)
    2861              :         //      DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
    2862              :         //    END DO
    2863              : 
    2864              :         // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
    2865        71216 :         if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
    2866        14980 :             for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
    2867        11984 :                 Real64 GndSurfReflectance = 0.0;
    2868        11984 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2869            0 :                     GndSurfReflectance =
    2870            0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2871              :                 } else {
    2872        11984 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2873              :                 }
    2874              :                 // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2875        11984 :                 Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2876        11984 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
    2877        11984 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2878        11984 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2879        11984 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2880              :                 // Incident direct (unreflected) beam
    2881        11984 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2882        11984 :                     currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
    2883              :                 // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2884        11984 :                 state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2885              :                 // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2886        11984 :                 state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2887              :                 // Incident diffuse solar from beam-to-diffuse reflection from ground
    2888        11984 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2889        11984 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2890              :                 // Incident diffuse solar from sky diffuse reflection from ground
    2891        11984 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2892        11984 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2893              :                 // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2894              :                 // in SkySolarInc.
    2895        11984 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2896        11984 :                     state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2897        11984 :                     state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    2898              :             }
    2899              :         }
    2900              : 
    2901        71216 :         Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
    2902              : 
    2903       462416 :         for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
    2904       391200 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2905              :             // Regular surface
    2906       391200 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2907       391200 :             Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2908              :             // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2909       391200 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    2910       391200 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2911              : 
    2912              :             // Report variables for various incident solar quantities
    2913              :             // Incident direct (unreflected) beam
    2914       391200 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2915       391200 :                 currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    2916       391200 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
    2917              : 
    2918       391200 :             Real64 GndSurfReflectance = 0.0;
    2919       391200 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2920            0 :                 GndSurfReflectance =
    2921            0 :                     state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2922              :             } else {
    2923       391200 :                 GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2924              :             }
    2925              :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2926       391200 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2927              :             // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2928       391200 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2929              :             // Incident diffuse solar from beam-to-diffuse reflection from ground
    2930       391200 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2931       391200 :                 currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2932              : 
    2933              :             // Incident diffuse solar from sky diffuse reflection from ground
    2934       391200 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2935       391200 :                 currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2936              :             // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2937              :             // in SkySolarInc.
    2938              :             // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
    2939              :             // TH2 CR 9056
    2940       391200 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2941       391200 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2942       391200 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    2943              : 
    2944       391200 :             if (state.dataSurface->CalcSolRefl) {
    2945              :                 // Incident beam solar from beam-to-beam (specular) reflection from obstructions
    2946            0 :                 state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    2947              :                 // Incident diffuse solar from beam-to-diffuse reflection from obstructions
    2948            0 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
    2949            0 :                     state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    2950              :                 // Incident diffuse solar from sky diffuse reflection from obstructions
    2951            0 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    2952              :                 // TH2 CR 9056: Add reflections from obstructions to the total incident
    2953            0 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
    2954            0 :                                                                      state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
    2955            0 :                                                                      state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
    2956              :             }
    2957              :         }
    2958        71216 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    2959            0 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
    2960            0 :             int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;    // TDD: DOME object number
    2961            0 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    2962            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    2963              : 
    2964              :             // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
    2965              :             // by dividing out diffuse solar transmittance of TDD:DIFFUSER
    2966            0 :             Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    2967              : 
    2968            0 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
    2969            0 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2970            0 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
    2971            0 :                                      TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
    2972              : 
    2973            0 :             state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
    2974            0 :                                                           state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
    2975            0 :                                                           TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
    2976              : 
    2977            0 :             state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
    2978            0 :                                                           state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
    2979              :             // Incident direct (unreflected) beam
    2980            0 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
    2981            0 :                                                                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
    2982            0 :                                                                                                       state.dataGlobal->TimeStep,
    2983            0 :                                                                                                       SurfNum2) *
    2984              :                                                                     ConInc; // NOTE: sunlit and coninc array set to SurfNum2
    2985              : 
    2986              :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2987            0 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
    2988            0 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2989            0 :                 (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2990            0 :                  state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
    2991              :         }
    2992              : 
    2993        71216 :         for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
    2994            0 :             int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window;       // Daylighting shelf object number
    2995            0 :             int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
    2996            0 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    2997            0 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2998            0 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2999            0 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3000              :             // Shelf diffuse solar radiation
    3001              :             Real64 ShelfSolarRad =
    3002            0 :                 (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
    3003            0 :                      state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
    3004            0 :                  state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
    3005            0 :                 state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
    3006              : 
    3007            0 :             GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    3008            0 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    3009            0 :                 GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
    3010              :             }
    3011              :             // Add all reflected solar from the outside shelf to the ground solar
    3012              :             // NOTE:  If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
    3013            0 :             state.dataSurface->SurfGndSolarInc(SurfNum) =
    3014            0 :                 GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
    3015              :         }
    3016              : 
    3017              :         // Calculate Exterior and Interior Absorbed Short Wave Radiation
    3018       170521 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3019       212058 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3020       112753 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3021       112753 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    3022       112753 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    3023       694797 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    3024       582044 :                     int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    3025       582044 :                     Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3026       582044 :                     currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3027       582044 :                     if (Surface(SurfNum).ExtSolar) {
    3028              :                         Real64 AbsExt =
    3029       348112 :                             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
    3030       348112 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3031       348112 :                             state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
    3032       348112 :                             AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
    3033              :                     }
    3034       582044 :                     if (ConstrNum > 0) {
    3035       582044 :                         int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
    3036       582044 :                         if (SurfSolIncPtr == 0) {
    3037       582044 :                             if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) {    // Opaque surface
    3038       582044 :                                 int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
    3039       582044 :                                 int InShelfSurf = 0;                                                // Inside daylighting shelf surface number
    3040       582044 :                                 if (ShelfNum > 0) {
    3041            0 :                                     InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
    3042              :                                 }
    3043       582044 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
    3044       582044 :                                     state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
    3045       582044 :                                 if (InShelfSurf > 0) { // Inside daylighting shelf
    3046              :                                     // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
    3047            0 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3048            0 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
    3049              :                                 } else { // Regular surface
    3050       582044 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3051       582044 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
    3052              :                                 }
    3053              :                             }
    3054              :                         } else {
    3055            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
    3056              :                         }
    3057              :                     }
    3058              :                 }
    3059       112753 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3060       112753 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3061       143857 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    3062        31104 :                     auto &surf = state.dataSurface->Surface(SurfNum);
    3063        31104 :                     auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3064        31104 :                     if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3065              :                         // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
    3066        31104 :                         int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3067        31104 :                         auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3068        31104 :                         Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
    3069        31104 :                         Real64 BeamSolar = currBeamSolar(SurfNum);                         // Local variable for BeamSolarRad
    3070        31104 :                         Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum);  // Sky diffuse solar incident on a surface
    3071        31104 :                         Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum);  // Ground diffuse solar incident on a surface
    3072              : 
    3073        31104 :                         DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3074              : 
    3075        60836 :                         if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
    3076        29732 :                             !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3077        29732 :                             int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3078        66665 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3079        36933 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3080              :                             }
    3081              : 
    3082        29732 :                             if (IS_SHADED(ShadeFlag)) { // Shaded window
    3083              : 
    3084            0 :                                 int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
    3085            0 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3086              : 
    3087            0 :                                 if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
    3088            0 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3089            0 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
    3090              :                                     }
    3091            0 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
    3092              : 
    3093            0 :                                 } else if (ANY_BLIND(ShadeFlag)) { // Blind on
    3094            0 :                                     auto &surfShade = state.dataSurface->surfShades(SurfNum);
    3095            0 :                                     int slatIdxLo = surfShade.blind.slatAngIdxLo;
    3096            0 :                                     int slatIdxHi = surfShade.blind.slatAngIdxHi;
    3097            0 :                                     Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3098              :                                     Real64 AbsDiffBlind;
    3099              : 
    3100              :                                     // For constructions, have to do interpolation whether we have movable slats or not
    3101            0 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3102            0 :                                         auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
    3103            0 :                                         auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
    3104              : 
    3105            0 :                                         AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
    3106            0 :                                         AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3107            0 :                                         AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3108              :                                     }
    3109              : 
    3110            0 :                                     auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
    3111            0 :                                     auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
    3112            0 :                                     AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
    3113              : 
    3114            0 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
    3115              : 
    3116            0 :                                     auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
    3117            0 :                                     if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
    3118            0 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
    3119              : 
    3120              :                                         // Need to do these interpolations unless we want to cache this in surfShade.blind.
    3121            0 :                                         Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3122            0 :                                         Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3123              : 
    3124            0 :                                         state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
    3125            0 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
    3126            0 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
    3127              :                                     }
    3128              :                                 }
    3129              : 
    3130              :                                 // Correct for shadowing of divider onto interior shading device (note that dividers are
    3131              :                                 // not allowed in windows with between-glass shade/blind)
    3132              : 
    3133            0 :                                 if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0)
    3134            0 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3135              : 
    3136            0 :                                 if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {        // Switchable glazing
    3137            0 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
    3138            0 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3139            0 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
    3140            0 :                                             Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
    3141              :                                     }
    3142              :                                 }
    3143              : 
    3144              :                             } // End of check if window has shading device on
    3145              : 
    3146        29732 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3147        66665 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3148        36933 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3149        36933 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
    3150        36933 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3151              :                                 // SurfWinA is from InteriorSolarDistribution
    3152        36933 :                                 if (ANY_BLIND(ShadeFlag)) {
    3153            0 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3154            0 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3155            0 :                                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3156            0 :                                     auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
    3157            0 :                                     if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
    3158              : 
    3159            0 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
    3160              : 
    3161            0 :                                         int slatIdxLo = surfShade.blind.slatAngIdxLo;
    3162            0 :                                         int slatIdxHi = surfShade.blind.slatAngIdxLo;
    3163            0 :                                         Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3164            0 :                                         auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
    3165            0 :                                         auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
    3166              : 
    3167            0 :                                         Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3168            0 :                                         Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3169              : 
    3170            0 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3171            0 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
    3172            0 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
    3173            0 :                                             state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3174              :                                     }
    3175              :                                 }
    3176              :                                 // Total solar absorbed in solid layer (W), for reporting
    3177        36933 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3178        36933 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3179              : 
    3180              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3181        36933 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3182              :                             }
    3183        29732 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3184        29732 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3185              :                             // Need to do it this way for now because of scheduled surface gains. They do work only with
    3186              :                             // BSDF windows and overwriting absorbtances will work only for ordinary windows
    3187              :                             // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
    3188              :                             //   SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
    3189              :                             //   inExtWindowModel->isExternalLibraryModel() ) {
    3190              :                             //   TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
    3191              :                             //   for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
    3192              :                             //     SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
    3193              :                             //       ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
    3194              :                             //   }
    3195         1372 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    3196            0 :                             int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
    3197              :                             // Number of solid layers in fenestration system (glass + shading)
    3198            0 :                             int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
    3199              :                             // Current state for Complex Fenestration
    3200              :                             // Examine for schedule surface gain
    3201            0 :                             Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
    3202              :                                 state,
    3203              :                                 SurfNum,
    3204            0 :                                 ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
    3205              : 
    3206            0 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3207            0 :                                 if (SurfSolAbs != 0) {
    3208            0 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) =
    3209            0 :                                         state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
    3210              :                                     // ABWin(Lay) = SurfWinA(SurfNum,Lay)
    3211            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
    3212              :                                 } else {
    3213              :                                     // Several notes about this equation.  First part is accounting for diffuse solar radiation for the ground
    3214              :                                     // and from the sky.  Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
    3215              :                                     // radiation originating from beam on exterior side.  Third item (SurfWinACFOverlap(SurfNum,Lay)) is
    3216              :                                     // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
    3217              :                                     // windows
    3218            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3219            0 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
    3220            0 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
    3221            0 :                                         state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3222            0 :                                         state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
    3223              :                                 }
    3224              :                                 // Total solar absorbed in solid layer (W), for reporting
    3225            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3226            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3227              : 
    3228              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3229            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3230              :                             }
    3231            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3232            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3233              : 
    3234         1372 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    3235         1372 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3236              :                             // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
    3237              :                             int TotSolidLay =
    3238         1372 :                                 state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
    3239         4970 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3240              :                                 // Absorbed window components include:
    3241              :                                 // (1) beam solar radiation absorbed by all layers in the fenestration
    3242              :                                 // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
    3243              :                                 // (3) diffuse short wave incident on the inside face of the fenestration.  The short wave internal sources
    3244              :                                 //     include light, ...
    3245         3598 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
    3246         3598 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3247         3598 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3248         3598 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
    3249              : 
    3250              :                                 // Total solar absorbed in solid layer (W), for reporting
    3251         3598 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3252         3598 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3253              : 
    3254              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3255         3598 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3256              :                             }
    3257              : 
    3258         1372 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3259         1372 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3260            0 :                         } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3261            0 :                             int SurfNum2 = SurfNum;
    3262            0 :                             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3263            0 :                                 SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    3264              :                             }
    3265              : 
    3266              :                             std::pair<Real64, Real64> incomingAngle =
    3267            0 :                                 Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
    3268            0 :                             Real64 Theta = incomingAngle.first;
    3269            0 :                             Real64 Phi = incomingAngle.second;
    3270              : 
    3271              :                             std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
    3272            0 :                                 Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
    3273            0 :                                     state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
    3274              : 
    3275            0 :                             size_t totLayers = aLayer->getNumOfLayers();
    3276            0 :                             for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
    3277            0 :                                 Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
    3278              :                                     Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
    3279              : 
    3280            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3281            0 :                                     AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3282              : 
    3283              :                                 // Total solar absorbed in solid layer (W), for reporting
    3284            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3285            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3286              : 
    3287              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3288            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3289              :                             }
    3290            0 :                         }
    3291              : 
    3292              :                         // Solar absorbed by window frame and dividers
    3293        31104 :                         int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
    3294        31104 :                         if (FrDivNum > 0) {
    3295            0 :                             Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum);                    // Frame, divider area (m2)
    3296            0 :                             Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
    3297            0 :                             Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
    3298            0 :                             Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
    3299            0 :                             Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
    3300            0 :                             Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
    3301            0 :                             Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
    3302            0 :                             Real64 CosIncAngHorProj = 0.0;  // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
    3303            0 :                             Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
    3304            0 :                             Real64 FracSunLit = 0.0;        // Fraction of window sunlit this time step
    3305              :                             Real64 BeamFaceInc;             // Beam solar incident window plane this time step (W/m2)
    3306              :                             Real64 DifSolarFaceInc;         // Diffuse solar incident on window plane this time step (W/m2)
    3307            0 :                             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3308            0 :                             Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3309            0 :                             if (FrArea > 0.0 || DivArea > 0.0) {
    3310            0 :                                 FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    3311            0 :                                 BeamFaceInc = currBeamSolarRad *
    3312            0 :                                               state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    3313              :                                               CosInc;
    3314            0 :                                 DifSolarFaceInc = SkySolarInc + GndSolarInc;
    3315              :                             }
    3316            0 :                             if (FracSunLit > 0.0) {
    3317            0 :                                 if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
    3318            0 :                                     (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
    3319              :                                     // Dot products used to calculate beam solar incident on faces of
    3320              :                                     // frame and divider perpendicular to the glass surface.
    3321              :                                     // Note that SOLCOS is the current timestep's solar direction cosines.
    3322              :                                     //                  PhiWin = ASIN(WALCOS(3,SurfNum))
    3323              :                                     Real64 PhiWin =
    3324            0 :                                         std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
    3325            0 :                                     Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
    3326            0 :                                     Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
    3327            0 :                                     Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
    3328            0 :                                     Real64 const cos_PhiWin(std::cos(PhiWin));
    3329            0 :                                     Real64 const cos_PhiSun(std::cos(PhiSun));
    3330              :                                     CosIncAngHorProj =
    3331            0 :                                         std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
    3332            0 :                                     CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
    3333              :                                 }
    3334              :                             }
    3335              :                             // Frame solar
    3336              :                             // (A window shade or blind, if present, is assumed to not shade the frame, so no special
    3337              :                             // treatment of frame solar needed if window has an exterior shade or blind.)
    3338            0 :                             if (FrArea > 0.0) {
    3339            0 :                                 Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
    3340            0 :                                 Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
    3341            0 :                                 Real64 TransDiffGl = 0.0;  // Diffuse solar transmittance
    3342            0 :                                 if (FrProjOut > 0.0 || FrProjIn > 0.0) {
    3343              :                                     Real64 BeamFrHorFaceInc =
    3344            0 :                                         currBeamSolarRad * CosIncAngHorProj *
    3345            0 :                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
    3346            0 :                                         FrArea;
    3347              :                                     Real64 BeamFrVertFaceInc =
    3348            0 :                                         currBeamSolarRad * CosIncAngVertProj *
    3349            0 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3350            0 :                                         FrArea;
    3351              :                                     // Beam solar on outside of frame
    3352            0 :                                     FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
    3353            0 :                                     if (FrProjIn > 0.0) {
    3354            0 :                                         Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3355            0 :                                         TransDiffGl = thisConstruct.TransDiff;
    3356            0 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3357            0 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3358            0 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3359            0 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3360            0 :                                             Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3361            0 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3362            0 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3363            0 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3364              :                                         }
    3365              :                                         // Beam solar on inside of frame
    3366            0 :                                         FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
    3367              :                                     }
    3368              :                                 }
    3369              :                                 // Beam plus diffuse solar on outside of frame
    3370            0 :                                 FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
    3371            0 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
    3372            0 :                                     FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3373              :                                 // Add diffuse from beam reflected from window outside reveal surfaces
    3374            0 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
    3375            0 :                                                                                       state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
    3376            0 :                                                                                       state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3377              : 
    3378              :                                 // Beam plus diffuse solar on inside of frame
    3379            0 :                                 FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
    3380            0 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3381              :                                 // Add diffuse from beam reflected from window inside reveal surfaces
    3382            0 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
    3383            0 :                                                                                      state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
    3384            0 :                                                                                      state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3385              :                             }
    3386              : 
    3387              :                             // Divider solar
    3388              :                             // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
    3389              :                             // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
    3390              :                             // DivProjIn will be zero in this case.)
    3391            0 :                             if (DivArea > 0.0) {                                                         // Solar absorbed by window divider
    3392            0 :                                 Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3393            0 :                                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    3394              :                                     // Suspended (between-glass) divider; account for effect glass on outside of divider
    3395              :                                     // (note that outside and inside projection for this type of divider are both zero)
    3396            0 :                                     int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
    3397            0 :                                     auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
    3398            0 :                                     assert(thisMaterial != nullptr);
    3399            0 :                                     Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
    3400            0 :                                     Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
    3401            0 :                                     Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3402            0 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3403            0 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3404            0 :                                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3405            0 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3406            0 :                                         Real64 MatNumGlSh = constructionSh.LayerPoint(1);
    3407            0 :                                         auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
    3408            0 :                                         assert(thisMaterialSh != nullptr);
    3409            0 :                                         Real64 TransGlSh = thisMaterialSh->Trans;
    3410            0 :                                         Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
    3411            0 :                                         Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
    3412            0 :                                         TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3413            0 :                                         ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
    3414            0 :                                         AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
    3415              :                                     }
    3416            0 :                                     Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
    3417            0 :                                     DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    3418              :                                 }
    3419              : 
    3420            0 :                                 Real64 BeamDivHorFaceInc = 0.0;  // Beam solar on divider's horizontal outside projection faces (W/m2)
    3421            0 :                                 Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
    3422              :                                 // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
    3423            0 :                                 if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3424            0 :                                     BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
    3425            0 :                                                         DivProjOut *
    3426            0 :                                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3427              :                                                         FracSunLit / DivArea;
    3428            0 :                                     BeamDivVertFaceInc =
    3429            0 :                                         currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
    3430            0 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3431              :                                         DivArea;
    3432              :                                 }
    3433            0 :                                 Real64 DivIncSolarOutBm =
    3434              :                                     0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
    3435            0 :                                 Real64 DivIncSolarOutDif =
    3436              :                                     0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
    3437            0 :                                 Real64 DivIncSolarInBm =
    3438              :                                     0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
    3439            0 :                                 Real64 DivIncSolarInDif =
    3440              :                                     0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
    3441            0 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
    3442            0 :                                     !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
    3443            0 :                                     DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
    3444            0 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3445            0 :                                     if (DivProjIn > 0.0) {
    3446            0 :                                         Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3447            0 :                                         Real64 TransDiffGl = thisConstruct.TransDiff;                       // Diffuse solar transmittance
    3448            0 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3449            0 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3450            0 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3451            0 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3452              : 
    3453            0 :                                             Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3454              :                                             // Outer glass solar trans, refl, absorptance if switched
    3455            0 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3456            0 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3457              :                                             // Diffuse solar transmittance, switched construction
    3458            0 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3459              :                                         }
    3460              :                                         // Beam plus diffuse solar on inside of divider
    3461              :                                         // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
    3462              :                                         // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
    3463              :                                         Real64 BeamDivHorFaceIncIn =
    3464            0 :                                             currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
    3465            0 :                                             (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3466            0 :                                             FracSunLit / DivArea;
    3467              :                                         Real64 BeamDivVertFaceIncIn =
    3468            0 :                                             currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
    3469            0 :                                             DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
    3470            0 :                                             FracSunLit / DivArea;
    3471            0 :                                         DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
    3472            0 :                                         DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
    3473              :                                     }
    3474              :                                 } else { // Exterior shade, screen or blind present
    3475              : 
    3476            0 :                                     DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3477            0 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3478            0 :                                     DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3479            0 :                                     DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3480              :                                 }
    3481              : 
    3482            0 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3483              :                                     // No exterior or between-glass shade, screen or blind
    3484            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
    3485            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
    3486              :                                     // Exterior shade, screen or blind
    3487              : 
    3488            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
    3489            0 :                                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3490              : 
    3491            0 :                                     int profIdxLo = surfShade.blind.profAngIdxLo;
    3492            0 :                                     int profIdxHi = surfShade.blind.profAngIdxHi;
    3493            0 :                                     Real64 profInterpFac = surfShade.blind.profAngInterpFac;
    3494              : 
    3495            0 :                                     auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
    3496            0 :                                     auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
    3497              : 
    3498            0 :                                     Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
    3499            0 :                                     Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
    3500              : 
    3501              :                                     // TBlBmBm - Blind beam-beam solar transmittance
    3502            0 :                                     Real64 TBlBmBm = surfShade.blind.bmBmTrans;
    3503            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3504            0 :                                         DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
    3505            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3506            0 :                                         DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
    3507              : 
    3508            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
    3509            0 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3510            0 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3511            0 :                                     auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
    3512            0 :                                     assert(matFen != nullptr);
    3513            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3514            0 :                                         DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
    3515            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3516            0 :                                         DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
    3517              : 
    3518            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
    3519            0 :                                     int screenNum = surfWin.screenNum;
    3520            0 :                                     auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
    3521            0 :                                     assert(screen != nullptr);
    3522              : 
    3523            0 :                                     auto &surf = state.dataSurface->Surface(SurfNum);
    3524              :                                     Real64 phi, theta;
    3525            0 :                                     Material::GetRelativePhiTheta(
    3526            0 :                                         surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
    3527              : #ifdef PRECALC_INTERP_SCREEN
    3528              :                                     int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
    3529              :                                     BilinearInterpCoeffs coeffs;
    3530            0 :                                     Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
    3531            0 :                                     GetBilinearInterpCoeffs(
    3532            0 :                                         phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
    3533            0 :                                     auto const &b11 = screen->btars[ip1][it1];
    3534            0 :                                     auto const &b12 = screen->btars[ip1][it2];
    3535            0 :                                     auto const &b21 = screen->btars[ip2][it1];
    3536            0 :                                     auto const &b22 = screen->btars[ip2][it2];
    3537            0 :                                     Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
    3538            0 :                                     Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
    3539              : 
    3540            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3541            0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3542            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3543            0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3544              : #else  // !PRECALC_INTERP_SCREEN
    3545              :                                     Material::ScreenBmTransAbsRef btar;
    3546              : 
    3547              :                                     Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
    3548              :                                     Real64 BmDfTrans = btar.DfTrans;
    3549              :                                     Real64 BmBmTrans = btar.BmTrans;
    3550              : 
    3551              :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3552              :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3553              :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3554              :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3555              : #endif // PRECALC_INTERP_SCREEN
    3556              :                                 }
    3557              :                             }
    3558              :                         }
    3559              :                     } // Surface(SurfNum)%ExtSolar
    3560              :                 }     // end of surface window loop
    3561              :             }         // end of space loop
    3562              :         }             // end of zone loop
    3563        71216 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    3564            0 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
    3565            0 :             int const ConstrNum = Surface(SurfNum).Construction;
    3566            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3567            0 :             int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3568            0 :             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3569            0 :             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3570            0 :                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3571            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3572            0 :                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
    3573            0 :                         (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
    3574            0 :                     state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
    3575            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3576            0 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3577            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3578            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3579            0 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3580              :             }
    3581              :         }
    3582              : 
    3583              :         // Average absorbed solar for representative surfaces
    3584        71216 :         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    3585            0 :             for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3586            0 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3587            0 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    3588            0 :                     int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    3589            0 :                     int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    3590            0 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3591            0 :                         auto &surface = state.dataSurface->Surface(surfNum);
    3592            0 :                         if (surface.ConstituentSurfaceNums.size() > 1) {
    3593            0 :                             Real64 QoutAtot = 0.0;
    3594            0 :                             Real64 QinAtot = 0.0;
    3595            0 :                             Real64 Atot = 0.0;
    3596            0 :                             for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3597            0 :                                 QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3598            0 :                                 QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3599            0 :                                 Atot += state.dataSurface->Surface(constSurfNum).Area;
    3600              :                             }
    3601              : 
    3602            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
    3603            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
    3604              :                         }
    3605              :                     }
    3606            0 :                     firstSurf = thisSpace.WindowSurfaceFirst;
    3607            0 :                     lastSurf = thisSpace.WindowSurfaceLast;
    3608            0 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3609            0 :                         auto const &surface = state.dataSurface->Surface(surfNum);
    3610            0 :                         if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
    3611              :                             // Absorbed in glazing
    3612              :                             int totalGlassLayers =
    3613            0 :                                 state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
    3614            0 :                             for (int layer = 1; layer <= totalGlassLayers; ++layer) {
    3615            0 :                                 Real64 QAtot = 0.0;
    3616            0 :                                 Real64 Atot = 0.0;
    3617            0 :                                 for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3618            0 :                                     QAtot +=
    3619            0 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
    3620            0 :                                     Atot += state.dataSurface->Surface(constSurfNum).Area;
    3621              :                                 }
    3622              : 
    3623            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
    3624              :                             }
    3625              : 
    3626              :                             // Absorbed by frame and dividers
    3627            0 :                             if (surface.FrameDivider > 0) {
    3628            0 :                                 if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    3629            0 :                                     Real64 QoutAtot = 0.0;
    3630            0 :                                     Real64 QinAtot = 0.0;
    3631            0 :                                     Real64 Atot = 0.0;
    3632            0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3633            0 :                                         QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
    3634            0 :                                                     state.dataSurface->SurfWinFrameArea(constSurfNum);
    3635            0 :                                         QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
    3636            0 :                                                    state.dataSurface->SurfWinFrameArea(constSurfNum);
    3637            0 :                                         Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
    3638              :                                     }
    3639              : 
    3640            0 :                                     state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
    3641            0 :                                     state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
    3642              :                                 }
    3643            0 :                                 if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    3644            0 :                                     Real64 QoutAtot = 0.0;
    3645            0 :                                     Real64 QinAtot = 0.0;
    3646            0 :                                     Real64 Atot = 0.0;
    3647            0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3648            0 :                                         QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
    3649            0 :                                                     state.dataSurface->SurfWinDividerArea(constSurfNum);
    3650            0 :                                         QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
    3651            0 :                                                    state.dataSurface->SurfWinDividerArea(constSurfNum);
    3652            0 :                                         Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
    3653              :                                     }
    3654              : 
    3655            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
    3656            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
    3657              :                                 }
    3658              :                             }
    3659              :                         }
    3660              :                     }
    3661              :                 }
    3662              :             }
    3663              :         }
    3664        71216 :     } // End of sun-up check
    3665       249960 : }
    3666              : 
    3667       249958 : void InitIntSolarDistribution(EnergyPlusData &state)
    3668              : {
    3669              : 
    3670              :     // SUBROUTINE INFORMATION:
    3671              :     //       AUTHOR         Anonymous
    3672              :     //       DATE WRITTEN   July 1977
    3673              :     //       MODIFIED       Oct 1999 (FW) to handle movable shades
    3674              :     //                      May 2000 (FW) to handle window frame and dividers
    3675              :     //                      May 2001 (FW) to handle window blinds
    3676              :     //                      Jan 2002 (FW) mods for between-glass shade/blind
    3677              :     //                      May 2006 (RR) to handle exterior window screens
    3678              :     //       RE-ENGINEERED  Mar98 (RKS)
    3679              : 
    3680              :     // PURPOSE OF THIS SUBROUTINE:
    3681              :     // This subroutine initializes the arrays associated with solar heat
    3682              :     // gains for both individual surfaces and for zones.
    3683              : 
    3684              :     // METHODOLOGY EMPLOYED:
    3685              :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    3686              :     // sun is up, various calculations are made.
    3687              : 
    3688              :     // REFERENCES:
    3689              :     // (I)BLAST legacy routine QSUN
    3690              : 
    3691              :     using Dayltg::DistributeTDDAbsorbedSolar;
    3692              :     using namespace DataWindowEquivalentLayer;
    3693              : 
    3694       249958 :     auto &s_mat = state.dataMaterial;
    3695              :     // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
    3696              :     // Note: If sun is not up, QS is only internal gains
    3697       605534 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3698       355576 :         Real64 sumSpaceQLTSW = 0.0;
    3699       728531 :         for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
    3700       372955 :             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3701              :         }
    3702       355576 :         state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
    3703       355576 :         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
    3704              :     }
    3705              : 
    3706       249958 :     if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
    3707              : 
    3708            2 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3709              : 
    3710            1 :             if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
    3711              : 
    3712            0 :                 for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
    3713              : 
    3714            0 :                     if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
    3715            0 :                         Real64 sumSpaceQLTSW = 0.0;
    3716            0 :                         for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
    3717            0 :                             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3718              :                         }
    3719            0 :                         state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
    3720            0 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3721            0 :                             (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
    3722            0 :                         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
    3723            0 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
    3724            0 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
    3725            0 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3726            0 :                             state.dataHeatBal->EnclSolQD(OtherenclosureNum);
    3727            0 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
    3728            0 :                             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
    3729              :                     }
    3730              :                 }
    3731              :             }
    3732              :         }
    3733              :     }
    3734              : 
    3735              :     // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
    3736              : 
    3737       249958 :     if (state.dataEnvrn->SunIsUp) {
    3738      1136548 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    3739      1015102 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    3740              :             //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    3741      1015102 :             if (surface.Class == DataSurfaces::SurfaceClass::Shading) continue;
    3742      1015102 :             int const enclosureNum = surface.SolarEnclIndex;
    3743      1015102 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
    3744      1015102 :                 state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
    3745      1015102 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
    3746      1015102 :                 state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
    3747      1015102 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
    3748      1015102 :                 state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3749              :         }
    3750              :     }
    3751              : 
    3752              :     // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
    3753       605534 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3754       355576 :         auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
    3755       355576 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    3756            1 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
    3757            1 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3758              :             // CR 8695, VMULT not based on visible
    3759            1 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
    3760            1 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3761              :         } else {
    3762       355575 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
    3763       355575 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
    3764              :         }
    3765              :     }
    3766              : 
    3767              :     // COMPUTE RADIANT GAINS ON SURFACES
    3768       586610 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3769       709607 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3770       372955 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3771       372955 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
    3772       372955 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
    3773      2358719 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
    3774      1985764 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3775      1985764 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3776      1985764 :                 int const ConstrNum = surface.Construction;
    3777      1985764 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3778              : 
    3779      1985764 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
    3780              :                 // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
    3781      1985764 :                 Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
    3782              : 
    3783      1985764 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
    3784      1985764 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
    3785              : 
    3786              :                 // Calculate absorbed solar on outside if movable exterior insulation in place
    3787      1985764 :                 if (state.dataSurface->AnyMovableInsulation) {
    3788            0 :                     auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
    3789            0 :                     if (movInsul.present) {
    3790            0 :                         Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
    3791            0 :                         auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
    3792            0 :                         state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
    3793            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
    3794              :                         // For transparent insulation, allow some sunlight to get through the movable insulation.
    3795              :                         // The equation below is derived by taking what is transmitted through the layer and applying
    3796              :                         // the fraction that is absorbed plus the back reflected portion (first order reflection only)
    3797              :                         // to the plane between the transparent insulation and the exterior surface face.
    3798            0 :                         auto const *matMovInsul = s_mat->materials(movInsul.matNum);
    3799            0 :                         auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
    3800            0 :                         Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
    3801              : 
    3802            0 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3803            0 :                             transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
    3804            0 :                             ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
    3805              :                     }
    3806              :                 }
    3807              :                 // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
    3808              :                 // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
    3809      1985764 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
    3810              :             } // end of opaque
    3811              : 
    3812       372955 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3813       372955 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3814       461519 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
    3815        88564 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3816        88564 :                 auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3817        88564 :                 int const radEnclosureNum = surface.RadEnclIndex;
    3818        88564 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3819        88564 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3820        88564 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3821              : 
    3822        88564 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
    3823        86195 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    3824              : 
    3825        86195 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    3826        86195 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3827              : 
    3828              :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    3829        86195 :                     Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
    3830        86195 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    3831        86189 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3832        86189 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3833        86189 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3834              :                     } else {
    3835              :                         // radiant value prior to adjustment for pulse for load component report
    3836            6 :                         Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    3837              :                         // for the loads component report during the special sizing run increase the radiant portion
    3838              :                         // a small amount to create a "pulse" of heat that is used for the
    3839              :                         // radiant value including adjustment for pulse for load component report
    3840            6 :                         Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    3841              :                         // ITABSF is the Inside Thermal Absorptance
    3842              :                         // EnclRadThermAbsMult is a multiplier for each zone/enclosure
    3843              :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    3844            6 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3845            6 :                             adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    3846            6 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3847              :                     }
    3848              : 
    3849        86195 :                     if (NOT_SHADED(ShadeFlag)) { // No window shading
    3850       196685 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3851       110490 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3852       110490 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    3853              :                         }
    3854            0 :                     } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    3855              :                         // Interior, exterior or between-glass shade, screen or blind in place
    3856            0 :                         auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    3857            0 :                         for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
    3858            0 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3859            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3860            0 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
    3861            0 :                             } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
    3862            0 :                                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3863            0 :                                 Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3864            0 :                                 auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
    3865            0 :                                 auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
    3866              :                                 // Glass layer back diffuse solar absorptance when blind in place
    3867            0 :                                 Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
    3868              : 
    3869            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3870            0 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
    3871              :                             }
    3872              :                         }
    3873            0 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    3874            0 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3875            0 :                                                                                  constrSh.ShadeAbsorpThermal *
    3876            0 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3877            0 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    3878            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3879            0 :                             Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
    3880            0 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3881            0 :                                                                                  EffBlEmiss *
    3882            0 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3883              :                         }
    3884              : 
    3885            0 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3886            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
    3887            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
    3888            0 :                         } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    3889            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3890            0 :                             auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
    3891            0 :                             auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
    3892            0 :                             Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3893            0 :                             Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
    3894              : 
    3895            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
    3896              :                         }
    3897              :                         // Correct for divider shadowing
    3898            0 :                         if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3899            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3900              :                         }
    3901              : 
    3902            0 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {       // Switchable glazing
    3903            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
    3904            0 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3905              : 
    3906            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3907            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    3908            0 :                                 Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    3909            0 :                                                  thisConstruct.AbsDiffBack(IGlass),
    3910            0 :                                                  constructionSh.AbsDiffBack(IGlass));
    3911              :                         }
    3912              : 
    3913              :                     } // End of shading flag check
    3914              : 
    3915              :                     // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
    3916        86195 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
    3917            3 :                         state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
    3918            3 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
    3919            3 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3920            3 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    3921            3 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    3922            3 :                                  state.dataSurface->SurfWinFrameEmis(SurfNum)) *
    3923            3 :                             (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));          // Window has a frame
    3924        86195 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {                     // Window has dividers
    3925            3 :                         Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum);    // Window divider thermal absorptance
    3926            3 :                         Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3927            3 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) ==
    3928              :                             DataSurfaces::FrameDividerType::Suspended) {                         // Suspended divider; account for inside glass
    3929            0 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
    3930            0 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
    3931            0 :                             assert(thisMaterial != nullptr);
    3932            0 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
    3933            0 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    3934            0 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3935            0 :                             Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
    3936            0 :                             DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
    3937            0 :                             DividerThermAbs = thisMaterial->AbsorpThermalBack;
    3938              :                         }
    3939              :                         // Correct for interior shade transmittance
    3940            3 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    3941            0 :                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3942            0 :                             int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
    3943            0 :                             auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
    3944            0 :                             assert(matSh != nullptr);
    3945            0 :                             DividerSolAbs *= matSh->Trans;
    3946            0 :                             DividerThermAbs *= matSh->TransThermal;
    3947              : 
    3948            3 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    3949            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3950            0 :                             Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
    3951            0 :                             Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
    3952              : 
    3953            0 :                             DividerSolAbs *= SolBackDiffDiffTrans;
    3954            0 :                             DividerThermAbs *= IRBackTrans;
    3955              :                         }
    3956              :                         // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
    3957            3 :                         state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
    3958            3 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
    3959            3 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3960            3 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    3961            3 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    3962            3 :                                  DividerThermAbs) *
    3963            3 :                             (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
    3964              :                     }
    3965              :                 } else {
    3966              :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    3967         2369 :                     Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
    3968         2369 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    3969         2369 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3970         2369 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3971         2369 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3972              :                     } else {
    3973              :                         // radiant value prior to adjustment for pulse for load component report
    3974            0 :                         Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    3975              :                         // for the loads component report during the special sizing run increase the radiant portion
    3976              :                         // a small amount to create a "pulse" of heat that is used for the
    3977              :                         // radiant value including adjustment for pulse for load component report
    3978            0 :                         Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    3979              :                         // ITABSF is the Inside Thermal Absorptance
    3980              :                         // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
    3981              :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    3982            0 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3983            0 :                             adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    3984            0 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3985              :                     }
    3986              :                     // Radiations absorbed by the window layers coming from zone side
    3987         2369 :                     int EQLNum = thisConstruct.EQLConsPtr;
    3988         8580 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    3989         6211 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
    3990         6211 :                             state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
    3991              :                     }
    3992              :                     // Window frame has not been included for equivalent layer model yet
    3993              : 
    3994              :                 } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
    3995              : 
    3996        88564 :                 if (surface.ExtBoundCond > 0) { // Interzone surface
    3997              :                     // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
    3998            0 :                     int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
    3999            0 :                     if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
    4000            0 :                         int TotGlassLayers = thisConstruct.TotGlassLayers;
    4001            0 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4002            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
    4003            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    4004            0 :                                 state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
    4005              :                             // Note that AbsDiff rather than AbsDiffBack is used in the above since the
    4006              :                             // radiation from the current zone is incident on the outside of the adjacent
    4007              :                             // zone's window.
    4008              :                         }
    4009              :                     } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
    4010            0 :                         int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
    4011            0 :                         int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
    4012            0 :                         for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4013            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
    4014            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
    4015              :                             // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
    4016              :                             // since the radiation from the current zone is incident on the outside of the
    4017              :                             // adjacent zone's window.
    4018              :                         }
    4019              :                     }
    4020              :                 }
    4021              : 
    4022        88564 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
    4023        86195 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4024        86195 :                     int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    4025        86195 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4026        86195 :                     if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
    4027       196685 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4028       110490 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4029              :                         }
    4030            0 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    4031            0 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4032            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4033              :                         }
    4034              :                     } else {
    4035            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4036              :                         // Interior, exterior or between-glass shade, screen or blind in place
    4037            0 :                         for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
    4038            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4039              :                         }
    4040            0 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4041            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
    4042              :                         }
    4043              :                     } // End of shading flag check
    4044         2369 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    4045            0 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    4046            0 :                     for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4047            0 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4048              :                     }
    4049         2369 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    4050              : 
    4051              :                     // ConstrNum   = Surface(SurfNum)%Construction
    4052         2369 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4053              : 
    4054         8580 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4055         6211 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
    4056              :                     }
    4057              :                 }
    4058              : 
    4059              :             } // End of window
    4060              :         }
    4061              :     }
    4062       249958 :     Dayltg::DistributeTDDAbsorbedSolar(state);
    4063       249958 : }
    4064              : 
    4065       249957 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
    4066              : {
    4067              : 
    4068              :     // SUBROUTINE INFORMATION:
    4069              :     //       AUTHOR         Legacy Code (George Walton)
    4070              :     //       DATE WRITTEN   Legacy: Dec 1976
    4071              :     //       MODIFIED       Nov. 99, FCW: to take into account movable interior shades and switchable glazing
    4072              :     //                      June 01, FCW: to take into account interior blinds.
    4073              : 
    4074              :     // PURPOSE OF THIS SUBROUTINE:
    4075              :     // This routine computes the fractions of long-wave radiation from lights, equipment and people
    4076              :     // that is absorbed by each zone surface.
    4077              : 
    4078              :     // METHODOLOGY EMPLOYED:
    4079              :     // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
    4080              : 
    4081              :     // REFERENCES:
    4082              :     // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
    4083       249957 :     auto &s_mat = state.dataMaterial;
    4084              : 
    4085       605532 :     for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    4086       355575 :         if (!thisEnclosure.radReCalc) continue;
    4087        20440 :         for (int spaceNum : thisEnclosure.spaceNums) {
    4088        10245 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4089        10245 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    4090        10245 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    4091        14181 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    4092         3936 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4093         3936 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4094            1 :                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4095            1 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
    4096              :                 } else {
    4097         3935 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4098         3935 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
    4099              :                 }
    4100              :             }
    4101              :         }
    4102              :     }
    4103       249957 :     if (state.dataSurface->AnyMovableSlat) {
    4104            0 :         for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
    4105              :             // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
    4106            0 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4107              :             // Not sure we need to do this anymore
    4108            0 :             if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4109            0 :                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4110            0 :                 state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
    4111              :             }
    4112              :         }
    4113              :     }
    4114              : 
    4115       605532 :     for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
    4116       355575 :         if (!thisRadEnclosure.radReCalc) continue;
    4117        10195 :         Real64 SUM1 = 0.0;
    4118        69427 :         for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
    4119        59232 :             auto &surf = state.dataSurface->Surface(SurfNum);
    4120        59232 :             int const ConstrNum = surf.Construction;
    4121        59232 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4122        59232 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4123        59232 :             if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    4124        59232 :                 SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4125              :             } else { // Switchable glazing
    4126            0 :                 SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    4127            0 :                                                      thisConstruct.InsideAbsorpThermal,
    4128            0 :                                                      state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
    4129              :             }
    4130              : 
    4131              :             // Window frame and divider effects
    4132        59232 :             if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
    4133            1 :                 SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
    4134            1 :                         state.dataSurface->SurfWinFrameEmis(SurfNum);
    4135        59232 :             if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4136            1 :                 Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
    4137              :                 // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
    4138            1 :                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended)
    4139            0 :                     DividerThermAbs = thisConstruct.InsideAbsorpThermal;
    4140            1 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4141              :                     // Interior shade or blind in place
    4142            0 :                     int const ConstrNumSh = surf.activeShadedConstruction;
    4143            0 :                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4144              : 
    4145            0 :                     if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
    4146            0 :                         auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4147              :                         // Shade layer material number
    4148            0 :                         int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
    4149            0 :                         auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
    4150            0 :                         assert(matSh != nullptr);
    4151              :                         // Shade or blind IR transmittance
    4152            0 :                         Real64 TauShIR = matSh->TransThermal;
    4153              :                         // Effective emissivity of shade or blind
    4154            0 :                         Real64 EffShDevEmiss = surfShade.effShadeEmi;
    4155              : 
    4156            0 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    4157            0 :                             TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
    4158              :                         }
    4159            0 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
    4160              :                     } else {
    4161              :                         // this is for EMS activated shade/blind but the window construction has no shade/blind layer
    4162            0 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4163              :                                 DividerThermAbs;
    4164              :                     }
    4165              :                 } else {
    4166            1 :                     SUM1 +=
    4167            1 :                         state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
    4168              :                 }
    4169              :             }
    4170              : 
    4171              :         } // End of loop over surfaces in zone/enclosure
    4172        10195 :         thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
    4173              : 
    4174              :     } // End of loop over enclosures
    4175       249957 : }
    4176              : 
    4177       249956 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
    4178              : {
    4179              : 
    4180              :     // SUBROUTINE INFORMATION:
    4181              :     //       AUTHOR         Legacy (George Walton)
    4182              :     //       DATE WRITTEN   Legacy (December 1980)
    4183              :     //       MODIFIED       Nov. 99, FW; now called every time step to account for movable
    4184              :     //                      window shades and insulation
    4185              :     //                      Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
    4186              :     //                      to ComputeIntSWAbsorpFactors
    4187              :     //                      May 00, FW; add window frame and divider effects
    4188              :     //                      June 01, FW: account for window blinds
    4189              :     //                      Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
    4190              :     //                      Jan 03, FW: add between-glass shade/blind
    4191              :     //                      May 06, RR: account for exterior window screens
    4192              : 
    4193              :     // PURPOSE OF THIS SUBROUTINE:
    4194              :     // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
    4195              :     // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
    4196              :     // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
    4197              : 
    4198              :     // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
    4199              :     // radiation absorbed by interior window shades).
    4200              : 
    4201              :     // REFERENCES:
    4202              :     // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
    4203              :     //                         From Zone Lights And Diffuse Solar.
    4204              : 
    4205              :     // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
    4206       249956 :     Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
    4207              : 
    4208       249956 :     auto &s_mat = state.dataMaterial;
    4209              : 
    4210       605530 :     for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
    4211       355574 :         if (!thisSolEnclosure.radReCalc) continue;
    4212        10194 :         Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
    4213              : 
    4214        69425 :         for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
    4215        59231 :             auto &thisSurf = state.dataSurface->Surface(SurfNum);
    4216        59231 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4217        59231 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4218        59231 :             if (thisConstruct.TransDiff <= 0.0) {
    4219              :                 // Opaque surface
    4220        55358 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
    4221        55358 :                 SUM1 += thisSurf.Area * AbsIntSurf;
    4222              : 
    4223              :             } else {
    4224              :                 // Window
    4225         3873 :                 if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
    4226         1566 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4227              : 
    4228         1566 :                     Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
    4229         1566 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4230         1566 :                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    4231              : 
    4232              :                     // Sum of absorptances of glass layers
    4233         3201 :                     for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
    4234         1635 :                         Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
    4235              : 
    4236              :                         // Window with shade, screen or blind
    4237         1635 :                         if (ConstrNumSh != 0) {
    4238           64 :                             auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4239           64 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    4240            0 :                                 AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
    4241           64 :                             } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4242            0 :                                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4243            0 :                                 auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
    4244            0 :                                 auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
    4245            0 :                                 Real64 interpFac = surfShade.blind.slatAngInterpFac;
    4246            0 :                                 AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
    4247              :                             }
    4248              :                         }
    4249              : 
    4250              :                         // Switchable glazing
    4251         1635 :                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4252            0 :                             assert(ConstrNumSh > 0); // Should this be included in the if above
    4253            0 :                             auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4254            0 :                             AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
    4255              :                         }
    4256         1635 :                         AbsDiffTotWin += AbsDiffLayWin;
    4257              :                     }
    4258              : 
    4259         1566 :                     Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
    4260         1566 :                     Real64 DiffAbsShade = 0.0;                     // Diffuse short-wave shade or blind absorptance
    4261              : 
    4262              :                     // Window with shade, screen or blind
    4263              : 
    4264         1566 :                     if (ConstrNumSh != 0) {
    4265           64 :                         auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4266           64 :                         if (ANY_SHADE_SCREEN(ShadeFlag)) {
    4267            0 :                             TransDiffWin = constrSh.TransDiff;
    4268            0 :                             DiffAbsShade = constrSh.AbsDiffBackShade;
    4269           64 :                         } else if (ANY_BLIND(ShadeFlag)) {
    4270            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4271            0 :                             auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
    4272            0 :                             auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
    4273            0 :                             Real64 interpFac = surfShade.blind.slatAngInterpFac;
    4274            0 :                             TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
    4275            0 :                             DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
    4276              :                         }
    4277              :                     }
    4278              : 
    4279              :                     // Switchable glazing
    4280              : 
    4281         1566 :                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4282            0 :                         assert(ConstrNumSh > 0);
    4283            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4284            0 :                         TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
    4285              :                     }
    4286              : 
    4287         1566 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
    4288              : 
    4289              :                     // Window frame and divider effects (shade area is glazed area plus divider area)
    4290              : 
    4291         1566 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
    4292            1 :                         SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
    4293            1 :                                 (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
    4294         1566 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4295            1 :                         Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    4296            1 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    4297              :                             // Suspended (between-glass) divider: account for glass on inside of divider
    4298            0 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
    4299            0 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
    4300            0 :                             assert(thisMaterial != nullptr);
    4301            0 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
    4302            0 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    4303            0 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    4304            0 :                             Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
    4305            0 :                             DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    4306              :                         }
    4307            1 :                         if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4308            0 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
    4309              :                         } else {
    4310            1 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4311              :                                     DividerAbs;
    4312              :                         }
    4313              :                     }
    4314              :                 } else { // equivalent layer window
    4315              :                     // In equivalent layer window solid layers (Glazing and shades) are treated equally
    4316              :                     // frames and dividers are not supported
    4317         2307 :                     Real64 AbsDiffTotWin = 0.0;
    4318         2307 :                     Real64 AbsDiffLayWin = 0.0;
    4319         2307 :                     Real64 TransDiffWin = thisConstruct.TransDiff;
    4320         8358 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
    4321         6051 :                         AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
    4322         6051 :                         AbsDiffTotWin += AbsDiffLayWin;
    4323              :                     }
    4324         2307 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
    4325              :                 }
    4326              :             } // End of check if opaque surface or window
    4327              :         }     // End of loop over surfaces in zone
    4328              : 
    4329        10194 :         if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
    4330        10194 :             thisSolEnclosure.solVMULT = 1.0 / SUM1;
    4331              : 
    4332              :         } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
    4333              :             // or they really want to disallow any solar from being absorbed on the inside surfaces.  Fire off a
    4334              :             // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
    4335              :             // back out whatever window is there.  Note that this also assumes that the shade has no effect.
    4336              :             // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
    4337              :             // in the zone?
    4338            0 :             if (thisSolEnclosure.solAbsFirstCalc) {
    4339            0 :                 ShowWarningError(
    4340              :                     state,
    4341            0 :                     format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
    4342            0 :                            thisSolEnclosure.Name));
    4343            0 :                 thisSolEnclosure.solAbsFirstCalc = false;
    4344              :             }
    4345            0 :             thisSolEnclosure.solVMULT = 0.0;
    4346              :         }
    4347              :     } // End of enclosure loop
    4348       249956 : }
    4349              : 
    4350            4 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
    4351              : {
    4352              : 
    4353              :     // SUBROUTINE INFORMATION:
    4354              :     //       MODIFIED       Jun 2007 - Lawrie - Speed enhancements.
    4355              :     //       RE-ENGINEERED  Winkelmann, Lawrie
    4356              : 
    4357              :     // PURPOSE OF THIS SUBROUTINE:
    4358              :     // This subroutine computes the diffuse solar exchange factors between enclosures with
    4359              :     // interzone windows.
    4360              : 
    4361            4 :     int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
    4362            4 :     if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
    4363            2 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
    4364            2 :         state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
    4365            2 :         state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
    4366              :     }
    4367              : 
    4368            4 :     state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
    4369            4 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
    4370            4 :     state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
    4371              : 
    4372              :     //      IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN  ! this caused massive diffs
    4373            4 :     if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) return;
    4374              :     //            Compute fraction transmitted in one pass.
    4375              : 
    4376            6 :     for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
    4377            4 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4378            4 :         if (surface.ExtBoundCond <= 0) continue;
    4379            4 :         if (surface.ExtBoundCond == SurfNum) continue;
    4380            4 :         if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) continue;
    4381              : 
    4382            4 :         int surfEnclNum = surface.SolarEnclIndex;
    4383            4 :         if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) continue;
    4384            2 :         int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
    4385            4 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
    4386            2 :                                                                          state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
    4387            2 :         if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
    4388              :     }
    4389              :     //          Compute fractions for multiple passes.
    4390              : 
    4391            2 :     Array2D<Real64>::size_type l(0u), m(0u), d(0u);
    4392            8 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
    4393            6 :         m = NZ - 1;
    4394            6 :         Real64 D_d(0.0); // Local accumulator
    4395           24 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
    4396           18 :             if (MZ == NZ) continue;
    4397           12 :             state.dataHeatBalSurfMgr->DiffuseArray[l] =
    4398           12 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
    4399           24 :                 (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
    4400           12 :                            state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
    4401           12 :             D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
    4402              :         }
    4403            6 :         state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
    4404              :     }
    4405              : 
    4406            2 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
    4407              :     // added for CR 7999 & 7869
    4408            2 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
    4409            2 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
    4410            8 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
    4411           19 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4412           15 :             if (MZ == NZ) continue;
    4413           10 :             if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
    4414            2 :                 state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
    4415            2 :                 break;
    4416              :             }
    4417              :         }
    4418              :     }
    4419              : 
    4420              :     //           Compute fractions for multiple zones.
    4421              : 
    4422            8 :     for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
    4423            6 :         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) continue;
    4424              : 
    4425            8 :         for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
    4426            6 :             if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) continue;
    4427            4 :             if (IZ == JZ) continue;
    4428            2 :             if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) continue;
    4429              : 
    4430            8 :             for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
    4431            6 :                 if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) continue;
    4432            4 :                 if (IZ == KZ) continue;
    4433            2 :                 if (JZ == KZ) continue;
    4434            0 :                 if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) continue;
    4435            0 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
    4436            0 :                     state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4437              : 
    4438            0 :                 for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
    4439            0 :                     if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) continue;
    4440            0 :                     if (IZ == LZ) continue;
    4441            0 :                     if (JZ == LZ) continue;
    4442            0 :                     if (KZ == LZ) continue;
    4443            0 :                     if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) continue;
    4444            0 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4445            0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
    4446            0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4447              : 
    4448            0 :                     for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4449            0 :                         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) continue;
    4450            0 :                         if (IZ == MZ) continue;
    4451            0 :                         if (JZ == MZ) continue;
    4452            0 :                         if (KZ == MZ) continue;
    4453            0 :                         if (LZ == MZ) continue;
    4454            0 :                         if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) continue;
    4455            0 :                         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
    4456            0 :                             state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4457            0 :                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4458              :                     } // MZ Loop
    4459              : 
    4460              :                 } // LZ Loop
    4461              : 
    4462              :             } // KZ Loop
    4463              : 
    4464              :         } // JZ Loop
    4465              : 
    4466              :     } // IZ Loop
    4467              : } // ComputeDifSolExcZoneWIZWindows()
    4468              : 
    4469       116073 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
    4470              : {
    4471              : 
    4472              :     // SUBROUTINE INFORMATION:
    4473              :     //       AUTHOR         B. Griffith
    4474              :     //       DATE WRITTEN   April 2011
    4475              : 
    4476              :     // PURPOSE OF THIS SUBROUTINE:
    4477              :     // initialize material and construction surface properties if being overridden by EMS
    4478              : 
    4479              :     // METHODOLOGY EMPLOYED:
    4480              :     // update solar, thermal and visible absorptance values when actuated by EMS
    4481              : 
    4482              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4483              :     int TotLayers;       // count of material layers in a construction
    4484              :     int InsideMaterNum;  // integer pointer for inside face's material layer
    4485              :     int OutsideMaterNum; // integer pointer for outside face's material layer
    4486              : 
    4487       116073 :     auto &s_mat = state.dataMaterial;
    4488              : 
    4489       116073 :     state.dataGlobal->AnySurfPropOverridesInModel = false;
    4490              :     // first determine if anything needs to be done, once yes, then always init
    4491       736781 :     for (auto const *mat : s_mat->materials) {
    4492       620708 :         if (mat->group != Material::Group::Regular) continue;
    4493              : 
    4494       613277 :         if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
    4495            0 :             state.dataGlobal->AnySurfPropOverridesInModel = true;
    4496            0 :             break;
    4497              :         }
    4498              :     }
    4499              : 
    4500       116073 :     if (!state.dataGlobal->AnySurfPropOverridesInModel) return; // quick return if nothing has ever needed to be done
    4501              : 
    4502              :     // first, loop over materials
    4503              :     // why is this a second loop?
    4504            0 :     for (auto *mat : s_mat->materials) {
    4505            0 :         if (mat->group != Material::Group::Regular) continue;
    4506              : 
    4507            0 :         mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
    4508            0 :         mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
    4509            0 :         mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
    4510              :     } // loop over materials
    4511              : 
    4512              :     // second, loop over constructions
    4513            0 :     for (auto &thisConstruct : state.dataConstruction->Construct) {
    4514            0 :         if (thisConstruct.TypeIsWindow) continue; // only override opaque constructions
    4515            0 :         TotLayers = thisConstruct.TotLayers;
    4516            0 :         if (TotLayers == 0) continue; // error condition
    4517            0 :         InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
    4518            0 :         if (InsideMaterNum != 0) {
    4519            0 :             auto const *mat = s_mat->materials(InsideMaterNum);
    4520            0 :             thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
    4521            0 :             thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
    4522            0 :             thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
    4523              :         }
    4524              : 
    4525            0 :         OutsideMaterNum = thisConstruct.LayerPoint(1);
    4526            0 :         if (OutsideMaterNum != 0) {
    4527            0 :             auto const *mat = s_mat->materials(OutsideMaterNum);
    4528            0 :             thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
    4529            0 :             thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
    4530            0 :             thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
    4531              :         }
    4532              :     } // for (ConstrNum)
    4533              : } // InitEMSControlledSurfaceProperties()
    4534              : 
    4535       116073 : void InitEMSControlledConstructions(EnergyPlusData &state)
    4536              : {
    4537              : 
    4538              :     // SUBROUTINE INFORMATION:
    4539              :     //       AUTHOR         B. Griffith
    4540              :     //       DATE WRITTEN   Jan 2012
    4541              : 
    4542              :     // PURPOSE OF THIS SUBROUTINE:
    4543              :     // change construction on surface if overridden by EMS
    4544              : 
    4545       116073 :     state.dataGlobal->AnyConstrOverridesInModel = false;
    4546       854204 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4547       745241 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
    4548         7110 :             state.dataGlobal->AnyConstrOverridesInModel = true;
    4549         7110 :             break;
    4550              :         }
    4551              :     }
    4552       116073 :     if (!state.dataGlobal->AnyConstrOverridesInModel) return;
    4553              : 
    4554        45714 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4555        38604 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4556              : 
    4557        38604 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
    4558              : 
    4559         7110 :             if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4560         7110 :                     .TypeIsWindow) { // okay, always allow windows
    4561         1352 :                 state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4562         1352 :                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4563              :             }
    4564              : 
    4565        14216 :             if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
    4566         7106 :                 (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
    4567              : 
    4568         7106 :                 surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4569         7106 :                 state.dataConstruction->Construct(surface.Construction).IsUsed = true;
    4570         7106 :                 state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4571              : 
    4572              :             } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
    4573            4 :                 if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
    4574              :                     // check if constructions appear compatible
    4575              : 
    4576            4 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    4577            0 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    4578              :                         // compare old construction to new construction and see if terms match
    4579              :                         // set as okay and turn false if find a big problem
    4580            4 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4581              :                             true;
    4582            4 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4583              :                             true;
    4584            4 :                         if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
    4585            4 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
    4586              :                             // throw warning, but allow
    4587            0 :                             ShowWarningError(state,
    4588              :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4589              :                                              "CTF timescales are being used.");
    4590            0 :                             ShowContinueError(state,
    4591            0 :                                               format("Construction named = {} has CTF timesteps = {}",
    4592            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4593            0 :                                                      state.dataConstruction->Construct(surface.Construction).NumHistories));
    4594            0 :                             ShowContinueError(
    4595              :                                 state,
    4596            0 :                                 format("While construction named = {} has CTF timesteps = {}",
    4597            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4598            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
    4599            0 :                             ShowContinueError(
    4600              :                                 state,
    4601            0 :                                 format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
    4602            0 :                                        surface.Name));
    4603              :                         }
    4604            4 :                         if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
    4605            4 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
    4606              :                             // throw warning, but allow
    4607            4 :                             ShowWarningError(state,
    4608              :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4609              :                                              "CTF terms are being used.");
    4610            4 :                             ShowContinueError(state,
    4611            4 :                                               format("Construction named = {} has number of CTF terms = {}",
    4612            2 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4613            2 :                                                      state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
    4614            4 :                             ShowContinueError(
    4615              :                                 state,
    4616            4 :                                 format("While construction named = {} has number of CTF terms = {}",
    4617            2 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4618            2 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
    4619            4 :                             ShowContinueError(state,
    4620            4 :                                               format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
    4621              :                                                      "name = {}, and the simulation continues",
    4622            2 :                                                      surface.Name));
    4623              :                         }
    4624              : 
    4625            4 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4626            0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4627              :                                 // throw warning, and do not allow
    4628            0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4629            0 :                                 ShowContinueError(state,
    4630            0 :                                                   format("Construction named = {} has internal source/sink",
    4631            0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4632            0 :                                 ShowContinueError(
    4633              :                                     state,
    4634            0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4635            0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4636            0 :                                 ShowContinueError(
    4637              :                                     state,
    4638            0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4639            0 :                                            surface.Name));
    4640              : 
    4641            0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4642            0 :                                                                                   SurfNum) = false;
    4643              :                             }
    4644              :                         }
    4645              : 
    4646            8 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4647              :                                                                               SurfNum)) {
    4648            4 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4649              :                         }
    4650              : 
    4651            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    4652            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4653              :                             true;
    4654            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4655              :                             true;
    4656            0 :                         if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
    4657            0 :                             state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
    4658              :                             // throw warning, and do not allow
    4659            0 :                             ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4660            0 :                             ShowContinueError(state,
    4661            0 :                                               format("Construction named = {} has number of finite difference nodes ={}",
    4662            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4663            0 :                                                      state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
    4664            0 :                             ShowContinueError(
    4665              :                                 state,
    4666            0 :                                 format("While construction named = {}has number of finite difference nodes ={}",
    4667            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4668            0 :                                        state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4669            0 :                                            .TotNodes));
    4670            0 :                             ShowContinueError(
    4671              :                                 state,
    4672            0 :                                 format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4673            0 :                                        surface.Name));
    4674              : 
    4675            0 :                             state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4676              :                                 false;
    4677              :                         }
    4678              : 
    4679            0 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4680            0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4681              :                                 // throw warning, and do not allow
    4682            0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4683            0 :                                 ShowContinueError(state,
    4684            0 :                                                   format("Construction named = {} has internal source/sink",
    4685            0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4686            0 :                                 ShowContinueError(
    4687              :                                     state,
    4688            0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4689            0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4690            0 :                                 ShowContinueError(
    4691              :                                     state,
    4692            0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4693            0 :                                            surface.Name));
    4694              : 
    4695            0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4696            0 :                                                                                   SurfNum) = false;
    4697              :                             }
    4698              :                         }
    4699              : 
    4700            0 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4701              :                                                                               SurfNum)) {
    4702            0 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4703              :                         }
    4704              : 
    4705            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
    4706            0 :                         ShowSevereError(state,
    4707              :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
    4708              :                                         "algorithm CombinedHeatAndMoistureFiniteElement.");
    4709            0 :                         ShowContinueError(
    4710              :                             state,
    4711            0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4712            0 :                                    surface.Name));
    4713            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4714              :                             true;
    4715            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4716              :                             false;
    4717              : 
    4718            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
    4719            0 :                         ShowSevereError(state,
    4720              :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
    4721              :                                         "Foundation Outside Boundary Condition.");
    4722            0 :                         ShowContinueError(
    4723              :                             state,
    4724            0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4725            0 :                                    surface.Name));
    4726            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4727              :                             true;
    4728            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4729              :                             false;
    4730              :                     }
    4731              : 
    4732              :                 } else {
    4733              :                     // do nothing, has been checked and is not okay with single warning already issued.
    4734              :                 }
    4735              :             }
    4736              :         } else {
    4737        31494 :             surface.Construction = surface.ConstructionStoredInputValue;
    4738        31494 :             state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
    4739              :         }
    4740              :     } // for (SurfNum)
    4741              : } // InitEMSControlledConstructions()
    4742              : 
    4743              : // End Initialization Section of the Module
    4744              : //******************************************************************************
    4745              : 
    4746              : // Begin Algorithm Section of the Module
    4747              : //******************************************************************************
    4748              : 
    4749              : // Beginning of Record Keeping subroutines for the HB Module
    4750              : // *****************************************************************************
    4751              : 
    4752       249967 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4753              : {
    4754       249967 :     int firstZone = 1;
    4755       249967 :     int lastZone = state.dataGlobal->NumOfZones;
    4756              : 
    4757       249967 :     if (present(ZoneToResimulate)) {
    4758            8 :         firstZone = ZoneToResimulate;
    4759            8 :         lastZone = ZoneToResimulate;
    4760              :     }
    4761              : 
    4762       586629 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4763       709651 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4764       372989 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4765       372989 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    4766       372989 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    4767       461551 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4768        88562 :                 if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
    4769        88560 :                     state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
    4770              :                 }
    4771              :             }
    4772              :             // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
    4773       372989 :             if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
    4774       341668 :                 state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4775       341668 :                 state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
    4776       341668 :                     state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4777              :             } else {
    4778        31321 :                 state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4779        31321 :                 state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
    4780        31321 :                     state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4781              :             }
    4782              :         }
    4783              :     }
    4784              : 
    4785       249967 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    4786            0 :         UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
    4787              :     }
    4788              : 
    4789              :     // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
    4790       586629 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4791       709651 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4792       372989 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4793       372989 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    4794       372989 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    4795      2447326 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4796      2074337 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
    4797      2074337 :                     -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4798      2074337 :                     (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4799              :             }
    4800              :         }
    4801              :     }
    4802              :     // Opaque surfaces
    4803       586629 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4804       709651 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4805       372989 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4806       372989 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    4807       372989 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    4808      2358768 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4809      1985779 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
    4810      1985779 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
    4811              :             }
    4812              :         }
    4813              :     }
    4814              :     // Inside face conduction calculation for Kiva surfaces
    4815       249968 :     for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
    4816            1 :         state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
    4817            1 :             -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    4818            1 :               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    4819            1 :               state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
    4820              :     }
    4821       249967 : }
    4822              : 
    4823            0 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4824              : {
    4825            0 :     int firstZone = 1;
    4826            0 :     int lastZone = state.dataGlobal->NumOfZones;
    4827              : 
    4828            0 :     if (present(ZoneToResimulate)) {
    4829            0 :         firstZone = ZoneToResimulate;
    4830            0 :         lastZone = ZoneToResimulate;
    4831              :     }
    4832              : 
    4833            0 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4834            0 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4835            0 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4836              :             // Heat transfer surfaces
    4837            0 :             int firstSurf = thisSpace.HTSurfaceFirst;
    4838            0 :             int lastSurf = thisSpace.HTSurfaceLast;
    4839            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4840            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    4841            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    4842              : 
    4843            0 :                 if (surfNum != repSurfNum) {
    4844              : #if 0
    4845              :                 // Check for divergence
    4846              :                 Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4847              :                                   (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4848              :                 Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
    4849              :                                      (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
    4850              :                 Real64 diff = surfConv - repSurfConv;
    4851              :                 if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
    4852              :                     ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
    4853              :                     ShowContinueErrorTimeStamp(state, "");
    4854              :                     ShowContinueError(state, format("  Original Surface: {}", surface.Name));
    4855              :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
    4856              :                     ShowContinueError(state,
    4857              :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    4858              :                     ShowContinueError(state,
    4859              :                                       format("    Sunlit fraction: {:.3R}",
    4860              :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
    4861              :                     ShowContinueError(state, format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
    4862              :                     ShowContinueError(state,
    4863              :                                       format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
    4864              :                     ShowContinueError(state, format("  Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
    4865              :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
    4866              :                     ShowContinueError(state,
    4867              :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
    4868              :                     ShowContinueError(state,
    4869              :                                       format("    Sunlit fraction: {:.3R}",
    4870              :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
    4871              :                     ShowContinueError(state,
    4872              :                                       format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
    4873              :                     ShowContinueError(
    4874              :                         state, format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
    4875              :                 }
    4876              : #endif
    4877              : 
    4878              :                     // Surface Heat Balance Arrays
    4879            0 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
    4880            0 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
    4881            0 :                     state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
    4882            0 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
    4883            0 :                     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
    4884            0 :                     state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
    4885            0 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
    4886              : 
    4887            0 :                     state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
    4888            0 :                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
    4889            0 :                     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
    4890            0 :                     state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
    4891            0 :                     state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
    4892            0 :                     state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
    4893              : 
    4894            0 :                     state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
    4895            0 :                     if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
    4896            0 :                         state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
    4897              :                     }
    4898              : 
    4899            0 :                     state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
    4900            0 :                     state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
    4901              : 
    4902            0 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    4903            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
    4904            0 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
    4905            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
    4906              : 
    4907              :                     // Internal (non reporting variables)
    4908            0 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
    4909            0 :                     state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
    4910              :                 }
    4911              :             }
    4912              : 
    4913              :             // Opaque surfaces
    4914            0 :             firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    4915            0 :             lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    4916            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4917            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    4918            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    4919              : 
    4920            0 :                 if (surfNum != repSurfNum) {
    4921              :                     // Surface Heat Balance Arrays
    4922            0 :                     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
    4923            0 :                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
    4924            0 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
    4925              :                 }
    4926              :             }
    4927              : 
    4928              :             // Window surfaces
    4929            0 :             firstSurf = thisSpace.WindowSurfaceFirst;
    4930            0 :             lastSurf = thisSpace.WindowSurfaceLast;
    4931            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4932            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    4933            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    4934              : 
    4935            0 :                 if (surfNum != repSurfNum) {
    4936            0 :                     Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    4937              : 
    4938              :                     // Glazing
    4939            0 :                     state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    4940            0 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    4941            0 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    4942              : 
    4943              :                     // Frame
    4944            0 :                     Real64 frameHeatGain = 0.0;
    4945            0 :                     if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    4946            0 :                         Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
    4947            0 :                         state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
    4948            0 :                         state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
    4949            0 :                         state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
    4950            0 :                         state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
    4951            0 :                         frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
    4952              :                     }
    4953              : 
    4954              :                     // Divider
    4955            0 :                     Real64 dividerHeatGain = 0.0;
    4956            0 :                     if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    4957            0 :                         Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
    4958            0 :                         state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
    4959            0 :                         state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
    4960            0 :                         state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
    4961            0 :                         state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
    4962            0 :                         dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
    4963              :                     }
    4964              : 
    4965            0 :                     state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
    4966              : 
    4967              :                     // Whole window
    4968            0 :                     state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
    4969            0 :                                                                    state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
    4970            0 :                                                                   state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
    4971              :                 }
    4972              :             }
    4973              :         }
    4974              :     }
    4975            0 : }
    4976              : 
    4977       249945 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
    4978              : {
    4979              : 
    4980              :     // SUBROUTINE INFORMATION:
    4981              :     //       AUTHOR         Rick Strand
    4982              :     //       DATE WRITTEN   December 2000
    4983              : 
    4984              :     // PURPOSE OF THIS SUBROUTINE:
    4985              :     // If a radiant system is present and was on for part of the time step,
    4986              :     // then we probably need to make yet another pass through the heat balance.
    4987              :     // This is necessary because the heat source/sink to the surface that is
    4988              :     // the radiant system may have varied during the system time steps.
    4989              : 
    4990              :     // METHODOLOGY EMPLOYED:
    4991              :     // First, determine whether or not the radiant system was running.  If
    4992              :     // any of the Qsource terms are non-zero, then it was running.  Then,
    4993              :     // update the current source terms with the "average" value calculated
    4994              :     // by the radiant system algorithm.  This requires the "USE" of the
    4995              :     // radiant algorithm module.  Finally, using this source value, redo
    4996              :     // the inside and outside heat balances.
    4997              : 
    4998              :     bool LowTempRadSysOn;     // .TRUE. if a low temperature radiant system is running
    4999              :     bool HighTempRadSysOn;    // .TRUE. if a high temperature radiant system is running
    5000              :     bool HWBaseboardSysOn;    // .TRUE. if a water baseboard heater is running
    5001              :     bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
    5002              :     bool ElecBaseboardSysOn;  // .TRUE. if a steam baseboard heater is running
    5003              :     bool CoolingPanelSysOn;   // true if a simple cooling panel is running
    5004              :     bool SwimmingPoolOn;      // true if a pool is present (running)
    5005              : 
    5006       249945 :     LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
    5007       249945 :     HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
    5008       249945 :     HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
    5009       249945 :     SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
    5010       249945 :     ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
    5011       249945 :     CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
    5012       249945 :     SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
    5013              : 
    5014       249945 :     if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
    5015              :         // Solve the zone heat balance 'Detailed' solution
    5016              :         // Call the outside and inside surface heat balances
    5017            4 :         CalcHeatBalanceOutsideSurf(state);
    5018            4 :         CalcHeatBalanceInsideSurf(state);
    5019              :     }
    5020       249945 : }
    5021              : 
    5022       200977 : void UpdateThermalHistories(EnergyPlusData &state)
    5023              : {
    5024              : 
    5025              :     // SUBROUTINE INFORMATION:
    5026              :     //       AUTHOR         Russ Taylor
    5027              :     //       DATE WRITTEN   June 1990
    5028              :     //       RE-ENGINEERED  Mar98 (RKS)
    5029              : 
    5030              :     // PURPOSE OF THIS SUBROUTINE:
    5031              :     // This subroutine updates and shifts the thermal and flux histories.
    5032              : 
    5033              :     // METHODOLOGY EMPLOYED:
    5034              :     // If a surface runs on the user selected subhourly time step, then the
    5035              :     // history terms for the temperatures and fluxes must simply be updated
    5036              :     // and shifted.  However, if the surface runs at a different (longer) time
    5037              :     // step, then the "master" history series is used for the interpolated
    5038              :     // update scheme.
    5039              : 
    5040              :     // REFERENCES:
    5041              :     // (I)BLAST legacy routine UTHRMH
    5042              :     // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
    5043              :     // Mechanical Systems in Heat Balance Based Energy Analysis Programs
    5044              :     // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
    5045              : 
    5046       200977 :     if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
    5047          103 :         state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5048          103 :         state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5049          103 :         state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5050          103 :         state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5051          103 :         state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
    5052          103 :         if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5053            1 :             state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5054            1 :             state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5055            1 :             state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5056              :         }
    5057          103 :         state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
    5058              :     }
    5059              : 
    5060       488650 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5061       611649 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5062       323976 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5063       323976 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5064       323976 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5065      2015835 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5066              :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5067      1691859 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5068              : 
    5069      1691859 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5070            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5071            0 :                     continue;
    5072              : 
    5073      1691859 :                 int const ConstrNum = surface.Construction;
    5074      1691859 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5075              : 
    5076      1691859 :                 if (construct.NumCTFTerms == 0) continue; // Skip surfaces with no history terms
    5077              : 
    5078              :                 // Sign convention for the various terms in the following two equations
    5079              :                 // is based on the form of the Conduction Transfer Function equation
    5080              :                 // given by:
    5081              :                 // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
    5082              :                 // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
    5083              :                 // In both equations, flux is positive from outside to inside.  The V and W terms are for radiant systems only.
    5084              : 
    5085              :                 // Set current inside flux:
    5086      1691859 :                 Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5087      1691859 :                 Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
    5088      1691859 :                                                 state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
    5089      1691859 :                                                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
    5090              :                 // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
    5091              :                 // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
    5092              :                 // redundant.
    5093      1691859 :                 if (construct.SourceSinkPresent) {
    5094            2 :                     SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
    5095              :                 }
    5096      1691859 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
    5097      1691859 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
    5098      1691859 :                 state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
    5099              : 
    5100              :                 // Update the temperature at the source/sink location (if one is present)
    5101      1691859 :                 if (construct.SourceSinkPresent) {
    5102            2 :                     state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
    5103            2 :                         SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
    5104            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
    5105            2 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    5106            2 :                     state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
    5107            2 :                         SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
    5108            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
    5109            2 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
    5110              :                 }
    5111              : 
    5112              :                 // Set current outside flux:
    5113      1691859 :                 if (construct.SourceSinkPresent) {
    5114            2 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
    5115            2 :                         SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5116            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
    5117            2 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
    5118              :                 } else {
    5119      3383714 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
    5120      1691857 :                                                                              state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5121      1691857 :                                                                              state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
    5122              :                 }
    5123              :                 // switch sign for balance at outside face
    5124      1691859 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5125      1691859 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
    5126              :             }
    5127              :         }
    5128              :     } // ...end of loop over all (heat transfer) surfaces...
    5129              : 
    5130       200977 :     if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
    5131              :         // Temporarily save the rvalue references of the last term arrays
    5132       193863 :         Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5133       193863 :         Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5134       193863 :         Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5135       193863 :         Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5136              :         // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
    5137      1325627 :         for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
    5138      1131764 :             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
    5139      1131764 :             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
    5140      1131764 :             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
    5141      1131764 :             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
    5142              :         }
    5143              :         // Reuse the pointers of the last term arrays for the second term arrays
    5144       193863 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
    5145       193863 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
    5146       193863 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
    5147       193863 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
    5148              :         // 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)
    5149       193863 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
    5150       193863 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
    5151       193863 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
    5152       193863 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
    5153       193863 :         return;
    5154       193863 :     }
    5155              : 
    5156        14230 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5157        14232 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5158         7116 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5159         7116 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5160         7116 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5161        44374 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5162        37258 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5163              :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5164        37258 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5165            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5166            0 :                     continue;
    5167        37258 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5168        37258 :                     state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5169        37258 :                     state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    5170        37258 :                     state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5171        37258 :                     state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
    5172              :                 }
    5173              :             }
    5174              :         }
    5175              : 
    5176              :     } // ...end of loop over all (heat transfer) surfaces...
    5177         7114 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5178            4 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5179            4 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5180            2 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5181            2 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5182            2 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5183            4 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5184            2 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5185              :                     // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5186            2 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5187            0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5188            0 :                         continue;
    5189            2 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5190            2 :                         state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
    5191            2 :                         state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
    5192            2 :                         state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
    5193              :                     }
    5194              :                 }
    5195              :             }
    5196              :         } // ...end of loop over all (heat transfer) surfaces...
    5197              :     }
    5198              : 
    5199              :     // SHIFT TEMPERATURE AND FLUX HISTORIES:
    5200              :     // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
    5201        14230 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5202        14232 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5203         7116 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5204         7116 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5205         7116 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5206        44374 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5207        37258 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5208              : 
    5209        37258 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5210            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5211            0 :                     continue;
    5212              : 
    5213        37258 :                 int const ConstrNum = surface.Construction;
    5214        37258 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5215              : 
    5216        37258 :                 ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
    5217        37258 :                 state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
    5218              : 
    5219        37258 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
    5220        37258 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    5221              : 
    5222        37258 :                     if (construct.NumCTFTerms > 1) {
    5223         7126 :                         int const numCTFTerms(construct.NumCTFTerms);
    5224        35612 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5225        28486 :                             state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
    5226        28486 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5227        28486 :                             state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
    5228        28486 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5229        28486 :                             state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
    5230        28486 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5231        28486 :                             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
    5232        28486 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5233        28486 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
    5234        28486 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5235        28486 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
    5236        28486 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5237        28486 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
    5238        28486 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5239        28486 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
    5240        28486 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5241              :                         }
    5242              :                     }
    5243              : 
    5244        37258 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
    5245        37258 :                     state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
    5246        37258 :                     state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
    5247        37258 :                     state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
    5248              : 
    5249        37258 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
    5250        37258 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
    5251        37258 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
    5252        37258 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
    5253              :                 } else {
    5254            0 :                     Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5255            0 :                     if (construct.NumCTFTerms > 1) {
    5256            0 :                         int const numCTFTerms(construct.NumCTFTerms);
    5257            0 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5258              :                             // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
    5259              :                             //                                 (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
    5260            0 :                             Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
    5261            0 :                             Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
    5262            0 :                             Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5263            0 :                             Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5264            0 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
    5265            0 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
    5266              : 
    5267            0 :                             Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
    5268            0 :                             Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
    5269            0 :                             Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5270            0 :                             Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5271            0 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
    5272            0 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
    5273              :                         }
    5274              :                     }
    5275              :                     // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
    5276            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
    5277            0 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
    5278            0 :                         (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
    5279            0 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
    5280            0 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
    5281            0 :                         (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
    5282            0 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
    5283            0 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
    5284            0 :                         (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
    5285            0 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
    5286            0 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
    5287            0 :                         (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
    5288              :                 }
    5289              :             }
    5290              :         }
    5291              :     } // ...end of loop over all (heat transfer) surfaces
    5292              : 
    5293         7114 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5294            4 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5295            4 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5296            2 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5297            2 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5298            2 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5299            4 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5300            2 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5301            2 :                     int const ConstrNum = surface.Construction;
    5302            2 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5303            2 :                     if (!construct.SourceSinkPresent) continue;
    5304            2 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5305            0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5306            0 :                         continue;
    5307              : 
    5308            2 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5309            2 :                         if (construct.NumCTFTerms > 1) {
    5310            2 :                             int const numCTFTerms = construct.NumCTFTerms;
    5311            2 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5312            2 :                             int m1 = m + 1;
    5313            4 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
    5314              :                                 // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
    5315              :                                 // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
    5316              :                                 // 1 );
    5317            2 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
    5318            2 :                                     state.dataHeatBalSurf->SurfTsrcHistM[m];
    5319            2 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
    5320            2 :                                     state.dataHeatBalSurf->SurfQsrcHistM[m];
    5321            2 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
    5322            2 :                                     state.dataHeatBalSurf->SurfTuserHistM[m];
    5323              :                             }
    5324              :                         }
    5325            2 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
    5326            2 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
    5327            2 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
    5328            2 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
    5329            2 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
    5330            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
    5331              :                     } else {
    5332            0 :                         Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5333              : 
    5334            0 :                         if (construct.NumCTFTerms > 1) {
    5335            0 :                             int const numCTFTerms = construct.NumCTFTerms;
    5336            0 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5337            0 :                             int m1 = m + 1;
    5338            0 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
    5339              :                                 // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
    5340              :                                 // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
    5341              :                                 // HistTermNum
    5342              :                                 // - 1 ) ) * sum_steps;  Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) );  SurfQsrcHist( SurfNum,
    5343              :                                 // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
    5344            0 :                                 Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
    5345            0 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] =
    5346            0 :                                     TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
    5347            0 :                                 Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
    5348            0 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] =
    5349            0 :                                     QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
    5350            0 :                                 Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
    5351            0 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] =
    5352            0 :                                     TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
    5353              :                             }
    5354              :                         }
    5355              :                         // Tuned Linear indexing
    5356              :                         // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
    5357              :                         // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
    5358            0 :                         int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
    5359            0 :                         state.dataHeatBalSurf->SurfTsrcHist[l2] =
    5360            0 :                             state.dataHeatBalSurf->SurfTsrcHistM[l2] -
    5361            0 :                             (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
    5362            0 :                         state.dataHeatBalSurf->SurfQsrcHist[l2] =
    5363            0 :                             state.dataHeatBalSurf->SurfQsrcHistM[l2] -
    5364            0 :                             (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
    5365            0 :                         state.dataHeatBalSurf->SurfTuserHist[l2] =
    5366            0 :                             state.dataHeatBalSurf->SurfTuserHistM[l2] -
    5367            0 :                             (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
    5368              :                     }
    5369              :                 }
    5370              :             }
    5371              :         } // ...end of loop over all (heat transfer) surfaces...
    5372              :     }     // ...end of AnyInternalHeatSourceInInput
    5373              : }
    5374              : 
    5375       249966 : void CalculateZoneMRT(EnergyPlusData &state,
    5376              :                       ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    5377              : {
    5378              : 
    5379              :     // SUBROUTINE INFORMATION:
    5380              :     //       AUTHOR         Rick Strand
    5381              :     //       DATE WRITTEN   November 2000
    5382              : 
    5383              :     // PURPOSE OF THIS SUBROUTINE:
    5384              :     // Calculates the current zone and enclosure MRT for thermal comfort and radiation
    5385              :     // calculation purposes.
    5386              : 
    5387       249966 :     if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5388          109 :         state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
    5389          109 :         state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
    5390          109 :         state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
    5391          109 :         state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
    5392          250 :         for (auto &encl : state.dataViewFactor->EnclRadInfo) {
    5393          141 :             encl.sumAE = 0.0;
    5394              :         }
    5395          904 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5396          795 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    5397          795 :             if (surface.HeatTransSurf) {
    5398          779 :                 auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
    5399          779 :                 thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
    5400          779 :                 int ZoneNum = surface.Zone;
    5401          779 :                 if (ZoneNum > 0) state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
    5402          779 :                 if (surface.RadEnclIndex > 0) state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
    5403              :             }
    5404              :         }
    5405              :     }
    5406              : 
    5407              :     // Zero sumAET for applicable enclosures
    5408       249966 :     if (present(ZoneToResimulate)) {
    5409           32 :         for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
    5410           24 :             int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
    5411           24 :             state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
    5412           24 :             state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
    5413              :         }
    5414              :     } else {
    5415       605542 :         for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5416       355584 :             thisEnclosure.reCalcMRT = true;
    5417              :         }
    5418              :     }
    5419       586633 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5420       336667 :         if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) continue;
    5421       336667 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    5422       336667 :         if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
    5423       336664 :             Real64 zoneSumAET = 0.0;
    5424       709655 :             for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
    5425       372991 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5426      2447340 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    5427      2074349 :                     Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
    5428      2074349 :                     zoneSumAET += surfAET;
    5429      2074349 :                     state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
    5430              :                 }
    5431              :             }
    5432       336664 :             thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
    5433              :         } else {
    5434            3 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5435            6 :                 ShowWarningError(
    5436              :                     state,
    5437            6 :                     format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
    5438            9 :                 ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
    5439              :             }
    5440            3 :             thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    5441              :         }
    5442              :     }
    5443              :     // Calculate MRT for applicable enclosures
    5444       605566 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5445       355600 :         if (!thisEnclosure.reCalcMRT) continue;
    5446       355600 :         if (thisEnclosure.sumAE > 0.01) {
    5447       355598 :             thisEnclosure.sumAET = 0.0;
    5448      2429919 :             for (int surfNum : thisEnclosure.SurfacePtr) {
    5449      2074321 :                 Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
    5450      2074321 :                 thisEnclosure.sumAET += surfAET;
    5451              :             }
    5452       355598 :             thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
    5453              :         } else {
    5454            2 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5455            4 :                 ShowWarningError(state,
    5456            4 :                                  format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
    5457            6 :                 ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
    5458              :             }
    5459            2 :             Real64 sumMATVol = 0.0;
    5460            2 :             Real64 sumVol = 0.0;
    5461            2 :             Real64 sumMAT = 0.0;
    5462            5 :             for (auto &spaceNum : thisEnclosure.spaceNums) {
    5463            3 :                 Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
    5464            3 :                 Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
    5465            3 :                 sumVol += spaceVolume;
    5466            3 :                 sumMATVol += spaceMAT * spaceVolume;
    5467            3 :                 sumMAT += spaceMAT;
    5468              :             }
    5469            2 :             if (sumVol > 0.01) {
    5470            2 :                 thisEnclosure.MRT = sumMATVol / sumVol;
    5471              :             } else {
    5472            0 :                 thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
    5473              :             }
    5474              :         }
    5475              :         // Set space MRTs
    5476       728594 :         for (int spaceNum : thisEnclosure.spaceNums) {
    5477       372994 :             state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
    5478              :         }
    5479              :     }
    5480              : 
    5481       249966 :     state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
    5482       249966 : }
    5483              : 
    5484              : // End of Record Keeping subroutines for the HB Module
    5485              : // *****************************************************************************
    5486              : 
    5487              : // Beginning of Reporting subroutines for the HB Module
    5488              : // *****************************************************************************
    5489              : 
    5490       249953 : void CalcThermalResilience(EnergyPlusData &state)
    5491              : {
    5492              :     // This function calculate timestep-wise heat index and humidex.
    5493              : 
    5494              :     // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
    5495              :     // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
    5496              :     // Technical Attachment (SR 90-23).
    5497              :     // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
    5498              : 
    5499              :     // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
    5500              :     // Canada's Atmospheric Environment Service in 1979.
    5501              :     // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
    5502              :     // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
    5503              :     //        using OutputProcessor::ReqRepVars;
    5504       249953 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
    5505          242 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5506          262 :             SetupOutputVariable(state,
    5507              :                                 "Zone Heat Index",
    5508              :                                 Constant::Units::C,
    5509          131 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
    5510              :                                 OutputProcessor::TimeStepType::Zone,
    5511              :                                 OutputProcessor::StoreType::Average,
    5512          131 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5513          262 :             SetupOutputVariable(state,
    5514              :                                 "Zone Humidity Index",
    5515              :                                 Constant::Units::None,
    5516          131 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
    5517              :                                 OutputProcessor::TimeStepType::Zone,
    5518              :                                 OutputProcessor::StoreType::Average,
    5519          131 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5520              :         }
    5521          580 :         for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
    5522          469 :             if (reqVar->name == "Zone Heat Index") {
    5523            0 :                 state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
    5524          469 :             } else if (reqVar->name == "Zone Humidity Index") {
    5525            0 :                 state.dataHeatBalSurfMgr->reportVarHumidex = true;
    5526              :             }
    5527              :         }
    5528              :     }
    5529              : 
    5530              :     // Calculate Heat Index and Humidex.
    5531              :     // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
    5532              :     // then heat index is calculated and converted back to C.
    5533       249953 :     if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5534       145262 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5535        75319 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5536        75319 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5537        75319 :             Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
    5538        75319 :             Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
    5539        75319 :             if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
    5540        75319 :                 Real64 constexpr c1 = -42.379;
    5541        75319 :                 Real64 constexpr c2 = 2.04901523;
    5542        75319 :                 Real64 constexpr c3 = 10.14333127;
    5543        75319 :                 Real64 constexpr c4 = -.22475541;
    5544        75319 :                 Real64 constexpr c5 = -.00683783;
    5545        75319 :                 Real64 constexpr c6 = -.05481717;
    5546        75319 :                 Real64 constexpr c7 = .00122874;
    5547        75319 :                 Real64 constexpr c8 = .00085282;
    5548        75319 :                 Real64 constexpr c9 = -.00000199;
    5549              :                 Real64 HI;
    5550              : 
    5551        75319 :                 if (ZoneTF < 80) {
    5552        40740 :                     HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
    5553              :                 } else {
    5554        34579 :                     HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
    5555        34579 :                          c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
    5556        34579 :                     if (ZoneRH < 13 && ZoneTF < 112) {
    5557          450 :                         HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
    5558        34129 :                     } else if (ZoneRH > 85 && ZoneTF < 87) {
    5559           86 :                         HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
    5560              :                     }
    5561              :                 }
    5562        75319 :                 HI = (HI - 32.0) * (5.0 / 9.0);
    5563        75319 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
    5564              :             } else {
    5565              :                 // calculate extended heat index
    5566            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
    5567            0 :                     ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
    5568              :             }
    5569              :         }
    5570              :     }
    5571       249953 :     if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5572       145262 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5573        75319 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5574        75319 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5575        75319 :             Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
    5576        75319 :             Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
    5577        75319 :             Real64 const h = 5.0 / 9.0 * (e - 10.0);
    5578        75319 :             Real64 const Humidex = ZoneT + h;
    5579        75319 :             state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
    5580              :         }
    5581              :     }
    5582       249953 : }
    5583              : 
    5584        69975 : void ReportThermalResilience(EnergyPlusData &state)
    5585              : {
    5586              : 
    5587        69975 :     Array1D_bool reportPeriodFlags;
    5588        69975 :     if (state.dataWeather->TotReportPers > 0) {
    5589           20 :         reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
    5590           20 :         General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
    5591              :     }
    5592              : 
    5593        69975 :     auto &ort = state.dataOutRptTab;
    5594        70015 :     for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5595           40 :         if (reportPeriodFlags(i)) {
    5596           18 :             int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    5597           18 :             state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    5598              :         }
    5599              :     }
    5600              : 
    5601        69975 :     if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
    5602           40 :         int constexpr HINoBins = 5;                     // Heat Index range - number of bins
    5603           40 :         int constexpr HumidexNoBins = 5;                // Humidex range - number of bins
    5604           40 :         int constexpr SETNoBins = 5;                    // SET report column numbers
    5605           40 :         int constexpr ColdHourOfSafetyNoBins = 5;       // Cold Stress Hour of Safety number of columns
    5606           40 :         int constexpr HeatHourOfSafetyNoBins = 5;       // Heat Stress Hour of Safety number of columns
    5607           40 :         int constexpr UnmetDegreeHourNoBins = 6;        // Unmet Degree Hour number of columns
    5608           40 :         int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
    5609              : 
    5610           40 :         if (state.dataHeatBal->TotPeople == 0) state.dataHeatBalSurfMgr->hasPierceSET = false;
    5611           54 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5612           14 :             if (!state.dataHeatBal->People(iPeople).Pierce) {
    5613           12 :                 state.dataHeatBalSurfMgr->hasPierceSET = false;
    5614              :             }
    5615              :         }
    5616           86 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5617              :             // the whole period
    5618              :             // user specified reporting period
    5619           48 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5620            2 :                 state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5621            2 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5622            2 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5623            2 :                 state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5624            2 :                 state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5625            2 :                 state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5626            2 :                 if (state.dataHeatBalSurfMgr->hasPierceSET) {
    5627            2 :                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5628            2 :                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5629              :                 }
    5630            2 :                 state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
    5631            2 :                 state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
    5632            2 :                 state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
    5633            2 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5634            2 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5635              :             }
    5636           46 :             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
    5637           46 :             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
    5638           46 :             state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
    5639           46 :             state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
    5640              :         }
    5641           40 :         state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5642           40 :         state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5643           40 :         state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5644           40 :         state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5645           40 :         state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
    5646              :     }
    5647              : 
    5648              :     // Count hours only during weather simulation periods
    5649        69975 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    5650              :         // use default value if there are no user inputs
    5651           40 :         Real64 ColdTempThresh = 15.56;
    5652           40 :         Real64 HeatTempThresh = 30.0;
    5653              :         // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
    5654              :         // Record last time step SET to trace SET unmet duration;
    5655              : 
    5656           40 :         Real64 valueNotInit = -999.0;
    5657           40 :         Real64 nearThreshold = 1.0;
    5658           80 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5659           40 :             state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
    5660           40 :             state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
    5661              :         }
    5662           80 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5663           40 :             int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
    5664           40 :             state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
    5665           40 :                 state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
    5666           40 :             state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5667           40 :             if (state.dataHeatBal->People(iPeople).Pierce) {
    5668           40 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
    5669              :             } else {
    5670            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
    5671              :             }
    5672              : 
    5673           40 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    5674           40 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5675           40 :             ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5676           40 :             bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
    5677           40 :             if (Temperature > ColdTempThresh) { // safe
    5678           36 :                 if (!CrossedColdThresh) {
    5679              :                     // compute the number of hours before threshold is reached
    5680           36 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5681              :                 }
    5682              :             } else { // danger
    5683              :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5684            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5685            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5686            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5687              :                 // first time crossing threshold
    5688            4 :                 if (!CrossedColdThresh) {
    5689              :                     // compute the time when the zone crosses the threshold temperature
    5690              :                     int encodedMonDayHrMin;
    5691            2 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5692            2 :                                                state.dataEnvrn->Month,
    5693            2 :                                                state.dataEnvrn->DayOfMonth,
    5694            2 :                                                state.dataGlobal->HourOfDay,
    5695            2 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5696              :                     // fixme: not sure how to aggregate by zone
    5697            2 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
    5698            2 :                     CrossedColdThresh = true;
    5699              :                 }
    5700              :             }
    5701           40 :             HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5702           40 :             bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
    5703           40 :             if (Temperature < HeatTempThresh) { // safe
    5704           16 :                 if (!CrossedHeatThresh) {
    5705              :                     // compute the number of hours before threshold is reached
    5706            6 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5707              :                 }
    5708              :             } else { // danger
    5709              :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5710           24 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5711           24 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5712           24 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5713              :                 // first time crossing threshold
    5714           24 :                 if (!CrossedHeatThresh) {
    5715              :                     // compute the time when the zone crosses the threshold temperature
    5716              :                     int encodedMonDayHrMin;
    5717            2 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5718            2 :                                                state.dataEnvrn->Month,
    5719            2 :                                                state.dataEnvrn->DayOfMonth,
    5720            2 :                                                state.dataGlobal->HourOfDay,
    5721            2 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5722            2 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
    5723            2 :                     CrossedHeatThresh = true;
    5724              :                 }
    5725              :             }
    5726              : 
    5727           40 :             Real64 VeryHotPMVThresh = 3.0;
    5728           40 :             Real64 WarmPMVThresh = 0.7;
    5729           40 :             Real64 CoolPMVThresh = -0.7;
    5730           40 :             Real64 VeryColdPMVThresh = -3.0;
    5731           40 :             Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
    5732           40 :             if (PMV < VeryColdPMVThresh) {
    5733           14 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
    5734           14 :                     (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5735           14 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
    5736           14 :                     (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5737              :             }
    5738           40 :             if (PMV < CoolPMVThresh) {
    5739           20 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
    5740           20 :                     (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5741           20 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
    5742           20 :                     (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5743              :             }
    5744           40 :             if (PMV > WarmPMVThresh) {
    5745           16 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
    5746           16 :                     (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5747           16 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
    5748           16 :                     (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5749              :             }
    5750           40 :             if (PMV > VeryHotPMVThresh) {
    5751            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
    5752            0 :                     (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5753            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
    5754            0 :                     (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5755              :             }
    5756              : 
    5757              :             // check whether PierceSET changed for people in a zone
    5758           40 :             if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
    5759           40 :                 state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5760              :             } else {
    5761            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
    5762            0 :                     ShowRecurringWarningErrorAtEnd(state,
    5763            0 :                                                    fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
    5764            0 :                                                    state.dataHeatBalFanSys->PierceSETerrorIndex);
    5765              :                 }
    5766              :             }
    5767              : 
    5768              :             // check whether PierceSET, PMV, etc. changed for different people in a zone
    5769           40 :             if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
    5770           40 :                 state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
    5771              :             } else {
    5772            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
    5773            0 :                     ShowRecurringWarningErrorAtEnd(state,
    5774            0 :                                                    fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
    5775            0 :                                                    state.dataHeatBalFanSys->PMVerrorIndex);
    5776              :                 }
    5777              :             }
    5778              : 
    5779           80 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5780           40 :                 if (reportPeriodFlags(i)) {
    5781           18 :                     int ReportPeriodIdx = i;
    5782           18 :                     ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5783           18 :                     bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5784           18 :                     if (Temperature > ColdTempThresh) { // safe
    5785           16 :                         if (!CrossedColdThreshRepPeriod) {
    5786              :                             // compute the number of hours before threshold is reached
    5787           16 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5788              :                         }
    5789              :                     } else { // danger
    5790              :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5791            2 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5792            2 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5793            2 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5794            2 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5795            2 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5796              :                         // first time crossing threshold
    5797            2 :                         if (!CrossedColdThreshRepPeriod) {
    5798              :                             // compute the time when the zone crosses the threshold temperature
    5799              :                             int encodedMonDayHrMin;
    5800            1 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5801            1 :                                                        state.dataEnvrn->Month,
    5802            1 :                                                        state.dataEnvrn->DayOfMonth,
    5803            1 :                                                        state.dataGlobal->HourOfDay,
    5804            1 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5805              :                             // fixme: not sure how to aggregate by zone
    5806            1 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5807            1 :                             CrossedColdThreshRepPeriod = true;
    5808              :                         }
    5809              :                     }
    5810           18 :                     HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5811           18 :                     bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5812           18 :                     if (Temperature < HeatTempThresh) { // safe
    5813            8 :                         if (!CrossedHeatThreshRepPeriod) {
    5814              :                             // compute the number of hours before threshold is reached
    5815            3 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5816              :                         }
    5817              :                     } else { // danger
    5818              :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5819           10 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5820           10 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5821           10 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5822           10 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5823           10 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5824              :                         // first time crossing threshold
    5825           10 :                         if (!CrossedHeatThreshRepPeriod) {
    5826              :                             // compute the time when the zone crosses the threshold temperature
    5827              :                             int encodedMonDayHrMin;
    5828            2 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5829            2 :                                                        state.dataEnvrn->Month,
    5830            2 :                                                        state.dataEnvrn->DayOfMonth,
    5831            2 :                                                        state.dataGlobal->HourOfDay,
    5832            2 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5833            2 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5834            2 :                             CrossedHeatThreshRepPeriod = true;
    5835              :                         }
    5836              :                     }
    5837              : 
    5838           18 :                     if (PMV < VeryColdPMVThresh) {
    5839            7 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5840            7 :                             (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5841            7 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5842            7 :                             (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5843              :                     }
    5844           18 :                     if (PMV < CoolPMVThresh) {
    5845           10 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    5846           10 :                             (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5847           10 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    5848           10 :                             (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5849              :                     }
    5850           18 :                     if (PMV > WarmPMVThresh) {
    5851            8 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    5852            8 :                             (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5853            8 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    5854            8 :                             (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5855              :                     }
    5856           18 :                     if (PMV > VeryHotPMVThresh) {
    5857            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5858            0 :                             (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5859            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5860            0 :                             (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5861              :                     }
    5862              :                 }
    5863              :             }
    5864              :         }
    5865           80 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5866           40 :             Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
    5867           40 :             Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
    5868              : 
    5869           40 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    5870           40 :             if (HI <= 26.7) {
    5871            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
    5872            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    5873            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5874           36 :             } else if (HI > 26.7 && HI <= 32.2) {
    5875            2 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
    5876            2 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    5877            2 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5878           34 :             } else if (HI > 32.2 && HI <= 39.4) {
    5879           34 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
    5880           34 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    5881           34 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5882            0 :             } else if (HI > 39.4 && HI <= 51.7) {
    5883            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
    5884            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5885            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5886              :             } else {
    5887            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
    5888            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    5889            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5890              :             }
    5891              : 
    5892           40 :             if (Humidex <= 29) {
    5893            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
    5894            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    5895            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5896           36 :             } else if (Humidex > 29 && Humidex <= 40) {
    5897           36 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
    5898           36 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    5899           36 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5900            0 :             } else if (Humidex > 40 && Humidex <= 45) {
    5901            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
    5902            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    5903            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5904            0 :             } else if (Humidex > 45 && Humidex <= 50) {
    5905            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
    5906            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5907            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5908              :             } else {
    5909            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
    5910            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    5911            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5912              :             }
    5913              : 
    5914           40 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5915           40 :             auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    5916           40 :             Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
    5917           40 :             Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
    5918              : 
    5919           40 :             if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    5920           30 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    5921           30 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
    5922           30 :                     NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    5923           30 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
    5924           30 :                     (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    5925              :             }
    5926           40 :             if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    5927            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    5928            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
    5929            4 :                     NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    5930            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
    5931            4 :                     (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    5932              :             }
    5933              : 
    5934           40 :             if (state.dataHeatBalSurfMgr->hasPierceSET) {
    5935              :                 int encodedMonDayHrMin;
    5936           40 :                 Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5937           40 :                 Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    5938              : 
    5939           40 :                 if (PierceSET <= 12.2) {
    5940           22 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    5941           22 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    5942           22 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5943              :                     // Reset duration when last step is out of range.
    5944           22 :                     if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    5945            4 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5946            4 :                                                    state.dataEnvrn->Month,
    5947            4 :                                                    state.dataEnvrn->DayOfMonth,
    5948            4 :                                                    state.dataGlobal->HourOfDay,
    5949            4 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5950            4 :                         state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    5951            4 :                         state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    5952              :                     }
    5953              :                     // Keep the longest duration record.
    5954           22 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    5955           36 :                     if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
    5956           14 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    5957           12 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
    5958           12 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
    5959              :                     }
    5960           18 :                 } else if (PierceSET > 30) {
    5961           14 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    5962           14 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    5963           14 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5964           14 :                     if (PierceSETLast == -1 || PierceSETLast <= 30) {
    5965            4 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5966            4 :                                                    state.dataEnvrn->Month,
    5967            4 :                                                    state.dataEnvrn->DayOfMonth,
    5968            4 :                                                    state.dataGlobal->HourOfDay,
    5969            4 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5970            4 :                         state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    5971            4 :                         state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    5972              :                     }
    5973           14 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    5974           28 :                     if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
    5975           14 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    5976            6 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
    5977            6 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
    5978              :                     }
    5979              :                 }
    5980              : 
    5981           40 :                 if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    5982           12 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    5983           12 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    5984              :                 }
    5985              :             }
    5986              : 
    5987           80 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5988           40 :                 if (reportPeriodFlags(i)) {
    5989           18 :                     int ReportPeriodIdx = i;
    5990              : 
    5991           18 :                     if (HI <= 26.7) {
    5992            2 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5993            2 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5994            2 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5995            2 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5996            2 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5997           16 :                     } else if (HI > 26.7 && HI <= 32.2) {
    5998            1 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    5999            1 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6000            1 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6001            1 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6002            1 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6003           15 :                     } else if (HI > 32.2 && HI <= 39.4) {
    6004           15 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6005           15 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6006           15 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6007           15 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6008           15 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6009            0 :                     } else if (HI > 39.4 && HI <= 51.7) {
    6010            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6011            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6012            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6013            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6014            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6015              :                     } else {
    6016            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6017            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6018            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6019            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6020            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6021              :                     }
    6022              : 
    6023           18 :                     if (Humidex <= 29) {
    6024            2 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6025            2 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6026            2 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6027            2 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6028            2 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6029           16 :                     } else if (Humidex > 29 && Humidex <= 40) {
    6030           16 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6031           16 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6032           16 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6033           16 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6034           16 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6035            0 :                     } else if (Humidex > 40 && Humidex <= 45) {
    6036            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6037            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6038            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6039            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6040            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6041            0 :                     } else if (Humidex > 45 && Humidex <= 50) {
    6042            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6043            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6044            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6045            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6046            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6047              :                     } else {
    6048            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6049            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6050            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6051            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6052            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6053              :                     }
    6054              : 
    6055           18 :                     if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6056              :                         int encodedMonDayHrMin;
    6057           18 :                         Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6058           18 :                         Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6059           18 :                         if (PierceSET <= 12.2) {
    6060           11 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6061           11 :                                 (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6062           11 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6063           11 :                                 (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6064           11 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6065           11 :                                 (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6066              :                             // Reset duration when last step is out of range
    6067           11 :                             if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6068            2 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6069            2 :                                                            state.dataEnvrn->Month,
    6070            2 :                                                            state.dataEnvrn->DayOfMonth,
    6071            2 :                                                            state.dataGlobal->HourOfDay,
    6072            2 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6073            2 :                                 state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6074            2 :                                 state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6075            9 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6076            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6077            0 :                                                            state.dataEnvrn->Month,
    6078            0 :                                                            state.dataEnvrn->DayOfMonth,
    6079            0 :                                                            state.dataGlobal->HourOfDay,
    6080            0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6081            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6082            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6083              :                             }
    6084              :                             // Keep the longest duration record.
    6085           11 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6086           11 :                             if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6087           21 :                                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6088           10 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6089            9 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6090            9 :                                     state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6091            9 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6092            9 :                                     state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6093              :                             }
    6094            7 :                         } else if (PierceSET > 30) {
    6095            7 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6096            7 :                                 (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6097            7 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6098            7 :                                 (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6099            7 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6100            7 :                                 (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6101              :                             // Reset duration when last step is out of range.
    6102            7 :                             if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6103            2 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6104            2 :                                                            state.dataEnvrn->Month,
    6105            2 :                                                            state.dataEnvrn->DayOfMonth,
    6106            2 :                                                            state.dataGlobal->HourOfDay,
    6107            2 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6108            2 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6109            2 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6110            5 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6111            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6112            0 :                                                            state.dataEnvrn->Month,
    6113            0 :                                                            state.dataEnvrn->DayOfMonth,
    6114            0 :                                                            state.dataGlobal->HourOfDay,
    6115            0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6116            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6117            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6118              :                             }
    6119            7 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6120            7 :                             if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6121           14 :                                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6122            7 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6123            3 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6124            3 :                                     state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6125            3 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6126            3 :                                     state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6127              :                             }
    6128              :                         }
    6129           18 :                         if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6130            6 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6131            6 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6132              :                         }
    6133              :                     }
    6134              : 
    6135           18 :                     if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6136           13 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6137           13 :                             (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6138           13 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6139           13 :                             NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6140           13 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6141           13 :                             (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6142              :                     }
    6143           18 :                     if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6144            2 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6145            2 :                             (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6146            2 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6147            2 :                             NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6148            2 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
    6149            2 :                             (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6150              :                     }
    6151              :                 }
    6152              :             }
    6153              :         } // loop over zones
    6154              :     }
    6155        69975 : }
    6156              : 
    6157           55 : void ReportCO2Resilience(EnergyPlusData &state)
    6158              : {
    6159           55 :     if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
    6160           40 :         int NoBins = 3;
    6161           86 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6162           48 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6163            2 :                 state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6164            2 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6165            2 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6166              :             }
    6167              :         }
    6168           40 :         state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
    6169           40 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    6170           38 :             if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
    6171            0 :                 ShowWarningError(state,
    6172              :                                  "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
    6173              :                                  "Zone Air CO2 Concentration output is required, "
    6174              :                                  "but no ZoneAirContaminantBalance object is defined.");
    6175              :             }
    6176           38 :             state.dataOutRptTab->displayCO2ResilienceSummary = false;
    6177           38 :             return;
    6178              :         }
    6179              :     }
    6180              : 
    6181           17 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6182           34 :         for (auto const &people : state.dataHeatBal->People) {
    6183           17 :             state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
    6184              :         }
    6185              : 
    6186           17 :         Array1D_bool reportPeriodFlags;
    6187           17 :         if (state.dataWeather->TotReportPers > 0) {
    6188           16 :             reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
    6189           16 :             General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
    6190              :         }
    6191              : 
    6192           17 :         auto &ort = state.dataOutRptTab;
    6193           49 :         for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6194           32 :             if (reportPeriodFlags(i)) {
    6195           16 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6196           16 :                 state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6197              :             }
    6198              :         }
    6199              : 
    6200           34 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6201           17 :             Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
    6202              : 
    6203           17 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6204           17 :             if (ZoneAirCO2 <= 1000) {
    6205            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6206            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6207            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6208           13 :             } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6209           12 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6210           12 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6211           12 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6212              :             } else {
    6213            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6214            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6215            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6216              :             }
    6217           49 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6218           32 :                 if (reportPeriodFlags(i)) {
    6219           16 :                     int ReportPeriodIdx = i;
    6220           16 :                     if (ZoneAirCO2 <= 1000) {
    6221            4 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6222            4 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6223            4 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6224            4 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6225            4 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6226           12 :                     } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6227           11 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6228           11 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6229           11 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6230           11 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6231           11 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6232              :                     } else {
    6233            1 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6234            1 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6235            1 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6236            1 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6237            1 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6238              :                     }
    6239              :                 }
    6240              :             }
    6241              :         }
    6242           17 :     } // loop over zones
    6243              : }
    6244              : 
    6245           55 : void ReportVisualResilience(EnergyPlusData &state)
    6246              : {
    6247           55 :     if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
    6248           40 :         int NoBins = 4;
    6249           86 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6250           48 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6251            2 :                 state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6252            2 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6253            2 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6254              :             }
    6255              :         }
    6256           40 :         state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
    6257           40 :         if ((int)state.dataDayltg->daylightControl.size() == 0) {
    6258           38 :             if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
    6259            0 :                 ShowWarningError(state,
    6260              :                                  "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
    6261              :                                  "Zone Average Daylighting Reference Point Illuminance output is required, "
    6262              :                                  "but no Daylighting Control Object is defined.");
    6263              :             }
    6264           38 :             state.dataOutRptTab->displayVisualResilienceSummary = false;
    6265           38 :             return;
    6266              :         }
    6267              :     }
    6268              : 
    6269           17 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6270           34 :         for (auto const &people : state.dataHeatBal->People) {
    6271           17 :             state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
    6272              :         }
    6273              :         // Accumulate across daylighting controls first
    6274           34 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6275           17 :             state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
    6276              :         }
    6277           34 :         for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
    6278           17 :             auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
    6279           17 :             if (thisDaylightControl.PowerReductionFactor > 0) {
    6280           34 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6281           17 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
    6282              :                 }
    6283              :             } else {
    6284            0 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6285            0 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
    6286            0 :                         thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
    6287              :                 }
    6288              :             }
    6289              :         }
    6290              : 
    6291           17 :         Array1D_bool reportPeriodFlags;
    6292           17 :         if (state.dataWeather->TotReportPers > 0) {
    6293           16 :             reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
    6294           32 :             General::findReportPeriodIdx(
    6295           16 :                 state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
    6296              :         }
    6297              : 
    6298           17 :         auto &ort = state.dataOutRptTab;
    6299           49 :         for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6300           32 :             if (reportPeriodFlags(i)) {
    6301           16 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6302           16 :                 state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6303              :             }
    6304              :         }
    6305              : 
    6306           34 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6307           17 :             if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) continue;
    6308              :             // Now divide by total reference points to get average
    6309           17 :             Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
    6310              : 
    6311           17 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6312           17 :             if (avgZoneIllum <= 100) {
    6313            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6314            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6315            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6316           11 :             } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6317            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6318            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6319            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6320            7 :             } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6321            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6322            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6323            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6324              :             } else {
    6325            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
    6326            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6327            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6328              :             }
    6329           49 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6330           32 :                 if (reportPeriodFlags(i)) {
    6331           16 :                     int ReportPeriodIdx = i;
    6332           16 :                     if (avgZoneIllum <= 100) {
    6333            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6334            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6335            6 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6336            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6337            6 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6338           10 :                     } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6339            4 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6340            4 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6341            4 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6342            4 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6343            4 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6344            6 :                     } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6345            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6346            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6347            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6348            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6349            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6350              :                     } else {
    6351            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6352            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6353            6 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6354            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6355            6 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6356              :                     }
    6357              :                 }
    6358              :             }
    6359              :         }
    6360           17 :     } // loop over zones
    6361              : }
    6362              : 
    6363       249948 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
    6364              : {
    6365              : 
    6366              :     // SUBROUTINE INFORMATION:
    6367              :     //       AUTHOR         Linda Lawrie
    6368              :     //       DATE WRITTEN   Oct 2000
    6369              : 
    6370              :     // PURPOSE OF THIS SUBROUTINE:
    6371              :     // This subroutine puts the reporting part of the HBSurface Module in one area.
    6372              : 
    6373       249948 :     SolarShading::ReportSurfaceShading(state);
    6374              : 
    6375       249948 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    6376            0 :         ReportNonRepresentativeSurfaceResults(state);
    6377              :     }
    6378              : 
    6379              :     // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
    6380              : 
    6381              :     // Opaque or window surfaces
    6382       586590 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6383       709587 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6384       372945 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6385       372945 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6386       372945 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6387      2447200 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6388      2074255 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6389              :                 // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
    6390      2074255 :                 state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
    6391      2074255 :                 state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
    6392      2074255 :                     state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6393              : 
    6394      2074255 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6395      2074255 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
    6396      2074255 :                     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6397              : 
    6398      2074255 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
    6399      2074255 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
    6400      2074255 :                     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6401              : 
    6402      2074255 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
    6403      2074255 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
    6404      2074255 :                     state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6405              : 
    6406      2074255 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
    6407              : 
    6408      2074255 :                 state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
    6409      2074255 :                     state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6410              : 
    6411      2074255 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
    6412      2074255 :                 state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
    6413      2074255 :                     state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6414              : 
    6415              :                 // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
    6416      2074255 :                 state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
    6417      2074255 :                     surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
    6418      2074255 :                     (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
    6419              : 
    6420              :                 // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
    6421      2074255 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
    6422      2074255 :                     state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
    6423              :             }
    6424              :         }
    6425              :     }
    6426              : 
    6427       249948 :     if (state.dataOutRptTab->displayHeatEmissionsSummary) {
    6428        69935 :         state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
    6429       508457 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6430       438522 :             if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    6431       350203 :                 state.dataHeatBalSurf->SumSurfaceHeatEmission +=
    6432       350203 :                     state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    6433              :             }
    6434              :         }
    6435              :     }
    6436              : 
    6437              :     // Window surfaces
    6438       586590 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6439       709587 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6440       372945 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6441       372945 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    6442       372945 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    6443       461506 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6444        88561 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6445        88561 :                 state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
    6446        88561 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
    6447              : 
    6448              :                 // Absorbed short wave radiation
    6449              :                 int TotGlassLayers;
    6450        88561 :                 int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    6451        88561 :                 auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
    6452        88561 :                 int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
    6453        88561 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
    6454        88561 :                 if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
    6455         2367 :                     TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
    6456        86194 :                 } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
    6457            0 :                     TotGlassLayers = thisConstruct.TotSolidLayers;
    6458        86194 :                 } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    6459        86194 :                     TotGlassLayers = thisConstruct.TotGlassLayers;
    6460              :                 } else {
    6461              :                     // Interior, exterior or between-glass shade, screen or blind in place
    6462            0 :                     TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
    6463              :                 }
    6464        88561 :                 state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
    6465        88561 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
    6466        88561 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
    6467       205255 :                 for (int lay = 1; lay <= TotGlassLayers; ++lay) {
    6468              :                     // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6469       116694 :                     state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
    6470       116694 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
    6471              :                     // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6472       116694 :                     state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6473              :                     // Total Shortwave Absorbed:All solid Layers[W]
    6474       116694 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6475              :                 }
    6476              : 
    6477              :                 // Window heat gain/loss
    6478        88561 :                 if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
    6479        32908 :                     state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
    6480        32908 :                     state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
    6481        32908 :                         state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6482              :                 } else {
    6483        55653 :                     state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
    6484        55653 :                     state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
    6485        55653 :                         state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6486              :                 }
    6487        88561 :                 state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
    6488        88561 :                     state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6489        88561 :                 if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    6490            0 :                     int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    6491            0 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
    6492            0 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
    6493              :                 }
    6494              :             }
    6495              :         }
    6496              :     }
    6497              : 
    6498       249948 :     if (state.dataSurface->AnyMovableInsulation) ReportIntMovInsInsideSurfTemp(state);
    6499              : 
    6500              :     // Opaque heat transfer surfaces
    6501       586590 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6502       709587 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6503       372945 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6504       372945 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6505       372945 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6506      2358639 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6507      1985694 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6508              : 
    6509      1985694 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
    6510      1985694 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
    6511      1985694 :                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6512              : 
    6513      1985694 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
    6514      1985694 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
    6515      1985694 :                     state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6516              : 
    6517      1985694 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
    6518      1985694 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
    6519      1985694 :                     state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6520              : 
    6521              :                 // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6522      1985694 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
    6523              :                 // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6524      1985694 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
    6525              : 
    6526              :                 // inside face conduction updates
    6527      1985694 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
    6528      1985694 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
    6529      1985694 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6530      1985694 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
    6531      1985694 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
    6532      1985694 :                 if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
    6533       843293 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6534              :                 } else {
    6535      1142401 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6536              :                 }
    6537              : 
    6538              :                 // outside face conduction updates
    6539      1985694 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
    6540      1985694 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
    6541      1985694 :                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6542      1985694 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
    6543      1985694 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
    6544      1985694 :                 if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
    6545      1325016 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6546              :                 } else {
    6547       660678 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6548              :                 }
    6549              :             }
    6550      2358639 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6551              :                 // do average surface conduction updates
    6552              : 
    6553      1985694 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
    6554      1985694 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
    6555      1985694 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
    6556      1985694 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
    6557      1985694 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
    6558      1985694 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6559      1985694 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
    6560      1985694 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
    6561      1985694 :                 if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
    6562       807690 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6563              :                 } else {
    6564      1178004 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6565              :                 }
    6566              : 
    6567              :                 // do surface storage rate updates
    6568      1985694 :                 state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
    6569      1985694 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
    6570      1985694 :                 state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
    6571      1985694 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
    6572      1985694 :                 state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
    6573      1985694 :                     state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6574      1985694 :                 state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
    6575      1985694 :                 state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
    6576      1985694 :                 if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
    6577      1048369 :                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6578              :                 } else {
    6579       937325 :                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6580              :                 }
    6581              :             }
    6582              :         }
    6583              :     }
    6584              : 
    6585       249948 :     if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
    6586              :         // This is by surface, so it works for both space and zone component loads
    6587        14868 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
    6588        14868 :         auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
    6589        43206 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6590        56676 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6591        28338 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6592        28338 :                 int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6593        28338 :                 int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6594       171426 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6595       143088 :                     surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
    6596       143088 :                     surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
    6597              :                 }
    6598        28338 :                 firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6599        28338 :                 lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6600       178212 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6601       149874 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6602       149874 :                     if (!state.dataGlobal->WarmupFlag) {
    6603        20640 :                         if (state.dataGlobal->isPulseZoneSizing) {
    6604        10320 :                             surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6605              :                         } else {
    6606        10320 :                             surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6607        10320 :                             surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6608              :                         }
    6609              :                     }
    6610              :                 }
    6611              :             }
    6612              :         }
    6613              :     }
    6614              : 
    6615       249948 :     if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6616            0 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6617            0 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6618            0 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6619            0 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6620            0 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6621            0 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6622            0 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6623            0 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6624              :                 }
    6625            0 :                 if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
    6626            0 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6627            0 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
    6628            0 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6629              :                 } else {
    6630            0 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6631            0 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
    6632            0 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6633              :                 }
    6634              : 
    6635            0 :                 if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
    6636            0 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6637            0 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
    6638            0 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6639              :                 } else {
    6640            0 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6641            0 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
    6642            0 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6643              :                 }
    6644              :             }
    6645              :         }
    6646              :     }
    6647       249948 : }
    6648              : 
    6649            0 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
    6650              : {
    6651            0 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6652            0 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6653            0 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6654              :             // Heat transfer surfaces
    6655            0 :             int firstSurf = thisSpace.HTSurfaceFirst;
    6656            0 :             int lastSurf = thisSpace.HTSurfaceLast;
    6657            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6658            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6659            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    6660            0 :                 if (surfNum != repSurfNum) {
    6661            0 :                     state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
    6662            0 :                     state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
    6663              :                 }
    6664              :             }
    6665              : 
    6666              :             // Windows
    6667            0 :             if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6668            0 :                 firstSurf = thisSpace.WindowSurfaceFirst;
    6669            0 :                 lastSurf = thisSpace.WindowSurfaceLast;
    6670            0 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6671            0 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6672            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    6673            0 :                     if (surfNum != repSurfNum) {
    6674            0 :                         Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    6675            0 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    6676            0 :                             state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    6677            0 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    6678            0 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    6679            0 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    6680            0 :                             state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
    6681              :                     }
    6682              :                 }
    6683              :             }
    6684              :         }
    6685              :     }
    6686            0 : }
    6687              : 
    6688            1 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
    6689              : {
    6690            1 :     state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
    6691            3 :     for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
    6692            2 :         if (state.dataSurface->intMovInsuls(SurfNum).present) {
    6693            1 :             state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    6694              :         }
    6695              :     }
    6696            1 : }
    6697              : // End of Reporting subroutines for the HB Module
    6698              : // *****************************************************************************
    6699              : 
    6700              : // *****************************************************************************
    6701              : // *****************************************************************************
    6702              : // *****************************************************************************
    6703              : // *****************************************************************************
    6704              : 
    6705              : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
    6706              : 
    6707       249962 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
    6708              :                                 ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    6709              : {
    6710              : 
    6711              :     // SUBROUTINE INFORMATION:
    6712              :     //       AUTHOR         George Walton
    6713              :     //       DATE WRITTEN   December 1979
    6714              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays);
    6715              :     //                      Aug 2000 (RJL for MTF moisture calculations)
    6716              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    6717              :     //                      Dec 2000 (RKS for radiant system model addition)
    6718              :     //                      Apr 2002 (COP removed denominator from OSC calculation
    6719              :     //                      Jul 2008 (P.Biddulph include calls to HAMT)
    6720              :     //                      Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
    6721              :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    6722              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    6723              : 
    6724              :     // PURPOSE OF THIS SUBROUTINE:
    6725              :     // This subroutine performs a heat balance on the outside face of each
    6726              :     // surface in the building.
    6727              : 
    6728              :     // METHODOLOGY EMPLOYED:
    6729              :     // Various boundary conditions are set and additional parameters are set-
    6730              :     // up.  Then, the proper heat balance equation is selected based on the
    6731              :     // presence of movable insulation, thermal mass of the surface construction,
    6732              :     // and convection model being used.
    6733              : 
    6734              :     // REFERENCES:
    6735              :     // (I)BLAST legacy routine HBOUT
    6736              :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    6737              : 
    6738              :     //    // Using/Aliasing
    6739              :     //    using namespace DataEnvironment;
    6740              :     //    using namespace DataHeatBalance;
    6741              :     //    using namespace DataHeatBalSurface;
    6742              :     //    using namespace DataSurfaces;
    6743              :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
    6744              :     //    using namespace Psychrometrics;
    6745              :     //    using EcoRoofManager::CalcEcoRoof;
    6746              :     //
    6747              :     //    // Locals
    6748              :     //    // SUBROUTINE ARGUMENT DEFINITIONS:
    6749              :     //
    6750              :     //>>>>>>> origin/develop
    6751              :     // SUBROUTINE PARAMETER DEFINITIONS:
    6752       249962 :     constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
    6753       249962 :     constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
    6754       249962 :     constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
    6755       249962 :     constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
    6756       249962 :     constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
    6757       249962 :     constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
    6758       249962 :     constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
    6759       249962 :     constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
    6760       249962 :     constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
    6761       249962 :     constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
    6762       249962 :     constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
    6763       249962 :     constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
    6764       249962 :     constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
    6765       249962 :     constexpr std::string_view Outside("Outside");
    6766              : 
    6767       249962 :     auto &s_mat = state.dataMaterial;
    6768              : 
    6769       249962 :     bool MovInsulErrorFlag = false; // Movable Insulation error flag
    6770              : 
    6771              :     // set ground surfaces average temperature
    6772       249962 :     GetGroundSurfacesTemperatureAverage(state);
    6773              : 
    6774              :     // set surrounding surfaces average temperature
    6775       249962 :     GetSurroundingSurfacesTemperatureAverage(state);
    6776              : 
    6777       249962 :     auto &Surface = state.dataSurface->Surface;
    6778              : 
    6779       249962 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    6780            0 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6781              :             // Need to transfer any source/sink for a surface to the local array.  Note that
    6782              :             // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
    6783              :             // This must be done at this location so that this is always updated correctly.
    6784            0 :             if (Surface(SurfNum).Area > 0.0)
    6785            0 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
    6786            0 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6787              : 
    6788              :             // next we add source (actually a sink) from any integrated PV
    6789            0 :             if (Surface(SurfNum).Area > 0.0)
    6790            0 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
    6791            0 :                     state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6792              :         }
    6793              :     }
    6794              : 
    6795       249962 :     if (present(ZoneToResimulate)) {
    6796           16 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6797            8 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
    6798              :     } else {
    6799       499908 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6800       249954 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
    6801              :     }
    6802              : 
    6803              :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    6804       249963 :     for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
    6805            1 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
    6806              :     }
    6807       586618 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
    6808       709639 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6809       372983 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    6810      2447306 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    6811      2074323 :                 if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) continue;
    6812      1985763 :                 if (present(ZoneToResimulate)) {
    6813           32 :                     if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
    6814            0 :                         continue; // skip surfaces that are not associated with this zone
    6815              :                     }
    6816              :                 }
    6817              :                 // Interior windows in partitions use "normal" heat balance calculations
    6818              :                 // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
    6819              :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
    6820              : 
    6821              :                 // Initializations for this surface
    6822      1985763 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    6823      1985763 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    6824      1985763 :                 Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
    6825      1985763 :                 Real64 HSky = 0.0;      // "Convection" coefficient from sky to surface
    6826      1985763 :                 Real64 HGround = 0.0;   // "Convection" coefficient from ground to surface
    6827      1985763 :                 Real64 HAir = 0.0;      // "Convection" coefficient from air to surface (radiation)
    6828      1985763 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    6829      1985763 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    6830      1985763 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    6831      1985763 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    6832      1985763 :                 state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
    6833              : 
    6834              :                 // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
    6835              :                 // various different boundary conditions
    6836      1985763 :                 switch (Surface(SurfNum).ExtBoundCond) {
    6837       121849 :                 case DataSurfaces::Ground: { // Surface in contact with ground
    6838       121849 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    6839       121849 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    6840              : 
    6841              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    6842       121849 :                     if (thisConstruct.SourceSinkPresent)
    6843            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    6844              : 
    6845              :                     // start HAMT
    6846       121849 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    6847              :                         // Set variables used in the HAMT moisture balance
    6848            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    6849            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    6850            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    6851            0 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
    6852            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    6853              : 
    6854            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    6855            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    6856            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    6857              :                                   state,
    6858            0 :                                   state.dataEnvrn->OutBaroPress,
    6859            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6860              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    6861            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6862              :                                                                 1.0,
    6863            0 :                                                                 state.dataEnvrn->OutBaroPress,
    6864            0 :                                                                 RoutineNameGroundTemp)) +
    6865            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    6866            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    6867              : 
    6868            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    6869            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    6870            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    6871              :                     }
    6872              :                     // end HAMT
    6873              : 
    6874       121849 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    6875              :                         // Set variables used in the FD moisture balance
    6876            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    6877            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    6878            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    6879            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
    6880            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    6881            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    6882            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    6883            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    6884              :                                   state,
    6885            0 :                                   state.dataEnvrn->OutBaroPress,
    6886            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6887              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    6888            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6889              :                                                                 1.0,
    6890            0 :                                                                 state.dataEnvrn->OutBaroPress,
    6891            0 :                                                                 RoutineNameGroundTemp)) +
    6892            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    6893            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    6894            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    6895            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    6896            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    6897              :                     }
    6898              :                     // Added for FCfactor grounds
    6899       121849 :                 } break;
    6900            0 :                 case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
    6901            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    6902            0 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    6903              : 
    6904              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    6905            0 :                     if (thisConstruct.SourceSinkPresent)
    6906            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    6907              : 
    6908            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    6909              :                         // Set variables used in the HAMT moisture balance
    6910            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    6911            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    6912            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    6913            0 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
    6914            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    6915              : 
    6916            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    6917            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    6918            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    6919              :                                   state,
    6920            0 :                                   state.dataEnvrn->OutBaroPress,
    6921            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    6922              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    6923            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    6924              :                                                                 1.0,
    6925            0 :                                                                 state.dataEnvrn->OutBaroPress,
    6926            0 :                                                                 RoutineNameGroundTempFC)) +
    6927            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    6928            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    6929              : 
    6930            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    6931            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    6932            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    6933              :                     }
    6934              : 
    6935            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    6936              :                         // Set variables used in the FD moisture balance
    6937            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    6938            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    6939            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    6940            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
    6941            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    6942            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    6943            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    6944            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    6945              :                                   state,
    6946            0 :                                   state.dataEnvrn->OutBaroPress,
    6947            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    6948              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    6949            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    6950              :                                                                 1.0,
    6951            0 :                                                                 state.dataEnvrn->OutBaroPress,
    6952            0 :                                                                 RoutineNameGroundTempFC)) +
    6953            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    6954            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    6955            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    6956            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    6957            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    6958              :                     }
    6959            0 :                 } break;
    6960            0 :                 case DataSurfaces::OtherSideCoefNoCalcExt: {
    6961              :                     // Use Other Side Coefficients to determine the surface film coefficient and
    6962              :                     // the exterior boundary condition temperature
    6963              : 
    6964            0 :                     int OPtr = Surface(SurfNum).OSCPtr;
    6965              :                     // Set surface temp from previous timestep
    6966            0 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    6967            0 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    6968              :                     }
    6969              : 
    6970            0 :                     if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
    6971            0 :                         state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
    6972              :                     }
    6973              : 
    6974              :                     //  Allow for modification of TemperatureCoefficient with unitary sine wave.
    6975              :                     Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
    6976            0 :                     if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
    6977            0 :                         ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
    6978              :                     } else {
    6979            0 :                         ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
    6980              :                     }
    6981              : 
    6982            0 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    6983            0 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    6984            0 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    6985            0 :                          ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    6986            0 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    6987            0 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    6988            0 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    6989            0 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    6990            0 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    6991              : 
    6992              :                     // Enforce max/min limits if applicable
    6993            0 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent)
    6994            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    6995            0 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    6996            0 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent)
    6997            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    6998            0 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    6999              : 
    7000            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7001              : 
    7002              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7003            0 :                     if (thisConstruct.SourceSinkPresent)
    7004            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7005              : 
    7006            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7007            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7008              :                         // Set variables used in the FD moisture balance and HAMT
    7009            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7010            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7011            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7012            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7013            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7014            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7015            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7016            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7017            0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7018              :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7019            0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7020              :                                                                                               1.0,
    7021            0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7022            0 :                                                                                               RoutineNameOtherSideCoefNoCalcExt)) +
    7023            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7024            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7025            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7026            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7027            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7028              :                     }
    7029              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7030            0 :                 } break;
    7031            0 :                 case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
    7032              :                     // First, set up the outside convection coefficient and the exterior temperature
    7033              :                     // boundary condition for the surface
    7034            0 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7035              :                     // Set surface temp from previous timestep
    7036            0 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7037            0 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7038              :                     }
    7039              : 
    7040            0 :                     if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
    7041            0 :                         state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
    7042              :                     }
    7043              : 
    7044            0 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
    7045              : 
    7046            0 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7047            0 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7048            0 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7049            0 :                          state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7050            0 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7051            0 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7052            0 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7053            0 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7054            0 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7055              : 
    7056              :                     // Enforce max/min limits if applicable
    7057            0 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent)
    7058            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7059            0 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7060            0 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent)
    7061            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7062            0 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7063              : 
    7064            0 :                     Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7065              : 
    7066              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7067            0 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent)
    7068            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7069              : 
    7070            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7071            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7072              :                         // Set variables used in the FD moisture balance and HAMT
    7073            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7074            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7075            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7076            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7077            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7078            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7079            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7080            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7081            0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7082              :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7083            0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7084              :                                                                                               1.0,
    7085            0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7086            0 :                                                                                               RoutineNameOtherSideCoefCalcExt)) +
    7087            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7088            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7089            0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7090            0 :                         state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7091            0 :                         state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7092              :                     }
    7093              : 
    7094              :                     // Call the outside surface temp calculation and pass the necessary terms
    7095            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7096            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7097            0 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7098            0 :                         if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7099              :                     }
    7100              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7101            0 :                 } break;
    7102            0 :                 case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
    7103              :                     // modeling that defines the "outside environment"
    7104              :                     // First, set up the outside convection coefficient and the exterior temperature
    7105              :                     // boundary condition for the surface
    7106            0 :                     int OPtr = Surface(SurfNum).OSCMPtr;
    7107              :                     // EMS overrides
    7108            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv)
    7109            0 :                         state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
    7110            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv)
    7111            0 :                         state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
    7112            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad)
    7113            0 :                         state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
    7114            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad)
    7115            0 :                         state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
    7116            0 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
    7117              : 
    7118            0 :                     Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
    7119              : 
    7120              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7121            0 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent)
    7122            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7123              : 
    7124            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7125            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7126              :                         // Set variables used in the FD moisture balance and HAMT
    7127            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7128            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7129            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7130            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7131            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7132            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7133            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7134              :                                   state,
    7135            0 :                                   state.dataEnvrn->OutBaroPress,
    7136            0 :                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7137              :                                   Psychrometrics::PsyWFnTdbRhPb(
    7138            0 :                                       state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
    7139            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7140            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7141            0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
    7142            0 :                         state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
    7143            0 :                         state.dataMstBal->HAirFD(SurfNum) = 0.0;  // CR 8046, null out and use only sky term for surface to baffle IR
    7144              :                     }
    7145              : 
    7146              :                     // Call the outside surface temp calculation and pass the necessary terms
    7147            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7148            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7149              : 
    7150            0 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7151            0 :                             CalcExteriorVentedCavity(state, SurfNum);
    7152              :                         }
    7153              : 
    7154            0 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7155            0 :                         if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7156              : 
    7157            0 :                     } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7158            0 :                                Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7159            0 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7160            0 :                             CalcExteriorVentedCavity(state, SurfNum);
    7161              :                         }
    7162              :                     }
    7163              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7164            0 :                 } break;
    7165      1298612 :                 case DataSurfaces::ExternalEnvironment: {
    7166              :                     // checking the EcoRoof presented in the external environment
    7167              :                     // recompute each load by calling ecoroof
    7168              : 
    7169              :                     Real64 TempExt;
    7170              : 
    7171      1298612 :                     if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
    7172            0 :                         EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
    7173            0 :                         continue;
    7174              :                     }
    7175              :                     // Roughness index of the exterior surface
    7176      1298612 :                     Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
    7177              :                     // Thermal absorptance of the exterior surface
    7178      1298612 :                     Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
    7179      1298612 :                     HMovInsul = 0;
    7180              :                     // Check for outside movable insulation
    7181      1298612 :                     if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
    7182            0 :                         HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
    7183              :                     }
    7184              : 
    7185              :                     // Check for exposure to wind (exterior environment)
    7186      1298612 :                     if (Surface(SurfNum).ExtWind) {
    7187              : 
    7188              :                         // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
    7189      1212250 :                         Convect::InitExtConvCoeff(state,
    7190              :                                                   SurfNum,
    7191              :                                                   HMovInsul,
    7192              :                                                   RoughSurf,
    7193              :                                                   AbsThermSurf,
    7194      1212250 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7195      1212250 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7196      1212250 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7197      1212250 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7198      1212250 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7199      1212250 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7200              : 
    7201      1212250 :                         if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
    7202              : 
    7203            0 :                             if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
    7204            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
    7205              :                             } else { // User set
    7206            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    7207              :                             }
    7208              : 
    7209            0 :                             TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
    7210              : 
    7211              :                             // start HAMT
    7212            0 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7213              :                                 // Set variables used in the HAMT moisture balance
    7214            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7215            0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7216            0 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
    7217            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7218            0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7219            0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7220            0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7221            0 :                                                                         state.dataEnvrn->OutBaroPress,
    7222            0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7223              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7224            0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7225              :                                                                                                       1.0,
    7226            0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7227            0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7228            0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7229            0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7230            0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7231            0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7232            0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7233              :                             }
    7234              :                             // end HAMT
    7235            0 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7236              :                                 // Set variables used in the FD moisture balance
    7237            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7238            0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7239            0 :                                     Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
    7240            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7241            0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7242            0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7243            0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7244            0 :                                                                         state.dataEnvrn->OutBaroPress,
    7245            0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7246              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7247            0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7248              :                                                                                                       1.0,
    7249            0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7250            0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7251            0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7252            0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7253            0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7254            0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7255            0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7256              :                             }
    7257              : 
    7258              :                         } else { // Surface is dry, use the normal correlation
    7259              : 
    7260      1212250 :                             TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7261              : 
    7262      2179640 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7263       967390 :                                 Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7264              :                                 // Set variables used in the FD moisture balance and HAMT
    7265       244860 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7266       244860 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7267       244860 :                                     state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7268       244860 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7269       244860 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7270       244860 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7271       489720 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7272       244860 :                                                                         state.dataEnvrn->OutBaroPress,
    7273       244860 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7274              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7275       244860 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7276              :                                                                                                       1.0,
    7277       244860 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7278       244860 :                                                                                                       RoutineNameExtEnvDrySurf)) +
    7279       489720 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7280       244860 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7281              :                                 //  check for saturation conditions of air
    7282              :                                 // Local temporary saturated vapor density for checking
    7283              :                                 Real64 RhoVaporSat =
    7284       244860 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
    7285       244860 :                                 if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
    7286       244860 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7287       244860 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7288       244860 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7289              :                             }
    7290              :                         }
    7291              : 
    7292              :                     } else { // No wind
    7293              : 
    7294              :                         // Calculate exterior heat transfer coefficients for windspeed = 0
    7295        86362 :                         Convect::InitExtConvCoeff(state,
    7296              :                                                   SurfNum,
    7297              :                                                   HMovInsul,
    7298              :                                                   RoughSurf,
    7299              :                                                   AbsThermSurf,
    7300        86362 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7301        86362 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7302        86362 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7303        86362 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7304        86362 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7305        86362 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7306              : 
    7307        86362 :                         TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7308              : 
    7309       172724 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7310        86362 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7311              :                             // Set variables used in the FD moisture balance and HAMT
    7312            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7313            0 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7314            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7315            0 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7316            0 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7317            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7318            0 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7319            0 :                                                                     state.dataEnvrn->OutBaroPress,
    7320            0 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7321              :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7322            0 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7323              :                                                                                                   1.0,
    7324            0 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7325            0 :                                                                                                   RoutineNameNoWind)) +
    7326            0 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7327            0 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7328            0 :                             state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7329            0 :                             state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7330            0 :                             state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7331              :                         }
    7332              :                     }
    7333              :                     // Calculate LWR from surrounding surfaces if defined for an exterior surface
    7334      1298612 :                     if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
    7335            6 :                         int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
    7336              :                         // Absolute temperature of the outside surface of an exterior surface
    7337            6 :                         Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
    7338           14 :                         for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
    7339              :                              SrdSurfNum++) {
    7340              :                             // View factor of a surrounding surface
    7341            8 :                             Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
    7342              :                             // Absolute temperature of a surrounding surface
    7343              :                             Real64 SrdSurfTempAbs =
    7344            8 :                                 state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
    7345            8 :                                 Constant::Kelvin;
    7346            8 :                             state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
    7347            8 :                                 Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
    7348              :                         }
    7349              :                     }
    7350              : 
    7351      1298612 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7352      1543472 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
    7353       244860 :                         Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7354      1053752 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7355      1053752 :                         if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7356              :                     }
    7357      1298612 :                 } break;
    7358              : 
    7359            0 :                 case DataSurfaces::KivaFoundation: {
    7360            0 :                     auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
    7361            0 :                     Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
    7362            0 :                     Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
    7363              : 
    7364              :                     // Set Kiva exterior convection algorithms
    7365            0 :                     Convect::InitExtConvCoeff(state,
    7366              :                                               SurfNum,
    7367              :                                               HMovInsul,
    7368              :                                               RoughSurf,
    7369              :                                               AbsThermSurf,
    7370            0 :                                               state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7371            0 :                                               state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7372            0 :                                               state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7373            0 :                                               state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7374            0 :                                               state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7375            0 :                                               state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7376            0 :                 } break;
    7377              : 
    7378       565302 :                 default: { // for interior or other zone surfaces
    7379              : 
    7380       565302 :                     if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
    7381              : 
    7382       402090 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7383              : 
    7384              :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7385              : 
    7386       755208 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7387       353118 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7388              :                             // Set variables used in the FD moisture balance HAMT
    7389        48972 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7390        48972 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
    7391        48972 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7392        48972 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7393        48972 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7394        97944 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7395              :                                       state,
    7396        48972 :                                       state.dataEnvrn->OutBaroPress,
    7397        48972 :                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7398              :                                       Psychrometrics::PsyWFnTdbRhPb(
    7399        48972 :                                           state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
    7400        97944 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7401        48972 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7402        48972 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7403        48972 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7404        48972 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7405              :                         }
    7406              : 
    7407              :                     } else { // Interzone partition
    7408              : 
    7409       163212 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7410       163212 :                             state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7411              : 
    7412              :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7413              : 
    7414       326424 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7415       163212 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7416              :                             // Set variables used in the FD moisture balance and HAMT
    7417            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7418            0 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
    7419            0 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
    7420            0 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7421            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7422            0 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7423            0 :                                                                     state.dataEnvrn->OutBaroPress,
    7424            0 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7425              :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7426            0 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7427              :                                                                                                   1.0,
    7428            0 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7429            0 :                                                                                                   RoutineNameIZPart)) +
    7430            0 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7431            0 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7432            0 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7433            0 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7434            0 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7435              :                         }
    7436              :                     }
    7437              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7438       565302 :                 } break;
    7439              :                 }
    7440              : 
    7441      1985763 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
    7442              :             }
    7443              :         }
    7444              :     } // ...end of DO loop over all surface (actually heat transfer surfaces)
    7445       249962 : }
    7446              : 
    7447      1985765 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
    7448              : {
    7449      1985765 :     auto const &surface = state.dataSurface->Surface(SurfNum);
    7450      1985765 :     int OPtr = surface.OSCMPtr;
    7451      1985765 :     if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
    7452            0 :         return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
    7453              :     } else {
    7454      1985765 :         if (state.dataEnvrn->IsRain) {
    7455            1 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7456            1 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
    7457              :         } else {
    7458      1985764 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7459      1985764 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
    7460              :         }
    7461              :     }
    7462              : }
    7463              : 
    7464       249963 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
    7465              :                                ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    7466              : {
    7467       249963 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
    7468          107 :         if (state.dataHeatBal->AnyEMPD) {
    7469            0 :             state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
    7470              :         }
    7471          107 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    7472            0 :             SetupOutputVariable(state,
    7473              :                                 "Surface Inside Face Heat Balance Calculation Iteration Count",
    7474              :                                 Constant::Units::None,
    7475            0 :                                 state.dataHeatBal->InsideSurfIterations,
    7476              :                                 OutputProcessor::TimeStepType::Zone,
    7477              :                                 OutputProcessor::StoreType::Sum,
    7478              :                                 "Simulation");
    7479              :         }
    7480              :         // Precompute whether CTF temperature limits will be needed
    7481          107 :         state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
    7482          235 :         for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
    7483          274 :             for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
    7484          146 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    7485          901 :                 for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
    7486          758 :                     DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
    7487          758 :                     if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
    7488              :                         (alg == DataSurfaces::HeatTransferModel::Kiva)) {
    7489            3 :                         state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
    7490            3 :                         break;
    7491              :                     }
    7492              :                 }
    7493              :             }
    7494              :         }
    7495          107 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
    7496              :     }
    7497              : 
    7498       249963 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
    7499          483 :         state.dataHeatBalSurf->SurfTempInsOld = 23.0;
    7500          483 :         state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
    7501          483 :         state.dataHeatBal->SurfTempEffBulkAir = 23.0;
    7502          483 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
    7503          483 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
    7504              : 
    7505              :         // Initialize Kiva instances ground temperatures
    7506          483 :         if (state.dataHeatBal->AnyKiva) {
    7507            0 :             state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
    7508              :         }
    7509              :     }
    7510       249963 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    7511       249480 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
    7512              :     }
    7513              : 
    7514       249963 :     sumSurfQdotRadHVAC(state);
    7515              : 
    7516              :     // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
    7517       249963 :     bool const PartialResimulate(present(ZoneToResimulate));
    7518              : 
    7519       249963 :     if (!PartialResimulate) {
    7520       249955 :         if (state.dataHeatBal->AllCTF) {
    7521       200983 :             CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
    7522              :         } else {
    7523        97944 :             CalcHeatBalanceInsideSurf2(state,
    7524        48972 :                                        state.dataSurface->AllHTSurfaceList,
    7525        48972 :                                        state.dataSurface->AllIZSurfaceList,
    7526        48972 :                                        state.dataSurface->AllHTNonWindowSurfaceList,
    7527        48972 :                                        state.dataSurface->AllHTWindowSurfaceList);
    7528              :         }
    7529              :     } else {
    7530            8 :         auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
    7531            8 :         auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
    7532            8 :         auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
    7533            8 :         auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
    7534              :         // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
    7535            8 :         CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
    7536              :     }
    7537       249963 :     CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
    7538       249963 :     UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
    7539       249963 : }
    7540              : 
    7541        48980 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
    7542              :                                 const std::vector<int> &HTSurfs,          // Heat transfer surfaces to simulate (opaque and windows)
    7543              :                                 const std::vector<int> &IZSurfs,          // Interzone heat transfer surfaces to simulate
    7544              :                                 const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
    7545              :                                 const std::vector<int> &HTWindowSurfs,    // Window heat transfer surfaces to simulate
    7546              :                                 ObjexxFCL::Optional_int_const ZoneToResimulate)
    7547              : {
    7548              :     // SUBROUTINE INFORMATION:
    7549              :     //       AUTHOR         George Walton
    7550              :     //       DATE WRITTEN   December 1979
    7551              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    7552              :     //                      Dec 1999 (FCW for window calculation)
    7553              :     //                      May 2000 (FCW for window frame and dividers)
    7554              :     //                      Aug 2000 (RJL for MTF moisture calculations)
    7555              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    7556              :     //                      Dec 2000 (RKS for radiant system model addition)
    7557              :     //                      Jul 2003 (CC) set the reference temperatures for inside surface heat balance
    7558              :     //                                    depending on convection algorithms and/or air models used
    7559              :     //                      May 2006 (RR  account for exterior window screen)
    7560              :     //                      Jul 2008 (P. Biddulph include calls to HAMT)
    7561              :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    7562              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    7563              : 
    7564              :     // PURPOSE OF THIS SUBROUTINE:
    7565              :     // This subroutine performs a heat balance on the inside face of each
    7566              :     // surface in the building.
    7567              : 
    7568              :     // METHODOLOGY EMPLOYED:
    7569              :     // Various boundary conditions are set and additional parameters are set-
    7570              :     // up.  Then, the proper heat balance equation is selected based on whether
    7571              :     // the surface is a partition or not and on whether or not movable
    7572              :     // insulation is present on the inside face.
    7573              : 
    7574              :     // REFERENCES:
    7575              :     // (I)BLAST legacy routine HBSRF
    7576              : 
    7577        48980 :     constexpr std::string_view rhoAirZone("RhoAirZone");
    7578        48980 :     constexpr std::string_view wsurf("Wsurf");
    7579        48980 :     constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
    7580        48980 :     constexpr std::string_view Inside("Inside");
    7581              : 
    7582              :     Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
    7583              :     Real64 SurfTempInSat;  // Local temporary surface dew point temperature
    7584              : 
    7585              :     Real64 Wsurf;         // Moisture ratio for HAMT
    7586              :     Real64 RhoAirZone;    // Zone moisture density for HAMT
    7587              :     int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
    7588              : 
    7589        48980 :     auto &s_mat = state.dataMaterial;
    7590              :     // determine reference air temperatures
    7591       342844 :     for (int SurfNum : HTSurfs) {
    7592              : 
    7593              :         // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
    7594       293864 :         if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome)
    7595            0 :             continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7596       293864 :         Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
    7597       293864 :         state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
    7598       293864 :         state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
    7599              :     }
    7600              : 
    7601              :     // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    7602              :     // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    7603              :     // CalcWindowHeatBalance.
    7604              :     // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    7605        48980 :     for (int surfNum : HTWindowSurfs) {
    7606            0 :         state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    7607            0 :         state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    7608            0 :         state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    7609            0 :         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    7610            0 :         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    7611            0 :         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    7612            0 :         state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    7613            0 :         state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    7614            0 :         state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    7615            0 :         state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    7616            0 :         state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    7617            0 :         state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    7618            0 :         state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    7619              :     }
    7620              : 
    7621        48980 :     state.dataHeatBal->InsideSurfIterations = 0;
    7622              : 
    7623              :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    7624        48980 :     for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    7625            0 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    7626            0 :             state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
    7627              :     }
    7628              : 
    7629              :     // Calculate Kiva instances
    7630        48980 :     if (state.dataHeatBal->AnyKiva) {
    7631            0 :         if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
    7632            0 :               state.dataGlobal->TimeStep == 1) ||
    7633            0 :              state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
    7634            0 :             !state.dataGlobal->WarmupFlag) {
    7635            0 :             state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
    7636              :         }
    7637              :     }
    7638              : 
    7639        48980 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    7640       148861 :     while (!Converged) {    // Start of main inside heat balance DO loop...
    7641              : 
    7642        99881 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    7643              : 
    7644        99881 :         if (state.dataHeatBal->AnyKiva) {
    7645            0 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7646            0 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
    7647              :             }
    7648              :         }
    7649              : 
    7650       199762 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    7651        99881 :                                                            state.dataHeatBalSurf->SurfTempIn,
    7652        99881 :                                                            state.dataHeatBal->InsideSurfIterations,
    7653        99881 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    7654              :                                                            ZoneToResimulate,
    7655              :                                                            Inside); // Update the radiation balance
    7656              : 
    7657        99881 :         if (state.dataHeatBal->AnyKiva) {
    7658            0 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7659            0 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
    7660              :             }
    7661              :         }
    7662              : 
    7663              :         // Every 30 iterations, recalculate the inside convection coefficients in case
    7664              :         // there has been a significant drift in the surface temperatures predicted.
    7665              :         // This is not fool-proof and it basically means that the outside surface
    7666              :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    7667              :         // The choice of 30 is not significant--just want to do this a couple of
    7668              :         // times before the iteration limit is hit.
    7669       150782 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    7670        50901 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    7671           16 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    7672              :         }
    7673              : 
    7674        99881 :         if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    7675            0 :             for (int SurfNum : HTSurfs) {
    7676            0 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    7677            0 :                 if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)
    7678            0 :                     continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7679              : 
    7680              :                 // Calculate the inside surface moisture quantities
    7681              :                 // calculate the inside surface moisture transfer conditions
    7682              :                 // check for saturation conditions of air
    7683            0 :                 if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
    7684            0 :                     (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
    7685            0 :                     int ZoneNum = surface.Zone;
    7686            0 :                     Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    7687            0 :                     Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
    7688            0 :                     Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    7689              : 
    7690            0 :                     state.dataMstBal->RhoVaporAirIn(SurfNum) =
    7691            0 :                         min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
    7692              :                             Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
    7693            0 :                     state.dataMstBal->HMassConvInFD(SurfNum) =
    7694            0 :                         HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
    7695            0 :                                         Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
    7696              :                 }
    7697              :             }
    7698              :         }
    7699              : 
    7700       699129 :         for (int SurfNum : HTNonWindowSurfs) {
    7701              :             // Perform heat balance on the inside face of the surface ...
    7702              :             // The following are possibilities here:
    7703              :             //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    7704              :             //   (b) the surface is a partition, in which case the temperature of both sides are the same
    7705              :             //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    7706              :             //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    7707              :             //   (e) standard opaque surface with movable insulation, special two-part equation
    7708              :             // In the surface calculation there are the following Algorithm types for opaque surfaces that
    7709              :             // do not have movable insulation:
    7710              :             //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    7711              :             //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    7712              :             //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    7713              :             //   (d) the HAMT calc (solutionalgo = UseHAMT).
    7714              : 
    7715       599248 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    7716       599248 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    7717            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    7718            0 :                 if (SurfNum != repSurfNum) continue;
    7719              :             }
    7720       599248 :             int const ZoneNum = surface.Zone;
    7721       599248 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7722       599248 :             int const ConstrNum = surface.Construction;
    7723       599248 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    7724       599248 :             Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    7725       599248 :             Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7726              : 
    7727       599248 :             if (surface.ExtBoundCond == SurfNum) {
    7728              :                 // CR6869 -- let Window HB take care of it      IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
    7729              :                 // Surface is adiabatic
    7730        99862 :                 if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7731        99862 :                     surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    7732              : 
    7733            0 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7734            0 :                         MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    7735            0 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    7736              :                     }
    7737              :                     // Pre-calculate a few terms
    7738              :                     Real64 const TempTerm(
    7739            0 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    7740            0 :                         state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    7741            0 :                         HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    7742            0 :                         state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    7743            0 :                         (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    7744            0 :                     Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    7745              :                     // Calculate the current inside surface temperature
    7746            0 :                     if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    7747            0 :                         ((state.dataSurface->SurfIsPool(SurfNum)) &&
    7748            0 :                          (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    7749            0 :                          (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    7750            0 :                         if (construct.SourceSinkPresent) {
    7751            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7752            0 :                                 (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    7753            0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7754              :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7755              :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7756              :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7757              :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7758              :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7759              :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7760              :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7761              :                         } else {
    7762            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7763            0 :                                 (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7764              :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7765              :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7766              :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7767              :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7768              :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7769              :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7770              :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7771              :                         }
    7772              :                     } else { // this is a pool and it has been simulated this time step
    7773            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7774            0 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    7775            0 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
    7776            0 :                             (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    7777              :                              DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
    7778              :                         // non-pool equation for details) | Iterative damping term (for stability) |
    7779              :                         // Conduction term (both partition sides same temp) | Pool and damping term
    7780              :                     }
    7781            0 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7782            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    7783            0 :                             state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
    7784              :                         // Conduction term (both partition sides same temp) |
    7785              :                         // Convection and damping term
    7786            0 :                         if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    7787            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    7788              :                         }
    7789              :                     }
    7790              :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    7791            0 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
    7792            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7793            0 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    7794            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    7795            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    7796              : 
    7797            0 :                     if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    7798              : 
    7799              :                         // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
    7800            0 :                         Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
    7801            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    7802            0 :                             TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
    7803              :                         // radiation from internal sources | Convection from surface to zone air | Radiant flux from
    7804              :                         // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
    7805              :                         // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
    7806              :                         // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
    7807              :                         // term (both partition sides same temp) | Convection and damping term
    7808            0 :                         state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    7809              :                             0.0; // The outside temp is assumed to be equal to the inside temp for a partition
    7810            0 :                         state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    7811            0 :                             construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
    7812              :                         // term (both partition sides same temp) | Convection and damping term
    7813              :                     }
    7814              : 
    7815        99862 :                 } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7816            0 :                            surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7817              : 
    7818        99862 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)
    7819            0 :                         HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
    7820              :                                                                   SurfNum,
    7821            0 :                                                                   state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
    7822              :                                                                   TempSurfOutTmp); // HAMT
    7823              : 
    7824        99862 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7825       199724 :                         HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    7826        99862 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    7827              :                     }
    7828              : 
    7829        99862 :                     TH11 = TempSurfOutTmp;
    7830              :                 }
    7831              : 
    7832        99862 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    7833              : 
    7834              :             } else { // Standard surface or interzone surface
    7835       499386 :                 bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
    7836       499386 :                 if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
    7837              : 
    7838       499386 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7839       499310 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    7840              : 
    7841           76 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7842            0 :                             MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    7843            0 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    7844              :                         }
    7845              :                         // Pre-calculate a few terms
    7846              :                         Real64 const TempTerm(
    7847           76 :                             state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    7848           76 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    7849           76 :                             HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    7850           76 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    7851           76 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    7852           76 :                         Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    7853              :                         // Calculate the current inside surface temperature
    7854           76 :                         if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    7855            0 :                             ((state.dataSurface->SurfIsPool(SurfNum)) &&
    7856            0 :                              (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    7857            0 :                              (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    7858           76 :                             if (construct.SourceSinkPresent) {
    7859            0 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7860            0 :                                     (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    7861            0 :                                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    7862            0 :                                      construct.CTFCross[0] * TH11) *
    7863              :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    7864              :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    7865              :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    7866              :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    7867              :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    7868              :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    7869              :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    7870              :                                 // Radiation from AFN ducts
    7871              :                             } else {
    7872           76 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7873           76 :                                     (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    7874           76 :                                      construct.CTFCross[0] * TH11) *
    7875              :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    7876              :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    7877              :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    7878              :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    7879              :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    7880              :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    7881              :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    7882              :                                 // Radiation from AFN ducts
    7883              :                             }
    7884              :                         } else { // surface is a pool and the pool has been simulated this time step
    7885            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7886            0 :                                 (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    7887            0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
    7888            0 :                                 (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    7889              :                                  DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
    7890              :                             // (see non-pool equation for details) | Iterative damping term (for
    7891              :                             // stability) | Current conduction from | the outside surface |
    7892              :                             // Coefficient for conduction (current time) | Pool and damping term
    7893              :                         }
    7894           76 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7895            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    7896            0 :                                 state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
    7897              :                                 TempDiv; // Coefficient for conduction (current time) | Convection and damping term
    7898            0 :                             if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    7899            0 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    7900              :                             }
    7901              :                         }
    7902              :                         // if any mixed heat transfer models in zone, apply limits to CTF result
    7903           76 :                         if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
    7904            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
    7905              :                                 DataHeatBalSurface::MinSurfaceTempLimit,
    7906            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    7907            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    7908              : 
    7909           76 :                         if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    7910              : 
    7911              :                             // Radiant system does not need the damping coefficient terms (hopefully)
    7912            0 :                             Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
    7913            0 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    7914            0 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    7915              :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    7916              :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    7917              :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    7918              :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    7919              :                             // sides same temp) | Convection and damping term
    7920            0 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    7921            0 :                                 construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
    7922              :                             // Cond term (both partition sides same temp) |
    7923              :                             // Convection and damping term
    7924            0 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    7925            0 :                                 construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
    7926              :                             // partition sides same temp) | Convection and
    7927              :                             // damping term
    7928              : 
    7929            0 :                             if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    7930              :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    7931              :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    7932              :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    7933              :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    7934            0 :                                 if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
    7935            0 :                                     int OtherSideSurfNum = surface.ExtBoundCond;
    7936            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    7937            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    7938            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    7939            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    7940            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    7941            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    7942            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    7943            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    7944            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
    7945            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    7946            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
    7947            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    7948              :                                 }
    7949              :                             }
    7950              :                         }
    7951              : 
    7952       499386 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7953            0 :                                surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7954              : 
    7955       499310 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7956            0 :                             if (surface.ExtBoundCond > 0) {
    7957              :                                 // HAMT get the correct other side zone zone air temperature --
    7958            0 :                                 int OtherSideSurfNum = surface.ExtBoundCond;
    7959              :                                 // ZoneNum = surface.Zone;
    7960            0 :                                 OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
    7961            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7962            0 :                                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
    7963              :                             }
    7964            0 :                             HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    7965              :                         }
    7966              : 
    7967       499310 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD)
    7968       998620 :                             HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    7969       499310 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    7970              : 
    7971       499310 :                         TH11 = TempSurfOutTmp;
    7972              : 
    7973       499310 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
    7974              :                         // Read Kiva results for each surface
    7975            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7976            0 :                             state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
    7977              : 
    7978            0 :                         TH11 = 0.0;
    7979              :                     }
    7980              : 
    7981       499386 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    7982              : 
    7983              :                 } else { // Movable insulation present
    7984            0 :                     Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
    7985            0 :                     if (construct.SourceSinkPresent) {
    7986              : 
    7987            0 :                         ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
    7988            0 :                         ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    7989            0 :                         ShowContinueError(state,
    7990            0 :                                           format("interior movable insulation {} for a surface with that construction.",
    7991            0 :                                                  s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
    7992            0 :                         ShowContinueError(state,
    7993              :                                           "This is not currently allowed because the heat balance equations do not currently accommodate "
    7994              :                                           "this combination.");
    7995            0 :                         ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    7996              :                     }
    7997              : 
    7998            0 :                     Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
    7999              : 
    8000            0 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) =
    8001            0 :                         (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    8002            0 :                          construct.CTFCross[0] * TH11 +
    8003            0 :                          F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    8004            0 :                                HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8005            0 :                                state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    8006            0 :                                state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    8007            0 :                                DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
    8008            0 :                         (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8009              : 
    8010            0 :                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8011            0 :                         (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    8012            0 :                          HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
    8013            0 :                          state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
    8014              :                         (HMovInsul);
    8015              :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    8016            0 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
    8017            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8018            0 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    8019            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8020            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8021              :                 }
    8022              :             }
    8023              :         }
    8024        99881 :         for (int SurfNum : HTWindowSurfs) {
    8025            0 :             auto &surface = state.dataSurface->Surface(SurfNum);
    8026            0 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8027            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    8028            0 :                 if (SurfNum != repSurfNum) continue;
    8029              :             }
    8030            0 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8031            0 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
    8032            0 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8033            0 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8034              :                 // Lookup up the TDD:DOME object
    8035            0 :                 int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8036            0 :                 int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8037              :                 // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8038            0 :                 Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8039              : 
    8040              :                 // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8041              :                 // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8042              :                 //   = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
    8043            0 :                 Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    8044            0 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8045            0 :                     (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    8046            0 :                      state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8047            0 :                      state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    8048            0 :                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8049            0 :                      Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8050            0 :                     (Ueff + HConvIn_surf +
    8051              :                      DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8052              :                                                          // solar | Convection from surface to zone air | Net radiant exchange with
    8053              :                                                          // other zone surfaces | Iterative damping term (for stability) | Current
    8054              :                                                          // conduction from the outside surface | Coefficient for conduction (current
    8055              :                                                          // time) | Convection and damping term
    8056            0 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8057              : 
    8058            0 :                 Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
    8059              : 
    8060              :                 // fill out report vars for components of Window Heat Gain
    8061            0 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
    8062            0 :                     HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
    8063            0 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
    8064            0 :                     state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8065            0 :                     (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
    8066            0 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
    8067            0 :                     state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8068            0 :                         (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8069            0 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
    8070              : 
    8071              :                 // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8072            0 :                 state.dataSurface->SurfWinHeatGain(SurfNum) =
    8073            0 :                     state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
    8074            0 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
    8075            0 :                     surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
    8076              :                 // Net transmitted solar | Convection | IR exchange | IR
    8077              :                 // Zone diffuse interior shortwave reflected back into the TDD
    8078              : 
    8079              :             } else {                                                // Regular window
    8080            0 :                 if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8081              :                     // Get outside convection coeff for exterior window here to avoid calling
    8082              :                     // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8083              :                     // (HeatBalanceSurfaceManager USEing and WindowManager and
    8084              :                     // WindowManager USEing HeatBalanceSurfaceManager)
    8085            0 :                     if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8086            0 :                         auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
    8087            0 :                         Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8088            0 :                         Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8089            0 :                         DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
    8090            0 :                         if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8091              :                             // Exterior shade in place
    8092            0 :                             int const ConstrNumSh = surface.activeShadedConstruction;
    8093            0 :                             if (ConstrNumSh != 0) {
    8094            0 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    8095            0 :                                 auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
    8096            0 :                                 assert(thisMaterial2 != nullptr);
    8097            0 :                                 RoughSurf = thisMaterial2->Roughness;
    8098            0 :                                 EmisOut = thisMaterial2->AbsorpThermal;
    8099              :                             }
    8100              :                         }
    8101              : 
    8102              :                         // Get the outside effective emissivity for Equivalent layer model
    8103            0 :                         if (construct.WindowTypeEQL) {
    8104            0 :                             EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    8105              :                         }
    8106              :                         // Set Exterior Convection Coefficient...
    8107            0 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8108              : 
    8109            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8110              : 
    8111            0 :                         } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    8112              : 
    8113              :                             // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    8114              :                             // subroutine)
    8115            0 :                             Convect::InitExtConvCoeff(state,
    8116              :                                                       SurfNum,
    8117              :                                                       0.0,
    8118              :                                                       RoughSurf,
    8119              :                                                       EmisOut,
    8120              :                                                       TH11,
    8121            0 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8122            0 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8123            0 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8124            0 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8125            0 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8126              : 
    8127            0 :                             if (state.dataEnvrn->IsRain) {                             // Raining: since wind exposed, outside window surface gets wet
    8128            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
    8129              :                             }
    8130              : 
    8131              :                         } else { // Not Wind exposed
    8132              : 
    8133              :                             // Calculate exterior heat transfer coefficients for windspeed = 0
    8134            0 :                             Convect::InitExtConvCoeff(state,
    8135              :                                                       SurfNum,
    8136              :                                                       0.0,
    8137              :                                                       RoughSurf,
    8138              :                                                       EmisOut,
    8139              :                                                       TH11,
    8140            0 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8141            0 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8142            0 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8143            0 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8144            0 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8145              :                         }
    8146              :                     } else { // Interior Surface
    8147              : 
    8148            0 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8149            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8150              :                         } else {
    8151              :                             // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    8152              :                             // same
    8153            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    8154              :                         }
    8155              :                     }
    8156              : 
    8157              :                     // Following call determines inside surface temperature of glazing, and of
    8158              :                     // frame and/or divider, if present
    8159            0 :                     Window::CalcWindowHeatBalance(
    8160            0 :                         state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
    8161            0 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8162              :                 }
    8163              :             }
    8164              :         } // ...end of inside surface heat balance equation selection
    8165              : 
    8166       699129 :         for (int SurfNum : HTSurfs) {
    8167       599248 :             int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
    8168       599248 :             auto &zone = state.dataHeatBal->Zone(ZoneNum);
    8169       599248 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8170       599248 :             Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    8171       599248 :             TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8172       599248 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
    8173       599248 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) continue;
    8174       599248 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8175              :                 // Tubular daylighting devices are treated as one big object with an effective R value.
    8176              :                 // The outside face temperature of the TDD:DOME and the inside face temperature of the
    8177              :                 // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    8178              :                 // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    8179              :                 // and the outside face of the TDD:DIFFUSER for reporting.
    8180              : 
    8181              :                 // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    8182            0 :                 int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    8183            0 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    8184            0 :                     state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8185              : 
    8186              :                 // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    8187              :                 // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    8188            0 :                 TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    8189            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    8190              :             }
    8191              : 
    8192       599248 :             if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8193            0 :                 TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    8194              :             }
    8195              : 
    8196              :         } // ...end of main loops over all surfaces for inside heat balances
    8197              : 
    8198              :         // Interzone surface updating: interzone surfaces have other side temperatures
    8199              :         // which can vary as the simulation iterates through the inside heat
    8200              :         // balance.  This block is intended to "lock" the opposite side (outside)
    8201              :         // temperatures to the correct value, namely the value calculated by the
    8202              :         // inside surface heat balance for the other side.
    8203              :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    8204              :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    8205        99881 :         for (int SurfNum : IZSurfs) {
    8206            0 :             int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
    8207              :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    8208              :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    8209              :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    8210              :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    8211            0 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    8212            0 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    8213              :         }
    8214              : 
    8215        99881 :         ++state.dataHeatBal->InsideSurfIterations;
    8216              : 
    8217              :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    8218        99881 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    8219       699129 :         for (int SurfNum : HTNonWindowSurfs) {
    8220       599248 :             MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
    8221       599248 :             if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8222              :                 // also check all internal nodes as well as surface faces
    8223       599172 :                 MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
    8224              :             }
    8225              :         } // ...end of loop to check for convergence
    8226              : 
    8227        99881 :         if (!state.dataHeatBal->AnyCondFD) {
    8228           19 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) Converged = true;
    8229              :         } else {
    8230        99862 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) Converged = true;
    8231              : 
    8232              :             // resets relaxation factor to speed up iterations when under-relaxation is not needed.
    8233        99862 :             if (state.dataHeatBal->InsideSurfIterations <= 1) {
    8234        48972 :                 state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    8235              :             }
    8236        99862 :             if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
    8237              :                 // adjust relaxation factor down, assume large number of iterations is result of instability
    8238          492 :                 state.dataHeatBal->CondFDRelaxFactor *= 0.9;
    8239          492 :                 if (state.dataHeatBal->CondFDRelaxFactor < 0.1) state.dataHeatBal->CondFDRelaxFactor = 0.1;
    8240              :             }
    8241              :         }
    8242              : 
    8243              : #ifdef EP_Count_Calls
    8244              :         state.dataTimingsData->NumMaxInsideSurfIterations =
    8245              :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    8246              : #endif
    8247              : 
    8248        99881 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) Converged = false;
    8249              : 
    8250        99881 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    8251            0 :             if (!state.dataGlobal->WarmupFlag) {
    8252            0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    8253            0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    8254            0 :                     if (!state.dataHeatBal->AnyCondFD) {
    8255            0 :                         ShowWarningError(state,
    8256            0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8257              :                                                 "Allowed Temp Diff [C] ={:.3R}",
    8258              :                                                 MaxDelTemp,
    8259            0 :                                                 state.dataHeatBal->MaxAllowedDelTemp));
    8260            0 :                         ShowContinueErrorTimeStamp(state, "");
    8261              :                     } else {
    8262            0 :                         ShowWarningError(state,
    8263            0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8264              :                                                 "Allowed Temp Diff [C] ={:.6R}",
    8265              :                                                 MaxDelTemp,
    8266            0 :                                                 state.dataHeatBal->MaxAllowedDelTempCondFD));
    8267            0 :                         ShowContinueErrorTimeStamp(state, "");
    8268              :                     }
    8269              :                 } else {
    8270            0 :                     ShowRecurringWarningErrorAtEnd(state,
    8271              :                                                    "Inside surface heat balance convergence problem continues",
    8272            0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    8273              :                                                    MaxDelTemp,
    8274              :                                                    MaxDelTemp,
    8275              :                                                    _,
    8276              :                                                    "[C]",
    8277              :                                                    "[C]");
    8278              :                 }
    8279              :             }
    8280            0 :             break; // iteration loop
    8281              :         }
    8282              : 
    8283              :     } // ...end of main inside heat balance DO loop (ends when Converged)
    8284              : 
    8285              :     // Update SumHmXXXX for non-window EMPD or HAMT surfaces
    8286        48980 :     if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    8287              : 
    8288              :         // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
    8289            0 :         for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
    8290            0 :             thisZoneHB.SumHmAW = 0.0;
    8291            0 :             thisZoneHB.SumHmARa = 0.0;
    8292            0 :             thisZoneHB.SumHmARaW = 0.0;
    8293              :         }
    8294              : 
    8295            0 :         for (int SurfNum : HTNonWindowSurfs) {
    8296            0 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    8297            0 :             int ZoneNum = surface.Zone;
    8298            0 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    8299              : 
    8300            0 :             if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8301            0 :                 HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
    8302              : 
    8303            0 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8304              : 
    8305            0 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8306              : 
    8307            0 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
    8308            0 :                 RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
    8309              :                     state,
    8310            0 :                     state.dataEnvrn->OutBaroPress,
    8311              :                     MAT_zone,
    8312            0 :                     Psychrometrics::PsyWFnTdbRhPb(
    8313              :                         state,
    8314              :                         MAT_zone,
    8315            0 :                         Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
    8316            0 :                         state.dataEnvrn->OutBaroPress));
    8317              : 
    8318            0 :                 Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
    8319              :                 Wsurf =
    8320            0 :                     Psychrometrics::PsyWFnTdbRhPb(state,
    8321              :                                                   surfInTemp,
    8322            0 :                                                   Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
    8323            0 :                                                   state.dataEnvrn->OutBaroPress);
    8324              : 
    8325            0 :                 thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
    8326              : 
    8327            0 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
    8328              : 
    8329            0 :             } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8330              :                 // need to calculate the amount of moisture that is entering or
    8331              :                 // leaving the zone  Qm [kg/sec] = hmi * Area * (Del Rhov)
    8332              :                 // {Hmi [m/sec];     Area [m2];    Rhov [kg moist/m3]  }
    8333              :                 // Positive values are into the zone and negative values are
    8334              :                 // leaving the zone.  SumHmAw is the sum of the moisture entering or
    8335              :                 // leaving the zone from all of the surfaces and is a rate.  Multiply
    8336              :                 // by time to get the actual amount affecting the zone volume of air.
    8337              : 
    8338            0 :                 MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
    8339            0 :                 state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
    8340            0 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8341            0 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8342            0 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    8343            0 :                 thisZoneHB.SumHmARa +=
    8344            0 :                     FD_Area_fac *
    8345            0 :                     Psychrometrics::PsyRhoAirFnPbTdbW(
    8346              :                         state,
    8347            0 :                         state.dataEnvrn->OutBaroPress,
    8348              :                         MAT_zone,
    8349            0 :                         Psychrometrics::PsyWFnTdbRhPb(state,
    8350              :                                                       MAT_zone,
    8351            0 :                                                       Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
    8352            0 :                                                       state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
    8353              :                 // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
    8354            0 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
    8355              :             }
    8356              :         }
    8357              :     }
    8358        48980 : }
    8359              : 
    8360       200983 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
    8361              :                                        const int FirstZone,             // First zone to simulate
    8362              :                                        const int LastZone,              // Last zone to simulate
    8363              :                                        const std::vector<int> &IZSurfs, // Last zone to simulate
    8364              :                                        ObjexxFCL::Optional_int_const ZoneToResimulate)
    8365              : {
    8366              : 
    8367              :     // This function performs a heat balance on the inside face of each
    8368              :     // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
    8369              :     // simplified for CTF surfaces only.
    8370              : 
    8371              :     // REFERENCES:
    8372              :     // (I)BLAST legacy routine HBSRF
    8373              : 
    8374       200983 :     auto &s_mat = state.dataMaterial;
    8375       200983 :     auto &Surface = state.dataSurface->Surface;
    8376              : 
    8377       200983 :     constexpr std::string_view Inside("Inside");
    8378              : 
    8379       200983 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
    8380              :         // Set up coefficient arrays that never change - loop over non-window HT surfaces
    8381          231 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8382          270 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8383          144 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8384          144 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8385          144 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8386          854 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8387          710 :                     int const ConstrNum = Surface(surfNum).Construction;
    8388          710 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8389          710 :                     if (Surface(surfNum).ExtBoundCond == surfNum) {
    8390          143 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
    8391              :                     } else {
    8392          567 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
    8393              :                     }
    8394          710 :                     if (construct.SourceSinkPresent) {
    8395            0 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
    8396              :                     } else {
    8397          710 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
    8398              :                     }
    8399              :                 }
    8400              :             }
    8401              :         }
    8402              : 
    8403          105 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
    8404              :     }
    8405              : 
    8406       488661 :     for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8407       611667 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8408       323989 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8409              :             // loop over all heat transfer surface except TDD Dome.
    8410       323989 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    8411       323989 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    8412              :             // determine reference air temperatures and other variable terms - loop over all surfaces
    8413      2104462 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8414      1780473 :                 auto const &surface = Surface(surfNum);
    8415      1780473 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8416            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8417            0 :                     if (surfNum != repSurfNum) continue;
    8418              :                 }
    8419              : 
    8420      1780473 :                 int const ConstrNum = Surface(surfNum).Construction;
    8421      1780473 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8422      1780473 :                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
    8423      1780473 :                 state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
    8424      1780473 :                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
    8425      1780473 :                 state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    8426      1780473 :                 if (construct.SourceSinkPresent) {
    8427            0 :                     state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
    8428              :                 }
    8429              : 
    8430              :                 // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
    8431      1780473 :                 if (state.dataSurface->SurfIsPool(surfNum)) {
    8432            0 :                     if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
    8433            0 :                         (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
    8434            0 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
    8435              :                     } else {
    8436            0 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
    8437              :                     }
    8438              :                 }
    8439      1780473 :                 Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
    8440      1780473 :                 state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
    8441      1780473 :                 state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
    8442              :             }
    8443              : 
    8444              :             // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    8445              :             // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    8446              :             // CalcWindowHeatBalance.
    8447              :             // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    8448       323989 :             int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8449       323989 :             int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8450       412551 :             for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8451        88562 :                 state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    8452        88562 :                 state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    8453        88562 :                 state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    8454        88562 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    8455        88562 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    8456        88562 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    8457        88562 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    8458        88562 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    8459        88562 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    8460        88562 :                 state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    8461        88562 :                 state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    8462        88562 :                 state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    8463        88562 :                 state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    8464              :             }
    8465              : 
    8466              :             // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    8467       323990 :             for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    8468            1 :                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    8469            1 :                     state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
    8470              :             }
    8471              : 
    8472              :             // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
    8473       323989 :             int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8474       323989 :             int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8475       323989 :             Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8476       323989 :             Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8477              :             // this loop auto-vectorizes
    8478      2015900 :             for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8479      1691911 :                 auto const &surface = Surface(surfNum);
    8480      1691911 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8481            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8482            0 :                     if (surfNum != repSurfNum) continue;
    8483              :                 }
    8484              : 
    8485              :                 // Pre-calculate a few terms before the iteration loop
    8486      1691911 :                 state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8487      1691911 :                     state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8488      1691911 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8489      1691911 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8490      1691911 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8491      1691911 :                     (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8492      1691911 :                 state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8493      1691911 :                     1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8494      1691911 :                            state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8495      1691911 :                            state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8496      1691911 :                            (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
    8497              :             }
    8498              :         }
    8499              :     }
    8500              : 
    8501       200983 :     state.dataHeatBal->InsideSurfIterations = 0;
    8502       200983 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    8503       978994 :     while (!Converged) {    // Start of main inside heat balance iteration loop...
    8504              : 
    8505       778011 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    8506              : 
    8507      1556022 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    8508       778011 :                                                            state.dataHeatBalSurf->SurfTempIn,
    8509       778011 :                                                            state.dataHeatBal->InsideSurfIterations,
    8510       778011 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    8511              :                                                            ZoneToResimulate,
    8512              :                                                            Inside); // Update the radiation balance
    8513              : 
    8514              :         // Every 30 iterations, recalculate the inside convection coefficients in case
    8515              :         // there has been a significant drift in the surface temperatures predicted.
    8516              :         // This is not fool-proof and it basically means that the outside surface
    8517              :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    8518              :         // The choice of 30 is not significant--just want to do this a couple of
    8519              :         // times before the iteration limit is hit.
    8520      1355039 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    8521       577028 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    8522          139 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    8523              :             // Since HConvIn has changed re-calculate a few terms - non-window surfaces
    8524          313 :             for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8525          348 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8526          174 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8527          174 :                     int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8528          174 :                     int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8529              : 
    8530          174 :                     Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8531          174 :                     Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8532              :                     // this loop auto-vectorizes
    8533         1258 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8534         1084 :                         auto const &surface = Surface(surfNum);
    8535         1084 :                         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8536            0 :                             int repSurfNum = surface.RepresentativeCalcSurfNum;
    8537            0 :                             if (surfNum != repSurfNum) continue;
    8538              :                         }
    8539              : 
    8540         1084 :                         state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8541         1084 :                             state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8542         1084 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8543         1084 :                             state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8544         1084 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8545         1084 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8546         1084 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8547         1084 :                             1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8548         1084 :                                    state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8549         1084 :                                    state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8550         1084 :                                    (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
    8551              :                                    iterDampConstant);
    8552              :                     }
    8553              :                 }
    8554              :             }
    8555              :         }
    8556              : 
    8557              :         // Loop over non-window surfaces
    8558      1926310 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8559      2401033 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8560      1252734 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8561      1252734 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8562      1252734 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8563      1252734 :                 Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
    8564              :                 // this loop auto-vectorizes
    8565      8063886 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8566              :                     // Perform heat balance on the inside face of the surface ...
    8567              :                     // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
    8568              :                     //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    8569              :                     //   (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
    8570              :                     //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    8571              :                     //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    8572              :                     //   (e) standard opaque surface with movable insulation, special two-part equation
    8573              :                     // In the surface calculation there are the following Algorithm types for opaque surfaces that
    8574              :                     // do not have movable insulation:
    8575              :                     //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    8576              :                     //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    8577              :                     //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    8578              :                     //   (d) the HAMT calc (solutionalgo = UseHAMT).
    8579              : 
    8580              :                     // For adiabatic surface:
    8581              :                     // Adiabatic:   TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
    8582              :                     // Adiabatic:   SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8583              :                     // Ad+Source:   SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
    8584              :                     // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool:     TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
    8585              :                     // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool:     SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
    8586              :                     // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8587              : 
    8588              :                     // For standard or interzone surface:
    8589              :                     // Standard:    TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
    8590              :                     // Standard:    SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
    8591              :                     // TempDiv; Std+Source:  SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
    8592              :                     // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool:    TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
    8593              :                     // IterDampConst); Std+Pool:    SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
    8594              :                     // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
    8595              : 
    8596              :                     // Composite with Adiabatic/Source/Pool flags:
    8597              :                     //              TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
    8598              :                     //              SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
    8599              :                     //              SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
    8600              :                     //              SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
    8601              :                     //                                        + IterDampConst * SurfTempInsOld(SurfNum)+
    8602              :                     //                                        IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
    8603              :                     //                                        * TH11) * TempDiv;
    8604              : 
    8605              :                     // Calculate the current inside surface temperature
    8606      6811152 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8607      6811152 :                         ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
    8608      6811152 :                              (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
    8609      6811152 :                          state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
    8610      6811152 :                              state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
    8611      6811152 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
    8612      6811152 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
    8613      6811152 :                          iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8614      6811152 :                          (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
    8615      6811152 :                              state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
    8616      6811152 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum);
    8617              :                     // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8618              :                     // radiation from internal sources | Convection from surface to zone air | Net radiant
    8619              :                     // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
    8620              :                     // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
    8621              :                     // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
    8622              :                     // an electric baseboard heater | Iterative damping term (for stability) | Current
    8623              :                     // conduction from | the outside surface | Coefficient for conduction (current time) |
    8624              :                     // Convection and damping term | Radiation from AFN ducts
    8625              : 
    8626      6811152 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8627              :                 }
    8628              : 
    8629              :                 // Loop over non-window surfaces (includes TubularDaylightingDomes)
    8630      8063886 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8631      6811152 :                     auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
    8632              : 
    8633      6811152 :                     bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
    8634      6811152 :                     if (movableInsulPresent) { // Movable insulation present, recalc surface temps
    8635            0 :                         Real64 HMovInsul = movInsul.H;
    8636            0 :                         Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
    8637            0 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) =
    8638            0 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8639            0 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
    8640            0 :                              F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8641            0 :                                    state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8642            0 :                                    state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8643            0 :                                    state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8644            0 :                                    state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8645            0 :                                    DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
    8646            0 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8647              : 
    8648            0 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8649            0 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
    8650            0 :                              HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
    8651            0 :                              state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
    8652            0 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
    8653              :                             (HMovInsul);
    8654              :                     }
    8655              : 
    8656      6811152 :                     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    8657            0 :                         if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
    8658              :                             // Set the appropriate parameters for the radiant system
    8659              :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8660              :                             Real64 const RadSysDiv(1.0 /
    8661            0 :                                                    (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    8662              :                             Real64 const TempTerm(
    8663            0 :                                 state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8664            0 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8665            0 :                                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8666            0 :                                 state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8667            0 :                                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8668            0 :                                 (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
    8669            0 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
    8670            0 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8671              :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8672              :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8673              :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8674              :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8675              :                             // sides same temp) | Convection and damping term
    8676            0 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
    8677            0 :                                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
    8678              :                             // Cond term (both partition sides same temp) |
    8679              :                             // Convection and damping term
    8680            0 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
    8681            0 :                                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
    8682              :                             // partition sides same temp) | Convection and
    8683              :                             // damping term
    8684              : 
    8685            0 :                             if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8686              :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8687              :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8688              :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8689              :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8690            0 :                                 if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
    8691            0 :                                     int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
    8692            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8693            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
    8694            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8695            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
    8696            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8697            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
    8698            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
    8699            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8700            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
    8701            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8702            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
    8703            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8704              :                                 }
    8705              :                             }
    8706              :                         }
    8707              :                     }
    8708              :                 }
    8709              : 
    8710              :                 // Loop over window surfaces
    8711      1252734 :                 int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8712      1252734 :                 int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8713      1632492 :                 for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8714       379758 :                     auto &surface = state.dataSurface->Surface(surfNum);
    8715       379758 :                     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8716            0 :                         int repSurfNum = surface.RepresentativeCalcSurfNum;
    8717            0 :                         if (surfNum != repSurfNum) continue;
    8718              :                     }
    8719       379758 :                     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
    8720       379758 :                     int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    8721       379758 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8722       379758 :                     if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8723              :                         // Lookup up the TDD:DOME object
    8724            2 :                         int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    8725            2 :                         int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8726              :                         // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8727            2 :                         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8728              : 
    8729              :                         // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8730              :                         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8731              :                         //   = SurfWinQRadSWwinAbs(surfNum,1)/2.0
    8732            2 :                         Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
    8733            2 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8734            2 :                             (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
    8735            2 :                              state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8736            2 :                              HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8737            2 :                              state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8738            2 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8739            2 :                              Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8740            2 :                             (Ueff + HConvIn_surf +
    8741              :                              DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8742              :                                                                  // solar | Convection from surface to zone air | Net radiant exchange with
    8743              :                                                                  // other zone surfaces | Iterative damping term (for stability) | Current
    8744              :                                                                  // conduction from the outside surface | Coefficient for conduction (current
    8745              :                                                                  // time) | Convection and damping term
    8746            2 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8747            2 :                         Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
    8748              : 
    8749              :                         // fill out report vars for components of Window Heat Gain
    8750            2 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    8751            4 :                             HConvIn_surf * surface.Area *
    8752            2 :                             (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    8753            2 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    8754            2 :                             state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8755            2 :                             (Sigma_Temp_4 -
    8756            2 :                              (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
    8757            2 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    8758            2 :                             state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8759            2 :                                 (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8760            2 :                             state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
    8761              : 
    8762              :                         // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8763            2 :                         state.dataSurface->SurfWinHeatGain(surfNum) =
    8764            2 :                             state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
    8765            2 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
    8766            2 :                             surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
    8767              :                         // Net transmitted solar | Convection | IR exchange | IR
    8768              :                         // Zone diffuse interior shortwave reflected back into the TDD
    8769              :                     } else {                                                // Regular window
    8770       379756 :                         if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8771              :                             // Get outside convection coeff for exterior window here to avoid calling
    8772              :                             // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8773              :                             // (HeatBalanceSurfaceManager USEing and WindowManager and
    8774              :                             // WindowManager USEing HeatBalanceSurfaceManager)
    8775        88560 :                             if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8776        88560 :                                 auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
    8777        88560 :                                 assert(thisMaterial != nullptr);
    8778        88560 :                                 Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8779        88560 :                                 Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8780        88560 :                                 DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
    8781        88560 :                                 if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8782              :                                     // Exterior shade in place
    8783            0 :                                     int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
    8784            0 :                                     if (ConstrNumSh != 0) {
    8785            0 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    8786            0 :                                         auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
    8787            0 :                                         RoughSurf = thisMaterial2->Roughness;
    8788            0 :                                         EmisOut = thisMaterial2->AbsorpThermal;
    8789              :                                     }
    8790              :                                 }
    8791              : 
    8792              :                                 // Get the outside effective emissivity for Equivalent layer model
    8793        88560 :                                 if (construct.WindowTypeEQL) {
    8794         2367 :                                     EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    8795              :                                 }
    8796              :                                 // Set Exterior Convection Coefficient...
    8797        88560 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    8798              : 
    8799            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    8800              : 
    8801        88560 :                                 } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    8802              : 
    8803              :                                     // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    8804              :                                     // subroutine)
    8805        88560 :                                     Convect::InitExtConvCoeff(state,
    8806              :                                                               surfNum,
    8807              :                                                               0.0,
    8808              :                                                               RoughSurf,
    8809              :                                                               EmisOut,
    8810              :                                                               TH11,
    8811        88560 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    8812        88560 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    8813        88560 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    8814        88560 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    8815        88560 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    8816              : 
    8817        88560 :                                     if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    8818            0 :                                         state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
    8819              :                                     }
    8820              : 
    8821              :                                 } else { // Not Wind exposed
    8822              : 
    8823              :                                     // Calculate exterior heat transfer coefficients for windspeed = 0
    8824            0 :                                     Convect::InitExtConvCoeff(state,
    8825              :                                                               surfNum,
    8826              :                                                               0.0,
    8827              :                                                               RoughSurf,
    8828              :                                                               EmisOut,
    8829              :                                                               TH11,
    8830            0 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    8831            0 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    8832            0 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    8833            0 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    8834            0 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    8835              :                                 }
    8836              : 
    8837              :                             } else { // Interior Surface
    8838              : 
    8839            0 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    8840            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    8841              :                                 } else {
    8842              :                                     // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    8843              :                                     // same
    8844            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    8845              :                                 }
    8846              :                             }
    8847              : 
    8848              :                             // Following call determines inside surface temperature of glazing, and of
    8849              :                             // frame and/or divider, if present
    8850        88560 :                             Window::CalcWindowHeatBalance(
    8851        88560 :                                 state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
    8852        88560 :                             state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8853              :                         }
    8854              :                     }
    8855              :                 }
    8856              : 
    8857      1252734 :                 int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    8858      1252734 :                 int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    8859      8443644 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8860      7190910 :                     auto &zone = state.dataHeatBal->Zone(zoneNum);
    8861              : 
    8862      7190910 :                     Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    8863      7190910 :                     Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
    8864      7190910 :                     TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
    8865      7190910 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11;                                                  // For reporting
    8866      7190910 :                     if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8867              :                         // Tubular daylighting devices are treated as one big object with an effective R value.
    8868              :                         // The outside face temperature of the TDD:DOME and the inside face temperature of the
    8869              :                         // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    8870              :                         // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    8871              :                         // and the outside face of the TDD:DIFFUSER for reporting.
    8872              : 
    8873              :                         // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    8874            2 :                         int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
    8875            2 :                         state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    8876            2 :                             state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
    8877              : 
    8878              :                         // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    8879              :                         // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    8880            2 :                         TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    8881            2 :                             state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    8882              :                     }
    8883              : 
    8884      7190910 :                     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8885            0 :                         TestSurfTempCalcHeatBalanceInsideSurf(
    8886            0 :                             state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    8887              :                     }
    8888              :                 }
    8889              :             }
    8890              :         } // ...end of main loops over all surfaces for inside heat balances
    8891              : 
    8892              :         // Interzone surface updating: interzone surfaces have other side temperatures
    8893              :         // which can vary as the simulation iterates through the inside heat
    8894              :         // balance.  This block is intended to "lock" the opposite side (outside)
    8895              :         // temperatures to the correct value, namely the value calculated by the
    8896              :         // inside surface heat balance for the other side.
    8897              :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    8898              :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    8899      1532725 :         for (int SurfNum : IZSurfs) {
    8900       754714 :             int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
    8901              :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    8902              :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    8903              :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    8904              :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    8905       754714 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    8906       754714 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    8907       754714 :             state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
    8908              :         }
    8909              : 
    8910       778011 :         ++state.dataHeatBal->InsideSurfIterations;
    8911              : 
    8912              :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    8913       778011 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    8914      1926310 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8915      2401033 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8916      1252734 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8917      1252734 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8918      1252734 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8919      8063886 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8920      6811152 :                     Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
    8921      6811152 :                     Real64 absDif = std::abs(delta);
    8922      6811152 :                     MaxDelTemp = std::max(absDif, MaxDelTemp);
    8923              :                 }
    8924              :             }
    8925              :         } // ...end of loop to check for convergence
    8926              : 
    8927       778011 :         if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) Converged = true;
    8928              : 
    8929              : #ifdef EP_Count_Calls
    8930              :         state.dataTimingsData->NumMaxInsideSurfIterations =
    8931              :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    8932              : #endif
    8933              : 
    8934       778011 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) Converged = false;
    8935              : 
    8936       778011 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    8937            0 :             if (!state.dataGlobal->WarmupFlag) {
    8938            0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    8939            0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    8940            0 :                     ShowWarningError(state,
    8941            0 :                                      format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
    8942              :                                             "Temp Diff [C] ={:.6R}",
    8943              :                                             MaxDelTemp,
    8944            0 :                                             state.dataHeatBal->MaxAllowedDelTempCondFD));
    8945            0 :                     ShowContinueErrorTimeStamp(state, "");
    8946              :                 } else {
    8947            0 :                     ShowRecurringWarningErrorAtEnd(state,
    8948              :                                                    "Inside surface heat balance convergence problem continues",
    8949            0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    8950              :                                                    MaxDelTemp,
    8951              :                                                    MaxDelTemp,
    8952              :                                                    _,
    8953              :                                                    "[C]",
    8954              :                                                    "[C]");
    8955              :                 }
    8956              :             }
    8957            0 :             break; // iteration loop
    8958              :         }
    8959              : 
    8960              :     } // ...end of main inside heat balance iteration loop (ends when Converged)
    8961       200983 : }
    8962              : 
    8963       249963 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
    8964              : {
    8965       249999 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
    8966           36 :         auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
    8967           36 :         state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
    8968           36 :                                                                    thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
    8969           36 :                                                                    thisSurfQRadFromHVAC.CoolingPanel;
    8970              :     }
    8971       249963 : }
    8972              : 
    8973            5 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
    8974              : {
    8975            5 :     std::string surfName = state.dataSurface->Surface(SurfNum).Name;
    8976              : 
    8977            5 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8978            4 :         if (state.dataGlobal->WarmupFlag) ++WarmupSurfTemp;
    8979            4 :         if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
    8980            4 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
    8981            2 :                 if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
    8982            4 :                     ShowSevereMessage(
    8983            4 :                         state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    8984            4 :                     ShowContinueErrorTimeStamp(state, "");
    8985            2 :                     if (!zone.TempOutOfBoundsReported) {
    8986            1 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    8987            1 :                         if (zone.FloorArea > 0.0) {
    8988            1 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    8989              :                         } else {
    8990            0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    8991              :                         }
    8992            1 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    8993            1 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    8994            1 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    8995              :                         } else {
    8996            0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    8997              :                         }
    8998            1 :                         if (zone.IsControlled) {
    8999            3 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9000              :                         } else {
    9001            0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9002              :                         }
    9003            1 :                         zone.TempOutOfBoundsReported = true;
    9004              :                     }
    9005           18 :                     ShowRecurringSevereErrorAtEnd(state,
    9006            4 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9007            2 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9008              :                                                   TH12,
    9009              :                                                   TH12,
    9010              :                                                   _,
    9011              :                                                   "C",
    9012              :                                                   "C");
    9013              :                 } else {
    9014            0 :                     ShowRecurringSevereErrorAtEnd(state,
    9015            0 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9016            0 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9017              :                                                   TH12,
    9018              :                                                   TH12,
    9019              :                                                   _,
    9020              :                                                   "C",
    9021              :                                                   "C");
    9022              :                 }
    9023              :             } else {
    9024            2 :                 if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
    9025            4 :                     ShowSevereMessage(
    9026            4 :                         state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9027            4 :                     ShowContinueErrorTimeStamp(state, "");
    9028            2 :                     if (!zone.TempOutOfBoundsReported) {
    9029            1 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9030            1 :                         if (zone.FloorArea > 0.0) {
    9031            1 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9032              :                         } else {
    9033            0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9034              :                         }
    9035            1 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9036            1 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9037            1 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9038              :                         } else {
    9039            0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9040              :                         }
    9041            1 :                         if (zone.IsControlled) {
    9042            3 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9043              :                         } else {
    9044            0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9045              :                         }
    9046            1 :                         zone.TempOutOfBoundsReported = true;
    9047              :                     }
    9048           18 :                     ShowRecurringSevereErrorAtEnd(state,
    9049            4 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9050            2 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9051              :                                                   TH12,
    9052              :                                                   TH12,
    9053              :                                                   _,
    9054              :                                                   "C",
    9055              :                                                   "C");
    9056              :                 } else {
    9057            0 :                     ShowRecurringSevereErrorAtEnd(state,
    9058            0 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9059            0 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9060              :                                                   TH12,
    9061              :                                                   TH12,
    9062              :                                                   _,
    9063              :                                                   "C",
    9064              :                                                   "C");
    9065              :                 }
    9066              :             }
    9067            4 :             if (zone.EnforcedReciprocity) {
    9068            0 :                 if (WarmupSurfTemp > 3) {
    9069            0 :                     ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
    9070            0 :                     ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
    9071            0 :                     ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9072              :                 }
    9073            4 :             } else if (WarmupSurfTemp > 10) {
    9074            0 :                 ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9075              :             }
    9076              :         }
    9077              :     }
    9078            5 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
    9079            0 :         if (!state.dataGlobal->WarmupFlag) {
    9080            0 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
    9081            0 :                 ShowSevereError(state,
    9082            0 :                                 format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9083            0 :                 ShowContinueErrorTimeStamp(state, "");
    9084            0 :                 if (!zone.TempOutOfBoundsReported) {
    9085            0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9086            0 :                     if (zone.FloorArea > 0.0) {
    9087            0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9088              :                     } else {
    9089            0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9090              :                     }
    9091            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9092            0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9093            0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9094              :                     } else {
    9095            0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9096              :                     }
    9097            0 :                     if (zone.IsControlled) {
    9098            0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9099              :                     } else {
    9100            0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9101              :                     }
    9102            0 :                     zone.TempOutOfBoundsReported = true;
    9103              :                 }
    9104            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9105              :             } else {
    9106            0 :                 ShowSevereError(state,
    9107            0 :                                 format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9108            0 :                 ShowContinueErrorTimeStamp(state, "");
    9109            0 :                 if (!zone.TempOutOfBoundsReported) {
    9110            0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9111            0 :                     if (zone.FloorArea > 0.0) {
    9112            0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9113              :                     } else {
    9114            0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9115              :                     }
    9116            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9117            0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9118            0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9119              :                     } else {
    9120            0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9121              :                     }
    9122            0 :                     if (zone.IsControlled) {
    9123            0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9124              :                     } else {
    9125            0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9126              :                     }
    9127            0 :                     zone.TempOutOfBoundsReported = true;
    9128              :                 }
    9129            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9130              :             }
    9131              :         } else {
    9132            0 :             if (TH12 < -10000. || TH12 > 10000.) {
    9133            0 :                 ShowSevereError(
    9134              :                     state,
    9135            0 :                     format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9136            0 :                 ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
    9137            0 :                 ShowContinueErrorTimeStamp(state, "");
    9138            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9139              :             }
    9140              :         }
    9141              :     }
    9142            5 : }
    9143              : 
    9144      1053753 : void CalcOutsideSurfTemp(EnergyPlusData &state,
    9145              :                          int const SurfNum,      // Surface number DO loop counter
    9146              :                          int const spaceNum,     // Space number the current surface is attached to
    9147              :                          int const ConstrNum,    // Construction index for the current surface
    9148              :                          Real64 const HMovInsul, // "Convection" coefficient of movable insulation
    9149              :                          Real64 const TempExt,   // Exterior temperature boundary condition
    9150              :                          bool &ErrorFlag         // Error flag for movable insulation problem
    9151              : )
    9152              : {
    9153              : 
    9154              :     // SUBROUTINE INFORMATION:
    9155              :     //       AUTHOR         George Walton
    9156              :     //       DATE WRITTEN   December 1979
    9157              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    9158              :     //                      Jul 2000 (RJL for Moisture algorithms)
    9159              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    9160              :     //                      Dec 2000 (RKS for radiant system model addition)
    9161              :     //                      Aug 2010 (BG added radiant heat flow rate reporting)
    9162              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    9163              : 
    9164              :     // PURPOSE OF THIS SUBROUTINE:
    9165              :     // This subroutine performs a heat balance on the outside face of each
    9166              :     // surface in the building.  NOTE that this also sets some coefficients
    9167              :     // that are needed for radiant system modeling.  Thus, it is extremely
    9168              :     // important that if someone makes changes to the heat balance equations
    9169              :     // at a later date that they must also make changes to the coefficient
    9170              :     // setting portion of this subroutine as well.
    9171              : 
    9172              :     // METHODOLOGY EMPLOYED:
    9173              :     // Various boundary conditions are set and additional parameters are set-
    9174              :     // up.  Then, the proper heat balance equation is selected based on the
    9175              :     // presence of movable insulation, thermal mass of the surface construction,
    9176              :     // and convection model being used.
    9177              : 
    9178              :     // REFERENCES:
    9179              :     // (I)BLAST legacy routine HBOUT
    9180              :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    9181              : 
    9182              :     // Determine whether or not movable insulation is present
    9183      1053753 :     bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
    9184              :     bool QuickConductionSurf;                 // .TRUE. if the cross CTF term is relatively large
    9185              :     Real64 F1;                                // Intermediate calculation variable
    9186              :     Real64 F2;                                // Intermediate calculation variable
    9187              :     // Determine whether this surface is a "slow conductive" or "quick conductive"
    9188              :     // surface.  Designates are inherited from BLAST.  Basically, a "quick" surface
    9189              :     // requires the inside heat balance to be accounted for in the heat balance
    9190              :     // while a "slow" surface can used the last time step's value for inside
    9191              :     // surface temperature.
    9192      1053753 :     auto &s_mat = state.dataMaterial;
    9193              : 
    9194      1053753 :     auto &surface = state.dataSurface->Surface(SurfNum);
    9195      1053753 :     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    9196      1053753 :     if (construct.CTFCross[0] > 0.01) {
    9197       711822 :         QuickConductionSurf = true;
    9198       711822 :         F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    9199              :     } else {
    9200       341931 :         QuickConductionSurf = false;
    9201              :     }
    9202              : 
    9203      1053753 :     Real64 TSky = state.dataEnvrn->SkyTemp;
    9204      1053753 :     Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
    9205      1053753 :     Real64 TSrdSurfs = 0.0;
    9206              : 
    9207      1053753 :     if (surface.SurfHasSurroundingSurfProperty) {
    9208            6 :         int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
    9209            6 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
    9210            3 :             TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
    9211              :         }
    9212            6 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
    9213            1 :             TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
    9214              :         }
    9215            6 :         TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
    9216              :     }
    9217      1053753 :     if (surface.UseSurfPropertyGndSurfTemp) {
    9218            3 :         TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
    9219              :     }
    9220              : 
    9221              :     // Now, calculate the outside surface temperature using the proper heat balance equation.
    9222              :     // Each case has been separated out into its own IF-THEN block for clarity.  Additional
    9223              :     // cases can simply be added anywhere in the following section.  This is the last step
    9224              :     // in the main loop.  Once the proper heat balance is done, the simulation goes on to
    9225              :     // the next SurfNum.
    9226              : 
    9227              :     // Outside heat balance case: Tubular daylighting device
    9228      1053753 :     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
    9229      1053753 :     if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    9230              : 
    9231              :         // Lookup up the TDD:DIFFUSER object
    9232            0 :         int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    9233            0 :         int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
    9234            0 :         int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
    9235            0 :         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    9236            0 :         F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
    9237              : 
    9238              :         // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
    9239              :         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    9240              :         //   SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
    9241              :         //+Construct(ConstrNum)%CTFSourceOut[0]     &   TDDs cannot be radiant systems
    9242              :         // *SurfQsrcHist(1,SurfNum)                     &
    9243              :         //+Construct(ConstrNum)%CTFSourceIn[0] &   TDDs cannot be radiant systems
    9244              :         // *SurfQsrcHist(1,SurfNum)                &
    9245            0 :         TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    9246            0 :                 (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9247            0 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
    9248            0 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9249            0 :                 F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
    9250            0 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
    9251            0 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
    9252            0 :                (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9253            0 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9254            0 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9255            0 :                 F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
    9256              :                             // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
    9257              : 
    9258              :         // Outside heat balance case: No movable insulation, slow conduction
    9259      1053753 :     } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
    9260              :         // Add LWR from surrounding surfaces
    9261       341930 :         if (surface.OSCMPtr == 0) {
    9262       341930 :             if (construct.SourceSinkPresent) {
    9263            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9264            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9265            0 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9266            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9267            0 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9268            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9269            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9270            0 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9271            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9272              :             } else {
    9273       341930 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9274       341930 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9275       341930 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9276       341930 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9277       341930 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9278       341930 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9279       341930 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9280       341930 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9281              :             }
    9282              :             // Outside Heat Balance case: Other Side Conditions Model
    9283              :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9284              :             // local copies of variables for clarity in radiation terms
    9285              :             // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
    9286              :             Real64 RadTemp =
    9287            0 :                 state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
    9288            0 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
    9289              : 
    9290              :             // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
    9291            0 :             if (construct.SourceSinkPresent) {
    9292            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9293            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9294            0 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9295            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9296            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9297              :             } else {
    9298            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9299            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9300            0 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9301            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9302              :             }
    9303              :         }
    9304              :         // Outside heat balance case: No movable insulation, quick conduction
    9305      1053753 :     } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
    9306       711822 :         if (surface.OSCMPtr == 0) {
    9307       711822 :             if (construct.SourceSinkPresent) {
    9308            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9309            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9310            0 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9311            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9312            0 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9313            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9314            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9315            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9316            0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9317            0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9318            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9319            0 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9320            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9321            0 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9322              :             } else {
    9323       711822 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9324       711822 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9325       711822 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9326       711822 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9327       711822 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9328       711822 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9329       711822 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9330       711822 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9331       711822 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9332       711822 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9333       711822 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9334       711822 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9335       711822 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9336              :             }
    9337              :             // Outside Heat Balance case: Other Side Conditions Model
    9338              :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9339              :             // local copies of variables for clarity in radiation terms
    9340            0 :             Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
    9341            0 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
    9342              :             // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
    9343            0 :             if (construct.SourceSinkPresent) {
    9344            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9345            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9346            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9347            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9348            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9349            0 :                               construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9350            0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9351            0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9352            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9353            0 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9354              :             } else {
    9355            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9356            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9357            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9358            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9359            0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9360            0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9361            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9362            0 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9363              :             }
    9364              :         }
    9365              :         // Outside heat balance case: Movable insulation, slow conduction
    9366       711823 :     } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
    9367              : 
    9368            1 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9369            1 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9370            1 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9371              : 
    9372            1 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9373            1 :                 construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9374            1 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9375            1 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9376            1 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9377            1 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9378            1 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
    9379              : 
    9380              :         // Outside heat balance case: Movable insulation, quick conduction
    9381            0 :     } else if ((MovInsulPresent) && (QuickConductionSurf)) {
    9382              : 
    9383            0 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9384            0 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9385            0 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9386              : 
    9387            0 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9388            0 :                 F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9389            0 :                       state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9390            0 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9391            0 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
    9392            0 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9393            0 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9394            0 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9395            0 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9396            0 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
    9397              : 
    9398              :     } // ...end of outside heat balance cases IF-THEN block
    9399              : 
    9400              :     // multiply out linearized radiation coeffs for reporting
    9401              :     Real64 const HExtSurf_fac(
    9402      1053753 :         -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
    9403      1053753 :           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
    9404      1053753 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
    9405              : 
    9406              :     // Set the radiant system heat balance coefficients if this surface is also a radiant system
    9407      1053753 :     if (construct.SourceSinkPresent) {
    9408              : 
    9409            1 :         if (MovInsulPresent) {
    9410              :             // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
    9411            2 :             ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
    9412            1 :             ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    9413            2 :             ShowContinueError(state,
    9414            2 :                               format("exterior movable insulation {} for a surface with that construction.",
    9415            1 :                                      s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
    9416            2 :             ShowContinueError(state,
    9417              :                               "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
    9418            1 :             ErrorFlag = true;
    9419            1 :             return;
    9420              : 
    9421              :         } else {
    9422            0 :             Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
    9423            0 :                                           state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
    9424            0 :                                           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
    9425            0 :                                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
    9426              : 
    9427            0 :             state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    9428            0 :                 (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9429            0 :                  state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9430            0 :                  (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9431            0 :                  state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
    9432              :                 RadSysDiv; // ODB used to approx ground surface temp
    9433              : 
    9434            0 :             state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
    9435              : 
    9436            0 :             state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
    9437              :         }
    9438              :     }
    9439              : }
    9440              : 
    9441            0 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
    9442              : {
    9443              : 
    9444              :     // SUBROUTINE INFORMATION:
    9445              :     //       AUTHOR         B Griffith
    9446              :     //       DATE WRITTEN   January 2005
    9447              : 
    9448              :     // PURPOSE OF THIS SUBROUTINE:
    9449              :     // manages calculating the temperatures of baffle and air cavity for
    9450              :     // multi-skin configuration.
    9451              : 
    9452              :     // METHODOLOGY EMPLOYED:
    9453              :     // derived from CalcPassiveTranspiredCollector
    9454              : 
    9455              :     // local working variables
    9456              :     Real64 HrPlen;
    9457              :     Real64 HcPlen;
    9458              :     Real64 Isc;
    9459              :     Real64 MdotVent;
    9460              :     Real64 VdotWind;
    9461              :     Real64 VdotThermal;
    9462              : 
    9463            0 :     int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
    9464            0 :     Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    9465            0 :     Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
    9466            0 :         state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
    9467            0 :     Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
    9468            0 :     Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
    9469              :     // Aspect Ratio of gap
    9470            0 :     Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
    9471            0 :     Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
    9472            0 :     Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
    9473              : 
    9474              :     // all the work is done in this routine located in GeneralRoutines.cc
    9475              : 
    9476            0 :     for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
    9477              : 
    9478            0 :         TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
    9479            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
    9480              :                                                           holeArea,
    9481            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
    9482            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
    9483            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
    9484            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
    9485            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
    9486            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
    9487              :                                                           AspRat,
    9488            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
    9489            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
    9490            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
    9491              :                                                           TmpTscoll,
    9492              :                                                           TmpTaPlen,
    9493              :                                                           HcPlen,
    9494              :                                                           HrPlen,
    9495              :                                                           Isc,
    9496              :                                                           MdotVent,
    9497              :                                                           VdotWind,
    9498              :                                                           VdotThermal);
    9499              : 
    9500              :     } // sequential solution
    9501              :     // now fill results into derived types
    9502            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
    9503            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
    9504            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
    9505            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
    9506            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
    9507            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
    9508            0 :         (MdotVent / RhoAir) *
    9509            0 :         (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
    9510              :         Constant::rSecsInHour;
    9511            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
    9512            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
    9513            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
    9514              : 
    9515              :     // now do some updates
    9516            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9517            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9518              : 
    9519              :     // update the OtherSideConditionsModel coefficients.
    9520            0 :     int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
    9521              : 
    9522            0 :     state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9523            0 :     state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
    9524            0 :     state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9525            0 :     state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
    9526            0 : }
    9527              : 
    9528        83022 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
    9529              : {
    9530              :     // SUBROUTINE INFORMATION:
    9531              :     //       AUTHOR         Jason Glazer
    9532              :     //       DATE WRITTEN   September 2012
    9533              : 
    9534              :     // PURPOSE OF THIS SUBROUTINE:
    9535              :     //   Gather values during sizing used for surface absorption factors
    9536              : 
    9537              :     // METHODOLOGY EMPLOYED:
    9538              :     //   Save sequence of values for report during sizing.
    9539              : 
    9540              :     // This is by surface, so it works for both space and zone component loads
    9541        83022 :     if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
    9542         7452 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
    9543         7452 :         auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
    9544        82566 :         for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
    9545        75114 :             auto const &surface = state.dataSurface->Surface(jSurf);
    9546        75114 :             if (!surface.HeatTransSurf || surface.Zone == 0) continue;           // Skip non-heat transfer surfaces
    9547        75114 :             if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) continue; // Skip tubular daylighting device domes
    9548        75114 :             surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
    9549        75114 :             surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
    9550              :         }
    9551              :     }
    9552        83022 : }
    9553              : 
    9554       625134 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
    9555              : {
    9556       625134 :     if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
    9557       625132 :         return 1.0;
    9558            2 :     } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
    9559            0 :         return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9560              :     } else {
    9561            2 :         return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9562              :     }
    9563              : }
    9564              : 
    9565          116 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
    9566              : {
    9567              : 
    9568              :     // purpose:
    9569              :     //   Initializes sky and ground surfaces view factors of exterior surfaces
    9570              :     //   used by SurfaceProperty:LocalEnvironment
    9571              :     //   view factors are constant hence should be set only once
    9572              : 
    9573          116 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9574          108 :         return;
    9575              :     }
    9576            8 :     if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    9577            0 :         return;
    9578              :     }
    9579              : 
    9580           50 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9581           42 :         auto &Surface = state.dataSurface->Surface(SurfNum);
    9582           42 :         if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
    9583              : 
    9584           18 :             int GndSurfsNum = 0;
    9585           18 :             int SrdSurfsNum = 0;
    9586           18 :             Real64 SrdSurfsViewFactor = 0.0;
    9587           18 :             Real64 SurfsSkyViewFactor = 0.0;
    9588           18 :             Real64 GroundSurfsViewFactor = 0.0;
    9589           18 :             bool IsSkyViewFactorSet = false;
    9590           18 :             bool IsGroundViewFactorSet = false;
    9591           18 :             bool SetGroundViewFactorObject = false;
    9592           18 :             if (Surface.SurfHasSurroundingSurfProperty) {
    9593           18 :                 SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
    9594           18 :                 auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
    9595           18 :                 SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
    9596           18 :                 IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
    9597           18 :                 if (SurfsSkyViewFactor > 0.0) {
    9598           12 :                     SrdSurfsViewFactor += SurfsSkyViewFactor;
    9599              :                 }
    9600           18 :                 if (!Surface.IsSurfPropertyGndSurfacesDefined) {
    9601            8 :                     SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
    9602            8 :                     IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
    9603            8 :                     GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
    9604              :                 }
    9605           46 :                 for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    9606           28 :                     SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
    9607              :                 }
    9608              :             }
    9609           18 :             if (Surface.IsSurfPropertyGndSurfacesDefined) {
    9610           10 :                 GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
    9611           10 :                 IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
    9612           10 :                 GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
    9613           10 :                 SrdSurfsViewFactor += GroundSurfsViewFactor;
    9614              :             }
    9615              : 
    9616              :             // Check if the sum of all defined view factors > 1.0
    9617           18 :             if (SrdSurfsViewFactor > 1.0) {
    9618            0 :                 ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
    9619            0 :                 ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
    9620              :             }
    9621           18 :             if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9622              :                 // If both surface sky and ground view factor defined, overwrite with the defined value
    9623            6 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9624            6 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9625           12 :             } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
    9626              :                 // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
    9627            6 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9628            6 :                 Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
    9629            6 :                 if (GndSurfsNum > 0) {
    9630            2 :                     SetGroundViewFactorObject = true;
    9631            2 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9632              :                 } else {
    9633            4 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9634              :                 }
    9635            6 :             } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9636              :                 // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
    9637            2 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9638            2 :                 Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
    9639            2 :                 if (SrdSurfsNum > 0) {
    9640            2 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9641            2 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9642              :                 }
    9643              :             } else {
    9644              :                 // If neither ground nor sky view factor specified, continue to use the original proportion.
    9645            4 :                 Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
    9646            4 :                 Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
    9647            4 :                 if (SrdSurfsNum > 0) {
    9648            4 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9649            4 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9650            4 :                     if (GndSurfsNum == 0) {
    9651            0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9652            0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
    9653              :                     }
    9654              :                 }
    9655            4 :                 if (GndSurfsNum > 0) {
    9656            4 :                     SetGroundViewFactorObject = true;
    9657            4 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9658              :                 }
    9659              :             }
    9660           18 :             if (SetGroundViewFactorObject) {
    9661            6 :                 ReSetGroundSurfacesViewFactor(state, SurfNum);
    9662              :             }
    9663              :         }
    9664              :     }
    9665              : }
    9666              : 
    9667       249966 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
    9668              : {
    9669              :     //  returns ground surfaces average temperature (deg C)
    9670              :     //  ground surfaces viewed by a building exterior surface
    9671              :     //  ground surfaces temperature weighed using view factors
    9672              : 
    9673       249966 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9674       249959 :         return;
    9675              :     }
    9676              : 
    9677           37 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9678           30 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) continue;
    9679            7 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9680            7 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9681            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9682            0 :             continue;
    9683              :         }
    9684            7 :         Real64 GndSurfaceTemp = 0.0;
    9685            7 :         Real64 GndSurfViewFactor = 0.0;
    9686            7 :         Real64 GndSurfaceTempSum = 0.0;
    9687           24 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9688           17 :             GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
    9689           17 :             if (GndSurfViewFactor == 0.0) continue;
    9690           11 :             if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) continue;
    9691           11 :             GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
    9692           11 :             GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
    9693              :         }
    9694            7 :         if (GndSurfaceTempSum == 0.0) {
    9695            0 :             GndSurfsProperty.SurfsTempAvg = 0.0;
    9696            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9697            0 :             continue;
    9698              :         }
    9699            7 :         GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
    9700              :     }
    9701              : }
    9702              : 
    9703       249960 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
    9704              : {
    9705              :     //  returns ground surfaces average reflectance (dimensionless)
    9706              :     //  ground reflectance viewed by a building exterior surface
    9707              :     //  ground surfaces reflectance weighed using view factors
    9708              : 
    9709       249960 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9710       249953 :         return;
    9711              :     }
    9712           37 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9713              : 
    9714           30 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) continue;
    9715            7 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9716            7 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9717            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9718            0 :             continue;
    9719              :         }
    9720            7 :         Real64 GndSurfRefl = 0.0;
    9721            7 :         Real64 GndSurfsReflSum = 0.0;
    9722           24 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9723           17 :             if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) continue;
    9724           12 :             GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
    9725           12 :             GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
    9726              :         }
    9727            7 :         if (GndSurfsReflSum == 0.0) {
    9728            3 :             GndSurfsProperty.SurfsReflAvg = 0.0;
    9729            3 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9730            3 :             continue;
    9731              :         }
    9732            4 :         GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
    9733              :     }
    9734              : }
    9735              : 
    9736            6 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
    9737              : {
    9738              :     //  resets ground view factors based on view factors identity
    9739              :     //  the ground view factor value is set to the first element
    9740              :     //  when the ground view factor input field is blank
    9741              : 
    9742            6 :     if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) return;
    9743            6 :     auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9744            6 :     GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
    9745              : 
    9746            6 :     if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9747            0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9748            0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9749            0 :         return;
    9750              :     }
    9751            6 :     GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
    9752              : }
    9753              : 
    9754       249965 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
    9755              : {
    9756              :     //  returns surrounding surfaces average temperature (deg C)
    9757              :     //  surrounding surfaces viewed by an exterior surface
    9758              :     //  surrounding surfaces temperature weighed using view factors
    9759              : 
    9760       249965 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9761       249959 :         return;
    9762              :     }
    9763              : 
    9764           33 :     for (auto &surface : state.dataSurface->Surface) {
    9765           27 :         if (!surface.SurfHasSurroundingSurfProperty) continue;
    9766              :         // local vars
    9767           10 :         Real64 SrdSurfaceTemp = 0.0;
    9768           10 :         Real64 SrdSurfaceTempSum = 0.0;
    9769           10 :         auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
    9770           26 :         for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    9771           16 :             SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
    9772           16 :             SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
    9773              :         }
    9774           10 :         surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
    9775              :     }
    9776              : }
    9777              : } // namespace EnergyPlus::HeatBalanceSurfaceManager
        

Generated by: LCOV version 2.0-1