LCOV - code coverage report
Current view: top level - EnergyPlus - HeatBalanceSurfaceManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 4664 5872 79.4 %
Date: 2024-08-24 18:31:18 Functions: 42 47 89.4 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // 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/FileSystem.hh>
      91             : #include <EnergyPlus/General.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 simluation 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     2804482 : 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     2804482 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Surfaces");
     159     2804482 :     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     2804482 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Outside Surface Heat Balance");
     164     2804482 :     CalcHeatBalanceOutsideSurf(state);
     165     2804482 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Inside Surface Heat Balance");
     166     2804482 :     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     2804482 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) DisplayString(state, "Calculate Air Heat Balance");
     171     2804482 :     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     2804482 :     UpdateFinalSurfaceHeatBalance(state);
     177             : 
     178             :     // Before we leave the Surface Manager the thermal histories need to be updated
     179     2804482 :     if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
     180     2629123 :         UpdateThermalHistories(state); // Update the thermal histories
     181             :     }
     182             : 
     183     2804482 :     if (state.dataHeatBal->AnyCondFD) {
     184     1930572 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     185     1772040 :             auto const &surface = state.dataSurface->Surface(SurfNum);
     186     1772040 :             int const ConstrNum = surface.Construction;
     187     1772040 :             if (ConstrNum <= 0) continue;                                            // Shading surface, not really a heat transfer surface
     188     1772040 :             if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) continue; //  Windows simulated in Window module
     189     1704756 :             if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) continue;
     190     1654326 :             state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
     191             :         }
     192             :     }
     193             : 
     194     2804482 :     ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
     195             : 
     196     2804482 :     ReportSurfaceHeatBalance(state);
     197     2804482 :     if (state.dataGlobal->ZoneSizingCalc) OutputReportTabular::GatherComponentLoadsSurface(state);
     198             : 
     199     2804482 :     CalcThermalResilience(state);
     200             : 
     201     2804482 :     if (state.dataOutRptTab->displayThermalResilienceSummary) {
     202     1081251 :         ReportThermalResilience(state);
     203             :     }
     204             : 
     205     2804482 :     if (state.dataOutRptTab->displayCO2ResilienceSummary) {
     206       19092 :         ReportCO2Resilience(state);
     207             :     }
     208             : 
     209     2804482 :     if (state.dataOutRptTab->displayVisualResilienceSummary) {
     210       91820 :         ReportVisualResilience(state);
     211             :     }
     212             : 
     213     2804482 :     state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
     214     2804482 : }
     215             : 
     216             : // Beginning Initialization Section of the Module
     217             : //******************************************************************************
     218             : 
     219     2804678 : void UpdateVariableAbsorptances(EnergyPlusData &state)
     220             : {
     221     2808527 :     for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
     222        3849 :         auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
     223        3849 :         auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(thisConstruct.LayerPoint(1)));
     224        3849 :         assert(thisMaterial != nullptr);
     225        3849 :         if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
     226           0 :             if (thisMaterial->absorpThermalVarSchedIdx > 0) {
     227           0 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
     228           0 :                     max(min(ScheduleManager::GetCurrentScheduleValue(state, thisMaterial->absorpThermalVarSchedIdx), 0.9999), 0.0001);
     229             :             }
     230           0 :             if (thisMaterial->absorpSolarVarSchedIdx > 0) {
     231           0 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
     232           0 :                     max(min(ScheduleManager::GetCurrentScheduleValue(state, thisMaterial->absorpThermalVarSchedIdx), 0.9999), 0.0001);
     233             :             }
     234             :         } else {
     235             :             Real64 triggerValue;
     236        3849 :             if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
     237        3849 :                 triggerValue = state.dataHeatBalSurf->SurfTempOut(surfNum);
     238           0 :             } else if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceReceivedSolarRadiation) {
     239           0 :                 triggerValue = state.dataHeatBal->SurfQRadSWOutIncident(surfNum);
     240             :             } else { // controlled by heating cooling mode
     241           0 :                 int zoneNum = state.dataSurface->Surface(surfNum).Zone;
     242           0 :                 bool isCooling = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).TotalOutputRequired < 0);
     243           0 :                 triggerValue = static_cast<Real64>(isCooling);
     244             :             }
     245        3849 :             if (thisMaterial->absorpThermalVarFuncIdx > 0) {
     246        3849 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
     247        3849 :                     max(min(Curve::CurveValue(state, thisMaterial->absorpThermalVarFuncIdx, triggerValue), 0.9999), 0.0001);
     248             :             }
     249        3849 :             if (thisMaterial->absorpSolarVarFuncIdx > 0) {
     250        3849 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
     251        3849 :                     max(min(Curve::CurveValue(state, thisMaterial->absorpSolarVarFuncIdx, triggerValue), 0.9999), 0.0001);
     252             :             }
     253             :         }
     254     2804678 :     }
     255     2804678 : }
     256             : 
     257     2804678 : void InitSurfaceHeatBalance(EnergyPlusData &state)
     258             : {
     259             : 
     260             :     // SUBROUTINE INFORMATION:
     261             :     //       AUTHOR         Richard J. Liesen
     262             :     //       DATE WRITTEN   January 1998
     263             :     //       MODIFIED       Nov. 1999, FCW,
     264             :     //                      Move ComputeIntThermalAbsorpFactors
     265             :     //                      so called every timestep
     266             :     //       MODIFIED       Aug. 2017
     267             :     //                      Add initializations of surface data to linked air node value if defined
     268             : 
     269             :     // PURPOSE OF THIS SUBROUTINE:
     270             :     // This subroutine is for surface initializations within the
     271             :     // heat balance.
     272             : 
     273             :     // METHODOLOGY EMPLOYED:
     274             :     // Uses the status flags to trigger record keeping events.
     275             : 
     276             :     //    // Using/Aliasing
     277             :     //    using namespace SolarShading;
     278             :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
     279             :     //    using HeatBalFiniteDiffManager::InitHeatBalFiniteDiff;
     280             :     //    using InternalHeatGains::ManageInternalHeatGains;
     281             :     //
     282             :     //    auto &Surface = state.dataSurface->Surface;
     283             :     //
     284     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Outdoor environment for Surfaces");
     285             : 
     286             :     // set zone level wind dir to global value
     287             :     // Initialize zone outdoor environmental variables
     288             :     // Bulk Initialization for Temperatures & WindSpeed
     289             :     // using the zone, modify the zone  Dry/Wet BulbTemps
     290             : 
     291             :     // Initialize surface outdoor environmental variables
     292             :     // Bulk Initialization for Temperatures & WindSpeed
     293             :     // using the surface centroids, modify the surface Dry/Wet BulbTemps
     294     2804678 :     DataSurfaces::SetSurfaceOutBulbTempAt(state);
     295     2804678 :     DataSurfaces::CheckSurfaceOutBulbTempAt(state);
     296             : 
     297     2804678 :     DataSurfaces::SetSurfaceWindSpeedAt(state);
     298     2804678 :     DataSurfaces::SetSurfaceWindDirAt(state);
     299     2804678 :     if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
     300      620862 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     301      613426 :             if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
     302        2706 :                 auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
     303        2706 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
     304        2706 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
     305        2706 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
     306        2706 :                 state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
     307             :             }
     308             :         }
     309             :     }
     310             :     // Overwriting surface and zone level environmental data with EMS override value
     311     2804678 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     312    40849555 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     313    40441038 :             if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
     314           0 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
     315             :             }
     316    40441038 :             if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
     317           0 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
     318             :             }
     319    40441038 :             if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
     320           0 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
     321             :             }
     322    40441038 :             if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
     323           0 :                 state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
     324             :             }
     325    40441038 :             if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
     326           0 :                 state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
     327             :             }
     328             :         }
     329             :     }
     330             : 
     331             :     // Do the Begin Simulation initializations
     332     2804678 :     if (state.dataGlobal->BeginSimFlag) {
     333         796 :         AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
     334        1592 :         state.dataHeatBalSurf->InterZoneWindow =
     335         796 :             std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
     336        1592 :                         state.dataViewFactor->EnclSolInfo.end(),
     337        5047 :                         [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
     338             :     }
     339     2804678 :     if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
     340        5852 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     341       10124 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     342        5068 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     343        5068 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
     344        5068 :                 int const lastSurf = thisSpace.HTSurfaceLast;
     345       49458 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     346       44390 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
     347       44390 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
     348       44390 :                     state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
     349       44390 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
     350       44390 :                     state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
     351       44390 :                     state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
     352       44390 :                     state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
     353             :                 }
     354        5056 :             }
     355             :         }
     356             :     }
     357             : 
     358             :     // yujie: variable thermal solar absorptance overrides
     359     2804678 :     UpdateVariableAbsorptances(state);
     360             : 
     361             :     // Do the Begin Environment initializations
     362     2804678 :     if (state.dataGlobal->BeginEnvrnFlag) {
     363        6443 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Temperature and Flux Histories");
     364        6443 :         InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
     365             :     }
     366             : 
     367             :     // Calc movable insulation properties
     368     2804678 :     if (state.dataSurface->AnyMovableInsulation) {
     369       10122 :         EvalOutsideMovableInsulation(state);
     370       10122 :         EvalInsideMovableInsulation(state);
     371             :     }
     372             : 
     373             :     // There are no daily initializations done in this portion of the surface heat balance
     374             :     // There are no hourly initializations done in this portion of the surface heat balance
     375             : 
     376     2804678 :     GetGroundSurfacesReflectanceAverage(state);
     377             : 
     378             :     // Need to be called each timestep in order to check if surface points to new construction (EMS) and if does then
     379             :     // complex fenestration needs to be initialized for additional states
     380     2804678 :     SolarShading::TimestepInitComplexFenestration(state);
     381             : 
     382             :     // Calculate exterior-surface multipliers that account for anisotropy of
     383             :     // sky radiance
     384     2804678 :     if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
     385      916286 :         SolarShading::AnisoSkyViewFactors(state);
     386             :     } else {
     387     1888392 :         state.dataSolarShading->SurfAnisoSkyMult = 0.0;
     388             :     }
     389             : 
     390             :     // Set shading flag for exterior windows (except flags related to daylighting) and
     391             :     // window construction (unshaded or shaded) to be used in heat balance calculation
     392     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Window Shading");
     393             : 
     394     2804678 :     SolarShading::WindowShadingManager(state);
     395             : 
     396     2804678 :     SolarShading::CheckGlazingShadingStatusChange(state);
     397             : 
     398             :     // Calculate factors that are used to determine how much long-wave radiation from internal
     399             :     // gains is absorbed by interior surfaces
     400     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Computing Interior Absorption Factors");
     401     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
     402     2804678 :     ComputeIntThermalAbsorpFactors(state);
     403             : 
     404             :     // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
     405     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
     406     2804678 :     ComputeIntSWAbsorpFactors(state);
     407             : 
     408     2804678 :     if (state.dataHeatBalSurf->InterZoneWindow) {
     409       12147 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     410           6 :             DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
     411             :         }
     412       12147 :         ComputeDifSolExcZonesWIZWindows(state);
     413             :     }
     414             : 
     415     2804678 :     Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
     416             : 
     417     5609356 :     HeatBalanceIntRadExchange::CalcInteriorRadExchange(
     418     2804678 :         state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
     419             : 
     420     2804678 :     if (state.dataSurface->AirflowWindows) SolarShading::WindowGapAirflowControl(state);
     421             : 
     422             :     // The order of these initializations is important currently.  Over time we hope to
     423             :     //  take the appropriate parts of these inits to the other heat balance managers
     424     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Solar Heat Gains");
     425             : 
     426     2804678 :     InitSolarHeatGains(state);
     427             : 
     428     2804678 :     Dayltg::manageDaylighting(state);
     429             : 
     430     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Internal Heat Gains");
     431     2804678 :     InternalHeatGains::ManageInternalHeatGains(state, false);
     432     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Interior Solar Distribution");
     433     2804678 :     InitIntSolarDistribution(state);
     434             : 
     435     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Initializing Interior Convection Coefficients");
     436     2804678 :     Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
     437             : 
     438     2804678 :     if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
     439             :         //    if (firstTime) CALL DisplayString('Reporting Surfaces')
     440             :         //    CALL ReportSurfaces
     441         796 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) DisplayString(state, "Gathering Information for Predefined Reporting");
     442         796 :         GatherForPredefinedReport(state);
     443             :     }
     444             : 
     445             :     // Initialize the temperature history terms for conduction through the surfaces
     446     2804678 :     if (state.dataHeatBal->AnyCondFD) {
     447      158532 :         HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
     448             :     }
     449             : 
     450    22672022 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     451    39783288 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     452    19915944 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     453    19915944 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     454    19915944 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     455   168309598 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     456   148393654 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
     457   148393654 :                 if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     458     2076486 :                     surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)
     459     1926468 :                     continue;
     460             :                 // Outside surface temp of "normal" windows not needed in Window5 calculation approach
     461             :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
     462             : 
     463   146467186 :                 int const ConstrNum = surface.Construction;
     464   146467186 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
     465   146467186 :                 state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
     466   146467186 :                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
     467   146467186 :                 if (construct.NumCTFTerms <= 1) continue;
     468             : 
     469  1050440572 :                 for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     470             :                     // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum )
     471             : 
     472             :                     // Sign convention for the various terms in the following two equations
     473             :                     // is based on the form of the Conduction Transfer Function equation
     474             :                     // given by:
     475             :                     // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old)
     476             :                     // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old)
     477             :                     // In both equations, flux is positive from outside to inside.
     478             : 
     479             :                     // Tuned Aliases and linear indexing
     480   913530709 :                     Real64 const ctf_cross(construct.CTFCross[Term]);
     481             : 
     482   913530709 :                     Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     483   913530709 :                     Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     484   913530709 :                     Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
     485   913530709 :                     Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
     486   913530709 :                     state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
     487   913530709 :                         ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
     488             : 
     489   913530709 :                     state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
     490   913530709 :                         construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
     491             :                 }
     492             :             }
     493    19867344 :         }
     494             :     }
     495     2804678 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
     496      646938 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     497      976482 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     498      488241 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     499      488241 :                 int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     500      488241 :                 int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     501     3778335 :                 for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     502     3290094 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
     503     3290094 :                     int const ConstrNum = surface.Construction;
     504     3290094 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
     505     3290094 :                     if (!construct.SourceSinkPresent) continue;
     506      559170 :                     if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     507      161478 :                         surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)
     508      161478 :                         continue;
     509      397692 :                     state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
     510      397692 :                     state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
     511      397692 :                     if (construct.NumCTFTerms <= 1) continue;
     512     4376034 :                     for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     513     3978342 :                         Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     514     3978342 :                         Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     515     3978342 :                         Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
     516             : 
     517     3978342 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
     518             : 
     519     3978342 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
     520             : 
     521     3978342 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
     522     3978342 :                             construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
     523     3978342 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
     524             : 
     525     3978342 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
     526     3978342 :                             construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
     527     3978342 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
     528             :                     }
     529             :                 }
     530      488241 :             } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances
     531             :         }
     532             :     }
     533             : 
     534             :     // Zero out all of the radiant system heat balance coefficient arrays
     535    22672022 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     536    39783288 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     537    19915944 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     538    19915944 :             int const firstSurf = thisSpace.HTSurfaceFirst;
     539    19915944 :             int const lastSurf = thisSpace.HTSurfaceLast;
     540   191536810 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     541   171620866 :                 state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
     542   171620866 :                 state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
     543   171620866 :                 state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
     544   171620866 :                 state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
     545   171620866 :                 state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
     546   171620866 :                 state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
     547             : 
     548   171620866 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
     549   171620866 :                 state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
     550   171620866 :                 state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
     551   171620866 :                 state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
     552             : 
     553             :             } // ...end of Zone Surf loop
     554    19867344 :         }
     555             :     } // ...end of Zone loop
     556             : 
     557     3028490 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
     558      223812 :         auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
     559      223812 :         thisSurfQRadFromHVAC.HTRadSys = 0.0;
     560      223812 :         thisSurfQRadFromHVAC.HWBaseboard = 0.0;
     561      223812 :         thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
     562      223812 :         thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
     563      223812 :         thisSurfQRadFromHVAC.CoolingPanel = 0.0;
     564     2804678 :     }
     565             : 
     566     2804678 :     if (state.dataGlobal->ZoneSizingCalc) GatherComponentLoadsSurfAbsFact(state);
     567             : 
     568     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     569         796 :         DisplayString(state, "Completed Initializing Surface Heat Balance");
     570             :     }
     571     2804678 :     state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
     572     2804678 : }
     573             : 
     574         796 : void GatherForPredefinedReport(EnergyPlusData &state)
     575             : {
     576             : 
     577             :     // SUBROUTINE INFORMATION:
     578             :     //       AUTHOR         Jason Glazer
     579             :     //       DATE WRITTEN   August 2006
     580             : 
     581             :     // PURPOSE OF THIS SUBROUTINE:
     582             :     // This subroutine reports the information for the predefined reports
     583             :     // related to envelope components.
     584             : 
     585             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     586         796 :     std::string surfName;
     587             :     Real64 mult;
     588             :     Real64 curAzimuth;
     589             :     Real64 curTilt;
     590             :     Real64 windowArea;
     591             :     Real64 frameWidth;
     592             :     Real64 frameArea;
     593             :     Real64 dividerArea;
     594             :     // counts for object count report
     595         796 :     int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
     596         796 :     Array1D_int numSurfaces(SurfaceClassCount);
     597         796 :     Array1D_int numExtSurfaces(SurfaceClassCount);
     598             :     int frameDivNum;
     599             :     bool isExterior;
     600         796 :     Array1D<Real64> computedNetArea; // holds the gross wall area minus the window and door areas
     601             : 
     602             :     // the following variables are for the CalcNominalWindowCond call but only SHGCSummer is needed
     603             :     Real64 nomCond;
     604             :     Real64 SHGCSummer;
     605             :     Real64 TransSolNorm;
     606             :     Real64 TransVisNorm;
     607             :     Real64 nomUfact;
     608             :     int errFlag;
     609             :     int curWSC;
     610             :     // following variables are totals for fenestration table
     611         796 :     Real64 windowAreaWMult(0.0);
     612         796 :     Real64 fenTotArea(0.0);
     613         796 :     Real64 fenTotAreaNorth(0.0);
     614         796 :     Real64 fenTotAreaNonNorth(0.0);
     615         796 :     Real64 ufactArea(0.0);
     616         796 :     Real64 ufactAreaNorth(0.0);
     617         796 :     Real64 ufactAreaNonNorth(0.0);
     618         796 :     Real64 shgcArea(0.0);
     619         796 :     Real64 shgcAreaNorth(0.0);
     620         796 :     Real64 shgcAreaNonNorth(0.0);
     621         796 :     Real64 vistranArea(0.0);
     622         796 :     Real64 vistranAreaNorth(0.0);
     623         796 :     Real64 vistranAreaNonNorth(0.0);
     624         796 :     Real64 intFenTotArea(0.0);
     625         796 :     Real64 intUfactArea(0.0);
     626         796 :     Real64 intShgcArea(0.0);
     627         796 :     Real64 intVistranArea(0.0);
     628             :     bool isNorth;
     629             : 
     630         796 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WinShadingType::Num)> WindowShadingTypeNames = {
     631             :         "No Shade",  // 0
     632             :         "Shade Off", // 1
     633             :         "Interior Shade",
     634             :         "Switchable Glazing",
     635             :         "Exterior Shade",
     636             :         "Exterior Screen",
     637             :         "Interior Blind",
     638             :         "Exterior Blind",
     639             :         "Between Glass Shade",
     640             :         "Between Glass Blind",
     641             :     };
     642             : 
     643         796 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WindowShadingControlType::Num)> WindowShadingControlTypeNames = {
     644             :         "Uncontrolled",
     645             :         "AlwaysOn",
     646             :         "AlwaysOff",
     647             :         "OnIfScheduleAllows",
     648             :         "OnIfHighSolarOnWindow",
     649             :         "OnIfHighHorizontalSolar",
     650             :         "OnIfHighOutdoorAirTemperature",
     651             :         "OnIfHighZoneAirTemperature",
     652             :         "OnIfHighZoneCooling",
     653             :         "OnIfHighGlare",
     654             :         "MeetDaylightIlluminanceSetpoint",
     655             :         "OnNightIfLowOutdoorTempAndOffDay",
     656             :         "OnNightIfLowInsideTempAndOffDay",
     657             :         "OnNightIfHeatingAndOffDay",
     658             :         "OnNightIfLowOutdoorTempAndOnDayIfCooling",
     659             :         "OnNightIfHeatingAndOnDayIfCooling",
     660             :         "OffNightAndOnDayIfCoolingAndHighSolarOnWindow",
     661             :         "OnNightAndOnDayIfCoolingAndHighSolarOnWindow",
     662             :         "OnIfHighOutdoorAirTempAndHighSolarOnWindow",
     663             :         "OnIfHighOutdoorAirTempAndHighHorizontalSolar",
     664             :         "OnIfHighZoneAirTempAndHighSolarOnWindow",
     665             :         "OnIfHighZoneAirTempAndHighHorizontalSolar"};
     666             : 
     667         796 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNames = {
     668             :         "CasementDouble", "CasementSingle",   "DualAction",
     669             :         "Fixed",          "Garage",           "Greenhouse",
     670             :         "HingedEscape",   "HorizontalSlider", "Jal",
     671             :         "Pivoted",        "ProjectingSingle", "ProjectingDual",
     672             :         "DoorSidelite",   "Skylight",         "SlidingPatioDoor",
     673             :         "CurtainWall",    "SpandrelPanel",    "SideHingedDoor",
     674             :         "DoorTransom",    "TropicalAwning",   "TubularDaylightingDevice",
     675             :         "VerticalSlider"};
     676             : 
     677         796 :     constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcWidth = {
     678             :         // width in meters from Table 4-3 of NFRC 100-2020
     679             :         1.200, 0.600, 1.200, //  CasementDouble,  CasementSingle,    DualAction,
     680             :         1.200, 2.134, 1.500, //  Fixed,           Garage,            Greenhouse,
     681             :         1.500, 1.500, 1.200, //  HingedEscape,    HorizontalSlider,  Jal,
     682             :         1.200, 1.500, 1.500, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     683             :         0.600, 1.200, 2.000, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     684             :         2.000, 2.000, 1.920, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     685             :         2.000, 1.500, 0.350, //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     686             :         1.200                //  VerticalSlider,
     687             :     };
     688             : 
     689         796 :     constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcHeight = {
     690             :         // height in meters from Table 4-3 of NFRC 100-2020
     691             :         1.500, 1.500, 1.500, //  CasementDouble,  CasementSingle,    DualAction,
     692             :         1.500, 2.134, 1.200, //  Fixed,           Garage,            Greenhouse,
     693             :         1.200, 1.200, 1.500, //  HingedEscape,    HorizontalSlider,  Jal,
     694             :         1.500, 1.200, 0.600, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     695             :         2.090, 1.200, 2.000, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     696             :         2.000, 1.200, 2.090, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     697             :         0.600, 1.200, 0.350, //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     698             :         1.500                //  VerticalSlider,
     699             :     };
     700             : 
     701         796 :     constexpr std::array<DataSurfaces::NfrcVisionType, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcVision = {
     702             :         DataSurfaces::NfrcVisionType::DualHorizontal, DataSurfaces::NfrcVisionType::Single,
     703             :         DataSurfaces::NfrcVisionType::DualVertical, //  CasementDouble,  CasementSingle,    DualAction,
     704             :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     705             :         DataSurfaces::NfrcVisionType::Single, //  Fixed,           Garage,            Greenhouse,
     706             :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::DualHorizontal,
     707             :         DataSurfaces::NfrcVisionType::Single, //  HingedEscape,    HorizontalSlider,  Jal,
     708             :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     709             :         DataSurfaces::NfrcVisionType::DualHorizontal, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     710             :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     711             :         DataSurfaces::NfrcVisionType::DualHorizontal, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     712             :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     713             :         DataSurfaces::NfrcVisionType::Single, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     714             :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     715             :         DataSurfaces::NfrcVisionType::Single,      //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     716             :         DataSurfaces::NfrcVisionType::DualVertical //  VerticalSlider
     717             :     };
     718             : 
     719         796 :     numSurfaces = 0;
     720         796 :     numExtSurfaces = 0;
     721             : 
     722         796 :     computedNetArea.allocate(state.dataSurface->TotSurfaces);
     723         796 :     computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
     724             : 
     725             :     // set up for EIO <FenestrationAssembly> output
     726         796 :     if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
     727          18 :         print(state.files.eio,
     728             :               "{}\n",
     729             :               "! <FenestrationAssembly>,Construction Name,Frame and Divider Name,NFRC Product Type,"
     730             :               "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
     731             :     }
     732             :     static constexpr std::string_view FenestrationAssemblyFormat("FenestrationAssembly,{},{},{},{:.3R},{:.3R},{:.3R}\n");
     733         796 :     std::vector<std::pair<int, int>> uniqConsFrame;
     734         796 :     std::pair<int, int> consAndFrame;
     735             : 
     736             :     // set up for EIO <FenestrationShadedState> output
     737         796 :     bool fenestrationShadedStateHeaderShown(false);
     738             :     static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
     739         796 :     std::vector<std::pair<int, int>> uniqShdConsFrame;
     740         796 :     std::pair<int, int> shdConsAndFrame;
     741             : 
     742       46840 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
     743       46044 :         auto &surface = state.dataSurface->Surface(iSurf);
     744       46044 :         surfName = surface.Name;
     745             :         // only exterior surfaces including underground
     746       46044 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
     747       24408 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
     748       21858 :             isExterior = true;
     749       21858 :             switch (surface.Class) {
     750       13618 :             case DataSurfaces::SurfaceClass::Wall:
     751             :             case DataSurfaces::SurfaceClass::Floor:
     752             :             case DataSurfaces::SurfaceClass::Roof: {
     753       13618 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
     754       13618 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     755       13618 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
     756       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
     757       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
     758       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
     759       13618 :                 OutputReportPredefined::PreDefTableEntry(
     760       13618 :                     state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
     761       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
     762       13618 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
     763       13618 :                 curAzimuth = surface.Azimuth;
     764             :                 // Round to two decimals, like the display in tables
     765             :                 // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
     766       13618 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     767       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
     768       13618 :                 curTilt = surface.Tilt;
     769       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
     770       13618 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     771        9098 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     772        2350 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
     773        6748 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     774        2154 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
     775        4594 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     776        2373 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
     777        2221 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     778        2221 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
     779             :                     }
     780             :                 }
     781       13618 :             } break;
     782        6205 :             case DataSurfaces::SurfaceClass::Window:
     783             :             case DataSurfaces::SurfaceClass::TDD_Dome: {
     784        6205 :                 auto &construct = state.dataConstruction->Construct(surface.Construction);
     785        6205 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     786        6205 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
     787        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
     788             :                 // if the construction report is requested the SummerSHGC is already calculated
     789        6205 :                 if (construct.SummerSHGC != 0) {
     790        5546 :                     SHGCSummer = construct.SummerSHGC;
     791        5546 :                     TransVisNorm = construct.VisTransNorm;
     792             :                 } else {
     793             :                     // must calculate Summer SHGC
     794         659 :                     if (!construct.WindowTypeEQL) {
     795         659 :                         Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
     796         659 :                         construct.SummerSHGC = SHGCSummer;
     797         659 :                         construct.VisTransNorm = TransVisNorm;
     798         659 :                         construct.SolTransNorm = TransSolNorm;
     799             :                     }
     800             :                 }
     801             :                 // include the frame area if present
     802        6205 :                 windowArea = surface.GrossArea;
     803        6205 :                 frameArea = 0.0;
     804        6205 :                 dividerArea = 0.0;
     805        6205 :                 frameDivNum = surface.FrameDivider;
     806        6205 :                 if (frameDivNum != 0) {
     807         381 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     808         381 :                     frameWidth = frameDivider.FrameWidth;
     809         381 :                     frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
     810         381 :                     windowArea += frameArea;
     811         381 :                     dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
     812         381 :                                                                frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
     813         381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
     814         381 :                     OutputReportPredefined::PreDefTableEntry(
     815         381 :                         state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
     816         381 :                     OutputReportPredefined::PreDefTableEntry(
     817         381 :                         state, state.dataOutRptPredefined->pdchFenDividerConductance, surfName, frameDivider.DividerConductance, 3);
     818             : 
     819             :                     // report the selected NRFC product type (specific sizes) and the NFRC rating for the assembly (glass + frame + divider)
     820         381 :                     std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     821         381 :                     const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     822         381 :                     const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     823         381 :                     const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     824             : 
     825         381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
     826             : 
     827         381 :                     Real64 uValueAssembly = 0.0;
     828         381 :                     Real64 shgcAssembly = 0.0;
     829         381 :                     Real64 vtAssembly = 0.0;
     830             : 
     831         381 :                     Window::GetWindowAssemblyNfrcForReport(
     832             :                         state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
     833         381 :                     if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
     834           0 :                         state.dataHeatBal->NominalU(surface.Construction) =
     835           0 :                             Window::GetIGUUValueForNFRCReport(state, iSurf, surface.Construction, windowWidth, windowHeight);
     836           0 :                         SHGCSummer = Window::GetSHGCValueForNFRCReporting(state, iSurf, surface.Construction, windowWidth, windowHeight);
     837             :                     }
     838         381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
     839         381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
     840         381 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
     841             : 
     842             :                     // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
     843         381 :                     if (state.dataGeneral->Constructions) {
     844         340 :                         consAndFrame = std::make_pair(surface.Construction, frameDivNum);
     845         340 :                         if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
     846          30 :                             uniqConsFrame.push_back(consAndFrame);
     847          30 :                             print(state.files.eio,
     848             :                                   FenestrationAssemblyFormat,
     849          30 :                                   construct.Name,
     850          30 :                                   frameDivider.Name,
     851             :                                   NFRCname,
     852             :                                   uValueAssembly,
     853             :                                   shgcAssembly,
     854             :                                   vtAssembly);
     855             :                         }
     856             :                     }
     857             :                 }
     858        6205 :                 windowAreaWMult = windowArea * mult;
     859        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
     860        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
     861        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
     862       12410 :                 OutputReportPredefined::PreDefTableEntry(
     863        6205 :                     state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
     864        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
     865        6205 :                 computedNetArea(surface.BaseSurf) -= windowAreaWMult;
     866        6205 :                 nomUfact = state.dataHeatBal->NominalU(surface.Construction);
     867        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
     868             : 
     869        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
     870        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
     871        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
     872        6205 :                 curAzimuth = surface.Azimuth;
     873             :                 // Round to two decimals, like the display in tables
     874        6205 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     875        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
     876        6205 :                 isNorth = false;
     877        6205 :                 curTilt = surface.Tilt;
     878        6205 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
     879        6205 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     880        5808 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     881        1449 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
     882        1449 :                         isNorth = true;
     883        4359 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     884        1048 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
     885        3311 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     886        2266 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
     887        1045 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     888        1045 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
     889             :                     }
     890             :                 }
     891             : 
     892             :                 // Report table for every shading control state
     893        6205 :                 const unsigned int totalStates = surface.windowShadingControlList.size();
     894        6205 :                 if (frameDivNum != 0) {
     895         381 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     896         422 :                     for (unsigned int i = 0; i < totalStates; ++i) {
     897          41 :                         const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     898          41 :                         const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     899          41 :                         const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     900             : 
     901          41 :                         const int stateConstrNum = surface.shadedConstructionList[i];
     902          41 :                         const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     903          41 :                         const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     904          41 :                         std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
     905             : 
     906          82 :                         OutputReportPredefined::PreDefTableEntry(
     907          41 :                             state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
     908          82 :                         OutputReportPredefined::PreDefTableEntry(
     909          82 :                             state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
     910          41 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
     911          41 :                         OutputReportPredefined::PreDefTableEntry(state,
     912          41 :                                                                  state.dataOutRptPredefined->pdchFenShdVisTr,
     913             :                                                                  constructionName,
     914          41 :                                                                  state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
     915          41 :                                                                  3);
     916             : 
     917          41 :                         Real64 stateAssemblyUValue{0.0};
     918          41 :                         Real64 stateAssemblySHGC{0.0};
     919          41 :                         Real64 stateAssemblyVT{0.0};
     920             : 
     921          41 :                         Window::GetWindowAssemblyNfrcForReport(
     922             :                             state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
     923             : 
     924          41 :                         std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     925          82 :                         OutputReportPredefined::PreDefTableEntry(
     926          41 :                             state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
     927             : 
     928          82 :                         OutputReportPredefined::PreDefTableEntry(
     929          82 :                             state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
     930          82 :                         OutputReportPredefined::PreDefTableEntry(
     931          82 :                             state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
     932          82 :                         OutputReportPredefined::PreDefTableEntry(
     933          82 :                             state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
     934             : 
     935          41 :                         if (state.dataGeneral->Constructions) {
     936          23 :                             if (!fenestrationShadedStateHeaderShown) {
     937           4 :                                 print(state.files.eio,
     938             :                                       "{}\n",
     939             :                                       "! <FenestrationShadedState>,Construction Name,Glass U-Factor {W/m2-K},"
     940             :                                       "Glass SHGC, Glass Visible Transmittance, Frame and Divider Name,NFRC Product Type,"
     941             :                                       "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
     942           4 :                                 fenestrationShadedStateHeaderShown = true;
     943             :                             }
     944             : 
     945          23 :                             shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
     946          23 :                             if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
     947          14 :                                 uniqShdConsFrame.push_back(shdConsAndFrame);
     948          14 :                                 print(state.files.eio,
     949             :                                       FenestrationShadedStateFormat,
     950             :                                       constructionName,
     951             :                                       stateUValue,
     952             :                                       stateSHGC,
     953          14 :                                       state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
     954          14 :                                       frameDivider.Name,
     955             :                                       NFRCname,
     956             :                                       stateAssemblyUValue,
     957             :                                       stateAssemblySHGC,
     958             :                                       stateAssemblyVT);
     959             :                             }
     960             :                         }
     961             :                     }
     962             :                 }
     963             : 
     964        6205 :                 curWSC = surface.activeWindowShadingControl;
     965             :                 // compute totals for area weighted averages
     966        6205 :                 fenTotArea += windowAreaWMult;
     967        6205 :                 ufactArea += nomUfact * windowAreaWMult;
     968        6205 :                 shgcArea += SHGCSummer * windowAreaWMult;
     969        6205 :                 vistranArea += TransVisNorm * windowAreaWMult;
     970        6205 :                 if (isNorth) {
     971        1449 :                     fenTotAreaNorth += windowAreaWMult;
     972        1449 :                     ufactAreaNorth += nomUfact * windowAreaWMult;
     973        1449 :                     shgcAreaNorth += SHGCSummer * windowAreaWMult;
     974        1449 :                     vistranAreaNorth += TransVisNorm * windowAreaWMult;
     975             :                 } else {
     976        4756 :                     fenTotAreaNonNorth += windowAreaWMult;
     977        4756 :                     ufactAreaNonNorth += nomUfact * windowAreaWMult;
     978        4756 :                     shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
     979        4756 :                     vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
     980             :                 }
     981             :                 // shading
     982        6205 :                 if (surface.HasShadeControl) {
     983         151 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
     984         302 :                     OutputReportPredefined::PreDefTableEntry(
     985         302 :                         state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
     986             :                     // shading report
     987         302 :                     OutputReportPredefined::PreDefTableEntry(
     988             :                         state,
     989         151 :                         state.dataOutRptPredefined->pdchWscShading,
     990             :                         surfName,
     991         151 :                         WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
     992         302 :                     OutputReportPredefined::PreDefTableEntry(
     993             :                         state,
     994         151 :                         state.dataOutRptPredefined->pdchWscControl,
     995             :                         surfName,
     996         151 :                         WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
     997             : 
     998             :                     // output list of all possible shading contructions for shaded windows including those with storms
     999         151 :                     std::string names;
    1000         306 :                     for (int construction : surface.shadedConstructionList) {
    1001         155 :                         if (!names.empty()) names.append("; ");
    1002         155 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1003         151 :                     }
    1004         151 :                     for (int construction : surface.shadedStormWinConstructionList) {
    1005           0 :                         if (!names.empty()) names.append("; ");
    1006           0 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1007         151 :                     }
    1008         151 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
    1009             : 
    1010         151 :                     if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
    1011          30 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
    1012             :                     } else {
    1013         121 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
    1014             :                     }
    1015         151 :                 } else {
    1016        6054 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
    1017             :                 }
    1018        6205 :             } break;
    1019         399 :             case DataSurfaces::SurfaceClass::Door: {
    1020         399 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1021         399 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1022         798 :                 OutputReportPredefined::PreDefTableEntry(
    1023         798 :                     state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
    1024         399 :                 OutputReportPredefined::PreDefTableEntry(
    1025         399 :                     state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1026         399 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
    1027         399 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
    1028         399 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1029         399 :             } break;
    1030        1636 :             default:
    1031        1636 :                 break;
    1032             :             }
    1033       21858 :         } else {
    1034             :             // interior surfaces
    1035       24186 :             isExterior = false;
    1036       24186 :             if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
    1037        6090 :                 (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
    1038       24092 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1039       24092 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1040       24092 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1041       24092 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
    1042       24092 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
    1043       24092 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
    1044       48184 :                 OutputReportPredefined::PreDefTableEntry(
    1045       24092 :                     state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
    1046       24092 :                 OutputReportPredefined::PreDefTableEntry(
    1047       24092 :                     state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1048       24092 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
    1049       24092 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
    1050       24092 :                 curAzimuth = surface.Azimuth;
    1051             :                 // Round to two decimals, like the display in tables
    1052             :                 // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
    1053       24092 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
    1054       24092 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
    1055       24092 :                 curTilt = surface.Tilt;
    1056       24092 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
    1057       24092 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
    1058       15921 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
    1059        5841 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
    1060       10080 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
    1061        3319 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
    1062        6761 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
    1063        3448 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
    1064        3313 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
    1065        3313 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
    1066             :                     }
    1067             :                 }
    1068             :                 // interior window report
    1069       24186 :             } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
    1070          14 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1071          14 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1072          14 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
    1073          14 :                 if (!has_prefix(surface.Name,
    1074             :                                 "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
    1075          12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
    1076             :                     // include the frame area if present
    1077          12 :                     windowArea = surface.GrossArea;
    1078          12 :                     if (surface.FrameDivider != 0) {
    1079           0 :                         frameWidth = state.dataSurface->FrameDivider(surface.FrameDivider).FrameWidth;
    1080           0 :                         frameArea = (surface.Height + 2 * frameWidth) * (surface.Width + 2 * frameWidth) - (surface.Height * surface.Width);
    1081           0 :                         windowArea += frameArea;
    1082             :                     }
    1083          12 :                     windowAreaWMult = windowArea * mult;
    1084          12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
    1085          12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
    1086          12 :                     computedNetArea(surface.BaseSurf) -= windowAreaWMult;
    1087          12 :                     nomUfact = state.dataHeatBal->NominalU(surface.Construction);
    1088          12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
    1089          12 :                     if (!construct.TypeIsAirBoundary) {
    1090             :                         // Solar properties not applicable for air boundary surfaces
    1091             :                         // if the construction report is requested the SummerSHGC is already calculated
    1092          12 :                         if (construct.SummerSHGC != 0) {
    1093          12 :                             SHGCSummer = construct.SummerSHGC;
    1094          12 :                             TransVisNorm = construct.VisTransNorm;
    1095             :                         } else {
    1096             :                             // must calculate Summer SHGC
    1097           0 :                             if (!construct.WindowTypeEQL) {
    1098           0 :                                 Window::CalcNominalWindowCond(
    1099             :                                     state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
    1100             :                             }
    1101             :                         }
    1102          12 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
    1103          12 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
    1104             :                         // compute totals for area weighted averages
    1105          12 :                         intShgcArea += SHGCSummer * windowAreaWMult;
    1106          12 :                         intVistranArea += TransVisNorm * windowAreaWMult;
    1107             :                     }
    1108          12 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
    1109             :                     // compute totals for area weighted averages
    1110          12 :                     intFenTotArea += windowAreaWMult;
    1111          12 :                     intUfactArea += nomUfact * windowAreaWMult;
    1112             :                 }
    1113          94 :             } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
    1114          80 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1115          80 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1116          80 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1117          80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
    1118          80 :                 OutputReportPredefined::PreDefTableEntry(
    1119          80 :                     state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1120          80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
    1121          80 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
    1122          80 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1123             :             }
    1124             :         }
    1125       46044 :         int currSurfaceClass = int(surface.Class);
    1126       46044 :         assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
    1127       46044 :         assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
    1128       46044 :         ++numSurfaces(currSurfaceClass);
    1129       46044 :         if (isExterior) {
    1130       21858 :             ++numExtSurfaces(currSurfaceClass);
    1131             :         }
    1132       46044 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) {
    1133        6217 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    1134         541 :                 ++numSurfaces((int)surface.OriginalClass);
    1135         541 :                 if (isExterior) {
    1136         539 :                     ++numExtSurfaces((int)surface.OriginalClass);
    1137             :                 }
    1138             :             }
    1139             :         }
    1140         796 :     }
    1141             :     // for fins and overhangs just add them explicitly since not otherwise classified
    1142         796 :     int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
    1143         796 :                        state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
    1144         796 :     numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1145         796 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1146         796 :     int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
    1147         796 :                   state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
    1148         796 :     numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1149         796 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1150             :     // go through all the surfaces again and this time insert the net area results
    1151       46840 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
    1152       46044 :         auto const &surface = state.dataSurface->Surface(iSurf);
    1153       46044 :         DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
    1154             :         // exterior surfaces including underground
    1155       46044 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
    1156       24408 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
    1157       21858 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1158             :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1159       13618 :                 surfName = surface.Name;
    1160       13618 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
    1161             :             }
    1162             :         } else {
    1163       24186 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1164             :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1165       21694 :                 surfName = surface.Name;
    1166       21694 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
    1167             :             }
    1168             :         } // interior surfaces
    1169         796 :     }
    1170             :     // total
    1171         796 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
    1172         796 :     if (fenTotArea > 0.0) {
    1173         699 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
    1174         699 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
    1175         699 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
    1176             :     } else {
    1177          97 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
    1178          97 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
    1179          97 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
    1180             :     }
    1181             :     // north
    1182         796 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
    1183         796 :     if (fenTotAreaNorth > 0.0) {
    1184         808 :         OutputReportPredefined::PreDefTableEntry(
    1185         808 :             state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
    1186         808 :         OutputReportPredefined::PreDefTableEntry(
    1187         808 :             state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
    1188         808 :         OutputReportPredefined::PreDefTableEntry(
    1189        1212 :             state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
    1190             :     } else {
    1191         392 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
    1192         392 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
    1193         392 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
    1194             :     }
    1195             :     // non-north
    1196         796 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
    1197         796 :     if (fenTotAreaNonNorth > 0.0) {
    1198        1396 :         OutputReportPredefined::PreDefTableEntry(
    1199        1396 :             state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
    1200        1396 :         OutputReportPredefined::PreDefTableEntry(
    1201        1396 :             state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
    1202        1396 :         OutputReportPredefined::PreDefTableEntry(
    1203        2094 :             state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
    1204             :     } else {
    1205          98 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
    1206          98 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
    1207          98 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
    1208             :     }
    1209             :     // interior fenestration totals
    1210         796 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
    1211         796 :     if (intFenTotArea > 0.0) {
    1212          12 :         OutputReportPredefined::PreDefTableEntry(
    1213          12 :             state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
    1214          12 :         OutputReportPredefined::PreDefTableEntry(
    1215          12 :             state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
    1216          12 :         OutputReportPredefined::PreDefTableEntry(
    1217          18 :             state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
    1218             :     } else {
    1219         790 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
    1220         790 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
    1221         790 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
    1222             :     }
    1223             :     // counts
    1224         796 :     OutputReportPredefined::PreDefTableEntry(
    1225         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1226         796 :     OutputReportPredefined::PreDefTableEntry(
    1227         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1228         796 :     OutputReportPredefined::PreDefTableEntry(
    1229         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1230         796 :     OutputReportPredefined::PreDefTableEntry(
    1231         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1232         796 :     OutputReportPredefined::PreDefTableEntry(
    1233         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1234         796 :     OutputReportPredefined::PreDefTableEntry(
    1235         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1236         796 :     OutputReportPredefined::PreDefTableEntry(
    1237         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1238         796 :     OutputReportPredefined::PreDefTableEntry(
    1239         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1240         796 :     OutputReportPredefined::PreDefTableEntry(
    1241         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1242         796 :     OutputReportPredefined::PreDefTableEntry(
    1243         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1244         796 :     OutputReportPredefined::PreDefTableEntry(
    1245         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1246         796 :     OutputReportPredefined::PreDefTableEntry(
    1247         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1248         796 :     OutputReportPredefined::PreDefTableEntry(
    1249         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1250         796 :     OutputReportPredefined::PreDefTableEntry(
    1251         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1252         796 :     OutputReportPredefined::PreDefTableEntry(
    1253         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1254         796 :     OutputReportPredefined::PreDefTableEntry(
    1255         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1256         796 :     OutputReportPredefined::PreDefTableEntry(
    1257         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1258         796 :     OutputReportPredefined::PreDefTableEntry(
    1259         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1260         796 :     OutputReportPredefined::PreDefTableEntry(
    1261         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1262         796 :     OutputReportPredefined::PreDefTableEntry(
    1263         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1264         796 :     OutputReportPredefined::PreDefTableEntry(
    1265         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1266         796 :     OutputReportPredefined::PreDefTableEntry(
    1267         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1268         796 :     OutputReportPredefined::PreDefTableEntry(
    1269         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1270         796 :     OutputReportPredefined::PreDefTableEntry(
    1271         796 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1272         796 :     OutputReportPredefined::PreDefTableEntry(
    1273         796 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1274         796 :     OutputReportPredefined::PreDefTableEntry(state,
    1275         796 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1276             :                                              "Tubular Daylighting Device Dome",
    1277         796 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1278         796 :     OutputReportPredefined::PreDefTableEntry(state,
    1279         796 :                                              state.dataOutRptPredefined->pdchSurfCntTot,
    1280             :                                              "Tubular Daylighting Device Diffuser",
    1281         796 :                                              numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1282         796 :     OutputReportPredefined::PreDefTableEntry(state,
    1283         796 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1284             :                                              "Tubular Daylighting Device Diffuser",
    1285         796 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1286         796 : }
    1287             : 
    1288         796 : void AllocateSurfaceHeatBalArrays(EnergyPlusData &state)
    1289             : {
    1290             : 
    1291             :     // SUBROUTINE INFORMATION:
    1292             :     //       AUTHOR         Richard Liesen
    1293             :     //       DATE WRITTEN   February 1998
    1294             : 
    1295             :     // METHODOLOGY EMPLOYED:
    1296             :     // Uses the status flags to trigger variable allocation.
    1297             : 
    1298             :     // Use the total number of surfaces to allocate variables to avoid a surface number limit
    1299         796 :     state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1300         796 :     state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1301         796 :     state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1302         796 :     state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1303         796 :     state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1304         796 :     state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1305         796 :     state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1306         796 :     state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
    1307         796 :     state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
    1308         796 :     state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
    1309         796 :     state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
    1310         796 :     state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
    1311         796 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1312          36 :         state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1313          36 :         state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1314             :     }
    1315             : 
    1316         796 :     state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
    1317         796 :     state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1318         796 :     state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1319         796 :     state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1320         796 :     state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1321         796 :     state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1322         796 :     state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1323             : 
    1324         796 :     state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1325         796 :     state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
    1326         796 :     state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1327         796 :     state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1328         796 :     state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1329             : 
    1330         796 :     state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
    1331         796 :     state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
    1332         796 :     state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
    1333         796 :     state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1334         796 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1335         796 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1336             : 
    1337         796 :     state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
    1338         796 :     state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
    1339         796 :     state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
    1340         796 :     state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
    1341       15920 :     for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1342       15124 :         state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1343       15124 :         state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1344       15124 :         state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1345       15124 :         state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1346             :     }
    1347             : 
    1348         796 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1349         137 :         state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
    1350             : 
    1351         137 :         state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1352         137 :         state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1353         137 :         state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1354         137 :         state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1355             : 
    1356        2740 :         for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1357        2603 :             state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1358        2603 :             state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1359        2603 :             state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1360        2603 :             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1361             :         }
    1362             :     }
    1363             : 
    1364         796 :     state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1365         796 :     state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1366         796 :     state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1367         796 :     state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1368         796 :     state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1369             : 
    1370         796 :     state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1371         796 :     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1372             : 
    1373         796 :     state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1374         796 :     state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1375         796 :     state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1376             : 
    1377         796 :     state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1378         796 :     state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1379             : 
    1380         796 :     state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1381         796 :     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1382             : 
    1383         796 :     state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1384         796 :     state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1385         796 :     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1386             : 
    1387         796 :     state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1388         796 :     state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1389         796 :     state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1390             : 
    1391         796 :     state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1392         796 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1393         796 :     state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1394             : 
    1395         796 :     state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1396         796 :     state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1397             : 
    1398         796 :     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1399         796 :     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1400             : 
    1401         796 :     state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1402         796 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1403         796 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1404         796 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1405         796 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1406             : 
    1407         796 :     state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1408         796 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1409         796 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1410         796 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1411         796 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1412             : 
    1413         796 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1414         796 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1415         796 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1416         796 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1417         796 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1418             : 
    1419         796 :     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1420         796 :     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1421         796 :     state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1422         796 :     state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1423         796 :     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1424             : 
    1425         796 :     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
    1426             : 
    1427         796 :     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1428         796 :     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1429             : 
    1430         796 :     state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1431         796 :     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1432         796 :     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1433             : 
    1434         796 :     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1435         796 :     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1436             : 
    1437         796 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1438          36 :         state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1439          36 :         state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
    1440          36 :         state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1441          36 :         state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1442          36 :         state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1443          36 :         state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1444          36 :         state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1445          36 :         state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1446             :     }
    1447             : 
    1448         796 :     state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1449         796 :     state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1450         796 :     state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1451         796 :     state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1452         796 :     state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1453         796 :     state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1454         796 :     state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1455         796 :     state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
    1456         796 :     state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
    1457         796 :     state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
    1458             : 
    1459             :     // allocate terms used for pool surface heat balance
    1460         796 :     state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
    1461         796 :     state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1462             : 
    1463             :     // allocate term used as sink for PV electricity
    1464         796 :     state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1465             : 
    1466             :     // Allocate the moisture balance arrays
    1467         796 :     state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1468         796 :     state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1469         796 :     state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1470         796 :     state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1471         796 :     state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1472         796 :     state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1473         796 :     state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1474         796 :     state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1475         796 :     state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1476         796 :     state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1477         796 :     state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1478             : 
    1479         796 :     state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1480         796 :     state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1481             :     // allocate movable insulation arrays
    1482         796 :     if (state.dataSurface->AnyMovableInsulation) {
    1483           5 :         state.dataHeatBalSurf->SurfMovInsulExtPresent.dimension(state.dataSurface->TotSurfaces, false);
    1484           5 :         state.dataHeatBalSurf->SurfMovInsulIntPresent.dimension(state.dataSurface->TotSurfaces, false);
    1485           5 :         state.dataHeatBalSurf->SurfMovInsulIntPresentPrevTS.dimension(state.dataSurface->TotSurfaces, false);
    1486           5 :         state.dataHeatBalSurf->SurfMovInsulHExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1487           5 :         state.dataHeatBalSurf->SurfMovInsulHInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1488             :     }
    1489         796 :     state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1490         796 :     state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1491         796 :     state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
    1492         796 :     state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1493         796 :     state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1494             : 
    1495         796 :     DisplayString(state, "Setting up Surface Reporting Variables");
    1496             :     // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
    1497       46840 :     for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
    1498       46044 :         auto &surface = state.dataSurface->Surface(loop);
    1499       46044 :         if (!surface.HeatTransSurf) continue;
    1500       88782 :         SetupOutputVariable(state,
    1501             :                             "Surface Inside Face Temperature",
    1502             :                             Constant::Units::C,
    1503       44391 :                             state.dataHeatBalSurf->SurfTempIn(loop),
    1504             :                             OutputProcessor::TimeStepType::Zone,
    1505             :                             OutputProcessor::StoreType::Average,
    1506       44391 :                             surface.Name);
    1507       88782 :         SetupOutputVariable(state,
    1508             :                             "Surface Inside Face Interior Movable Insulation Temperature",
    1509             :                             Constant::Units::C,
    1510       44391 :                             state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
    1511             :                             OutputProcessor::TimeStepType::Zone,
    1512             :                             OutputProcessor::StoreType::Average,
    1513       44391 :                             surface.Name);
    1514             : 
    1515       44391 :         if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1516       88706 :             SetupOutputVariable(state,
    1517             :                                 "Surface Outside Face Temperature",
    1518             :                                 Constant::Units::C,
    1519       44353 :                                 state.dataHeatBalSurf->SurfTempOut(loop),
    1520             :                                 OutputProcessor::TimeStepType::Zone,
    1521             :                                 OutputProcessor::StoreType::Average,
    1522       44353 :                                 surface.Name);
    1523             :         }
    1524             : 
    1525       88782 :         SetupOutputVariable(state,
    1526             :                             "Surface Inside Face Adjacent Air Temperature",
    1527             :                             Constant::Units::C,
    1528       44391 :                             state.dataHeatBal->SurfTempEffBulkAir(loop),
    1529             :                             OutputProcessor::TimeStepType::Zone,
    1530             :                             OutputProcessor::StoreType::Average,
    1531       44391 :                             surface.Name);
    1532       88782 :         SetupOutputVariable(state,
    1533             :                             "Surface Inside Face Convection Heat Transfer Coefficient",
    1534             :                             Constant::Units::W_m2K,
    1535       44391 :                             state.dataHeatBalSurf->SurfHConvInt(loop),
    1536             :                             OutputProcessor::TimeStepType::Zone,
    1537             :                             OutputProcessor::StoreType::Average,
    1538       44391 :                             surface.Name);
    1539       88782 :         SetupOutputVariable(state,
    1540             :                             "Surface Inside Face Convection Heat Gain Rate",
    1541             :                             Constant::Units::W,
    1542       44391 :                             state.dataHeatBalSurf->SurfQdotConvInRep(loop),
    1543             :                             OutputProcessor::TimeStepType::Zone,
    1544             :                             OutputProcessor::StoreType::Average,
    1545       44391 :                             surface.Name);
    1546       88782 :         SetupOutputVariable(state,
    1547             :                             "Surface Inside Face Convection Heat Gain Rate per Area",
    1548             :                             Constant::Units::W_m2,
    1549       44391 :                             state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
    1550             :                             OutputProcessor::TimeStepType::Zone,
    1551             :                             OutputProcessor::StoreType::Average,
    1552       44391 :                             surface.Name);
    1553       88782 :         SetupOutputVariable(state,
    1554             :                             "Surface Inside Face Convection Heat Gain Energy",
    1555             :                             Constant::Units::J,
    1556       44391 :                             state.dataHeatBalSurf->SurfQConvInRep(loop),
    1557             :                             OutputProcessor::TimeStepType::Zone,
    1558             :                             OutputProcessor::StoreType::Sum,
    1559       44391 :                             surface.Name);
    1560             : 
    1561       88782 :         SetupOutputVariable(state,
    1562             :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
    1563             :                             Constant::Units::W,
    1564       44391 :                             state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
    1565             :                             OutputProcessor::TimeStepType::Zone,
    1566             :                             OutputProcessor::StoreType::Average,
    1567       44391 :                             surface.Name);
    1568       88782 :         SetupOutputVariable(state,
    1569             :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
    1570             :                             Constant::Units::W_m2,
    1571       44391 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
    1572             :                             OutputProcessor::TimeStepType::Zone,
    1573             :                             OutputProcessor::StoreType::Average,
    1574       44391 :                             surface.Name);
    1575       88782 :         SetupOutputVariable(state,
    1576             :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
    1577             :                             Constant::Units::J,
    1578       44391 :                             state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
    1579             :                             OutputProcessor::TimeStepType::Zone,
    1580             :                             OutputProcessor::StoreType::Sum,
    1581       44391 :                             surface.Name);
    1582             : 
    1583       44391 :         if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1584       76348 :             SetupOutputVariable(state,
    1585             :                                 "Surface Inside Face Solar Radiation Heat Gain Rate",
    1586             :                                 Constant::Units::W,
    1587       38174 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
    1588             :                                 OutputProcessor::TimeStepType::Zone,
    1589             :                                 OutputProcessor::StoreType::Average,
    1590       38174 :                                 surface.Name);
    1591       76348 :             SetupOutputVariable(state,
    1592             :                                 "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
    1593             :                                 Constant::Units::W_m2,
    1594       38174 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
    1595             :                                 OutputProcessor::TimeStepType::Zone,
    1596             :                                 OutputProcessor::StoreType::Average,
    1597       38174 :                                 surface.Name);
    1598       76348 :             SetupOutputVariable(state,
    1599             :                                 "Surface Inside Face Solar Radiation Heat Gain Energy",
    1600             :                                 Constant::Units::J,
    1601       38174 :                                 state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
    1602             :                                 OutputProcessor::TimeStepType::Zone,
    1603             :                                 OutputProcessor::StoreType::Sum,
    1604       38174 :                                 surface.Name);
    1605             : 
    1606       76348 :             SetupOutputVariable(state,
    1607             :                                 "Surface Inside Face Lights Radiation Heat Gain Rate",
    1608             :                                 Constant::Units::W,
    1609       38174 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
    1610             :                                 OutputProcessor::TimeStepType::Zone,
    1611             :                                 OutputProcessor::StoreType::Average,
    1612       38174 :                                 surface.Name);
    1613       76348 :             SetupOutputVariable(state,
    1614             :                                 "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
    1615             :                                 Constant::Units::W_m2,
    1616       38174 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
    1617             :                                 OutputProcessor::TimeStepType::Zone,
    1618             :                                 OutputProcessor::StoreType::Average,
    1619       38174 :                                 surface.Name);
    1620       76348 :             SetupOutputVariable(state,
    1621             :                                 "Surface Inside Face Lights Radiation Heat Gain Energy",
    1622             :                                 Constant::Units::J,
    1623       38174 :                                 state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
    1624             :                                 OutputProcessor::TimeStepType::Zone,
    1625             :                                 OutputProcessor::StoreType::Sum,
    1626       38174 :                                 surface.Name);
    1627             :         }
    1628             : 
    1629       88782 :         SetupOutputVariable(state,
    1630             :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
    1631             :                             Constant::Units::W,
    1632       44391 :                             state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
    1633             :                             OutputProcessor::TimeStepType::Zone,
    1634             :                             OutputProcessor::StoreType::Average,
    1635       44391 :                             surface.Name);
    1636       88782 :         SetupOutputVariable(state,
    1637             :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
    1638             :                             Constant::Units::W_m2,
    1639       44391 :                             state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
    1640             :                             OutputProcessor::TimeStepType::Zone,
    1641             :                             OutputProcessor::StoreType::Average,
    1642       44391 :                             surface.Name);
    1643       88782 :         SetupOutputVariable(state,
    1644             :                             "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
    1645             :                             Constant::Units::J,
    1646       44391 :                             state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
    1647             :                             OutputProcessor::TimeStepType::Zone,
    1648             :                             OutputProcessor::StoreType::Sum,
    1649       44391 :                             surface.Name);
    1650             : 
    1651       88782 :         SetupOutputVariable(state,
    1652             :                             "Surface Inside Face System Radiation Heat Gain Rate",
    1653             :                             Constant::Units::W,
    1654       44391 :                             state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
    1655             :                             OutputProcessor::TimeStepType::Zone,
    1656             :                             OutputProcessor::StoreType::Average,
    1657       44391 :                             surface.Name);
    1658       88782 :         SetupOutputVariable(state,
    1659             :                             "Surface Inside Face System Radiation Heat Gain Rate per Area",
    1660             :                             Constant::Units::W_m2,
    1661       44391 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
    1662             :                             OutputProcessor::TimeStepType::Zone,
    1663             :                             OutputProcessor::StoreType::Average,
    1664       44391 :                             surface.Name);
    1665       88782 :         SetupOutputVariable(state,
    1666             :                             "Surface Inside Face System Radiation Heat Gain Energy",
    1667             :                             Constant::Units::J,
    1668       44391 :                             state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
    1669             :                             OutputProcessor::TimeStepType::Zone,
    1670             :                             OutputProcessor::StoreType::Sum,
    1671       44391 :                             surface.Name);
    1672             : 
    1673       44391 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
    1674       36120 :             SetupOutputVariable(state,
    1675             :                                 "Surface Outside Face Outdoor Air Drybulb Temperature",
    1676             :                                 Constant::Units::C,
    1677       18060 :                                 state.dataSurface->SurfOutDryBulbTemp(loop),
    1678             :                                 OutputProcessor::TimeStepType::Zone,
    1679             :                                 OutputProcessor::StoreType::Average,
    1680       18060 :                                 surface.Name);
    1681       36120 :             SetupOutputVariable(state,
    1682             :                                 "Surface Outside Face Outdoor Air Wetbulb Temperature",
    1683             :                                 Constant::Units::C,
    1684       18060 :                                 state.dataSurface->SurfOutWetBulbTemp(loop),
    1685             :                                 OutputProcessor::TimeStepType::Zone,
    1686             :                                 OutputProcessor::StoreType::Average,
    1687       18060 :                                 surface.Name);
    1688       36120 :             SetupOutputVariable(state,
    1689             :                                 "Surface Outside Face Outdoor Air Wind Speed",
    1690             :                                 Constant::Units::m_s,
    1691       18060 :                                 state.dataSurface->SurfOutWindSpeed(loop),
    1692             :                                 OutputProcessor::TimeStepType::Zone,
    1693             :                                 OutputProcessor::StoreType::Average,
    1694       18060 :                                 surface.Name);
    1695       36120 :             SetupOutputVariable(state,
    1696             :                                 "Surface Outside Face Outdoor Air Wind Direction",
    1697             :                                 Constant::Units::deg,
    1698       18060 :                                 state.dataSurface->SurfOutWindDir(loop),
    1699             :                                 OutputProcessor::TimeStepType::Zone,
    1700             :                                 OutputProcessor::StoreType::Average,
    1701       18060 :                                 surface.Name);
    1702       36120 :             SetupOutputVariable(state,
    1703             :                                 "Surface Outside Face Convection Heat Gain Rate",
    1704             :                                 Constant::Units::W,
    1705       18060 :                                 state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
    1706             :                                 OutputProcessor::TimeStepType::Zone,
    1707             :                                 OutputProcessor::StoreType::Average,
    1708       18060 :                                 surface.Name);
    1709       36120 :             SetupOutputVariable(state,
    1710             :                                 "Surface Outside Face Convection Heat Gain Rate per Area",
    1711             :                                 Constant::Units::W_m2,
    1712       18060 :                                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
    1713             :                                 OutputProcessor::TimeStepType::Zone,
    1714             :                                 OutputProcessor::StoreType::Average,
    1715       18060 :                                 surface.Name);
    1716       36120 :             SetupOutputVariable(state,
    1717             :                                 "Surface Outside Face Convection Heat Gain Energy",
    1718             :                                 Constant::Units::J,
    1719       18060 :                                 state.dataHeatBalSurf->SurfQConvOutReport(loop),
    1720             :                                 OutputProcessor::TimeStepType::Zone,
    1721             :                                 OutputProcessor::StoreType::Sum,
    1722       18060 :                                 surface.Name);
    1723       36120 :             SetupOutputVariable(state,
    1724             :                                 "Surface Outside Face Convection Heat Transfer Coefficient",
    1725             :                                 Constant::Units::W_m2K,
    1726       18060 :                                 state.dataHeatBalSurf->SurfHConvExt(loop),
    1727             :                                 OutputProcessor::TimeStepType::Zone,
    1728             :                                 OutputProcessor::StoreType::Average,
    1729       18060 :                                 surface.Name);
    1730       36120 :             SetupOutputVariable(state,
    1731             :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
    1732             :                                 Constant::Units::W,
    1733       18060 :                                 state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
    1734             :                                 OutputProcessor::TimeStepType::Zone,
    1735             :                                 OutputProcessor::StoreType::Average,
    1736       18060 :                                 surface.Name);
    1737       36120 :             SetupOutputVariable(state,
    1738             :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
    1739             :                                 Constant::Units::W_m2,
    1740       18060 :                                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
    1741             :                                 OutputProcessor::TimeStepType::Zone,
    1742             :                                 OutputProcessor::StoreType::Average,
    1743       18060 :                                 surface.Name);
    1744       36120 :             SetupOutputVariable(state,
    1745             :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
    1746             :                                 Constant::Units::J,
    1747       18060 :                                 state.dataHeatBalSurf->SurfQRadOutReport(loop),
    1748             :                                 OutputProcessor::TimeStepType::Zone,
    1749             :                                 OutputProcessor::StoreType::Sum,
    1750       18060 :                                 surface.Name);
    1751       36120 :             SetupOutputVariable(state,
    1752             :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
    1753             :                                 Constant::Units::W_m2K,
    1754       18060 :                                 state.dataHeatBalSurf->SurfHAirExt(loop),
    1755             :                                 OutputProcessor::TimeStepType::Zone,
    1756             :                                 OutputProcessor::StoreType::Average,
    1757       18060 :                                 surface.Name);
    1758       36120 :             SetupOutputVariable(state,
    1759             :                                 "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
    1760             :                                 Constant::Units::W_m2K,
    1761       18060 :                                 state.dataHeatBalSurf->SurfHSkyExt(loop),
    1762             :                                 OutputProcessor::TimeStepType::Zone,
    1763             :                                 OutputProcessor::StoreType::Average,
    1764       18060 :                                 surface.Name);
    1765       36120 :             SetupOutputVariable(state,
    1766             :                                 "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
    1767             :                                 Constant::Units::W_m2K,
    1768       18060 :                                 state.dataHeatBalSurf->SurfHGrdExt(loop),
    1769             :                                 OutputProcessor::TimeStepType::Zone,
    1770             :                                 OutputProcessor::StoreType::Average,
    1771       18060 :                                 surface.Name);
    1772       36120 :             SetupOutputVariable(state,
    1773             :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
    1774             :                                 Constant::Units::W,
    1775       18060 :                                 state.dataHeatBalSurf->SurfQAirExtReport(loop),
    1776             :                                 OutputProcessor::TimeStepType::Zone,
    1777             :                                 OutputProcessor::StoreType::Average,
    1778       18060 :                                 surface.Name);
    1779       36120 :             SetupOutputVariable(state,
    1780             :                                 "Surface Outside Face Heat Emission to Air Rate",
    1781             :                                 Constant::Units::W,
    1782       18060 :                                 state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
    1783             :                                 OutputProcessor::TimeStepType::Zone,
    1784             :                                 OutputProcessor::StoreType::Average,
    1785       18060 :                                 surface.Name);
    1786             : 
    1787       18060 :             if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1788       23714 :                 SetupOutputVariable(state,
    1789             :                                     "Surface Outside Face Solar Radiation Heat Gain Rate",
    1790             :                                     Constant::Units::W,
    1791       11857 :                                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
    1792             :                                     OutputProcessor::TimeStepType::Zone,
    1793             :                                     OutputProcessor::StoreType::Average,
    1794       11857 :                                     surface.Name);
    1795       23714 :                 SetupOutputVariable(state,
    1796             :                                     "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
    1797             :                                     Constant::Units::W_m2,
    1798       11857 :                                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
    1799             :                                     OutputProcessor::TimeStepType::Zone,
    1800             :                                     OutputProcessor::StoreType::Average,
    1801       11857 :                                     surface.Name);
    1802       23714 :                 SetupOutputVariable(state,
    1803             :                                     "Surface Outside Face Solar Radiation Heat Gain Energy",
    1804             :                                     Constant::Units::J,
    1805       11857 :                                     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
    1806             :                                     OutputProcessor::TimeStepType::Zone,
    1807             :                                     OutputProcessor::StoreType::Sum,
    1808       11857 :                                     surface.Name);
    1809             :             }
    1810             :         }
    1811       44391 :         if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
    1812       14898 :             surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
    1813        6699 :             surface.Class == DataSurfaces::SurfaceClass::Door) {
    1814             :             //      IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    1815       76342 :             SetupOutputVariable(state,
    1816             :                                 "Surface Inside Face Conduction Heat Transfer Rate",
    1817             :                                 Constant::Units::W,
    1818       38171 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
    1819             :                                 OutputProcessor::TimeStepType::Zone,
    1820             :                                 OutputProcessor::StoreType::Average,
    1821       38171 :                                 surface.Name);
    1822       76342 :             SetupOutputVariable(state,
    1823             :                                 "Surface Inside Face Conduction Heat Gain Rate",
    1824             :                                 Constant::Units::W,
    1825       38171 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
    1826             :                                 OutputProcessor::TimeStepType::Zone,
    1827             :                                 OutputProcessor::StoreType::Average,
    1828       38171 :                                 surface.Name);
    1829       76342 :             SetupOutputVariable(state,
    1830             :                                 "Surface Inside Face Conduction Heat Loss Rate",
    1831             :                                 Constant::Units::W,
    1832       38171 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
    1833             :                                 OutputProcessor::TimeStepType::Zone,
    1834             :                                 OutputProcessor::StoreType::Average,
    1835       38171 :                                 surface.Name);
    1836       76342 :             SetupOutputVariable(state,
    1837             :                                 "Surface Inside Face Conduction Heat Transfer Rate per Area",
    1838             :                                 Constant::Units::W_m2,
    1839       38171 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
    1840             :                                 OutputProcessor::TimeStepType::Zone,
    1841             :                                 OutputProcessor::StoreType::Average,
    1842       38171 :                                 surface.Name);
    1843       76342 :             SetupOutputVariable(state,
    1844             :                                 "Surface Inside Face Conduction Heat Transfer Energy",
    1845             :                                 Constant::Units::J,
    1846       38171 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
    1847             :                                 OutputProcessor::TimeStepType::Zone,
    1848             :                                 OutputProcessor::StoreType::Sum,
    1849       38171 :                                 surface.Name);
    1850             : 
    1851       38171 :             if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1852       76266 :                 SetupOutputVariable(state,
    1853             :                                     "Surface Outside Face Conduction Heat Transfer Rate",
    1854             :                                     Constant::Units::W,
    1855       38133 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
    1856             :                                     OutputProcessor::TimeStepType::Zone,
    1857             :                                     OutputProcessor::StoreType::Average,
    1858       38133 :                                     surface.Name);
    1859       76266 :                 SetupOutputVariable(state,
    1860             :                                     "Surface Outside Face Conduction Heat Gain Rate",
    1861             :                                     Constant::Units::W,
    1862       38133 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
    1863             :                                     OutputProcessor::TimeStepType::Zone,
    1864             :                                     OutputProcessor::StoreType::Average,
    1865       38133 :                                     surface.Name);
    1866       76266 :                 SetupOutputVariable(state,
    1867             :                                     "Surface Outside Face Conduction Heat Loss Rate",
    1868             :                                     Constant::Units::W,
    1869       38133 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
    1870             :                                     OutputProcessor::TimeStepType::Zone,
    1871             :                                     OutputProcessor::StoreType::Average,
    1872       38133 :                                     surface.Name);
    1873       76266 :                 SetupOutputVariable(state,
    1874             :                                     "Surface Outside Face Conduction Heat Transfer Rate per Area",
    1875             :                                     Constant::Units::W_m2,
    1876       38133 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
    1877             :                                     OutputProcessor::TimeStepType::Zone,
    1878             :                                     OutputProcessor::StoreType::Average,
    1879       38133 :                                     surface.Name);
    1880       76266 :                 SetupOutputVariable(state,
    1881             :                                     "Surface Outside Face Conduction Heat Transfer Energy",
    1882             :                                     Constant::Units::J,
    1883       38133 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
    1884             :                                     OutputProcessor::TimeStepType::Zone,
    1885             :                                     OutputProcessor::StoreType::Sum,
    1886       38133 :                                     surface.Name);
    1887             : 
    1888       76266 :                 SetupOutputVariable(state,
    1889             :                                     "Surface Average Face Conduction Heat Transfer Rate",
    1890             :                                     Constant::Units::W,
    1891       38133 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
    1892             :                                     OutputProcessor::TimeStepType::Zone,
    1893             :                                     OutputProcessor::StoreType::Average,
    1894       38133 :                                     surface.Name);
    1895       76266 :                 SetupOutputVariable(state,
    1896             :                                     "Surface Average Face Conduction Heat Gain Rate",
    1897             :                                     Constant::Units::W,
    1898       38133 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
    1899             :                                     OutputProcessor::TimeStepType::Zone,
    1900             :                                     OutputProcessor::StoreType::Average,
    1901       38133 :                                     surface.Name);
    1902       76266 :                 SetupOutputVariable(state,
    1903             :                                     "Surface Average Face Conduction Heat Loss Rate",
    1904             :                                     Constant::Units::W,
    1905       38133 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
    1906             :                                     OutputProcessor::TimeStepType::Zone,
    1907             :                                     OutputProcessor::StoreType::Average,
    1908       38133 :                                     surface.Name);
    1909       76266 :                 SetupOutputVariable(state,
    1910             :                                     "Surface Average Face Conduction Heat Transfer Rate per Area",
    1911             :                                     Constant::Units::W_m2,
    1912       38133 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
    1913             :                                     OutputProcessor::TimeStepType::Zone,
    1914             :                                     OutputProcessor::StoreType::Average,
    1915       38133 :                                     surface.Name);
    1916       76266 :                 SetupOutputVariable(state,
    1917             :                                     "Surface Average Face Conduction Heat Transfer Energy",
    1918             :                                     Constant::Units::J,
    1919       38133 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
    1920             :                                     OutputProcessor::TimeStepType::Zone,
    1921             :                                     OutputProcessor::StoreType::Sum,
    1922       38133 :                                     surface.Name);
    1923             : 
    1924       76266 :                 SetupOutputVariable(state,
    1925             :                                     "Surface Heat Storage Rate",
    1926             :                                     Constant::Units::W,
    1927       38133 :                                     state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
    1928             :                                     OutputProcessor::TimeStepType::Zone,
    1929             :                                     OutputProcessor::StoreType::Average,
    1930       38133 :                                     surface.Name);
    1931       76266 :                 SetupOutputVariable(state,
    1932             :                                     "Surface Heat Storage Gain Rate",
    1933             :                                     Constant::Units::W,
    1934       38133 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
    1935             :                                     OutputProcessor::TimeStepType::Zone,
    1936             :                                     OutputProcessor::StoreType::Average,
    1937       38133 :                                     surface.Name);
    1938       76266 :                 SetupOutputVariable(state,
    1939             :                                     "Surface Heat Storage Loss Rate",
    1940             :                                     Constant::Units::W,
    1941       38133 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
    1942             :                                     OutputProcessor::TimeStepType::Zone,
    1943             :                                     OutputProcessor::StoreType::Average,
    1944       38133 :                                     surface.Name);
    1945       76266 :                 SetupOutputVariable(state,
    1946             :                                     "Surface Heat Storage Rate per Area",
    1947             :                                     Constant::Units::W_m2,
    1948       38133 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
    1949             :                                     OutputProcessor::TimeStepType::Zone,
    1950             :                                     OutputProcessor::StoreType::Average,
    1951       38133 :                                     surface.Name);
    1952       76266 :                 SetupOutputVariable(state,
    1953             :                                     "Surface Heat Storage Energy",
    1954             :                                     Constant::Units::J,
    1955       38133 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
    1956             :                                     OutputProcessor::TimeStepType::Zone,
    1957             :                                     OutputProcessor::StoreType::Sum,
    1958       38133 :                                     surface.Name);
    1959             :             }
    1960             : 
    1961             :             //      ENDIF
    1962             :             // CurrentModuleObject='Opaque Surfaces'
    1963             : 
    1964       76342 :             SetupOutputVariable(state,
    1965             :                                 "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
    1966             :                                 Constant::Units::W,
    1967       38171 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
    1968             :                                 OutputProcessor::TimeStepType::Zone,
    1969             :                                 OutputProcessor::StoreType::Average,
    1970       38171 :                                 surface.Name);
    1971             :         }
    1972       44391 :         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    1973         284 :             SetupOutputVariable(state,
    1974             :                                 "Surface Internal Source Location Temperature",
    1975             :                                 Constant::Units::C,
    1976         142 :                                 state.dataHeatBalSurf->SurfTempSource(loop),
    1977             :                                 OutputProcessor::TimeStepType::Zone,
    1978             :                                 OutputProcessor::StoreType::Average,
    1979         142 :                                 surface.Name);
    1980         284 :             SetupOutputVariable(state,
    1981             :                                 "Surface Internal User Specified Location Temperature",
    1982             :                                 Constant::Units::C,
    1983         142 :                                 state.dataHeatBalSurf->SurfTempUserLoc(loop),
    1984             :                                 OutputProcessor::TimeStepType::Zone,
    1985             :                                 OutputProcessor::StoreType::Average,
    1986         142 :                                 surface.Name);
    1987             :         }
    1988             : 
    1989       44391 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
    1990       12434 :             SetupOutputVariable(state,
    1991             :                                 "Surface Shading Device Is On Time Fraction",
    1992             :                                 Constant::Units::None,
    1993        6217 :                                 state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
    1994             :                                 OutputProcessor::TimeStepType::Zone,
    1995             :                                 OutputProcessor::StoreType::Average,
    1996        6217 :                                 surface.Name);
    1997        6217 :             SetupOutputVariable(state,
    1998             :                                 "Surface Storm Window On Off Status",
    1999             :                                 Constant::Units::None,
    2000        6217 :                                 state.dataSurface->SurfWinStormWinFlag(loop),
    2001             :                                 OutputProcessor::TimeStepType::Zone,
    2002             :                                 OutputProcessor::StoreType::Average,
    2003        6217 :                                 surface.Name);
    2004       12434 :             SetupOutputVariable(state,
    2005             :                                 "Surface Window Blind Slat Angle",
    2006             :                                 Constant::Units::deg,
    2007        6217 :                                 state.dataSurface->SurfWinSlatAngThisTSDeg(loop),
    2008             :                                 OutputProcessor::TimeStepType::Zone,
    2009             :                                 OutputProcessor::StoreType::Average,
    2010        6217 :                                 surface.Name);
    2011             :         }
    2012             :         //    IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    2013       44391 :         SetupOutputVariable(state,
    2014             :                             "Surface Inside Face Convection Classification Index",
    2015             :                             Constant::Units::None,
    2016       44391 :                             state.dataSurface->surfIntConv(loop).convClassRpt,
    2017             :                             OutputProcessor::TimeStepType::Zone,
    2018             :                             OutputProcessor::StoreType::Average,
    2019       44391 :                             surface.Name);
    2020       44391 :         SetupOutputVariable(state,
    2021             :                             "Surface Inside Face Convection Model Equation Index",
    2022             :                             Constant::Units::None,
    2023       44391 :                             state.dataSurface->surfIntConv(loop).hcModelEqRpt,
    2024             :                             OutputProcessor::TimeStepType::Zone,
    2025             :                             OutputProcessor::StoreType::Average,
    2026       44391 :                             surface.Name);
    2027       44391 :         SetupOutputVariable(state,
    2028             :                             "Surface Inside Face Convection Reference Air Index",
    2029             :                             Constant::Units::None,
    2030       44391 :                             state.dataSurface->SurfTAirRefRpt(loop),
    2031             :                             OutputProcessor::TimeStepType::Zone,
    2032             :                             OutputProcessor::StoreType::Average,
    2033       44391 :                             surface.Name);
    2034       44391 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    2035       17800 :             SetupOutputVariable(state,
    2036             :                                 "Surface Outside Face Convection Classification Index",
    2037             :                                 Constant::Units::None,
    2038       17800 :                                 state.dataSurface->surfExtConv(loop).convClassRpt,
    2039             :                                 OutputProcessor::TimeStepType::Zone,
    2040             :                                 OutputProcessor::StoreType::Average,
    2041       17800 :                                 surface.Name);
    2042       17800 :             SetupOutputVariable(state,
    2043             :                                 "Surface Outside Face Forced Convection Model Equation Index",
    2044             :                                 Constant::Units::None,
    2045       17800 :                                 state.dataSurface->surfExtConv(loop).hfModelEqRpt,
    2046             :                                 OutputProcessor::TimeStepType::Zone,
    2047             :                                 OutputProcessor::StoreType::Average,
    2048       17800 :                                 surface.Name);
    2049       17800 :             SetupOutputVariable(state,
    2050             :                                 "Surface Outside Face Natural Convection Model Equation Index",
    2051             :                                 Constant::Units::None,
    2052       17800 :                                 state.dataSurface->surfExtConv(loop).hnModelEqRpt,
    2053             :                                 OutputProcessor::TimeStepType::Zone,
    2054             :                                 OutputProcessor::StoreType::Average,
    2055       17800 :                                 surface.Name);
    2056             :         }
    2057             : 
    2058       88782 :         SetupOutputVariable(state,
    2059             :                             "Surface Inside Face Heat Source Gain Rate per Area",
    2060             :                             Constant::Units::W_m2,
    2061       44391 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
    2062             :                             OutputProcessor::TimeStepType::Zone,
    2063             :                             OutputProcessor::StoreType::Average,
    2064       44391 :                             surface.Name);
    2065       88782 :         SetupOutputVariable(state,
    2066             :                             "Surface Outside Face Heat Source Gain Rate per Area",
    2067             :                             Constant::Units::W_m2,
    2068       44391 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
    2069             :                             OutputProcessor::TimeStepType::Zone,
    2070             :                             OutputProcessor::StoreType::Average,
    2071       44391 :                             surface.Name);
    2072             : 
    2073             :         //     ENDIF
    2074       44391 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    2075         596 :             SetupOutputVariable(state,
    2076             :                                 "Surface Construction Index",
    2077             :                                 Constant::Units::None,
    2078         596 :                                 surface.Construction,
    2079             :                                 OutputProcessor::TimeStepType::Zone,
    2080             :                                 OutputProcessor::StoreType::Average,
    2081         596 :                                 surface.Name);
    2082             :         }
    2083             :     }
    2084        1592 :     SetupOutputVariable(state,
    2085             :                         "Site Total Surface Heat Emission to Air",
    2086             :                         Constant::Units::J,
    2087         796 :                         state.dataHeatBalSurf->SumSurfaceHeatEmission,
    2088             :                         OutputProcessor::TimeStepType::Zone,
    2089             :                         OutputProcessor::StoreType::Sum,
    2090             :                         "Environment");
    2091         796 : }
    2092             : 
    2093        6443 : void InitThermalAndFluxHistories(EnergyPlusData &state)
    2094             : {
    2095             : 
    2096             :     // SUBROUTINE INFORMATION:
    2097             :     //       AUTHOR         George Walton
    2098             :     //       DATE WRITTEN   March 1978
    2099             :     //       RE-ENGINEERED  Feb98 (RKS)
    2100             : 
    2101             :     // PURPOSE OF THIS SUBROUTINE:
    2102             :     // This subroutine sets the initial temperature and flux histories
    2103             :     // needed for a stable and reasonable heat balance solution starting
    2104             :     // point.
    2105             : 
    2106             :     // METHODOLOGY EMPLOYED:
    2107             :     // This subroutine assumes that the simulation is at steady state at
    2108             :     // the beginning and then begins to vary.  Thus, the temperatures, the
    2109             :     // fluxes. and their histories can all be set to the same value.  Some
    2110             :     // of the initializations depend on the surface characteristics.  This
    2111             :     // requires a DO loop to perform the proper calculation.
    2112             : 
    2113             :     // REFERENCES:
    2114             :     // (I)BLAST legacy routine INITTH
    2115             : 
    2116             :     // First do the "bulk" initializations of arrays sized to NumOfZones
    2117       55104 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2118             :         // TODO: Reinitializing this entire struct may cause diffs
    2119       48661 :         new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
    2120             :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2121       48661 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
    2122       48661 :         thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2123       48661 :         thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
    2124       48661 :         state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
    2125             :     }
    2126       55094 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    2127       48651 :         thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
    2128        6443 :     }
    2129             :     // Reset spaceHeatBalance even if doSpaceHeatBalance is false, beause spaceHB is used to gether zoneHB in some cases
    2130       55248 :     for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
    2131       48805 :         new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
    2132             :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2133       48805 :         thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2134       48805 :         thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
    2135        6443 :     }
    2136             : 
    2137             :     // "Bulk" initializations of arrays sized to TotSurfaces
    2138       55104 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2139       97466 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2140       48805 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2141       48805 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2142       48805 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2143      477751 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2144      428946 :                 state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2145      428946 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;        // module level array
    2146      428946 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp;     // module level array
    2147      428946 :                 state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
    2148      428946 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    2149      428946 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    2150      428946 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    2151      428946 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    2152      428946 :                 state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
    2153      428946 :                 state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
    2154      428946 :                 state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
    2155      428946 :                 state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
    2156      428946 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
    2157      428946 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
    2158      428946 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
    2159      428946 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
    2160      428946 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
    2161      428946 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
    2162      428946 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
    2163      428946 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
    2164      428946 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
    2165      428946 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
    2166      428946 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
    2167      428946 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
    2168      428946 :                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
    2169      428946 :                 state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
    2170      428946 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
    2171      428946 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
    2172      428946 :                 state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
    2173      428946 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
    2174      428946 :                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
    2175      428946 :                 state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
    2176      428946 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
    2177             :             } // end of  Surf array
    2178       48805 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2179       48805 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2180       48805 :             if (firstSurfOpaq >= 0) {
    2181      417310 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2182      368505 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
    2183      368505 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
    2184      368505 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
    2185      368505 :                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2186             :                 } // end of Zone Surf
    2187             :             }
    2188       48805 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2189       48805 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2190       48805 :             if (firstSurfWin >= 0) {
    2191      109236 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2192             :                     // Initialize window frame and divider temperatures
    2193       60431 :                     state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2194       60431 :                     state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2195       60431 :                     state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2196       60431 :                     state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2197       60431 :                     state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2198       60431 :                     state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2199             : 
    2200             :                     // Initialize previous-timestep shading indicators
    2201       60431 :                     state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2202       60431 :                     state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2203             :                 } // end of Zone Surf
    2204             :             }
    2205       48661 :         }
    2206             :     } // end of Zone
    2207             : 
    2208             :     // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
    2209       55104 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2210       97466 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2211       48805 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2212       48805 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2213       48805 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2214      976100 :             for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2215     9077269 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2216     8149974 :                     state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2217     8149974 :                     state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2218     8149974 :                     state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2219     8149974 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2220             :                 }
    2221             :             }
    2222       48661 :         }
    2223             :     }
    2224        6443 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2225       15859 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2226       29406 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2227       14751 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2228       14751 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2229       14751 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2230      154741 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2231      139990 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    2232             :                 }
    2233      295020 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2234     2940079 :                     for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2235     2659810 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2236     2659810 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2237     2659810 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2238     2659810 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2239             :                     }
    2240             :                 }
    2241       14655 :             }
    2242             :         }
    2243             :     }
    2244        6443 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    2245        1170 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2246        1770 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2247         885 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2248         885 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2249         885 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2250        7313 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2251      128560 :                     for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2252      122132 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2253      122132 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2254      122132 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2255      122132 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2256      122132 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
    2257      122132 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
    2258             :                     }
    2259             :                 }
    2260         885 :             }
    2261             :         }
    2262             :     }
    2263        6443 :     state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    2264             : 
    2265             :     // Perform other initializations that depend on the surface characteristics
    2266       71812 :     for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
    2267     4691120 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2268     4625751 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2269             :             // Reset outside boundary conditions if necessary
    2270     4625751 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2271     1765646 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2272     2860105 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2273      217076 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2274      217076 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2275     2643029 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2276       18169 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2277       18169 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2278             :             }
    2279             :             // Initialize the flux histories
    2280     4625751 :             state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
    2281     4625751 :                 state.dataConstruction->Construct(surface.Construction).UValue *
    2282     4625751 :                 (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
    2283     4625751 :             state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2284       65369 :         }
    2285             :     }
    2286      435394 :     for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2287      428951 :         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    2288          30 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
    2289          30 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
    2290             :         }
    2291        6443 :     }
    2292             :     // Initialize Kiva convection algorithms
    2293        6699 :     for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
    2294         256 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
    2295         256 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
    2296         256 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
    2297        6443 :     }
    2298        6443 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2299      141194 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2300      139990 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2301      139990 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2302     1049280 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2303      996816 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2304             :                 }
    2305      139990 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2306       79320 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2307       75354 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2308       75354 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2309             :                 }
    2310       83560 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2311       39820 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2312       37829 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2313       37829 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2314             :                 }
    2315             :             }
    2316      848884 :             for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
    2317      708894 :                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2318      708894 :                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2319             :             }
    2320        1204 :         }
    2321             :     }
    2322             : 
    2323        6443 :     if (state.dataSurface->TotOSCM >= 1) {
    2324         292 :         for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
    2325         202 :             auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
    2326         202 :             thisOSC.TConv = 20.0;
    2327         202 :             thisOSC.HConv = 4.0;
    2328         202 :             thisOSC.TRad = 20.0;
    2329         202 :             thisOSC.HRad = 4.0;
    2330             :         }
    2331             :     }
    2332        6443 : }
    2333             : 
    2334       10122 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
    2335             : {
    2336             :     // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
    2337       20244 :     for (int SurfNum : state.dataHeatBalSurf->SurfMovInsulIndexList) {
    2338       10122 :         Real64 MovInsulSchedVal = ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->SurfSchedMovInsulExt(SurfNum));
    2339       10122 :         if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
    2340        6075 :             state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum) = false;
    2341        6075 :             int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    2342        6075 :             auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(
    2343        6075 :                 state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)));
    2344        6075 :             assert(thisMaterial != nullptr);
    2345        6075 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
    2346        6075 :             state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
    2347        6075 :             state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
    2348        6075 :             continue;
    2349        6075 :         }
    2350        4047 :         int const MaterialIndex(state.dataSurface->SurfMaterialMovInsulExt(SurfNum));
    2351        4047 :         auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(MaterialIndex));
    2352        4047 :         assert(thisMaterial != nullptr);
    2353        4047 :         Material::Group const MaterialGroupNum(state.dataMaterial->Material(MaterialIndex)->group);
    2354        4047 :         state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum) = true;
    2355        4047 :         state.dataHeatBalSurf->SurfMovInsulHExt(SurfNum) = 1.0 / (MovInsulSchedVal * thisMaterial->Resistance);
    2356        4047 :         if (MaterialGroupNum == Material::Group::WindowGlass || MaterialGroupNum == Material::Group::GlassEquivalentLayer) {
    2357        2022 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - thisMaterial->Trans - thisMaterial->ReflectSolBeamFront);
    2358             :         } else {
    2359        2025 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
    2360             :         }
    2361        4047 :         state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
    2362        4047 :         state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
    2363       10122 :     }
    2364       10122 : }
    2365             : 
    2366       10122 : void EvalInsideMovableInsulation(EnergyPlusData &state)
    2367             : {
    2368             :     // This subroutine determines whether or not inside movable insulation is present at the current time.
    2369       20244 :     for (int SurfNum : state.dataHeatBalSurf->SurfMovInsulIndexList) {
    2370       10122 :         Real64 MovInsulSchedVal = ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->SurfSchedMovInsulInt(SurfNum));
    2371       10122 :         if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
    2372        4047 :             state.dataHeatBalSurf->SurfMovInsulIntPresent(SurfNum) = false;
    2373        4047 :             int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    2374        4047 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    2375        4047 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
    2376        4047 :             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
    2377        4047 :             continue;
    2378        4047 :         }
    2379        6075 :         int const MaterialIndex(state.dataSurface->SurfMaterialMovInsulInt(SurfNum));
    2380        6075 :         auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(MaterialIndex));
    2381        6075 :         assert(thisMaterial != nullptr);
    2382        6075 :         Material::Group const MaterialGroupNum(thisMaterial->group);
    2383        6075 :         state.dataHeatBalSurf->SurfMovInsulIntPresent(SurfNum) = true;
    2384        6075 :         state.dataHeatBalSurf->SurfMovInsulHInt(SurfNum) = 1.0 / (MovInsulSchedVal * thisMaterial->Resistance);
    2385        6075 :         if (MaterialGroupNum == Material::Group::WindowGlass || MaterialGroupNum == Material::Group::GlassEquivalentLayer) {
    2386           0 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - thisMaterial->Trans - thisMaterial->ReflectSolBeamFront);
    2387             :         } else {
    2388        6075 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisMaterial->AbsorpSolar;
    2389             :         }
    2390        6075 :         state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisMaterial->AbsorpThermal;
    2391       10122 :     }
    2392       10122 : }
    2393             : 
    2394     2804678 : void InitSolarHeatGains(EnergyPlusData &state)
    2395             : {
    2396             : 
    2397             :     // SUBROUTINE INFORMATION:
    2398             :     //       AUTHOR         Anonymous
    2399             :     //       DATE WRITTEN   July 1977
    2400             :     //       MODIFIED       Mar99 (FW): handle movable interior shades and
    2401             :     //                                  switchable glazing
    2402             :     //                      Oct99 (FW): account for Window5 glass calculation approach
    2403             :     //                      May01 (FW): handle interior and exterior blinds
    2404             :     //                      Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
    2405             :     //                      May06 (RR): handle exterior window screens
    2406             :     //       RE-ENGINEERED  Feb98 (RKS)
    2407             : 
    2408             :     // PURPOSE OF THIS SUBROUTINE:
    2409             :     // This subroutine initializes the arrays associated with solar heat
    2410             :     // gains for both individual surfaces and for zones.  As a result,
    2411             :     // this routine sets the following variable arrays:
    2412             :     // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
    2413             :     // SurfWinQRadSWwinAbs (for windows)
    2414             : 
    2415             :     // METHODOLOGY EMPLOYED:
    2416             :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    2417             :     // sun is up, various calculations are made.
    2418             : 
    2419             :     // REFERENCES:
    2420             :     // (I)BLAST legacy routine QSUN
    2421             : 
    2422     2804678 :     auto &Surface = state.dataSurface->Surface;
    2423             : 
    2424             :     // Using/Aliasing
    2425             :     using Dayltg::TransTDD;
    2426             :     using General::POLYF;
    2427             :     using SolarShading::CalcInteriorSolarDistribution;
    2428             :     using namespace DataWindowEquivalentLayer;
    2429             :     using SolarShading::SurfaceScheduledSolarInc;
    2430             :     using SolarShading::WindowScheduledSolarAbs;
    2431             : 
    2432     2804678 :     auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
    2433     2804678 :     auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
    2434     2804678 :     auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
    2435             : 
    2436    22672022 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2437    19867344 :         state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
    2438    19867344 :         state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
    2439    19867344 :         state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
    2440    19867344 :         state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
    2441    19867344 :         state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
    2442    19867344 :         state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
    2443             : 
    2444    19867344 :         state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
    2445    19867344 :         state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
    2446    19867344 :         state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
    2447    19867344 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
    2448    19867344 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
    2449    19867344 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
    2450    19867344 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
    2451    19867344 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
    2452    19867344 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
    2453             :     }
    2454    22667978 :     for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2455    19863300 :         state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
    2456             :     }
    2457    22672022 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2458    39783288 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2459    19915944 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2460    19915944 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2461    19915944 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2462   168309598 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2463   148393654 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
    2464   148393654 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
    2465   148393654 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
    2466   148393654 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
    2467   148393654 :                 state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
    2468   148393654 :                 state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
    2469   148393654 :                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2470   148393654 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
    2471   148393654 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
    2472             :             }
    2473             : 
    2474    19915944 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2475    19915944 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2476    43139106 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2477             :                 // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
    2478    23223162 :                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
    2479    23223162 :                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
    2480    23223162 :                 state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
    2481    23223162 :                 state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
    2482    23223162 :                 state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
    2483    23223162 :                 state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
    2484    23223162 :                 state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
    2485    23223162 :                 state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
    2486    23223162 :                 state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
    2487    23223162 :                 state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
    2488             :             }
    2489             : 
    2490    43139106 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2491    23223162 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
    2492    23223162 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
    2493    23223162 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
    2494    23223162 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
    2495    23223162 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
    2496    23223162 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
    2497    23223162 :                 state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
    2498    23223162 :                 state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
    2499    23223162 :                 state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
    2500             :             }
    2501    43139106 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2502    23223162 :                 state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
    2503    23223162 :                 state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
    2504    23223162 :                 state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
    2505    23223162 :                 state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
    2506    23223162 :                 state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
    2507    23223162 :                 state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
    2508    23223162 :                 state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
    2509             :             }
    2510   159327552 :             for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2511   301973742 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2512   162562134 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
    2513             :                 }
    2514             :             }
    2515    19867344 :         }
    2516             :     }
    2517     2804678 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    2518       46840 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2519       46044 :             state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2520       46044 :             state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2521             :         }
    2522             :     }
    2523             :     bool currSolRadPositive =
    2524     2804678 :         state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
    2525     2804678 :     bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
    2526     2804678 :     bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
    2527     2804678 :     bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
    2528     2804678 :                       sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
    2529     2804678 :     state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
    2530             : 
    2531     2804678 :     if (currSolRadPositive || resetSolar) {
    2532    91095138 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2533    89674751 :             state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2534    89674751 :             state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2535    89674751 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2536    89674751 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2537    89674751 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
    2538             : 
    2539    89674751 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
    2540    89674751 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
    2541    89674751 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
    2542    89674751 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
    2543             : 
    2544    89674751 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
    2545    89674751 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
    2546    89674751 :             state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
    2547    89674751 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
    2548    89674751 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
    2549             : 
    2550    89674751 :             state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
    2551    89674751 :             state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
    2552             :         }
    2553    11508170 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2554    10087783 :             state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
    2555    10087783 :             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
    2556    10087783 :             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
    2557    10087783 :             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
    2558    10087783 :             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
    2559    10087783 :             state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
    2560    10087783 :             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2561    10087783 :             state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2562    10087783 :             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2563    10087783 :             state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2564             :         }
    2565    11510238 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2566    20204542 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2567    10114691 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2568    10114691 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2569    10114691 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2570    21963368 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2571    11848677 :                     state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
    2572    11848677 :                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
    2573    11848677 :                     state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
    2574    11848677 :                     state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
    2575    11848677 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    2576    11848677 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
    2577    11848677 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
    2578    11848677 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
    2579    11848677 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
    2580    11848677 :                     state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
    2581             :                 }
    2582    21963368 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2583    11848677 :                     state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
    2584    11848677 :                     state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
    2585    11848677 :                     state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
    2586    11848677 :                     state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
    2587    11848677 :                     state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
    2588    11848677 :                     state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
    2589    11848677 :                     state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
    2590    11848677 :                     state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
    2591    11848677 :                     state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
    2592    11848677 :                     state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
    2593    11848677 :                     state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
    2594    11848677 :                     state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
    2595    11848677 :                     state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
    2596             :                 }
    2597    21963368 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2598    11848677 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
    2599    11848677 :                     state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
    2600    11848677 :                     state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
    2601    11848677 :                     state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
    2602    11848677 :                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2603    11848677 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2604    11848677 :                     state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
    2605    11848677 :                     state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
    2606    11848677 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
    2607             :                 }
    2608    21963368 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2609    11848677 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
    2610    11848677 :                     state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
    2611    11848677 :                     state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
    2612    11848677 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
    2613    11848677 :                     state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
    2614    11848677 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
    2615    11848677 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
    2616    11848677 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
    2617    11848677 :                     state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
    2618             :                 }
    2619             : 
    2620    21963368 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2621    11848677 :                     state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
    2622    11848677 :                     state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
    2623    11848677 :                     state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
    2624    11848677 :                     state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
    2625    11848677 :                     state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
    2626    11848677 :                     state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
    2627    11848677 :                     state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
    2628    11848677 :                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
    2629    11848677 :                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
    2630    11848677 :                     state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
    2631    11848677 :                     state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
    2632    11848677 :                     state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
    2633    11848677 :                     state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
    2634             :                 }
    2635    80959721 :                 for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
    2636   153862764 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2637    83017734 :                         state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
    2638             :                     }
    2639             :                 }
    2640    70802837 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
    2641   131780208 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2642    71092062 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
    2643             :                     }
    2644             :                 }
    2645    10089851 :             }
    2646             :         }
    2647             :     }
    2648     2804678 :     if (resetSolar) {
    2649     4267997 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2650     3764073 :             state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
    2651     3764073 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
    2652             :         }
    2653             : 
    2654             :         // TTD domes are currently not considered in the window list of a zone
    2655      503924 :         if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
    2656        1233 :             for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
    2657         822 :                 e.TransSolBeam = 0.0;
    2658         822 :                 e.TransSolDiff = 0.0;
    2659         822 :                 e.TransVisBeam = 0.0;
    2660         822 :                 e.TransVisDiff = 0.0;
    2661         822 :                 e.TransmittedSolar = 0.0;
    2662         822 :                 int SurfDome = e.Dome;
    2663         822 :                 state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
    2664         822 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
    2665         822 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
    2666        6576 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2667        5754 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
    2668             :                 }
    2669             :             }
    2670             :         }
    2671             : 
    2672      503924 :         if (state.dataSurface->CalcSolRefl) {
    2673       30161 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2674       27071 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
    2675       27071 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
    2676       27071 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
    2677             :             }
    2678             :         }
    2679    34076902 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2680    33572978 :             state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
    2681    33572978 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
    2682    33572978 :             state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
    2683    33572978 :             state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
    2684    33572978 :             state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
    2685    33572978 :             state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
    2686    33572978 :             state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
    2687             :         }
    2688             :     }
    2689     2804678 :     if (currSolRadPositive) { // Sun is up, calculate solar quantities
    2690      916463 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2691             :                                 state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
    2692      916463 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2693             :                                 state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
    2694      916463 :         Real64 GndReflSolarRad = 0.0;
    2695      916463 :         Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
    2696             : 
    2697    57018236 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2698    56101773 :             state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
    2699             :         }
    2700    57018236 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2701    56101773 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2702    56101773 :             state.dataSurface->SurfSkySolarInc(SurfNum) =
    2703    56101773 :                 state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2704    56101773 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2705        9408 :                 GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
    2706        4704 :                                   state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2707        4704 :                 Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
    2708             :             } else {
    2709    56097069 :                 GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    2710             :             }
    2711    56101773 :             state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
    2712    56101773 :             state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2713    56101773 :             state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
    2714             :         }
    2715      916463 :         if (state.dataSurface->CalcSolRefl) {
    2716             :             // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
    2717       22948 :             Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
    2718       22948 :             Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
    2719             :             // For Complex Fenestrations:
    2720      313495 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2721      290547 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2722             : 
    2723      290547 :                 Real64 GndSurfReflectance = 0.0;
    2724      290547 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2725           0 :                     GndSurfReflectance =
    2726           0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2727             :                 } else {
    2728      290547 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2729             :                 }
    2730      290547 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2731      290547 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2732      290547 :                 state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
    2733      290547 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2734      290547 :                 state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
    2735      290547 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2736      290547 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
    2737      290547 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
    2738      290547 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
    2739      290547 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
    2740      290547 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
    2741      290547 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
    2742      290547 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
    2743      290547 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
    2744      290547 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
    2745             :                 // TH2 CR 9056
    2746      290547 :                 state.dataSurface->SurfSkySolarInc(SurfNum) +=
    2747      290547 :                     currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
    2748      290547 :                     currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    2749      290547 :                 state.dataSurface->SurfGndSolarInc(SurfNum) =
    2750      290547 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
    2751      290547 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2752      290547 :                 state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2753             :             }
    2754             :         }
    2755             : 
    2756      916463 :         SolarShading::CalcWindowProfileAngles(state);
    2757             : 
    2758      916463 :         if (state.dataHeatBal->CalcWindowRevealReflection) SolarShading::CalcBeamSolarOnWinRevealSurface(state);
    2759             : 
    2760      916463 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2761         826 :             SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
    2762         826 :             if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2763         826 :                 SolarShading::CalcInteriorSolarDistributionWCESimple(state);
    2764             :             }
    2765             :         } else {
    2766      915637 :             SolarShading::CalcInteriorSolarDistribution(state);
    2767             :         }
    2768             : 
    2769     7240173 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2770             : 
    2771             :             // TH 3/24/2010 - QBV is not used!
    2772             :             // unused      QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
    2773             : 
    2774             :             // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
    2775             :             // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
    2776             :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2777             : 
    2778             :             // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
    2779             :             // QDforDaylight(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2780             :             //                          +EnclSolDS(ZoneNum)*DifSolarRad  &
    2781             :             //                          +EnclSolDG(ZoneNum)*GndSolarRad
    2782             : 
    2783             :             //  Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
    2784             :             //  EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
    2785             :             //  Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
    2786             :             //   diffuse solar rather than using weighted area*absorptance
    2787     6323710 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
    2788     6323710 :                 (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
    2789     6323710 :                 state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2790             : 
    2791             :             // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
    2792             :             // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
    2793             :             // and transmitted through interior windows
    2794             :             // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
    2795             :             // QD(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2796             :             //                +EnclSolDS(ZoneNum)*DifSolarRad  &
    2797             :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2798    12647420 :             state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
    2799     6323710 :                                                          state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
    2800     6323710 :                                                          state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2801             :         }
    2802             : 
    2803             :         // Flux of diffuse solar in each zone
    2804             : 
    2805     7240173 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2806     6323710 :             state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
    2807             :         }
    2808             : 
    2809      916463 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    2810       18955 :             for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2811       15164 :                 if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
    2812        7582 :                     Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
    2813        7582 :                     int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
    2814        7582 :                                                                                  1)); // Tuned Linear indexing
    2815       37910 :                     for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
    2816       30328 :                         if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
    2817        7582 :                             EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
    2818        7582 :                                                    state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
    2819             :                         }
    2820             :                     }
    2821        7582 :                     state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
    2822             :                 }
    2823             :             }
    2824             :         }
    2825             : 
    2826     7240173 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2827     6323710 :             if (state.dataHeatBalSurf->InterZoneWindow)
    2828       15164 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
    2829       15164 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2830             :             else
    2831     6308546 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2832             :         }
    2833             : 
    2834             :         //    RJH - 09-12-07 commented out report varariable calcs here since they refer to old distribution method
    2835             :         //    DO SurfNum = 1, TotSurfaces
    2836             :         //      IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
    2837             :         //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    2838             :         //      IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
    2839             :         //      ZoneNum = Surface(SurfNum)%Zone
    2840             :         // Diffuse solar entering zone through exterior windows is assumed to be uniformly
    2841             :         // distributed on inside face of surfaces of zone
    2842             :         //      DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) /  &
    2843             :         //        Zone(ZoneNum)%TotalSurfArea
    2844             :         //      DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) *  &
    2845             :         //        DifIncInsSurfIntensRep(SurfNum)
    2846             :         //      DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
    2847             :         //    END DO
    2848             : 
    2849             :         // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
    2850      916463 :         if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
    2851     2027294 :             for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
    2852     1719230 :                 Real64 GndSurfReflectance = 0.0;
    2853     1719230 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2854           0 :                     GndSurfReflectance =
    2855           0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2856             :                 } else {
    2857     1719230 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2858             :                 }
    2859             :                 // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2860     1719230 :                 Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2861     1719230 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
    2862     1719230 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2863     1719230 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2864     1719230 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2865             :                 // Incident direct (unreflected) beam
    2866     1719230 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2867     1719230 :                     currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
    2868             :                 // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2869     1719230 :                 state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2870             :                 // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2871     1719230 :                 state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2872             :                 // Incident diffuse solar from beam-to-diffuse reflection from ground
    2873     1719230 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2874     1719230 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2875             :                 // Incident diffuse solar from sky diffuse reflection from ground
    2876     1719230 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2877     1719230 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2878             :                 // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2879             :                 // in SkySolarInc.
    2880     1719230 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2881     1719230 :                     state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2882     1719230 :                     state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    2883             :             }
    2884             :         }
    2885             : 
    2886      916463 :         Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
    2887             : 
    2888    23551118 :         for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
    2889    22634655 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2890             :             // Regular surface
    2891    22634655 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2892    22634655 :             Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2893             :             // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2894    22634655 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    2895    22634655 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2896             : 
    2897             :             // Report variables for various incident solar quantities
    2898             :             // Incident direct (unreflected) beam
    2899    22634655 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2900    22634655 :                 currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    2901    22634655 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
    2902             : 
    2903    22634655 :             Real64 GndSurfReflectance = 0.0;
    2904    22634655 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2905        3528 :                 GndSurfReflectance =
    2906        3528 :                     state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2907             :             } else {
    2908    22631127 :                 GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2909             :             }
    2910             :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2911    22634655 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2912             :             // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2913    22634655 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2914             :             // Incident diffuse solar from beam-to-diffuse reflection from ground
    2915    22634655 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2916    22634655 :                 currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2917             : 
    2918             :             // Incident diffuse solar from sky diffuse reflection from ground
    2919    22634655 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2920    22634655 :                 currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2921             :             // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2922             :             // in SkySolarInc.
    2923             :             // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
    2924             :             // TH2 CR 9056
    2925    22634655 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2926    22634655 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2927    22634655 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    2928             : 
    2929    22634655 :             if (state.dataSurface->CalcSolRefl) {
    2930             :                 // Incident beam solar from beam-to-beam (specular) reflection from obstructions
    2931      173511 :                 state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    2932             :                 // Incident diffuse solar from beam-to-diffuse reflection from obstructions
    2933      173511 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
    2934      173511 :                     state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    2935             :                 // Incident diffuse solar from sky diffuse reflection from obstructions
    2936      173511 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    2937             :                 // TH2 CR 9056: Add reflections from obstructions to the total incident
    2938      347022 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
    2939      173511 :                                                                      state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
    2940      173511 :                                                                      state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
    2941             :             }
    2942      916463 :         }
    2943      917695 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    2944        1232 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
    2945        1232 :             int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;    // TDD: DOME object number
    2946        1232 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    2947        1232 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    2948             : 
    2949             :             // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
    2950             :             // by dividing out diffuse solar transmittance of TDD:DIFFUSER
    2951        1232 :             Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    2952             : 
    2953        1232 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
    2954        1232 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2955        1232 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
    2956        1232 :                                      TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
    2957             : 
    2958        2464 :             state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
    2959        1232 :                                                           state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
    2960        1232 :                                                           TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
    2961             : 
    2962        2464 :             state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
    2963        1232 :                                                           state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
    2964             :             // Incident direct (unreflected) beam
    2965        2464 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
    2966        2464 :                                                                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
    2967        1232 :                                                                                                       state.dataGlobal->TimeStep,
    2968        1232 :                                                                                                       SurfNum2) *
    2969             :                                                                     ConInc; // NOTE: sunlit and coninc array set to SurfNum2
    2970             : 
    2971             :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2972        1232 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
    2973        1232 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2974        1232 :                 (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2975        1232 :                  state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
    2976             :         }
    2977             : 
    2978      917079 :         for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
    2979         616 :             int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window;       // Daylighting shelf object number
    2980         616 :             int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
    2981         616 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    2982         616 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2983         616 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2984         616 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2985             :             // Shelf diffuse solar radiation
    2986             :             Real64 ShelfSolarRad =
    2987         616 :                 (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
    2988         616 :                      state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
    2989         616 :                  state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
    2990         616 :                 state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
    2991             : 
    2992         616 :             GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    2993         616 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2994           0 :                 GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
    2995             :             }
    2996             :             // Add all reflected solar from the outside shelf to the ground solar
    2997             :             // NOTE:  If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
    2998         616 :             state.dataSurface->SurfGndSolarInc(SurfNum) =
    2999         616 :                 GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
    3000             :         }
    3001             : 
    3002             :         // Calculate Exterior and Interior Absorbed Short Wave Radiation
    3003     7241412 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3004    12664766 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3005     6339817 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3006     6339817 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    3007     6339817 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    3008    53185870 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    3009    46846053 :                     int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    3010    46846053 :                     Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3011    46846053 :                     currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3012    46846053 :                     if (Surface(SurfNum).ExtSolar) {
    3013             :                         Real64 AbsExt =
    3014    13410979 :                             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
    3015    13410979 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3016    13410979 :                             state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
    3017    13410979 :                             AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
    3018             :                     }
    3019    46846053 :                     if (ConstrNum > 0) {
    3020    46846053 :                         int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
    3021    46846053 :                         if (SurfSolIncPtr == 0) {
    3022    46845465 :                             if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) {    // Opaque surface
    3023    46845465 :                                 int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
    3024    46845465 :                                 int InShelfSurf = 0;                                                // Inside daylighting shelf surface number
    3025    46845465 :                                 if (ShelfNum > 0) {
    3026           0 :                                     InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
    3027             :                                 }
    3028    46845465 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
    3029    46845465 :                                     state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
    3030    46845465 :                                 if (InShelfSurf > 0) { // Inside daylighting shelf
    3031             :                                     // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
    3032           0 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3033           0 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
    3034             :                                 } else { // Regular surface
    3035    46845465 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3036    46845465 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
    3037             :                                 }
    3038             :                             }
    3039             :                         } else {
    3040         588 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
    3041             :                         }
    3042             :                     }
    3043             :                 }
    3044     6339817 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3045     6339817 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3046    13852773 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    3047     7512956 :                     auto &surf = state.dataSurface->Surface(SurfNum);
    3048     7512956 :                     auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3049     7512956 :                     if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3050             :                         // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
    3051     7504446 :                         int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3052     7504446 :                         auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3053     7504446 :                         Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
    3054     7504446 :                         Real64 BeamSolar = currBeamSolar(SurfNum);                         // Local variable for BeamSolarRad
    3055     7504446 :                         Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum);  // Sky diffuse solar incident on a surface
    3056     7504446 :                         Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum);  // Ground diffuse solar incident on a surface
    3057             : 
    3058     7504446 :                         DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3059             : 
    3060    14994171 :                         if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
    3061     7489725 :                             !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3062     7488899 :                             int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3063    17211499 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3064     9722600 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3065             :                             }
    3066             : 
    3067     7488899 :                             if (IS_SHADED(ShadeFlag)) { // Shaded window
    3068             : 
    3069      184682 :                                 int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
    3070      184682 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3071             : 
    3072      184682 :                                 if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
    3073      116158 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3074       74692 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
    3075             :                                     }
    3076       41466 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
    3077      143216 :                                 } else if (ANY_BLIND(ShadeFlag)) { // Blind on
    3078       71430 :                                     int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    3079       71430 :                                     Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    3080             :                                     Real64 AbsDiffBlind;
    3081       71430 :                                     if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3082        3444 :                                         for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3083        1722 :                                             AbsDiffWin(Lay) = General::Interp(
    3084        1722 :                                                 constructionSh.BlAbsDiff(SurfWinSlatsAngIndex, Lay),
    3085        1722 :                                                 constructionSh.BlAbsDiff(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay),
    3086             :                                                 SurfWinSlatsAngInterpFac);
    3087        1722 :                                             AbsDiffWinGnd(Lay) = General::Interp(
    3088        1722 :                                                 constructionSh.BlAbsDiffGnd(SurfWinSlatsAngIndex, Lay),
    3089        1722 :                                                 constructionSh.BlAbsDiffGnd(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay),
    3090             :                                                 SurfWinSlatsAngInterpFac);
    3091        1722 :                                             AbsDiffWinSky(Lay) = General::Interp(
    3092        1722 :                                                 constructionSh.BlAbsDiffSky(SurfWinSlatsAngIndex, Lay),
    3093        3444 :                                                 constructionSh.BlAbsDiffSky(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay),
    3094             :                                                 SurfWinSlatsAngInterpFac);
    3095             :                                         }
    3096             :                                         AbsDiffBlind =
    3097        1722 :                                             General::Interp(constructionSh.AbsDiffBlind(SurfWinSlatsAngIndex),
    3098        3444 :                                                             constructionSh.AbsDiffBlind(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    3099             :                                                             SurfWinSlatsAngInterpFac);
    3100             :                                     } else {
    3101      143854 :                                         for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3102       74146 :                                             state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.BlAbsDiff(1, Lay);
    3103       74146 :                                             state.dataHeatBalSurfMgr->AbsDiffWinGnd(Lay) = constructionSh.BlAbsDiffGnd(1, Lay);
    3104       74146 :                                             state.dataHeatBalSurfMgr->AbsDiffWinSky(Lay) = constructionSh.BlAbsDiffSky(1, Lay);
    3105             :                                         }
    3106       69708 :                                         AbsDiffBlind = constructionSh.AbsDiffBlind(1);
    3107             :                                     }
    3108       71430 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
    3109             : 
    3110       71430 :                                     if (state.dataMaterial->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
    3111             :                                         DataWindowEquivalentLayer::Orientation::Horizontal) {
    3112       71430 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
    3113             :                                         Real64 AbsDiffBlindGnd;
    3114             :                                         Real64 AbsDiffBlindSky;
    3115       71430 :                                         if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3116        3444 :                                             AbsDiffBlindGnd = General::Interp(
    3117        1722 :                                                 constructionSh.AbsDiffBlindGnd(SurfWinSlatsAngIndex),
    3118        1722 :                                                 constructionSh.AbsDiffBlindGnd(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    3119             :                                                 SurfWinSlatsAngInterpFac);
    3120        3444 :                                             AbsDiffBlindSky = General::Interp(
    3121        1722 :                                                 constructionSh.AbsDiffBlindSky(SurfWinSlatsAngIndex),
    3122        3444 :                                                 constructionSh.AbsDiffBlindSky(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    3123             :                                                 SurfWinSlatsAngInterpFac);
    3124             :                                         } else {
    3125       69708 :                                             AbsDiffBlindGnd = constructionSh.AbsDiffBlindGnd(1);
    3126       69708 :                                             AbsDiffBlindSky = constructionSh.AbsDiffBlindSky(1);
    3127             :                                         }
    3128       71430 :                                         state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
    3129       71430 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
    3130       71430 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
    3131             :                                     }
    3132             :                                 }
    3133             : 
    3134             :                                 // Correct for shadowing of divider onto interior shading device (note that dividers are
    3135             :                                 // not allowed in windows with between-glass shade/blind)
    3136             : 
    3137      184682 :                                 if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0)
    3138         742 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3139             : 
    3140      184682 :                                 if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {        // Switchable glazing
    3141       71786 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
    3142      215358 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3143      143572 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
    3144      143572 :                                             Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
    3145             :                                     }
    3146             :                                 }
    3147             : 
    3148             :                             } // End of check if window has shading device on
    3149             : 
    3150     7488899 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3151    17211499 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3152     9722600 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3153     9722600 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
    3154     9722600 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3155             :                                 // SurfWinA is from InteriorSolarDistribution
    3156     9722600 :                                 if (ANY_BLIND(ShadeFlag)) {
    3157       75868 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3158       75868 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3159       75868 :                                     if (state.dataMaterial->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
    3160             :                                         DataWindowEquivalentLayer::Orientation::Horizontal) {
    3161       75868 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
    3162             :                                         Real64 AbsDiffGlassLayGnd; // System glass layer ground diffuse solar absorptance with blind on
    3163             :                                         Real64 AbsDiffGlassLaySky; // System glass layer sky diffuse solar absorptance with blind on
    3164       75868 :                                         if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3165        5166 :                                             AbsDiffGlassLayGnd = General::Interp(
    3166        1722 :                                                 constructionSh.BlAbsDiffGnd(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay),
    3167        1722 :                                                 constructionSh.BlAbsDiffGnd(
    3168        1722 :                                                     std::min(Material::MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay),
    3169        1722 :                                                 state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    3170        5166 :                                             AbsDiffGlassLaySky = General::Interp(
    3171        1722 :                                                 constructionSh.BlAbsDiffSky(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay),
    3172        1722 :                                                 constructionSh.BlAbsDiffSky(
    3173        3444 :                                                     std::min(Material::MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay),
    3174        1722 :                                                 state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    3175             :                                         } else {
    3176       74146 :                                             AbsDiffGlassLayGnd = constructionSh.BlAbsDiffGnd(1, Lay);
    3177       74146 :                                             AbsDiffGlassLaySky = constructionSh.BlAbsDiffSky(1, Lay);
    3178             :                                         }
    3179       75868 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3180       75868 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
    3181      151736 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
    3182       75868 :                                             state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3183             :                                     }
    3184             :                                 }
    3185             :                                 // Total solar absorbed in solid layer (W), for reporting
    3186     9722600 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3187     9722600 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3188             : 
    3189             :                                 // Total solar absorbed in all glass layers (W), for reporting
    3190     9722600 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3191             :                             }
    3192     7488899 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3193     7488899 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3194             :                             // Need to do it this way for now beaucse of scheduled surface gains. They do work only with
    3195             :                             // BSDF windows and overwriting absorbtances will work only for ordinary windows
    3196             :                             // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
    3197             :                             //   SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
    3198             :                             //   inExtWindowModel->isExternalLibraryModel() ) {
    3199             :                             //   TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
    3200             :                             //   for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
    3201             :                             //     SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
    3202             :                             //       ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
    3203             :                             //   }
    3204       15547 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    3205       12243 :                             int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
    3206             :                             // Number of solid layers in fenestration system (glass + shading)
    3207       12243 :                             int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
    3208             :                             // Current state for Complex Fenestration
    3209             :                             // Examine for schedule surface gain
    3210       12243 :                             Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
    3211             :                                 state,
    3212             :                                 SurfNum,
    3213       12243 :                                 ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
    3214             : 
    3215       46277 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3216       34034 :                                 if (SurfSolAbs != 0) {
    3217         294 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) =
    3218         294 :                                         ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->FenLayAbsSSG(SurfSolAbs).SchedPtrs(Lay));
    3219             :                                     // ABWin(Lay) = SurfWinA(SurfNum,Lay)
    3220         294 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
    3221             :                                 } else {
    3222             :                                     // Several notes about this equation.  First part is accounting for duffuse solar radiation for the ground
    3223             :                                     // and from the sky.  Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
    3224             :                                     // radiation originating from beam on exterior side.  Third item (SurfWinACFOverlap(SurfNum,Lay)) is
    3225             :                                     // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
    3226             :                                     // windows
    3227       33740 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3228       33740 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
    3229       33740 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
    3230       33740 :                                         state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3231       33740 :                                         state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
    3232             :                                 }
    3233             :                                 // Total solar absorbed in solid layer (W), for reporting
    3234       34034 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3235       34034 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3236             : 
    3237             :                                 // Total solar absorbed in all glass layers (W), for reporting
    3238       34034 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3239             :                             }
    3240       12243 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3241       12243 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3242             : 
    3243        3304 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    3244        2478 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3245             :                             // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
    3246             :                             int TotSolidLay =
    3247        2478 :                                 state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
    3248       11564 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3249             :                                 // Absorbed window components include:
    3250             :                                 // (1) beam solar radiation absorbed by all layers in the fenestration
    3251             :                                 // (2) sky and ground reflected duffuse solar radiation absorbed by all layers
    3252             :                                 // (3) diffuse short wave incident on the inside face of the fenestration.  The short wave internal sources
    3253             :                                 //     include light, ...
    3254        9086 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
    3255        9086 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3256        9086 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3257        9086 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
    3258             : 
    3259             :                                 // Total solar absorbed in solid layer (W), for reporting
    3260        9086 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3261        9086 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3262             : 
    3263             :                                 // Total solar absorbed in all glass layers (W), for reporting
    3264        9086 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3265             :                             }
    3266             : 
    3267        2478 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3268        2478 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3269         826 :                         } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3270         826 :                             int SurfNum2 = SurfNum;
    3271         826 :                             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3272           0 :                                 SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    3273             :                             }
    3274             : 
    3275             :                             std::pair<Real64, Real64> incomingAngle =
    3276         826 :                                 Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
    3277         826 :                             Real64 Theta = incomingAngle.first;
    3278         826 :                             Real64 Phi = incomingAngle.second;
    3279             : 
    3280             :                             std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
    3281         826 :                                 Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
    3282         826 :                                     state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
    3283             : 
    3284         826 :                             size_t totLayers = aLayer->getNumOfLayers();
    3285        1652 :                             for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
    3286         826 :                                 Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
    3287             :                                     Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
    3288             : 
    3289         826 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3290         826 :                                     AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3291             : 
    3292             :                                 // Total solar absorbed in solid layer (W), for reporting
    3293         826 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3294         826 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3295             : 
    3296             :                                 // Total solar absorbed in all glass layers (W), for reporting
    3297         826 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3298             :                             }
    3299         826 :                         }
    3300             : 
    3301             :                         // Solar absorbed by window frame and dividers
    3302     7504446 :                         int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
    3303     7504446 :                         if (FrDivNum > 0) {
    3304      410270 :                             Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum);                    // Frame, divider area (m2)
    3305      410270 :                             Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
    3306      410270 :                             Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
    3307      410270 :                             Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
    3308      410270 :                             Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
    3309      410270 :                             Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
    3310      410270 :                             Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
    3311      410270 :                             Real64 CosIncAngHorProj = 0.0;  // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
    3312      410270 :                             Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
    3313      410270 :                             Real64 FracSunLit = 0.0;        // Fraction of window sunlit this time step
    3314             :                             Real64 BeamFaceInc;             // Beam solar incident window plane this time step (W/m2)
    3315             :                             Real64 DifSolarFaceInc;         // Diffuse solar incident on window plane this time step (W/m2)
    3316      410270 :                             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3317      410270 :                             Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3318      410270 :                             if (FrArea > 0.0 || DivArea > 0.0) {
    3319      240670 :                                 FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    3320      240670 :                                 BeamFaceInc = currBeamSolarRad *
    3321      240670 :                                               state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    3322             :                                               CosInc;
    3323      240670 :                                 DifSolarFaceInc = SkySolarInc + GndSolarInc;
    3324             :                             }
    3325      410270 :                             if (FracSunLit > 0.0) {
    3326      183719 :                                 if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
    3327       19536 :                                     (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
    3328             :                                     // Dot products used to calculate beam solar incident on faces of
    3329             :                                     // frame and divider perpendicular to the glass surface.
    3330             :                                     // Note that SOLCOS is the current timestep's solar direction cosines.
    3331             :                                     //                  PhiWin = ASIN(WALCOS(3,SurfNum))
    3332             :                                     Real64 PhiWin =
    3333      155489 :                                         std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
    3334      155489 :                                     Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
    3335      155489 :                                     Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
    3336      155489 :                                     Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
    3337      155489 :                                     Real64 const cos_PhiWin(std::cos(PhiWin));
    3338      155489 :                                     Real64 const cos_PhiSun(std::cos(PhiSun));
    3339             :                                     CosIncAngHorProj =
    3340      155489 :                                         std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
    3341      155489 :                                     CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
    3342             :                                 }
    3343             :                             }
    3344             :                             // Frame solar
    3345             :                             // (A window shade or blind, if present, is assumed to not shade the frame, so no special
    3346             :                             // treatment of frame solar needed if window has an exterior shade or blind.)
    3347      410270 :                             if (FrArea > 0.0) {
    3348      240670 :                                 Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside offrame including solar
    3349      240670 :                                 Real64 FrIncSolarIn = 0.0; // Total solar incident on inside offrame including solar on frame projection (W/m2)
    3350      240670 :                                 Real64 TransDiffGl = 0.0;  // Diffuse solar transmittance
    3351      240670 :                                 if (FrProjOut > 0.0 || FrProjIn > 0.0) {
    3352             :                                     Real64 BeamFrHorFaceInc =
    3353      372244 :                                         currBeamSolarRad * CosIncAngHorProj *
    3354      186122 :                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
    3355      186122 :                                         FrArea;
    3356             :                                     Real64 BeamFrVertFaceInc =
    3357      372244 :                                         currBeamSolarRad * CosIncAngVertProj *
    3358      186122 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3359      186122 :                                         FrArea;
    3360             :                                     // Beam solar on outside of frame
    3361      186122 :                                     FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
    3362      186122 :                                     if (FrProjIn > 0.0) {
    3363      186122 :                                         Real64 TransGl = General::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3364      186122 :                                         TransDiffGl = thisConstruct.TransDiff;
    3365      186122 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3366       71044 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3367       71044 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3368       71044 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3369       71044 :                                             Real64 TransGlSh = General::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3370       71044 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3371       71044 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3372       71044 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3373             :                                         }
    3374             :                                         // Beam solar on inside of frame
    3375      186122 :                                         FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
    3376             :                                     }
    3377             :                                 }
    3378             :                                 // Beam plus diffuse solar on outside of frame
    3379      240670 :                                 FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
    3380      240670 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
    3381      240670 :                                     FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3382             :                                 // Add diffuse from beam reflected from window outside reveal surfaces
    3383      240670 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
    3384      240670 :                                                                                       state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
    3385      240670 :                                                                                       state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3386             : 
    3387             :                                 // Beam plus diffuse solar on inside of frame
    3388      240670 :                                 FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
    3389      240670 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3390             :                                 // Add diffuse from beam reflected from window inside reveal surfaces
    3391      240670 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
    3392      240670 :                                                                                      state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
    3393      240670 :                                                                                      state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3394             :                             }
    3395             : 
    3396             :                             // Divider solar
    3397             :                             // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
    3398             :                             // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
    3399             :                             // DivProjIn will be zero in this case.)
    3400      410270 :                             if (DivArea > 0.0) {                                                         // Solar absorbed by window divider
    3401      140164 :                                 Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3402      140164 :                                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    3403             :                                     // Suspended (between-glass) divider; account for effect glass on outside of divider
    3404             :                                     // (note that outside and inside projection for this type of divider are both zero)
    3405        8004 :                                     int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
    3406        8004 :                                     auto const *thisMaterial = dynamic_cast<Material::MaterialChild *>(state.dataMaterial->Material(MatNumGl));
    3407        8004 :                                     assert(thisMaterial != nullptr);
    3408        8004 :                                     Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
    3409        8004 :                                     Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
    3410        8004 :                                     Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3411        8004 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3412        8004 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3413        8004 :                                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3414           0 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3415           0 :                                         Real64 MatNumGlSh = constructionSh.LayerPoint(1);
    3416             :                                         auto const *thisMaterialSh =
    3417           0 :                                             dynamic_cast<Material::MaterialChild *>(state.dataMaterial->Material(MatNumGlSh));
    3418           0 :                                         assert(thisMaterialSh != nullptr);
    3419           0 :                                         Real64 TransGlSh = thisMaterialSh->Trans;
    3420           0 :                                         Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
    3421           0 :                                         Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
    3422           0 :                                         TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3423           0 :                                         ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
    3424           0 :                                         AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
    3425             :                                     }
    3426        8004 :                                     Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
    3427        8004 :                                     DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    3428             :                                 }
    3429             : 
    3430      140164 :                                 Real64 BeamDivHorFaceInc = 0.0;  // Beam solar on divider's horizontal outside projection faces (W/m2)
    3431      140164 :                                 Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
    3432             :                                 // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
    3433      140164 :                                 if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3434       95784 :                                     BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
    3435       95784 :                                                         DivProjOut *
    3436       95784 :                                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3437             :                                                         FracSunLit / DivArea;
    3438       95784 :                                     BeamDivVertFaceInc =
    3439       95784 :                                         currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
    3440       95784 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3441             :                                         DivArea;
    3442             :                                 }
    3443      140164 :                                 Real64 DivIncSolarOutBm =
    3444             :                                     0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
    3445      140164 :                                 Real64 DivIncSolarOutDif =
    3446             :                                     0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
    3447      140164 :                                 Real64 DivIncSolarInBm =
    3448             :                                     0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
    3449      140164 :                                 Real64 DivIncSolarInDif =
    3450             :                                     0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
    3451      271788 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
    3452      131624 :                                     !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
    3453      131624 :                                     DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
    3454      131624 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3455      131624 :                                     if (DivProjIn > 0.0) {
    3456       95784 :                                         Real64 TransGl = General::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3457       95784 :                                         Real64 TransDiffGl = thisConstruct.TransDiff;                       // Diffuse solar transmittance
    3458       95784 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3459       71044 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3460       71044 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3461       71044 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3462             : 
    3463       71044 :                                             Real64 TransGlSh = General::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3464             :                                             // Outer glass solar trans, refl, absorptance if switched
    3465       71044 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3466       71044 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3467             :                                             // Diffuse solar transmittance, switched construction
    3468       71044 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3469             :                                         }
    3470             :                                         // Beam plus diffuse solar on inside of divider
    3471             :                                         // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
    3472             :                                         // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
    3473             :                                         Real64 BeamDivHorFaceIncIn =
    3474       95784 :                                             currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
    3475       95784 :                                             (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3476       95784 :                                             FracSunLit / DivArea;
    3477             :                                         Real64 BeamDivVertFaceIncIn =
    3478       95784 :                                             currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
    3479       95784 :                                             DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
    3480       95784 :                                             FracSunLit / DivArea;
    3481       95784 :                                         DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
    3482       95784 :                                         DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
    3483             :                                     }
    3484             :                                 } else { // Exterior shade, screen or blind present
    3485             : 
    3486        8540 :                                     DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3487        8540 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3488        8540 :                                     DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3489        8540 :                                     DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3490             :                                 }
    3491      140164 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3492             :                                     // No exterior or between-glass shade, screen or blind
    3493      131624 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
    3494      131624 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
    3495             :                                     // Exterior shade, screen or blind
    3496        8540 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
    3497           0 :                                     int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
    3498           0 :                                     int SlatsAngIndexLower = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    3499           0 :                                     int SlatsAngIndexUpper = std::min(Material::MaxProfAngs, SlatsAngIndexLower + 1);
    3500           0 :                                     Real64 SlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    3501             : 
    3502             :                                     Real64 FrontDiffTrans;
    3503             :                                     Real64 TBlBmDif; // Blind diffuse-diffuse solar transmittance
    3504           0 :                                     if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3505           0 :                                         FrontDiffTrans = General::Interp(state.dataMaterial->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexLower),
    3506           0 :                                                                          state.dataMaterial->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexUpper),
    3507             :                                                                          SlatsAngInterpFac);
    3508           0 :                                         TBlBmDif = Window::InterpProfSlat(
    3509           0 :                                             state.dataMaterial->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower,
    3510           0 :                                                                                                    state.dataSurface->SurfWinProfAngIndex(SurfNum)),
    3511           0 :                                             state.dataMaterial->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper,
    3512           0 :                                                                                                    state.dataSurface->SurfWinProfAngIndex(SurfNum)),
    3513           0 :                                             state.dataMaterial->Blind(BlNum).SolFrontBeamDiffTrans(
    3514             :                                                 SlatsAngIndexLower,
    3515           0 :                                                 std::min(Material::MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)),
    3516           0 :                                             state.dataMaterial->Blind(BlNum).SolFrontBeamDiffTrans(
    3517             :                                                 SlatsAngIndexUpper,
    3518           0 :                                                 std::min(Material::MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)),
    3519             :                                             SlatsAngInterpFac,
    3520           0 :                                             state.dataSurface->SurfWinProfAngInterpFac(SurfNum));
    3521             :                                     } else {
    3522           0 :                                         FrontDiffTrans = state.dataMaterial->Blind(BlNum).SolFrontDiffDiffTrans(1);
    3523           0 :                                         TBlBmDif = General::Interp(
    3524           0 :                                             state.dataMaterial->Blind(BlNum).SolFrontBeamDiffTrans(1,
    3525           0 :                                                                                                    state.dataSurface->SurfWinProfAngIndex(SurfNum)),
    3526           0 :                                             state.dataMaterial->Blind(BlNum).SolFrontBeamDiffTrans(
    3527           0 :                                                 1, std::min(Material::MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)),
    3528             :                                             SlatsAngInterpFac);
    3529             :                                     }
    3530             : 
    3531             :                                     // TBlBmBm - Blind beam-beam solar transmittance
    3532           0 :                                     Real64 TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum);
    3533           0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3534           0 :                                         DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
    3535           0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3536           0 :                                         DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
    3537             : 
    3538        8540 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
    3539        8540 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3540        8540 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3541             : 
    3542             :                                     auto const *thisMaterial =
    3543        8540 :                                         dynamic_cast<Material::MaterialChild *>(state.dataMaterial->Material(constructionSh.LayerPoint(1)));
    3544        8540 :                                     assert(thisMaterial != nullptr);
    3545        8540 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3546        8540 :                                         DividerAbs * thisMaterial->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
    3547        8540 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3548        8540 :                                         DividerAbs * thisMaterial->Trans * (DivIncSolarInBm + DivIncSolarInDif);
    3549             : 
    3550           0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
    3551           0 :                                     int screenNum = surfWin.screenNum;
    3552           0 :                                     auto const *screen = dynamic_cast<Material::MaterialScreen const *>(state.dataMaterial->Material(screenNum));
    3553           0 :                                     assert(screen != nullptr);
    3554             : 
    3555           0 :                                     auto &surf = state.dataSurface->Surface(SurfNum);
    3556             :                                     Real64 phi, theta;
    3557           0 :                                     Material::GetRelativePhiTheta(
    3558           0 :                                         surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
    3559             : #ifdef PRECALC_INTERP_SCREEN
    3560             :                                     int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
    3561             :                                     General::BilinearInterpCoeffs coeffs;
    3562           0 :                                     Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
    3563           0 :                                     GetBilinearInterpCoeffs(
    3564           0 :                                         phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
    3565           0 :                                     auto const &b11 = screen->btars[ip1][it1];
    3566           0 :                                     auto const &b12 = screen->btars[ip1][it2];
    3567           0 :                                     auto const &b21 = screen->btars[ip2][it1];
    3568           0 :                                     auto const &b22 = screen->btars[ip2][it2];
    3569           0 :                                     Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
    3570           0 :                                     Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
    3571             : 
    3572           0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3573           0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3574           0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3575           0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3576             : #else  // !PRECALC_INTERP_SCREEN
    3577             :                                     Material::ScreenBmTransAbsRef btar;
    3578             : 
    3579             :                                     Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
    3580             :                                     Real64 BmDfTrans = btar.DfTrans;
    3581             :                                     Real64 BmBmTrans = btar.BmTrans;
    3582             : 
    3583             :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3584             :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3585             :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3586             :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3587             : #endif // PRECALC_INTERP_SCREEN
    3588             :                                 }
    3589             :                             }
    3590             :                         }
    3591             :                     } // Surface(SurfNum)%ExtSolar
    3592             :                 }     // end of surface window loop
    3593     6324949 :             }         // end of space loop
    3594             :         }             // end of zone loop
    3595      917695 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    3596        1232 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
    3597        1232 :             int const ConstrNum = Surface(SurfNum).Construction;
    3598        1232 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3599        1232 :             int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3600        1232 :             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3601        2464 :             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3602        1232 :                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3603        1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3604        1232 :                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
    3605        1232 :                         (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
    3606        1232 :                     state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
    3607        1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3608        1232 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3609        1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3610        1232 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3611        1232 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3612             :             }
    3613             :         }
    3614             : 
    3615             :         // Average absorbed solar for representative surfaces
    3616      916463 :         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    3617        9212 :             for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3618       18032 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3619        9016 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    3620        9016 :                     int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    3621        9016 :                     int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    3622       87612 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3623       78596 :                         auto &surface = state.dataSurface->Surface(surfNum);
    3624       78596 :                         if (surface.ConstituentSurfaceNums.size() > 1) {
    3625        2940 :                             Real64 QoutAtot = 0.0;
    3626        2940 :                             Real64 QinAtot = 0.0;
    3627        2940 :                             Real64 Atot = 0.0;
    3628        9212 :                             for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3629        6272 :                                 QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3630        6272 :                                 QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3631        6272 :                                 Atot += state.dataSurface->Surface(constSurfNum).Area;
    3632        2940 :                             }
    3633             : 
    3634        2940 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
    3635        2940 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
    3636             :                         }
    3637             :                     }
    3638        9016 :                     firstSurf = thisSpace.WindowSurfaceFirst;
    3639        9016 :                     lastSurf = thisSpace.WindowSurfaceLast;
    3640       43904 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3641       34888 :                         auto const &surface = state.dataSurface->Surface(surfNum);
    3642       34888 :                         if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
    3643             :                             // Absorbed in glazing
    3644             :                             int totalGlassLayers =
    3645        3724 :                                 state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
    3646       11172 :                             for (int layer = 1; layer <= totalGlassLayers; ++layer) {
    3647        7448 :                                 Real64 QAtot = 0.0;
    3648        7448 :                                 Real64 Atot = 0.0;
    3649       59584 :                                 for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3650       52136 :                                     QAtot +=
    3651       52136 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
    3652       52136 :                                     Atot += state.dataSurface->Surface(constSurfNum).Area;
    3653        7448 :                                 }
    3654             : 
    3655        7448 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
    3656             :                             }
    3657             : 
    3658             :                             // Absorbed by frame and dividers
    3659        3724 :                             if (surface.FrameDivider > 0) {
    3660         392 :                                 if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    3661           0 :                                     Real64 QoutAtot = 0.0;
    3662           0 :                                     Real64 QinAtot = 0.0;
    3663           0 :                                     Real64 Atot = 0.0;
    3664           0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3665           0 :                                         QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
    3666           0 :                                                     state.dataSurface->SurfWinFrameArea(constSurfNum);
    3667           0 :                                         QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
    3668           0 :                                                    state.dataSurface->SurfWinFrameArea(constSurfNum);
    3669           0 :                                         Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
    3670           0 :                                     }
    3671             : 
    3672           0 :                                     state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
    3673           0 :                                     state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
    3674             :                                 }
    3675         392 :                                 if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    3676           0 :                                     Real64 QoutAtot = 0.0;
    3677           0 :                                     Real64 QinAtot = 0.0;
    3678           0 :                                     Real64 Atot = 0.0;
    3679           0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3680           0 :                                         QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
    3681           0 :                                                     state.dataSurface->SurfWinDividerArea(constSurfNum);
    3682           0 :                                         QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
    3683           0 :                                                    state.dataSurface->SurfWinDividerArea(constSurfNum);
    3684           0 :                                         Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
    3685           0 :                                     }
    3686             : 
    3687           0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
    3688           0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
    3689             :                                 }
    3690             :                             }
    3691             :                         }
    3692             :                     }
    3693        9016 :                 }
    3694             :             }
    3695             :         }
    3696      916463 :     } // End of sun-up check
    3697     2804678 : }
    3698             : 
    3699     2804678 : void InitIntSolarDistribution(EnergyPlusData &state)
    3700             : {
    3701             : 
    3702             :     // SUBROUTINE INFORMATION:
    3703             :     //       AUTHOR         Anonymous
    3704             :     //       DATE WRITTEN   July 1977
    3705             :     //       MODIFIED       Oct 1999 (FW) to handle movable shades
    3706             :     //                      May 2000 (FW) to handle window frame and dividers
    3707             :     //                      May 2001 (FW) to handle window blinds
    3708             :     //                      Jan 2002 (FW) mods for between-glass shade/blind
    3709             :     //                      May 2006 (RR) to handle exterior window screens
    3710             :     //       RE-ENGINEERED  Mar98 (RKS)
    3711             : 
    3712             :     // PURPOSE OF THIS SUBROUTINE:
    3713             :     // This subroutine initializes the arrays associated with solar heat
    3714             :     // gains for both individual surfaces and for zones.
    3715             : 
    3716             :     // METHODOLOGY EMPLOYED:
    3717             :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    3718             :     // sun is up, various calculations are made.
    3719             : 
    3720             :     // REFERENCES:
    3721             :     // (I)BLAST legacy routine QSUN
    3722             : 
    3723             :     using Dayltg::DistributeTDDAbsorbedSolar;
    3724             :     using namespace DataWindowEquivalentLayer;
    3725             : 
    3726             :     // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
    3727             :     // Note: If sun is not up, QS is only internal gains
    3728    22667978 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3729    19863300 :         Real64 sumSpaceQLTSW = 0.0;
    3730    39779244 :         for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
    3731    19915944 :             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3732    19863300 :         }
    3733    19863300 :         state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
    3734    19863300 :         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
    3735             :     }
    3736             : 
    3737     2804678 :     if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
    3738             : 
    3739       60735 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3740             : 
    3741       48588 :             if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
    3742             : 
    3743      120960 :                 for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
    3744             : 
    3745       96768 :                     if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
    3746       24192 :                         Real64 sumSpaceQLTSW = 0.0;
    3747       48384 :                         for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
    3748       24192 :                             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3749       24192 :                         }
    3750       24192 :                         state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
    3751       24192 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3752       24192 :                             (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
    3753       24192 :                         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
    3754       24192 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
    3755       24192 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
    3756       24192 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3757       24192 :                             state.dataHeatBal->EnclSolQD(OtherenclosureNum);
    3758       24192 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
    3759       24192 :                             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
    3760             :                     }
    3761             :                 }
    3762             :             }
    3763             :         }
    3764             :     }
    3765             : 
    3766             :     // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
    3767             : 
    3768     2804678 :     if (state.dataEnvrn->SunIsUp) {
    3769    87342653 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    3770    85941117 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    3771             :             //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    3772    85941117 :             if (surface.Class == DataSurfaces::SurfaceClass::Shading) continue;
    3773    85939988 :             int const enclosureNum = surface.SolarEnclIndex;
    3774    85939988 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
    3775    85939988 :                 state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
    3776    85939988 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
    3777    85939988 :                 state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
    3778    85939988 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
    3779    85939988 :                 state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3780     1401536 :         }
    3781             :     }
    3782             : 
    3783             :     // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
    3784    22667978 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3785    19863300 :         auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
    3786    19863300 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    3787       48588 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
    3788       48588 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3789             :             // CR 8695, VMULT not based on visible
    3790       48588 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
    3791       48588 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3792             :         } else {
    3793    19814712 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
    3794    19814712 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
    3795             :         }
    3796             :     }
    3797             : 
    3798             :     // COMPUTE RADIANT GAINS ON SURFACES
    3799    22672022 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3800    39783288 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3801    19915944 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3802    19915944 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
    3803    19915944 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
    3804   168309598 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
    3805   148393654 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3806   148393654 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3807   148393654 :                 int const ConstrNum = surface.Construction;
    3808   148393654 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3809             : 
    3810   148393654 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
    3811             :                 // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
    3812   148393654 :                 Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
    3813             : 
    3814   148393654 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
    3815   148393654 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
    3816             : 
    3817             :                 // Calculate absorbed solar on outside if movable exterior insulation in place
    3818   148454386 :                 if (state.dataSurface->AnyMovableInsulation &&
    3819       60732 :                     state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum)) { // Movable outside insulation in place
    3820        4047 :                     Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
    3821             :                     auto const *thisMaterial =
    3822        4047 :                         dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(thisConstruct.LayerPoint(1)));
    3823        4047 :                     assert(thisMaterial != nullptr);
    3824        4047 :                     state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
    3825        4047 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
    3826             :                     // For transparent insulation, allow some sunlight to get through the movable insulation.
    3827             :                     // The equation below is derived by taking what is transmitted through the layer and applying
    3828             :                     // the fraction that is absorbed plus the back reflected portion (first order reflection only)
    3829             :                     // to the plane between the transparent insulation and the exterior surface face.
    3830        4047 :                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3831        4047 :                         dynamic_cast<const Material::MaterialChild *>(
    3832        4047 :                             state.dataMaterial->Material(state.dataSurface->SurfMaterialMovInsulExt(SurfNum)))
    3833        8094 :                             ->Trans *
    3834        4047 :                         state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) * ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
    3835             :                 }
    3836             :                 // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
    3837             :                 // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
    3838   148393654 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
    3839             :             } // end of opaque
    3840             : 
    3841    19915944 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3842    19915944 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3843    43139106 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
    3844    23223162 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3845    23223162 :                 auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3846    23223162 :                 int const radEnclosureNum = surface.RadEnclIndex;
    3847    23223162 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3848    23223162 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3849    23223162 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3850             : 
    3851    23223162 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
    3852    23215053 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    3853             : 
    3854    23215053 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    3855    23215053 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3856             : 
    3857             :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    3858    23215053 :                     Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
    3859    23215053 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    3860    23214653 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3861    23214653 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3862    23214653 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3863             :                     } else {
    3864         400 :                         state.dataHeatBalSurfMgr->curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    3865             :                         // for the loads component report during the special sizing run increase the radiant portion
    3866             :                         // a small amount to create a "pulse" of heat that is used for the
    3867         800 :                         state.dataHeatBalSurfMgr->adjQL =
    3868         400 :                             state.dataHeatBalSurfMgr->curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    3869             :                         // ITABSF is the Inside Thermal Absorptance
    3870             :                         // EnclRadThermAbsMult is a multiplier for each zone/enclosure
    3871             :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    3872         400 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3873         400 :                             state.dataHeatBalSurfMgr->adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    3874         400 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3875             :                     }
    3876             : 
    3877    23215053 :                     if (NOT_SHADED(ShadeFlag)) { // No window shading
    3878    52447294 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3879    29519022 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3880    29519022 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    3881             :                         }
    3882      286781 :                     } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    3883             :                         // Interior, exterior or between-glass shade, screen or blind in place
    3884      188958 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3885      433806 :                         for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
    3886      244848 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3887       93925 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3888       93925 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constructionSh.AbsDiffBack(IGlass);
    3889      150923 :                             } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
    3890             :                                 Real64 BlAbsDiffBk; // Glass layer back diffuse solar absorptance when blind in place
    3891      129219 :                                 if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3892        9393 :                                     BlAbsDiffBk = General::Interp(
    3893        3131 :                                         constructionSh.BlAbsDiffBack(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), IGlass),
    3894        3131 :                                         constructionSh.BlAbsDiffBack(
    3895        6262 :                                             std::min(Material::MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), IGlass),
    3896        3131 :                                         state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    3897             :                                 } else {
    3898      126088 :                                     BlAbsDiffBk = constructionSh.BlAbsDiffBack(1, IGlass);
    3899             :                                 }
    3900      129219 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3901      129219 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
    3902             :                             }
    3903             :                         }
    3904      188958 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    3905       44850 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3906       44850 :                                                                                  constructionSh.ShadeAbsorpThermal *
    3907       22425 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3908      166533 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    3909             :                             Real64 EffBlEmiss; // Blind emissivity (thermal absorptance) as part of glazing system
    3910      128113 :                             if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3911        2578 :                                 EffBlEmiss = General::Interp(
    3912        2578 :                                     state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[state.dataSurface->SurfWinSlatsAngIndex(SurfNum)],
    3913        2578 :                                     state.dataSurface->SurfaceWindow(SurfNum)
    3914        5156 :                                         .EffShBlindEmiss[std::min(Material::MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)],
    3915        2578 :                                     state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    3916             :                             } else {
    3917      125535 :                                 EffBlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[1];
    3918             :                             }
    3919      256226 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3920      128113 :                                                                                  EffBlEmiss *
    3921      128113 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3922             :                         }
    3923      188958 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3924       50909 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
    3925       50909 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constructionSh.AbsDiffBackShade;
    3926      138049 :                         } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    3927             :                             Real64 AbsDiffBkBl;
    3928      138049 :                             if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3929        3131 :                                 AbsDiffBkBl = General::Interp(constructionSh.AbsDiffBackBlind(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
    3930        3131 :                                                               constructionSh.AbsDiffBackBlind(std::min(
    3931        6262 :                                                                   Material::MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
    3932        3131 :                                                               state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    3933             :                             } else {
    3934      134918 :                                 AbsDiffBkBl = constructionSh.AbsDiffBackBlind(1);
    3935             :                             }
    3936      138049 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
    3937             :                         }
    3938             :                         // Correct for divider shadowing
    3939      188958 :                         if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3940       21502 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3941             :                         }
    3942             : 
    3943      286781 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {       // Switchable glazing
    3944       71786 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
    3945      215358 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3946             : 
    3947      143572 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3948      143572 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    3949      143572 :                                 Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    3950      143572 :                                                  thisConstruct.AbsDiffBack(IGlass),
    3951      143572 :                                                  constructionSh.AbsDiffBack(IGlass));
    3952             :                         }
    3953             : 
    3954             :                     } // End of shading flag check
    3955             : 
    3956             :                     // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
    3957    23215053 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
    3958      659148 :                         state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
    3959      659148 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
    3960      659148 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3961      659148 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    3962      659148 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    3963      659148 :                                  state.dataSurface->SurfWinFrameEmis(SurfNum)) *
    3964      659148 :                             (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));          // Window has a frame
    3965    23215053 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {                     // Window has dividers
    3966      328875 :                         Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum);    // Window divider thermal absorptance
    3967      328875 :                         Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3968      328875 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) ==
    3969             :                             DataSurfaces::FrameDividerType::Suspended) {                         // Suspended divider; account for inside glass
    3970       29589 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
    3971       29589 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(MatNumGl));
    3972       29589 :                             assert(thisMaterial != nullptr);
    3973       29589 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
    3974       29589 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    3975       29589 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3976       29589 :                             Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
    3977       29589 :                             DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
    3978       29589 :                             DividerThermAbs = thisMaterial->AbsorpThermalBack;
    3979             :                         }
    3980             :                         // Correct for interior shade transmittance
    3981      328875 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    3982         742 :                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3983         742 :                             int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
    3984         742 :                             auto const *thisMaterialSh = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(MatNumSh));
    3985         742 :                             DividerSolAbs *= thisMaterialSh->Trans;
    3986         742 :                             DividerThermAbs *= thisMaterialSh->TransThermal;
    3987      328133 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    3988           0 :                             int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
    3989             :                             Real64 SolBackDiffDiffTrans;
    3990             :                             Real64 IRBackTrans;
    3991           0 :                             if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3992           0 :                                 int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    3993           0 :                                 Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    3994           0 :                                 SolBackDiffDiffTrans = General::Interp(
    3995           0 :                                     state.dataMaterial->Blind(BlNum).SolBackDiffDiffTrans(SurfWinSlatsAngIndex),
    3996           0 :                                     state.dataMaterial->Blind(BlNum).SolBackDiffDiffTrans(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    3997             :                                     SurfWinSlatsAngInterpFac);
    3998           0 :                                 IRBackTrans = General::Interp(
    3999           0 :                                     state.dataMaterial->Blind(BlNum).IRBackTrans(SurfWinSlatsAngIndex),
    4000           0 :                                     state.dataMaterial->Blind(BlNum).IRBackTrans(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    4001             :                                     SurfWinSlatsAngInterpFac);
    4002             :                             } else {
    4003           0 :                                 SolBackDiffDiffTrans = state.dataMaterial->Blind(BlNum).SolBackDiffDiffTrans(1);
    4004           0 :                                 IRBackTrans = state.dataMaterial->Blind(BlNum).IRBackTrans(1);
    4005             :                             }
    4006           0 :                             DividerSolAbs *= SolBackDiffDiffTrans;
    4007           0 :                             DividerThermAbs *= IRBackTrans;
    4008             :                         }
    4009             :                         // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
    4010      328875 :                         state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
    4011      328875 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
    4012      328875 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    4013      328875 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    4014      328875 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    4015      328875 :                                  DividerThermAbs) *
    4016      328875 :                             (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
    4017             :                     }
    4018             :                 } else {
    4019             :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    4020        8109 :                     Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
    4021        8109 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    4022        8109 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    4023        8109 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    4024        8109 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4025             :                     } else {
    4026           0 :                         state.dataHeatBalSurfMgr->curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    4027             :                         // for the loads component report during the special sizing run increase the radiant portion
    4028             :                         // a small amount to create a "pulse" of heat that is used for the
    4029           0 :                         state.dataHeatBalSurfMgr->adjQL =
    4030           0 :                             state.dataHeatBalSurfMgr->curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    4031             :                         // ITABSF is the Inside Thermal Absorptance
    4032             :                         // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
    4033             :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    4034           0 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    4035           0 :                             state.dataHeatBalSurfMgr->adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    4036           0 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4037             :                     }
    4038             :                     // Radiations absorbed by the window layers coming from zone side
    4039        8109 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4040       37842 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4041       29733 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
    4042       29733 :                             state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
    4043             :                     }
    4044             :                     // Window frame has not been included for equivalent layer model yet
    4045             : 
    4046             :                 } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
    4047             : 
    4048    23223162 :                 if (surface.ExtBoundCond > 0) { // Interzone surface
    4049             :                     // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
    4050       27192 :                     int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
    4051       27192 :                     if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
    4052       27192 :                         int TotGlassLayers = thisConstruct.TotGlassLayers;
    4053       54384 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4054       27192 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
    4055       27192 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    4056       27192 :                                 state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
    4057             :                             // Note that AbsDiff rather than AbsDiffBack is used in the above since the
    4058             :                             // radiation from the current zone is incident on the outside of the adjacent
    4059             :                             // zone's window.
    4060             :                         }
    4061             :                     } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
    4062           0 :                         int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
    4063           0 :                         int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
    4064           0 :                         for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4065           0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
    4066           0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
    4067             :                             // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
    4068             :                             // since the radiation from the current zone is incident on the outside of the
    4069             :                             // adjacent zone's window.
    4070             :                         }
    4071             :                     }
    4072             :                 }
    4073             : 
    4074    23223162 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
    4075    23175513 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4076    23175513 :                     int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    4077    23175513 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4078    23175513 :                     if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
    4079    52400710 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4080    29485941 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4081             :                         }
    4082      260744 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    4083      215358 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4084      143572 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4085             :                         }
    4086             :                     } else {
    4087      188958 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4088             :                         // Interior, exterior or between-glass shade, screen or blind in place
    4089      433806 :                         for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
    4090      244848 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4091             :                         }
    4092      188958 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4093      188958 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
    4094             :                         }
    4095             :                     } // End of shading flag check
    4096       47649 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    4097       39540 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    4098      119289 :                     for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4099       79749 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4100             :                     }
    4101        8109 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    4102             : 
    4103             :                     // ConstrNum   = Surface(SurfNum)%Construction
    4104        8109 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4105             : 
    4106       37842 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4107       29733 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
    4108             :                     }
    4109             :                 }
    4110             : 
    4111             :             } // End of window
    4112    19867344 :         }
    4113             :     }
    4114     2804678 :     Dayltg::DistributeTDDAbsorbedSolar(state);
    4115     2804678 : }
    4116             : 
    4117     2804678 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
    4118             : {
    4119             : 
    4120             :     // SUBROUTINE INFORMATION:
    4121             :     //       AUTHOR         Legacy Code (George Walton)
    4122             :     //       DATE WRITTEN   Legacy: Dec 1976
    4123             :     //       MODIFIED       Nov. 99, FCW: to take into account movable interior shades and switchable glazing
    4124             :     //                      June 01, FCW: to take into account interior blinds.
    4125             : 
    4126             :     // PURPOSE OF THIS SUBROUTINE:
    4127             :     // This routine computes the fractions of long-wave radiation from lights, equipment and people
    4128             :     // that is absorbed by each zone surface.
    4129             : 
    4130             :     // METHODOLOGY EMPLOYED:
    4131             :     // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
    4132             : 
    4133             :     // REFERENCES:
    4134             :     // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
    4135             : 
    4136    22667978 :     for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    4137    19863300 :         if (!thisEnclosure.radReCalc) continue;
    4138      354762 :         for (int spaceNum : thisEnclosure.spaceNums) {
    4139      177458 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4140      177458 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    4141      177458 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    4142      600304 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    4143      422846 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4144      422846 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4145       10800 :                     Real64 BlindEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[1];
    4146       10800 :                     Real64 GlassEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss[1];
    4147       10800 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = BlindEmiss + GlassEmiss;
    4148             :                 } else {
    4149      412046 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4150      412046 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
    4151             :                 }
    4152             :             }
    4153      177304 :         }
    4154     2804678 :     }
    4155     2804678 :     if (state.dataSurface->AnyMovableSlat) {
    4156       12150 :         for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
    4157             :             // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
    4158        6075 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4159        6075 :             if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4160        2578 :                 if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    4161             :                     Real64 BlindEmiss;
    4162             :                     Real64 GlassEmiss;
    4163        2578 :                     int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    4164        2578 :                     Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    4165        2578 :                     BlindEmiss = General::Interp(
    4166        2578 :                         state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[SurfWinSlatsAngIndex],
    4167        2578 :                         state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)],
    4168             :                         SurfWinSlatsAngInterpFac);
    4169        2578 :                     GlassEmiss = General::Interp(
    4170        2578 :                         state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss[SurfWinSlatsAngIndex],
    4171        2578 :                         state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss[std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)],
    4172             :                         SurfWinSlatsAngInterpFac);
    4173        2578 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = BlindEmiss + GlassEmiss;
    4174             :                 }
    4175             :             }
    4176        6075 :         }
    4177             :     }
    4178             : 
    4179    22667978 :     for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
    4180    19863300 :         if (!thisRadEnclosure.radReCalc) continue;
    4181      177304 :         Real64 SUM1 = 0.0;
    4182     1910966 :         for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
    4183     1733662 :             auto &thisSurf = state.dataSurface->Surface(SurfNum);
    4184     1733662 :             int const ConstrNum = thisSurf.Construction;
    4185     1733662 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4186     1733662 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4187     1733662 :             if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    4188     1733662 :                 SUM1 += thisSurf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4189             :             } else { // Switchable glazing
    4190           0 :                 SUM1 += thisSurf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    4191           0 :                                                          thisConstruct.InsideAbsorpThermal,
    4192           0 :                                                          state.dataConstruction->Construct(thisSurf.activeShadedConstruction).InsideAbsorpThermal);
    4193             :             }
    4194             : 
    4195             :             // Window frame and divider effects
    4196     1733662 :             if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
    4197      122581 :                 SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
    4198      122581 :                         state.dataSurface->SurfWinFrameEmis(SurfNum);
    4199     1733662 :             if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4200      121392 :                 Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
    4201             :                 // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
    4202      121392 :                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended)
    4203          95 :                     DividerThermAbs = thisConstruct.InsideAbsorpThermal;
    4204      121392 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4205             :                     // Interior shade or blind in place
    4206          14 :                     int const ConstrNumSh = thisSurf.activeShadedConstruction;
    4207          14 :                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4208             : 
    4209          14 :                     if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
    4210             :                         // Shade layer material number
    4211          14 :                         int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
    4212             :                         // Shade or blind IR transmittance
    4213          14 :                         Real64 TauShIR = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(MatNumSh))->TransThermal;
    4214             :                         // Effective emissivity of shade or blind
    4215          14 :                         Real64 EffShDevEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[1];
    4216          14 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    4217           0 :                             TauShIR = state.dataMaterial->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).IRBackTrans(1);
    4218           0 :                             if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    4219           0 :                                 int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    4220           0 :                                 Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    4221           0 :                                 TauShIR = General::Interp(
    4222           0 :                                     state.dataMaterial->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).IRBackTrans(SurfWinSlatsAngIndex),
    4223           0 :                                     state.dataMaterial->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum))
    4224           0 :                                         .IRBackTrans(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    4225             :                                     SurfWinSlatsAngInterpFac);
    4226           0 :                                 EffShDevEmiss = General::Interp(state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[SurfWinSlatsAngIndex],
    4227           0 :                                                                 state.dataSurface->SurfaceWindow(SurfNum)
    4228           0 :                                                                     .EffShBlindEmiss[std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)],
    4229             :                                                                 SurfWinSlatsAngInterpFac);
    4230             :                             }
    4231             :                         }
    4232          14 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
    4233             :                     } else {
    4234             :                         // this is for EMS activated shade/blind but the window construction has no shade/blind layer
    4235           0 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4236             :                                 DividerThermAbs;
    4237             :                     }
    4238             :                 } else {
    4239      121378 :                     SUM1 +=
    4240      121378 :                         state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
    4241             :                 }
    4242             :             }
    4243             : 
    4244             :         } // End of loop over surfaces in zone/enclosure
    4245      177304 :         thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
    4246             : 
    4247     2804678 :     } // End of loop over enclosures
    4248     2804678 : }
    4249             : 
    4250     2804678 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
    4251             : {
    4252             : 
    4253             :     // SUBROUTINE INFORMATION:
    4254             :     //       AUTHOR         Legacy (George Walton)
    4255             :     //       DATE WRITTEN   Legacy (December 1980)
    4256             :     //       MODIFIED       Nov. 99, FW; now called every time step to account for movable
    4257             :     //                      window shades and insulation
    4258             :     //                      Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
    4259             :     //                      to ComputeIntSWAbsorpFactors
    4260             :     //                      May 00, FW; add window frame and divider effects
    4261             :     //                      June 01, FW: account for window blinds
    4262             :     //                      Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
    4263             :     //                      Jan 03, FW: add between-glass shade/blind
    4264             :     //                      May 06, RR: account for exterior window screens
    4265             : 
    4266             :     // PURPOSE OF THIS SUBROUTINE:
    4267             :     // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
    4268             :     // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
    4269             :     // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
    4270             : 
    4271             :     // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
    4272             :     // radiation absorbed by interior window shades).
    4273             : 
    4274             :     // REFERENCES:
    4275             :     // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
    4276             :     //                         From Zone Lights And Diffuse Solar.
    4277             : 
    4278             :     // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
    4279     2804678 :     Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
    4280             : 
    4281    22667978 :     for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
    4282    19863300 :         if (!thisSolEnclosure.radReCalc) continue;
    4283      177304 :         Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
    4284             : 
    4285     1912145 :         for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
    4286     1734841 :             auto &thisSurf = state.dataSurface->Surface(SurfNum);
    4287     1734841 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4288     1734841 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4289     1734841 :             if (thisConstruct.TransDiff <= 0.0) {
    4290             :                 // Opaque surface
    4291     1314100 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
    4292     1314100 :                 SUM1 += thisSurf.Area * AbsIntSurf;
    4293             : 
    4294             :             } else {
    4295             :                 // Window
    4296      420741 :                 if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
    4297      414747 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4298             : 
    4299      414747 :                     Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
    4300      414747 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4301      414747 :                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    4302             : 
    4303             :                     // Sum of absorptances of glass layers
    4304      993333 :                     for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
    4305      578586 :                         Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
    4306             : 
    4307             :                         // Window with shade, screen or blind
    4308      578586 :                         if (ConstrNumSh != 0) {
    4309      269078 :                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4310      269078 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    4311       13665 :                                 AbsDiffLayWin = constructionSh.AbsDiffBack(Lay);
    4312      255413 :                             } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4313        8643 :                                 if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    4314        9393 :                                     AbsDiffLayWin = General::Interp(
    4315        3131 :                                         constructionSh.BlAbsDiffBack(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay),
    4316        3131 :                                         constructionSh.BlAbsDiffBack(
    4317        6262 :                                             std::min(Material::MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay),
    4318        3131 :                                         state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    4319             :                                 } else {
    4320        5512 :                                     AbsDiffLayWin = constructionSh.BlAbsDiffBack(1, Lay);
    4321             :                                 }
    4322             :                             }
    4323             :                         }
    4324             : 
    4325             :                         // Switchable glazing
    4326      578586 :                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4327           0 :                             assert(ConstrNumSh > 0); // Should this be included in the if above
    4328           0 :                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4329           0 :                             AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constructionSh.AbsDiffBack(Lay));
    4330             :                         }
    4331      578586 :                         AbsDiffTotWin += AbsDiffLayWin;
    4332             :                     }
    4333             : 
    4334      414747 :                     Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
    4335      414747 :                     Real64 DiffAbsShade = 0.0;                     // Diffuse short-wave shade or blind absorptance
    4336             : 
    4337             :                     // Window with shade, screen or blind
    4338             : 
    4339      414747 :                     if (ConstrNumSh != 0) {
    4340      143568 :                         auto &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4341      143568 :                         if (ANY_SHADE_SCREEN(ShadeFlag)) {
    4342        7679 :                             TransDiffWin = constructionSh.TransDiff;
    4343        7679 :                             DiffAbsShade = constructionSh.AbsDiffBackShade;
    4344      135889 :                         } else if (ANY_BLIND(ShadeFlag)) {
    4345        8605 :                             if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    4346        3131 :                                 int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    4347        3131 :                                 Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    4348        3131 :                                 TransDiffWin = General::Interp(constructionSh.BlTransDiff(SurfWinSlatsAngIndex),
    4349        3131 :                                                                constructionSh.BlTransDiff(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    4350             :                                                                SurfWinSlatsAngInterpFac);
    4351             :                                 DiffAbsShade =
    4352        3131 :                                     General::Interp(constructionSh.AbsDiffBackBlind(SurfWinSlatsAngIndex),
    4353        6262 :                                                     constructionSh.AbsDiffBackBlind(std::min(Material::MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    4354             :                                                     SurfWinSlatsAngInterpFac);
    4355             :                             } else {
    4356        5474 :                                 TransDiffWin = constructionSh.BlTransDiff(1);
    4357        5474 :                                 DiffAbsShade = constructionSh.AbsDiffBackBlind(1);
    4358             :                             }
    4359             :                         }
    4360             :                     }
    4361             : 
    4362             :                     // Switchable glazing
    4363             : 
    4364      414747 :                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4365           0 :                         assert(ConstrNumSh > 0);
    4366           0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4367           0 :                         TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
    4368             :                     }
    4369             : 
    4370      414747 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
    4371             : 
    4372             :                     // Window frame and divider effects (shade area is glazed area plus divider area)
    4373             : 
    4374      414747 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0)
    4375      122581 :                         SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
    4376      122581 :                                 (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
    4377      414747 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4378      121392 :                         Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    4379      121392 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    4380             :                             // Suspended (between-glass) divider: account for glass on inside of divider
    4381          95 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
    4382          95 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(MatNumGl));
    4383          95 :                             assert(thisMaterial != nullptr);
    4384          95 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
    4385          95 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    4386          95 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    4387          95 :                             Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
    4388          95 :                             DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    4389             :                         }
    4390      121392 :                         if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4391          14 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
    4392             :                         } else {
    4393      121378 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4394             :                                     DividerAbs;
    4395             :                         }
    4396             :                     }
    4397             :                 } else { // equivalent layer window
    4398             :                     // In equivalent layer window solid layers (Glazing and shades) are treated equally
    4399             :                     // frames and dividers are not supported
    4400        5994 :                     Real64 AbsDiffTotWin = 0.0;
    4401        5994 :                     Real64 AbsDiffLayWin = 0.0;
    4402        5994 :                     Real64 TransDiffWin = thisConstruct.TransDiff;
    4403       28000 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
    4404       22006 :                         AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
    4405       22006 :                         AbsDiffTotWin += AbsDiffLayWin;
    4406             :                     }
    4407        5994 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
    4408             :                 }
    4409             :             } // End of check if opaque surface or window
    4410             :         }     // End of loop over surfaces in zone
    4411             : 
    4412      177304 :         if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
    4413      177299 :             thisSolEnclosure.solVMULT = 1.0 / SUM1;
    4414             : 
    4415             :         } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
    4416             :             // or they really want to disallow any solar from being absorbed on the inside surfaces.  Fire off a
    4417             :             // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
    4418             :             // back out whatever window is there.  Note that this also assumes that the shade has no effect.
    4419             :             // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
    4420             :             // in the zone?
    4421           5 :             if (thisSolEnclosure.solAbsFirstCalc) {
    4422           2 :                 ShowWarningError(
    4423             :                     state,
    4424           2 :                     format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
    4425           1 :                            thisSolEnclosure.Name));
    4426           1 :                 thisSolEnclosure.solAbsFirstCalc = false;
    4427             :             }
    4428           5 :             thisSolEnclosure.solVMULT = 0.0;
    4429             :         }
    4430     2804678 :     } // End of enclosure loop
    4431     2804678 : }
    4432             : 
    4433       12147 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
    4434             : {
    4435             : 
    4436             :     // SUBROUTINE INFORMATION:
    4437             :     //       MODIFIED       Jun 2007 - Lawrie - Speed enhancements.
    4438             :     //       RE-ENGINEERED  Winkelmann, Lawrie
    4439             : 
    4440             :     // PURPOSE OF THIS SUBROUTINE:
    4441             :     // This subroutine computes the diffuse solar exchange factors between enclosures with
    4442             :     // interzone windows.
    4443             : 
    4444       12147 :     int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
    4445       12147 :     if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
    4446           6 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
    4447           6 :         state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
    4448           6 :         state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
    4449             :     }
    4450             : 
    4451       12147 :     state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
    4452       12147 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
    4453       12147 :     state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
    4454             : 
    4455             :     //      IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN  ! this caused massive diffs
    4456       12147 :     if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) return;
    4457             :     //            Compute fraction transmitted in one pass.
    4458             : 
    4459      101664 :     for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
    4460       89568 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4461       89568 :         if (surface.ExtBoundCond <= 0) continue;
    4462       27072 :         if (surface.ExtBoundCond == SurfNum) continue;
    4463       27072 :         if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) continue;
    4464             : 
    4465       27072 :         int surfEnclNum = surface.SolarEnclIndex;
    4466       27072 :         if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) continue;
    4467       27072 :         int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
    4468       54144 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
    4469       27072 :                                                                          state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
    4470       27072 :         if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
    4471       12096 :     }
    4472             :     //          Compute fractions for multiple passes.
    4473             : 
    4474       12096 :     Array2D<Real64>::size_type l(0u), m(0u), d(0u);
    4475       60480 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
    4476       48384 :         m = NZ - 1;
    4477       48384 :         Real64 D_d(0.0); // Local accumulator
    4478      241920 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
    4479      193536 :             if (MZ == NZ) continue;
    4480      145152 :             state.dataHeatBalSurfMgr->DiffuseArray[l] =
    4481      145152 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
    4482      290304 :                 (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
    4483      145152 :                            state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
    4484      145152 :             D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
    4485             :         }
    4486       48384 :         state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
    4487             :     }
    4488             : 
    4489       12096 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
    4490             :     // added for CR 7999 & 7869
    4491       12096 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
    4492       12096 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
    4493       60480 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
    4494      197568 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4495      173376 :             if (MZ == NZ) continue;
    4496      137088 :             if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
    4497       24192 :                 state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
    4498       24192 :                 break;
    4499             :             }
    4500             :         }
    4501             :     }
    4502             : 
    4503             :     //           Compute fractions for multiple zones.
    4504             : 
    4505       60480 :     for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
    4506       48384 :         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) continue;
    4507             : 
    4508      120960 :         for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
    4509       96768 :             if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) continue;
    4510       48384 :             if (IZ == JZ) continue;
    4511       24192 :             if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) continue;
    4512             : 
    4513      120960 :             for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
    4514       96768 :                 if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) continue;
    4515       48384 :                 if (IZ == KZ) continue;
    4516       24192 :                 if (JZ == KZ) continue;
    4517           0 :                 if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) continue;
    4518           0 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
    4519           0 :                     state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4520             : 
    4521           0 :                 for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
    4522           0 :                     if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) continue;
    4523           0 :                     if (IZ == LZ) continue;
    4524           0 :                     if (JZ == LZ) continue;
    4525           0 :                     if (KZ == LZ) continue;
    4526           0 :                     if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) continue;
    4527           0 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4528           0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
    4529           0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4530             : 
    4531           0 :                     for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4532           0 :                         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) continue;
    4533           0 :                         if (IZ == MZ) continue;
    4534           0 :                         if (JZ == MZ) continue;
    4535           0 :                         if (KZ == MZ) continue;
    4536           0 :                         if (LZ == MZ) continue;
    4537           0 :                         if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) continue;
    4538           0 :                         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
    4539           0 :                             state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4540           0 :                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4541             :                     } // MZ Loop
    4542             : 
    4543             :                 } // LZ Loop
    4544             : 
    4545             :             } // KZ Loop
    4546             : 
    4547             :         } // JZ Loop
    4548             : 
    4549             :     } // IZ Loop
    4550             : } // ComputeDifSolExcZoneWIZWindows()
    4551             : 
    4552      408517 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
    4553             : {
    4554             : 
    4555             :     // SUBROUTINE INFORMATION:
    4556             :     //       AUTHOR         B. Griffith
    4557             :     //       DATE WRITTEN   April 2011
    4558             : 
    4559             :     // PURPOSE OF THIS SUBROUTINE:
    4560             :     // initialize material and construction surface properties if being overriden by EMS
    4561             : 
    4562             :     // METHODOLOGY EMPLOYED:
    4563             :     // update solar, thermal and visible absorptance values when actuated by EMS
    4564             : 
    4565             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4566             :     int MaterNum;        // do loop counter over materials
    4567             :     int ConstrNum;       // do loop counter over constructions
    4568             :     int TotLayers;       // count of material layers in a construction
    4569             :     int InsideMaterNum;  // integer pointer for inside face's material layer
    4570             :     int OutsideMaterNum; // integer pointer for outside face's material layer
    4571             : 
    4572      408517 :     state.dataGlobal->AnySurfPropOverridesInModel = false;
    4573             :     // first determine if anything needs to be done, once yes, then always init
    4574     9016814 :     for (auto const *matBase : state.dataMaterial->Material) {
    4575     8608297 :         if (matBase->group != Material::Group::Regular) continue;
    4576             : 
    4577     7384988 :         auto const *mat = dynamic_cast<Material::MaterialChild const *>(matBase);
    4578     7384988 :         assert(mat != nullptr);
    4579             : 
    4580     7384988 :         if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
    4581           0 :             state.dataGlobal->AnySurfPropOverridesInModel = true;
    4582           0 :             break;
    4583             :         }
    4584      408517 :     }
    4585             : 
    4586      408517 :     if (!state.dataGlobal->AnySurfPropOverridesInModel) return; // quick return if nothing has ever needed to be done
    4587             : 
    4588             :     // first, loop over materials
    4589           0 :     for (auto *matBase : state.dataMaterial->Material) {
    4590           0 :         if (matBase->group != Material::Group::Regular) continue;
    4591             : 
    4592           0 :         auto *mat = dynamic_cast<Material::MaterialChild *>(matBase);
    4593           0 :         assert(mat != nullptr);
    4594             : 
    4595           0 :         mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
    4596           0 :         mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
    4597           0 :         mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
    4598           0 :     } // loop over materials
    4599             : 
    4600             :     // second, loop over constructions
    4601           0 :     for (auto &thisConstruct : state.dataConstruction->Construct) {
    4602           0 :         if (thisConstruct.TypeIsWindow) continue; // only override opaque constructions
    4603           0 :         TotLayers = thisConstruct.TotLayers;
    4604           0 :         if (TotLayers == 0) continue; // error condition
    4605           0 :         InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
    4606           0 :         if (InsideMaterNum != 0) {
    4607           0 :             auto const *mat = state.dataMaterial->Material(InsideMaterNum);
    4608           0 :             thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
    4609           0 :             thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
    4610           0 :             thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
    4611             :         }
    4612             : 
    4613           0 :         OutsideMaterNum = thisConstruct.LayerPoint(1);
    4614           0 :         if (OutsideMaterNum != 0) {
    4615           0 :             auto const *mat = state.dataMaterial->Material(OutsideMaterNum);
    4616           0 :             thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
    4617           0 :             thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
    4618           0 :             thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
    4619             :         }
    4620             :     } // for (ConstrNum)
    4621             : } // InitEMSControlledSurfaceProperties()
    4622             : 
    4623      408517 : void InitEMSControlledConstructions(EnergyPlusData &state)
    4624             : {
    4625             : 
    4626             :     // SUBROUTINE INFORMATION:
    4627             :     //       AUTHOR         B. Griffith
    4628             :     //       DATE WRITTEN   Jan 2012
    4629             : 
    4630             :     // PURPOSE OF THIS SUBROUTINE:
    4631             :     // change construction on surface if overriden by EMS
    4632             : 
    4633      408517 :     state.dataGlobal->AnyConstrOverridesInModel = false;
    4634    40516310 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4635    40113852 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
    4636        6059 :             state.dataGlobal->AnyConstrOverridesInModel = true;
    4637        6059 :             break;
    4638             :         }
    4639             :     }
    4640      408517 :     if (!state.dataGlobal->AnyConstrOverridesInModel) return;
    4641             : 
    4642      424130 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4643      418071 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4644             : 
    4645      418071 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
    4646             : 
    4647        6059 :             if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4648        6059 :                     .TypeIsWindow) { // okay, allways allow windows
    4649        6059 :                 state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4650        6059 :                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4651             :             }
    4652             : 
    4653       12118 :             if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
    4654        6059 :                 (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
    4655             : 
    4656        6059 :                 surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4657        6059 :                 state.dataConstruction->Construct(surface.Construction).IsUsed = true;
    4658        6059 :                 state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4659             : 
    4660             :             } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
    4661           0 :                 if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
    4662             :                     // check if constructions appear compatible
    4663             : 
    4664           0 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    4665           0 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    4666             :                         // compare old construction to new construction and see if terms match
    4667             :                         // set as okay and turn false if find a big problem
    4668           0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4669             :                             true;
    4670           0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4671             :                             true;
    4672           0 :                         if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
    4673           0 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
    4674             :                             // thow warning, but allow
    4675           0 :                             ShowWarningError(state,
    4676             :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4677             :                                              "CTF timescales are being used.");
    4678           0 :                             ShowContinueError(state,
    4679           0 :                                               format("Construction named = {} has CTF timesteps = {}",
    4680           0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4681           0 :                                                      state.dataConstruction->Construct(surface.Construction).NumHistories));
    4682           0 :                             ShowContinueError(
    4683             :                                 state,
    4684           0 :                                 format("While construction named = {} has CTF timesteps = {}",
    4685           0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4686           0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
    4687           0 :                             ShowContinueError(
    4688             :                                 state,
    4689           0 :                                 format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
    4690           0 :                                        surface.Name));
    4691             :                         }
    4692           0 :                         if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
    4693           0 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
    4694             :                             // throw warning, but allow
    4695           0 :                             ShowWarningError(state,
    4696             :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4697             :                                              "CTF terms are being used.");
    4698           0 :                             ShowContinueError(state,
    4699           0 :                                               format("Construction named = {} has number of CTF terms = {}",
    4700           0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4701           0 :                                                      state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
    4702           0 :                             ShowContinueError(
    4703             :                                 state,
    4704           0 :                                 format("While construction named = {} has number of CTF terms = {}",
    4705           0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4706           0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
    4707           0 :                             ShowContinueError(state,
    4708           0 :                                               format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
    4709             :                                                      "name = {}, and the simulation continues",
    4710           0 :                                                      surface.Name));
    4711             :                         }
    4712             : 
    4713           0 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4714           0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4715             :                                 // thow warning, and do not allow
    4716           0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4717           0 :                                 ShowContinueError(state,
    4718           0 :                                                   format("Construction named = {} has internal source/sink",
    4719           0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4720           0 :                                 ShowContinueError(
    4721             :                                     state,
    4722           0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4723           0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4724           0 :                                 ShowContinueError(
    4725             :                                     state,
    4726           0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4727           0 :                                            surface.Name));
    4728             : 
    4729           0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4730           0 :                                                                                   SurfNum) = false;
    4731             :                             }
    4732             :                         }
    4733             : 
    4734           0 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4735             :                                                                               SurfNum)) {
    4736           0 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4737             :                         }
    4738             : 
    4739           0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    4740           0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4741             :                             true;
    4742           0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4743             :                             true;
    4744           0 :                         if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
    4745           0 :                             state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
    4746             :                             // thow warning, and do not allow
    4747           0 :                             ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4748           0 :                             ShowContinueError(state,
    4749           0 :                                               format("Construction named = {} has number of finite difference nodes ={}",
    4750           0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4751           0 :                                                      state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
    4752           0 :                             ShowContinueError(
    4753             :                                 state,
    4754           0 :                                 format("While construction named = {}has number of finite difference nodes ={}",
    4755           0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4756           0 :                                        state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4757           0 :                                            .TotNodes));
    4758           0 :                             ShowContinueError(
    4759             :                                 state,
    4760           0 :                                 format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4761           0 :                                        surface.Name));
    4762             : 
    4763           0 :                             state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4764             :                                 false;
    4765             :                         }
    4766             : 
    4767           0 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4768           0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4769             :                                 // thow warning, and do not allow
    4770           0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4771           0 :                                 ShowContinueError(state,
    4772           0 :                                                   format("Construction named = {} has internal source/sink",
    4773           0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4774           0 :                                 ShowContinueError(
    4775             :                                     state,
    4776           0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4777           0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4778           0 :                                 ShowContinueError(
    4779             :                                     state,
    4780           0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4781           0 :                                            surface.Name));
    4782             : 
    4783           0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4784           0 :                                                                                   SurfNum) = false;
    4785             :                             }
    4786             :                         }
    4787             : 
    4788           0 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4789             :                                                                               SurfNum)) {
    4790           0 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4791             :                         }
    4792             : 
    4793           0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
    4794           0 :                         ShowSevereError(state,
    4795             :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
    4796             :                                         "algorithm CombinedHeatAndMoistureFiniteElement.");
    4797           0 :                         ShowContinueError(
    4798             :                             state,
    4799           0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4800           0 :                                    surface.Name));
    4801           0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4802             :                             true;
    4803           0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4804             :                             false;
    4805             : 
    4806           0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
    4807           0 :                         ShowSevereError(state,
    4808             :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
    4809             :                                         "Foundation Outside Boundary Condition.");
    4810           0 :                         ShowContinueError(
    4811             :                             state,
    4812           0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4813           0 :                                    surface.Name));
    4814           0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4815             :                             true;
    4816           0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4817             :                             false;
    4818             :                     }
    4819             : 
    4820             :                 } else {
    4821             :                     // do nothing, has been checked and is not okay with single warning already issued.
    4822             :                 }
    4823             :             }
    4824             :         } else {
    4825      412012 :             surface.Construction = surface.ConstructionStoredInputValue;
    4826      412012 :             state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
    4827             :         }
    4828             :     } // for (SurfNum)
    4829             : } // InitEMSControlledConstructions()
    4830             : 
    4831             : // End Initialization Section of the Module
    4832             : //******************************************************************************
    4833             : 
    4834             : // Begin Algorithm Section of the Module
    4835             : //******************************************************************************
    4836             : 
    4837             : // Beginning of Record Keeping subroutines for the HB Module
    4838             : // *****************************************************************************
    4839             : 
    4840     3735792 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4841             : {
    4842     3735792 :     int firstZone = 1;
    4843     3735792 :     int lastZone = state.dataGlobal->NumOfZones;
    4844             : 
    4845     3735792 :     if (present(ZoneToResimulate)) {
    4846      795123 :         firstZone = ZoneToResimulate;
    4847      795123 :         lastZone = ZoneToResimulate;
    4848             :     }
    4849             : 
    4850    25001171 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4851    42579358 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4852    21313979 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4853    21313979 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    4854    21313979 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    4855    45520062 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4856    24206083 :                 if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
    4857    24174841 :                     state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
    4858             :                 }
    4859             :             }
    4860             :             // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
    4861    21313979 :             if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
    4862    12621173 :                 state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4863    12621173 :                 state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
    4864    12621173 :                     state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4865             :             } else {
    4866     8692806 :                 state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4867     8692806 :                 state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
    4868     8692806 :                     state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4869             :             }
    4870    21265379 :         }
    4871             :     }
    4872             : 
    4873     3735792 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    4874         687 :         UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
    4875             :     }
    4876             : 
    4877             :     // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
    4878    25001171 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4879    42579358 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4880    21313979 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4881    21313979 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    4882    21313979 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    4883   203302544 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4884   181988565 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
    4885   181988565 :                     -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4886   181988565 :                     (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4887             :             }
    4888    21265379 :         }
    4889             :     }
    4890             :     // Opaque surfaces
    4891    25001171 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4892    42579358 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4893    21313979 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4894    21313979 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    4895    21313979 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    4896   179096461 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4897   157782482 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
    4898   157782482 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
    4899             :             }
    4900    21265379 :         }
    4901             :     }
    4902             :     // Inside face conduction calculation for Kiva surfaces
    4903     3836370 :     for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
    4904      100578 :         state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
    4905      100578 :             -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    4906      100578 :               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    4907      100578 :               state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
    4908     3735792 :     }
    4909     3735792 : }
    4910             : 
    4911         687 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4912             : {
    4913         687 :     int firstZone = 1;
    4914         687 :     int lastZone = state.dataGlobal->NumOfZones;
    4915             : 
    4916         687 :     if (present(ZoneToResimulate)) {
    4917           0 :         firstZone = ZoneToResimulate;
    4918           0 :         lastZone = ZoneToResimulate;
    4919             :     }
    4920             : 
    4921       32289 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4922       63204 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4923       31602 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4924             :             // Heat transfer surfaces
    4925       31602 :             int firstSurf = thisSpace.HTSurfaceFirst;
    4926       31602 :             int lastSurf = thisSpace.HTSurfaceLast;
    4927      429375 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4928      397773 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    4929      397773 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    4930             : 
    4931      397773 :                 if (surfNum != repSurfNum) {
    4932             : #if 0
    4933             :                 // Check for divergence
    4934             :                 Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4935             :                                   (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4936             :                 Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
    4937             :                                      (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
    4938             :                 Real64 diff = surfConv - repSurfConv;
    4939             :                 if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
    4940             :                     ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
    4941             :                     ShowContinueErrorTimeStamp(state, "");
    4942             :                     ShowContinueError(state, format("  Original Surface: {}", surface.Name));
    4943             :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
    4944             :                     ShowContinueError(state,
    4945             :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    4946             :                     ShowContinueError(state,
    4947             :                                       format("    Sunlit fraction: {:.3R}",
    4948             :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
    4949             :                     ShowContinueError(state, format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
    4950             :                     ShowContinueError(state,
    4951             :                                       format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
    4952             :                     ShowContinueError(state, format("  Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
    4953             :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
    4954             :                     ShowContinueError(state,
    4955             :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
    4956             :                     ShowContinueError(state,
    4957             :                                       format("    Sunlit fraction: {:.3R}",
    4958             :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
    4959             :                     ShowContinueError(state,
    4960             :                                       format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
    4961             :                     ShowContinueError(
    4962             :                         state, format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
    4963             :                 }
    4964             : #endif
    4965             : 
    4966             :                     // Surface Heat Balance Arrays
    4967       89997 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
    4968       89997 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
    4969       89997 :                     state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
    4970       89997 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
    4971       89997 :                     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
    4972       89997 :                     state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
    4973       89997 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
    4974             : 
    4975       89997 :                     state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
    4976       89997 :                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
    4977       89997 :                     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
    4978       89997 :                     state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
    4979       89997 :                     state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
    4980       89997 :                     state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
    4981             : 
    4982       89997 :                     state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
    4983       89997 :                     if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
    4984           0 :                         state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
    4985             :                     }
    4986             : 
    4987       89997 :                     state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
    4988       89997 :                     state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
    4989             : 
    4990       89997 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    4991       89997 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
    4992       89997 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
    4993       89997 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
    4994             : 
    4995             :                     // Internal (non reporting variables)
    4996       89997 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
    4997       89997 :                     state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
    4998             :                 }
    4999             :             }
    5000             : 
    5001             :             // Opaque surfaces
    5002       31602 :             firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    5003       31602 :             lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    5004      307089 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    5005      275487 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    5006      275487 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    5007             : 
    5008      275487 :                 if (surfNum != repSurfNum) {
    5009             :                     // Surface Heat Balance Arrays
    5010       11679 :                     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
    5011       11679 :                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
    5012       11679 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
    5013             :                 }
    5014             :             }
    5015             : 
    5016             :             // Window surfaces
    5017       31602 :             firstSurf = thisSpace.WindowSurfaceFirst;
    5018       31602 :             lastSurf = thisSpace.WindowSurfaceLast;
    5019      153888 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    5020      122286 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    5021      122286 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    5022             : 
    5023      122286 :                 if (surfNum != repSurfNum) {
    5024       78318 :                     Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    5025             : 
    5026             :                     // Glazing
    5027       78318 :                     state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    5028       78318 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    5029       78318 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    5030             : 
    5031             :                     // Frame
    5032       78318 :                     Real64 frameHeatGain = 0.0;
    5033       78318 :                     if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    5034           0 :                         Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
    5035           0 :                         state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
    5036           0 :                         state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
    5037           0 :                         state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
    5038           0 :                         state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
    5039           0 :                         frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
    5040             :                     }
    5041             : 
    5042             :                     // Divider
    5043       78318 :                     Real64 dividerHeatGain = 0.0;
    5044       78318 :                     if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    5045           0 :                         Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
    5046           0 :                         state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
    5047           0 :                         state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
    5048           0 :                         state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
    5049           0 :                         state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
    5050           0 :                         dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
    5051             :                     }
    5052             : 
    5053       78318 :                     state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
    5054             : 
    5055             :                     // Whole window
    5056      156636 :                     state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
    5057       78318 :                                                                    state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
    5058       78318 :                                                                   state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
    5059             :                 }
    5060             :             }
    5061       31602 :         }
    5062             :     }
    5063         687 : }
    5064             : 
    5065     2804482 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
    5066             : {
    5067             : 
    5068             :     // SUBROUTINE INFORMATION:
    5069             :     //       AUTHOR         Rick Strand
    5070             :     //       DATE WRITTEN   December 2000
    5071             : 
    5072             :     // PURPOSE OF THIS SUBROUTINE:
    5073             :     // If a radiant system is present and was on for part of the time step,
    5074             :     // then we probably need to make yet another pass through the heat balance.
    5075             :     // This is necessary because the heat source/sink to the surface that is
    5076             :     // the radiant system may have varied during the system time steps.
    5077             : 
    5078             :     // METHODOLOGY EMPLOYED:
    5079             :     // First, determine whether or not the radiant system was running.  If
    5080             :     // any of the Qsource terms are non-zero, then it was running.  Then,
    5081             :     // update the current source terms with the "average" value calculated
    5082             :     // by the radiant system algorithm.  This requires the "USE" of the
    5083             :     // radiant algorithm module.  Finally, using this source value, redo
    5084             :     // the inside and outside heat balances.
    5085             : 
    5086             :     bool LowTempRadSysOn;     // .TRUE. if a low temperature radiant system is running
    5087             :     bool HighTempRadSysOn;    // .TRUE. if a high temperature radiant system is running
    5088             :     bool HWBaseboardSysOn;    // .TRUE. if a water baseboard heater is running
    5089             :     bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
    5090             :     bool ElecBaseboardSysOn;  // .TRUE. if a steam baseboard heater is running
    5091             :     bool CoolingPanelSysOn;   // true if a simple cooling panel is running
    5092             :     bool SwimmingPoolOn;      // true if a pool is present (running)
    5093             : 
    5094     2804482 :     LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
    5095     2804482 :     HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
    5096     2804482 :     HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
    5097     2804482 :     SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
    5098     2804482 :     ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
    5099     2804482 :     CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
    5100     2804482 :     SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
    5101             : 
    5102     2804482 :     if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
    5103             :         // Solve the zone heat balance 'Detailed' solution
    5104             :         // Call the outside and inside surface heat balances
    5105       82564 :         CalcHeatBalanceOutsideSurf(state);
    5106       82564 :         CalcHeatBalanceInsideSurf(state);
    5107             :     }
    5108     2804482 : }
    5109             : 
    5110     2629123 : void UpdateThermalHistories(EnergyPlusData &state)
    5111             : {
    5112             : 
    5113             :     // SUBROUTINE INFORMATION:
    5114             :     //       AUTHOR         Russ Taylor
    5115             :     //       DATE WRITTEN   June 1990
    5116             :     //       RE-ENGINEERED  Mar98 (RKS)
    5117             : 
    5118             :     // PURPOSE OF THIS SUBROUTINE:
    5119             :     // This subroutine updates and shifts the thermal and flux histories.
    5120             : 
    5121             :     // METHODOLOGY EMPLOYED:
    5122             :     // If a surface runs on the user selected subhourly time step, then the
    5123             :     // history terms for the temperatures and fluxes must simply be updated
    5124             :     // and shifted.  However, if the surface runs at a different (longer) time
    5125             :     // step, then the "master" history series is used for the interpolated
    5126             :     // update scheme.
    5127             : 
    5128             :     // REFERENCES:
    5129             :     // (I)BLAST legacy routine UTHRMH
    5130             :     // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
    5131             :     // Mechanical Systems in Heat Balance Based Energy Analysis Programs
    5132             :     // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
    5133             : 
    5134     2629123 :     if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
    5135         783 :         state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5136         783 :         state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5137         783 :         state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5138         783 :         state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5139         783 :         state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
    5140         783 :         if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5141          31 :             state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5142          31 :             state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5143          31 :             state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5144             :         }
    5145         783 :         state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
    5146             :     }
    5147             : 
    5148    22212280 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5149    39214914 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5150    19631757 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5151    19631757 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5152    19631757 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5153   166211853 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5154             :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5155   146580096 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5156             : 
    5157   146580096 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5158      270768 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5159      120750 :                     continue;
    5160             : 
    5161   146459346 :                 int const ConstrNum = surface.Construction;
    5162   146459346 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5163             : 
    5164   146459346 :                 if (construct.NumCTFTerms == 0) continue; // Skip surfaces with no history terms
    5165             : 
    5166             :                 // Sign convention for the various terms in the following two equations
    5167             :                 // is based on the form of the Conduction Transfer Function equation
    5168             :                 // given by:
    5169             :                 // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
    5170             :                 // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
    5171             :                 // In both equations, flux is positive from outside to inside.  The V and W terms are for radiant systems only.
    5172             : 
    5173             :                 // Set current inside flux:
    5174   146459346 :                 Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5175   146459346 :                 Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
    5176   146459346 :                                                 state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
    5177   146459346 :                                                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
    5178             :                 // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
    5179             :                 // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
    5180             :                 // reduncant.
    5181   146459346 :                 if (construct.SourceSinkPresent) {
    5182      397692 :                     SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
    5183             :                 }
    5184   146459346 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
    5185   146459346 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
    5186   146459346 :                 state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
    5187             : 
    5188             :                 // Update the temperature at the source/sink location (if one is present)
    5189   146459346 :                 if (construct.SourceSinkPresent) {
    5190      397692 :                     state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
    5191      397692 :                         SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
    5192      397692 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
    5193      397692 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    5194      397692 :                     state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
    5195      397692 :                         SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
    5196      397692 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
    5197      397692 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
    5198             :                 }
    5199             : 
    5200             :                 // Set current outside flux:
    5201   146459346 :                 if (construct.SourceSinkPresent) {
    5202      397692 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
    5203      397692 :                         SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5204      397692 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
    5205      397692 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
    5206             :                 } else {
    5207   292123308 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
    5208   146061654 :                                                                              state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5209   146061654 :                                                                              state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
    5210             :                 }
    5211             :                 // switch sign for balance at outside face
    5212   146459346 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5213   146459346 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
    5214             :             }
    5215    19583157 :         }
    5216             :     } // ...end of loop over all (heat transfer) surfaces...
    5217             : 
    5218     2629123 :     if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
    5219             :         // Temporarily save the rvalue references of the last term arrays
    5220     2172810 :         Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5221     2172810 :         Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5222     2172810 :         Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5223     2172810 :         Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5224             :         // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
    5225    19428336 :         for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
    5226    17255526 :             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
    5227    17255526 :             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
    5228    17255526 :             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
    5229    17255526 :             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
    5230             :         }
    5231             :         // Reuse the pointers of the last term arrays for the second term arrays
    5232     2172810 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
    5233     2172810 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
    5234     2172810 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
    5235     2172810 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
    5236             :         // 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)
    5237     2172810 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
    5238     2172810 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
    5239     2172810 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
    5240     2172810 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
    5241     2172810 :         return;
    5242     2172810 :     }
    5243             : 
    5244     3004231 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5245     5112036 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5246     2564118 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5247     2564118 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5248     2564118 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5249    21376566 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5250    18812448 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5251             :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5252    18812448 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5253           0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5254           0 :                     continue;
    5255    18812448 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5256    15212002 :                     state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5257    15212002 :                     state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    5258    15212002 :                     state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5259    15212002 :                     state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
    5260             :                 }
    5261             :             }
    5262     2547918 :         }
    5263             : 
    5264             :     } // ...end of loop over all (heat transfer) surfaces...
    5265      456313 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5266      431634 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5267      653526 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5268      326763 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5269      326763 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5270      326763 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5271     2540337 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5272     2213574 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5273             :                     // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5274     2213574 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5275           0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5276           0 :                         continue;
    5277     2213574 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5278     2201448 :                         state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
    5279     2201448 :                         state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
    5280     2201448 :                         state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
    5281             :                     }
    5282             :                 }
    5283      326763 :             }
    5284             :         } // ...end of loop over all (heat transfer) surfaces...
    5285             :     }
    5286             : 
    5287             :     // SHIFT TEMPERATURE AND FLUX HISTORIES:
    5288             :     // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
    5289     3004231 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5290     5112036 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5291     2564118 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5292     2564118 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5293     2564118 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5294    21376566 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5295    18812448 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5296             : 
    5297    18812448 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5298           0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5299           0 :                     continue;
    5300             : 
    5301    18812448 :                 int const ConstrNum = surface.Construction;
    5302    18812448 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5303             : 
    5304    18812448 :                 ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
    5305    18812448 :                 state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
    5306             : 
    5307    18812448 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
    5308    15210194 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    5309             : 
    5310    15210194 :                     if (construct.NumCTFTerms > 1) {
    5311    14983439 :                         int const numCTFTerms(construct.NumCTFTerms);
    5312   125422369 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5313   110438930 :                             state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
    5314   110438930 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5315   110438930 :                             state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
    5316   110438930 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5317   110438930 :                             state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
    5318   110438930 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5319   110438930 :                             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
    5320   110438930 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5321   110438930 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
    5322   110438930 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5323   110438930 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
    5324   110438930 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5325   110438930 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
    5326   110438930 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5327   110438930 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
    5328   110438930 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5329             :                         }
    5330             :                     }
    5331             : 
    5332    15210194 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
    5333    15210194 :                     state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
    5334    15210194 :                     state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
    5335    15210194 :                     state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
    5336             : 
    5337    15210194 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
    5338    15210194 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
    5339    15210194 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
    5340    15210194 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
    5341             :                 } else {
    5342     3602254 :                     Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5343     3602254 :                     if (construct.NumCTFTerms > 1) {
    5344     3602254 :                         int const numCTFTerms(construct.NumCTFTerms);
    5345    51693972 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5346             :                             // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
    5347             :                             //                                 (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
    5348    48091718 :                             Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
    5349    48091718 :                             Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
    5350    48091718 :                             Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5351    48091718 :                             Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5352    48091718 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
    5353    48091718 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
    5354             : 
    5355    48091718 :                             Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
    5356    48091718 :                             Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
    5357    48091718 :                             Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5358    48091718 :                             Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5359    48091718 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
    5360    48091718 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
    5361             :                         }
    5362             :                     }
    5363             :                     // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
    5364     3602254 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
    5365     3602254 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
    5366     3602254 :                         (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
    5367     3602254 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
    5368     3602254 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
    5369     3602254 :                         (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
    5370     3602254 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
    5371     3602254 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
    5372     3602254 :                         (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
    5373     3602254 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
    5374     3602254 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
    5375     3602254 :                         (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
    5376             :                 }
    5377             :             }
    5378     2547918 :         }
    5379             :     } // ...end of loop over all (heat transfer) surfaces
    5380             : 
    5381      456313 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5382      431634 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5383      653526 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5384      326763 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5385      326763 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5386      326763 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5387     2540337 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5388     2213574 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5389     2213574 :                     int const ConstrNum = surface.Construction;
    5390     2213574 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5391     2213574 :                     if (!construct.SourceSinkPresent) continue;
    5392      397692 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5393           0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD))
    5394           0 :                         continue;
    5395             : 
    5396      397692 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5397      385536 :                         if (construct.NumCTFTerms > 1) {
    5398      385536 :                             int const numCTFTerms = construct.NumCTFTerms;
    5399      385536 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5400      385536 :                             int m1 = m + 1;
    5401     3820314 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
    5402             :                                 // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
    5403             :                                 // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
    5404             :                                 // 1 );
    5405     3434778 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
    5406     3434778 :                                     state.dataHeatBalSurf->SurfTsrcHistM[m];
    5407     3434778 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
    5408     3434778 :                                     state.dataHeatBalSurf->SurfQsrcHistM[m];
    5409     3434778 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
    5410     3434778 :                                     state.dataHeatBalSurf->SurfTuserHistM[m];
    5411             :                             }
    5412             :                         }
    5413      385536 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
    5414      385536 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
    5415      385536 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
    5416      385536 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
    5417      385536 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
    5418      385536 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
    5419             :                     } else {
    5420       12156 :                         Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5421             : 
    5422       12156 :                         if (construct.NumCTFTerms > 1) {
    5423       12156 :                             int const numCTFTerms = construct.NumCTFTerms;
    5424       12156 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5425       12156 :                             int m1 = m + 1;
    5426      158028 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
    5427             :                                 // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
    5428             :                                 // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
    5429             :                                 // HistTermNum
    5430             :                                 // - 1 ) ) * sum_steps;  Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) );  SurfQsrcHist( SurfNum,
    5431             :                                 // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
    5432      145872 :                                 Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
    5433      145872 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] =
    5434      145872 :                                     TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
    5435      145872 :                                 Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
    5436      145872 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] =
    5437      145872 :                                     QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
    5438      145872 :                                 Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
    5439      145872 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] =
    5440      145872 :                                     TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
    5441             :                             }
    5442             :                         }
    5443             :                         // Tuned Linear indexing
    5444             :                         // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
    5445             :                         // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
    5446       12156 :                         int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
    5447       12156 :                         state.dataHeatBalSurf->SurfTsrcHist[l2] =
    5448       12156 :                             state.dataHeatBalSurf->SurfTsrcHistM[l2] -
    5449       12156 :                             (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
    5450       12156 :                         state.dataHeatBalSurf->SurfQsrcHist[l2] =
    5451       12156 :                             state.dataHeatBalSurf->SurfQsrcHistM[l2] -
    5452       12156 :                             (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
    5453       12156 :                         state.dataHeatBalSurf->SurfTuserHist[l2] =
    5454       12156 :                             state.dataHeatBalSurf->SurfTuserHistM[l2] -
    5455       12156 :                             (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
    5456             :                     }
    5457             :                 }
    5458      326763 :             }
    5459             :         } // ...end of loop over all (heat transfer) surfaces...
    5460             :     }     // ...end of AnyInternalHeatSourceInInput
    5461             : }
    5462             : 
    5463     3735792 : void CalculateZoneMRT(EnergyPlusData &state,
    5464             :                       ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    5465             : {
    5466             : 
    5467             :     // SUBROUTINE INFORMATION:
    5468             :     //       AUTHOR         Rick Strand
    5469             :     //       DATE WRITTEN   November 2000
    5470             : 
    5471             :     // PURPOSE OF THIS SUBROUTINE:
    5472             :     // Calculates the current zone and enclosure MRT for thermal comfort and radiation
    5473             :     // calculation purposes.
    5474             : 
    5475     3735792 :     if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5476         796 :         state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
    5477         796 :         state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
    5478         796 :         state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
    5479         796 :         state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
    5480        5851 :         for (auto &encl : state.dataViewFactor->EnclRadInfo) {
    5481        5055 :             encl.sumAE = 0.0;
    5482         796 :         }
    5483       46840 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5484       46044 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    5485       46044 :             if (surface.HeatTransSurf) {
    5486       44391 :                 auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
    5487       44391 :                 thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
    5488       44391 :                 int ZoneNum = surface.Zone;
    5489       44391 :                 if (ZoneNum > 0) state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
    5490       44391 :                 if (surface.RadEnclIndex > 0) state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
    5491             :             }
    5492             :         }
    5493             :     }
    5494             : 
    5495             :     // Zero sumAET for applicable enclosures
    5496     3735792 :     if (present(ZoneToResimulate)) {
    5497     1590246 :         for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
    5498      795123 :             int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
    5499      795123 :             state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
    5500      795123 :             state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
    5501      795123 :         }
    5502             :     } else {
    5503    23406881 :         for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5504    20466212 :             thisEnclosure.reCalcMRT = true;
    5505     2940669 :         }
    5506             :     }
    5507    26972563 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5508    23236771 :         if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) continue;
    5509    21265379 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    5510    21265379 :         if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
    5511    21263354 :             Real64 zoneSumAET = 0.0;
    5512    42575308 :             for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
    5513    21311954 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5514   203292419 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    5515   181980465 :                     Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
    5516   181980465 :                     zoneSumAET += surfAET;
    5517   181980465 :                     state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
    5518             :                 }
    5519    21263354 :             }
    5520    21263354 :             thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
    5521             :         } else {
    5522        2025 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5523           2 :                 ShowWarningError(
    5524             :                     state,
    5525           2 :                     format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
    5526           1 :                 ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
    5527             :             }
    5528        2025 :             thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    5529             :         }
    5530             :     }
    5531             :     // Calculate MRT for applicable enclosures
    5532    26968519 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5533    23232727 :         if (!thisEnclosure.reCalcMRT) continue;
    5534    23232727 :         if (thisEnclosure.sumAE > 0.01) {
    5535    23230702 :             thisEnclosure.sumAET = 0.0;
    5536   219540335 :             for (int surfNum : thisEnclosure.SurfacePtr) {
    5537   196309633 :                 Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
    5538   196309633 :                 thisEnclosure.sumAET += surfAET;
    5539             :             }
    5540    23230702 :             thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
    5541             :         } else {
    5542        2025 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5543           2 :                 ShowWarningError(state,
    5544           2 :                                  format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
    5545           1 :                 ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
    5546             :             }
    5547        2025 :             Real64 sumMATVol = 0.0;
    5548        2025 :             Real64 sumVol = 0.0;
    5549        2025 :             Real64 sumMAT = 0.0;
    5550        4050 :             for (auto &spaceNum : thisEnclosure.spaceNums) {
    5551        2025 :                 Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
    5552        2025 :                 Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
    5553        2025 :                 sumVol += spaceVolume;
    5554        2025 :                 sumMATVol += spaceMAT * spaceVolume;
    5555        2025 :                 sumMAT += spaceMAT;
    5556        2025 :             }
    5557        2025 :             if (sumVol > 0.01) {
    5558        2025 :                 thisEnclosure.MRT = sumMATVol / sumVol;
    5559             :             } else {
    5560           0 :                 thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
    5561             :             }
    5562             :         }
    5563             :         // Set space MRTs
    5564    46518098 :         for (int spaceNum : thisEnclosure.spaceNums) {
    5565    23285371 :             state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
    5566    23232727 :         }
    5567     3735792 :     }
    5568             : 
    5569     3735792 :     state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
    5570     3735792 : }
    5571             : 
    5572             : // End of Record Keeping subroutines for the HB Module
    5573             : // *****************************************************************************
    5574             : 
    5575             : // Beginning of Reporting subroutines for the HB Module
    5576             : // *****************************************************************************
    5577             : 
    5578     2804482 : void CalcThermalResilience(EnergyPlusData &state)
    5579             : {
    5580             :     // This function calculate timestep-wise heat index and humidex.
    5581             : 
    5582             :     // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
    5583             :     // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
    5584             :     // Technical Attachment (SR 90-23).
    5585             :     // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
    5586             : 
    5587             :     // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
    5588             :     // Canada's Atmospheric Environment Service in 1979.
    5589             :     // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
    5590             :     // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmosheric Environment Servic
    5591             :     //        using OutputProcessor::ReqRepVars;
    5592     2804482 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
    5593        5852 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5594       10112 :             SetupOutputVariable(state,
    5595             :                                 "Zone Heat Index",
    5596             :                                 Constant::Units::C,
    5597        5056 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
    5598             :                                 OutputProcessor::TimeStepType::Zone,
    5599             :                                 OutputProcessor::StoreType::Average,
    5600        5056 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5601       10112 :             SetupOutputVariable(state,
    5602             :                                 "Zone Humidity Index",
    5603             :                                 Constant::Units::None,
    5604        5056 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
    5605             :                                 OutputProcessor::TimeStepType::Zone,
    5606             :                                 OutputProcessor::StoreType::Average,
    5607        5056 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5608             :         }
    5609       22338 :         for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
    5610       21542 :             if (reqVar->name == "Zone Heat Index") {
    5611           0 :                 state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
    5612       21542 :             } else if (reqVar->name == "Zone Humidity Index") {
    5613           0 :                 state.dataHeatBalSurfMgr->reportVarHumidex = true;
    5614             :             }
    5615         796 :         }
    5616             :     }
    5617             : 
    5618             :     // Calculate Heat Index and Humidex.
    5619             :     // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
    5620             :     // then heat index is calculated and converted back to C.
    5621     2804482 :     if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5622             :         // Constance for heat index regression equation of Rothfusz.
    5623     1081251 :         Real64 constexpr c1 = -42.379;
    5624     1081251 :         Real64 constexpr c2 = 2.04901523;
    5625     1081251 :         Real64 constexpr c3 = 10.14333127;
    5626     1081251 :         Real64 constexpr c4 = -.22475541;
    5627     1081251 :         Real64 constexpr c5 = -.00683783;
    5628     1081251 :         Real64 constexpr c6 = -.05481717;
    5629     1081251 :         Real64 constexpr c7 = .00122874;
    5630     1081251 :         Real64 constexpr c8 = .00085282;
    5631     1081251 :         Real64 constexpr c9 = -.00000199;
    5632     6341862 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5633     5260611 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5634     5260611 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5635     5260611 :             Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
    5636     5260611 :             Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
    5637             :             Real64 HI;
    5638             : 
    5639     5260611 :             if (ZoneTF < 80) {
    5640     4527593 :                 HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
    5641             :             } else {
    5642      733018 :                 HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
    5643      733018 :                      c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
    5644      733018 :                 if (ZoneRH < 13 && ZoneTF < 112) {
    5645       33992 :                     HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
    5646      699026 :                 } else if (ZoneRH > 85 && ZoneTF < 87) {
    5647       15017 :                     HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
    5648             :                 }
    5649             :             }
    5650     5260611 :             HI = (HI - 32.0) * (5.0 / 9.0);
    5651     5260611 :             state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
    5652             :         }
    5653             :     }
    5654     2804482 :     if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5655     6341862 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5656     5260611 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5657     5260611 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5658     5260611 :             Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
    5659     5260611 :             Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
    5660     5260611 :             Real64 const h = 5.0 / 9.0 * (e - 10.0);
    5661     5260611 :             Real64 const Humidex = ZoneT + h;
    5662     5260611 :             state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
    5663             :         }
    5664             :     }
    5665     2804482 : }
    5666             : 
    5667     1081251 : void ReportThermalResilience(EnergyPlusData &state)
    5668             : {
    5669             : 
    5670     1081251 :     Array1D_bool reportPeriodFlags;
    5671     1081251 :     if (state.dataWeather->TotReportPers > 0) {
    5672        5376 :         reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
    5673        5376 :         General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
    5674             :     }
    5675             : 
    5676     1081251 :     auto &ort = state.dataOutRptTab;
    5677     1088163 :     for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5678        6912 :         if (reportPeriodFlags(i)) {
    5679           0 :             int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    5680           0 :             state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    5681             :         }
    5682             :     }
    5683             : 
    5684     1081251 :     if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
    5685         675 :         int constexpr HINoBins = 5;                     // Heat Index range - number of bins
    5686         675 :         int constexpr HumidexNoBins = 5;                // Humidex range - number of bins
    5687         675 :         int constexpr SETNoBins = 5;                    // SET report column numbers
    5688         675 :         int constexpr ColdHourOfSafetyNoBins = 5;       // Cold Stress Hour of Safety number of columns
    5689         675 :         int constexpr HeatHourOfSafetyNoBins = 5;       // Heat Stress Hour of Safety number of columns
    5690         675 :         int constexpr UnmetDegreeHourNoBins = 6;        // Unmet Degree Hour number of columns
    5691         675 :         int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
    5692             : 
    5693         675 :         if (state.dataHeatBal->TotPeople == 0) state.dataHeatBalSurfMgr->hasPierceSET = false;
    5694        3571 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5695        2896 :             if (!state.dataHeatBal->People(iPeople).Pierce) {
    5696        2885 :                 state.dataHeatBalSurfMgr->hasPierceSET = false;
    5697             :             }
    5698             :         }
    5699        4215 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5700             :             // the whole period
    5701             :             // user specified reporting period
    5702        3545 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5703           5 :                 state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5704           5 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5705           5 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5706           5 :                 state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5707           5 :                 state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5708           5 :                 state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5709           5 :                 if (state.dataHeatBalSurfMgr->hasPierceSET) {
    5710           5 :                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5711           5 :                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5712             :                 }
    5713           5 :                 state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
    5714           5 :                 state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
    5715           5 :                 state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
    5716           5 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5717           5 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5718             :             }
    5719        3540 :             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
    5720        3540 :             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
    5721        3540 :             state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
    5722        3540 :             state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
    5723             :         }
    5724         675 :         state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5725         675 :         state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5726         675 :         state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5727         675 :         state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5728         675 :         state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
    5729             :     }
    5730             : 
    5731             :     // Count hours only during weather simulation periods
    5732     1081251 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    5733             :         // use default value if there are no user inputs
    5734      210336 :         Real64 ColdTempThresh = 15.56;
    5735      210336 :         Real64 HeatTempThresh = 30.0;
    5736             :         // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
    5737             :         // Record last time step SET to trace SET unmet duration;
    5738             : 
    5739      210336 :         Real64 valueNotInit = -999.0;
    5740      210336 :         Real64 nearThreshold = 1.0;
    5741     1156992 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5742      946656 :             state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
    5743      946656 :             state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
    5744             :         }
    5745     1051776 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5746      841440 :             int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
    5747      841440 :             state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
    5748      841440 :                 state.dataHeatBal->People(iPeople).NumberOfPeople *
    5749      841440 :                 ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatBal->People(iPeople).NumberOfPeoplePtr);
    5750      841440 :             state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5751      841440 :             if (state.dataHeatBal->People(iPeople).Pierce) {
    5752           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
    5753             :             } else {
    5754      841440 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
    5755             :             }
    5756             : 
    5757      841440 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    5758      841440 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5759      841440 :             ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5760      841440 :             bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
    5761      841440 :             if (Temperature > ColdTempThresh) { // safe
    5762      772448 :                 if (!CrossedColdThresh) {
    5763             :                     // compute the number of hours before threshold is reached
    5764      387536 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5765             :                 }
    5766             :             } else { // danger
    5767             :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5768       68992 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5769       68992 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5770       68992 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5771             :                 // first time crossing threshold
    5772       68992 :                 if (!CrossedColdThresh) {
    5773             :                     // compute the time when the zone crosses the threshold temperature
    5774             :                     int encodedMonDayHrMin;
    5775          10 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5776          10 :                                                state.dataEnvrn->Month,
    5777          10 :                                                state.dataEnvrn->DayOfMonth,
    5778          10 :                                                state.dataGlobal->HourOfDay,
    5779          10 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5780             :                     // fixme: not sure how to aggregate by zone
    5781          10 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
    5782          10 :                     CrossedColdThresh = true;
    5783             :                 }
    5784             :             }
    5785      841440 :             HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5786      841440 :             bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
    5787      841440 :             if (Temperature < HeatTempThresh) { // safe
    5788      836286 :                 if (!CrossedHeatThresh) {
    5789             :                     // compute the number of hours before threshold is reached
    5790      451457 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5791             :                 }
    5792             :             } else { // danger
    5793             :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5794        5154 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5795        5154 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5796        5154 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5797             :                 // first time crossing threshold
    5798        5154 :                 if (!CrossedHeatThresh) {
    5799             :                     // compute the time when the zone crosses the threshold temperature
    5800             :                     int encodedMonDayHrMin;
    5801          13 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5802          13 :                                                state.dataEnvrn->Month,
    5803          13 :                                                state.dataEnvrn->DayOfMonth,
    5804          13 :                                                state.dataGlobal->HourOfDay,
    5805          13 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5806          13 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
    5807          13 :                     CrossedHeatThresh = true;
    5808             :                 }
    5809             :             }
    5810             : 
    5811      841440 :             Real64 VeryHotPMVThresh = 3.0;
    5812      841440 :             Real64 WarmPMVThresh = 0.7;
    5813      841440 :             Real64 CoolPMVThresh = -0.7;
    5814      841440 :             Real64 VeryColdPMVThresh = -3.0;
    5815      841440 :             Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
    5816      841440 :             if (PMV < VeryColdPMVThresh) {
    5817           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
    5818           0 :                     (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5819           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
    5820           0 :                     (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5821             :             }
    5822      841440 :             if (PMV < CoolPMVThresh) {
    5823       91082 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
    5824       91082 :                     (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5825       91082 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
    5826       91082 :                     (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5827             :             }
    5828      841440 :             if (PMV > WarmPMVThresh) {
    5829       94796 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
    5830       94796 :                     (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5831       94796 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
    5832       94796 :                     (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5833             :             }
    5834      841440 :             if (PMV > VeryHotPMVThresh) {
    5835         402 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
    5836         402 :                     (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5837         402 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
    5838         402 :                     (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5839             :             }
    5840             : 
    5841             :             // check whether PierceSET changed for people in a zone
    5842      841440 :             if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
    5843      841440 :                 state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5844             :             } else {
    5845           0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
    5846           0 :                     ShowRecurringWarningErrorAtEnd(state,
    5847           0 :                                                    fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
    5848           0 :                                                    state.dataHeatBalFanSys->PierceSETerrorIndex);
    5849             :                 }
    5850             :             }
    5851             : 
    5852             :             // check whether PierceSET, PMV, etc. changed for different people in a zone
    5853      841440 :             if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
    5854      841440 :                 state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
    5855             :             } else {
    5856           0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
    5857           0 :                     ShowRecurringWarningErrorAtEnd(state,
    5858           0 :                                                    fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
    5859           0 :                                                    state.dataHeatBalFanSys->PMVerrorIndex);
    5860             :                 }
    5861             :             }
    5862             : 
    5863      841440 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5864           0 :                 if (reportPeriodFlags(i)) {
    5865           0 :                     int ReportPeriodIdx = i;
    5866           0 :                     ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5867           0 :                     bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5868           0 :                     if (Temperature > ColdTempThresh) { // safe
    5869           0 :                         if (!CrossedColdThreshRepPeriod) {
    5870             :                             // compute the number of hours before threshold is reached
    5871           0 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5872             :                         }
    5873             :                     } else { // danger
    5874             :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5875           0 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5876           0 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5877           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5878           0 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5879           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5880             :                         // first time crossing threshold
    5881           0 :                         if (!CrossedColdThreshRepPeriod) {
    5882             :                             // compute the time when the zone crosses the threshold temperature
    5883             :                             int encodedMonDayHrMin;
    5884           0 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5885           0 :                                                        state.dataEnvrn->Month,
    5886           0 :                                                        state.dataEnvrn->DayOfMonth,
    5887           0 :                                                        state.dataGlobal->HourOfDay,
    5888           0 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5889             :                             // fixme: not sure how to aggregate by zone
    5890           0 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5891           0 :                             CrossedColdThreshRepPeriod = true;
    5892             :                         }
    5893             :                     }
    5894           0 :                     HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5895           0 :                     bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5896           0 :                     if (Temperature < HeatTempThresh) { // safe
    5897           0 :                         if (!CrossedHeatThreshRepPeriod) {
    5898             :                             // compute the number of hours before threshold is reached
    5899           0 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5900             :                         }
    5901             :                     } else { // danger
    5902             :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5903           0 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5904           0 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5905           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5906           0 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5907           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5908             :                         // first time crossing threshold
    5909           0 :                         if (!CrossedHeatThreshRepPeriod) {
    5910             :                             // compute the time when the zone crosses the threshold temperature
    5911             :                             int encodedMonDayHrMin;
    5912           0 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5913           0 :                                                        state.dataEnvrn->Month,
    5914           0 :                                                        state.dataEnvrn->DayOfMonth,
    5915           0 :                                                        state.dataGlobal->HourOfDay,
    5916           0 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5917           0 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5918           0 :                             CrossedHeatThreshRepPeriod = true;
    5919             :                         }
    5920             :                     }
    5921             : 
    5922           0 :                     if (PMV < VeryColdPMVThresh) {
    5923           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5924           0 :                             (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5925           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5926           0 :                             (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5927             :                     }
    5928           0 :                     if (PMV < CoolPMVThresh) {
    5929           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    5930           0 :                             (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5931           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    5932           0 :                             (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5933             :                     }
    5934           0 :                     if (PMV > WarmPMVThresh) {
    5935           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    5936           0 :                             (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5937           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    5938           0 :                             (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5939             :                     }
    5940           0 :                     if (PMV > VeryHotPMVThresh) {
    5941           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5942           0 :                             (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5943           0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5944           0 :                             (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5945             :                     }
    5946             :                 }
    5947             :             }
    5948             :         }
    5949     1156992 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5950      946656 :             Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
    5951      946656 :             Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
    5952             : 
    5953      946656 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    5954      946656 :             if (HI <= 26.7) {
    5955      896589 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
    5956      896589 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    5957      896589 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5958       50067 :             } else if (HI > 26.7 && HI <= 32.2) {
    5959       40732 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
    5960       40732 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    5961       40732 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5962        9335 :             } else if (HI > 32.2 && HI <= 39.4) {
    5963        4137 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
    5964        4137 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    5965        4137 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5966        5198 :             } else if (HI > 39.4 && HI <= 51.7) {
    5967        3288 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
    5968        3288 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5969        3288 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5970             :             } else {
    5971        1910 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
    5972        1910 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    5973        1910 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5974             :             }
    5975             : 
    5976      946656 :             if (Humidex <= 29) {
    5977      859310 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
    5978      859310 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    5979      859310 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5980       87346 :             } else if (Humidex > 29 && Humidex <= 40) {
    5981       77202 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
    5982       77202 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    5983       77202 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5984       10144 :             } else if (Humidex > 40 && Humidex <= 45) {
    5985        4496 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
    5986        4496 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    5987        4496 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5988        5648 :             } else if (Humidex > 45 && Humidex <= 50) {
    5989        2966 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
    5990        2966 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5991        2966 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5992             :             } else {
    5993        2682 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
    5994        2682 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    5995        2682 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5996             :             }
    5997             : 
    5998      946656 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5999      946656 :             Real64 CoolingSetpoint = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum);
    6000      946656 :             Real64 HeatingSetpoint = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum);
    6001             : 
    6002      946656 :             if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6003       41810 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6004       41810 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
    6005       41810 :                     NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6006       41810 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
    6007       41810 :                     (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6008             :             }
    6009      946656 :             if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6010       65535 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6011       65535 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
    6012       65535 :                     NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6013       65535 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
    6014       65535 :                     (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6015             :             }
    6016             : 
    6017      946656 :             if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6018             :                 int encodedMonDayHrMin;
    6019           0 :                 Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6020           0 :                 Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6021             : 
    6022           0 :                 if (PierceSET <= 12.2) {
    6023           0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6024           0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6025           0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6026             :                     // Reset duration when last step is out of range.
    6027           0 :                     if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6028           0 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6029           0 :                                                    state.dataEnvrn->Month,
    6030           0 :                                                    state.dataEnvrn->DayOfMonth,
    6031           0 :                                                    state.dataGlobal->HourOfDay,
    6032           0 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6033           0 :                         state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    6034           0 :                         state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    6035             :                     }
    6036             :                     // Keep the longest duration record.
    6037           0 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    6038           0 :                     if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
    6039           0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6040           0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
    6041           0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
    6042             :                     }
    6043           0 :                 } else if (PierceSET > 30) {
    6044           0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6045           0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6046           0 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6047           0 :                     if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6048           0 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6049           0 :                                                    state.dataEnvrn->Month,
    6050           0 :                                                    state.dataEnvrn->DayOfMonth,
    6051           0 :                                                    state.dataGlobal->HourOfDay,
    6052           0 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6053           0 :                         state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    6054           0 :                         state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    6055             :                     }
    6056           0 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    6057           0 :                     if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
    6058           0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6059           0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
    6060           0 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
    6061             :                     }
    6062             :                 }
    6063             : 
    6064           0 :                 if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6065           0 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    6066           0 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    6067             :                 }
    6068             :             }
    6069             : 
    6070      946656 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    6071           0 :                 if (reportPeriodFlags(i)) {
    6072           0 :                     int ReportPeriodIdx = i;
    6073             : 
    6074           0 :                     if (HI <= 26.7) {
    6075           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6076           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6077           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6078           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6079           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6080           0 :                     } else if (HI > 26.7 && HI <= 32.2) {
    6081           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6082           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6083           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6084           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6085           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6086           0 :                     } else if (HI > 32.2 && HI <= 39.4) {
    6087           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6088           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6089           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6090           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6091           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6092           0 :                     } else if (HI > 39.4 && HI <= 51.7) {
    6093           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6094           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6095           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6096           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6097           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6098             :                     } else {
    6099           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6100           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6101           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6102           0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6103           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6104             :                     }
    6105             : 
    6106           0 :                     if (Humidex <= 29) {
    6107           0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6108           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6109           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6110           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6111           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6112           0 :                     } else if (Humidex > 29 && Humidex <= 40) {
    6113           0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6114           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6115           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6116           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6117           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6118           0 :                     } else if (Humidex > 40 && Humidex <= 45) {
    6119           0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6120           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6121           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6122           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6123           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6124           0 :                     } else if (Humidex > 45 && Humidex <= 50) {
    6125           0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6126           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6127           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6128           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6129           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6130             :                     } else {
    6131           0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6132           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6133           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6134           0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6135           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6136             :                     }
    6137             : 
    6138           0 :                     if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6139             :                         int encodedMonDayHrMin;
    6140           0 :                         Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6141           0 :                         Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6142           0 :                         if (PierceSET <= 12.2) {
    6143           0 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6144           0 :                                 (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6145           0 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6146           0 :                                 (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6147           0 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6148           0 :                                 (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6149             :                             // Reset duration when last step is out of range
    6150           0 :                             if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6151           0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6152           0 :                                                            state.dataEnvrn->Month,
    6153           0 :                                                            state.dataEnvrn->DayOfMonth,
    6154           0 :                                                            state.dataGlobal->HourOfDay,
    6155           0 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6156           0 :                                 state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6157           0 :                                 state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6158           0 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6159           0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6160           0 :                                                            state.dataEnvrn->Month,
    6161           0 :                                                            state.dataEnvrn->DayOfMonth,
    6162           0 :                                                            state.dataGlobal->HourOfDay,
    6163           0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6164           0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6165           0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6166             :                             }
    6167             :                             // Keep the longest duration record.
    6168           0 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6169           0 :                             if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6170           0 :                                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6171           0 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6172           0 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6173           0 :                                     state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6174           0 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6175           0 :                                     state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6176             :                             }
    6177           0 :                         } else if (PierceSET > 30) {
    6178           0 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6179           0 :                                 (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6180           0 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6181           0 :                                 (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6182           0 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6183           0 :                                 (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6184             :                             // Reset duration when last step is out of range.
    6185           0 :                             if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6186           0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6187           0 :                                                            state.dataEnvrn->Month,
    6188           0 :                                                            state.dataEnvrn->DayOfMonth,
    6189           0 :                                                            state.dataGlobal->HourOfDay,
    6190           0 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6191           0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6192           0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6193           0 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6194           0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6195           0 :                                                            state.dataEnvrn->Month,
    6196           0 :                                                            state.dataEnvrn->DayOfMonth,
    6197           0 :                                                            state.dataGlobal->HourOfDay,
    6198           0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6199           0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6200           0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6201             :                             }
    6202           0 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6203           0 :                             if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6204           0 :                                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6205           0 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6206           0 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6207           0 :                                     state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6208           0 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6209           0 :                                     state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6210             :                             }
    6211             :                         }
    6212           0 :                         if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6213           0 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6214           0 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6215             :                         }
    6216             :                     }
    6217             : 
    6218           0 :                     if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6219           0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6220           0 :                             (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6221           0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6222           0 :                             NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6223           0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6224           0 :                             (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6225             :                     }
    6226           0 :                     if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6227           0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6228           0 :                             (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6229           0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6230           0 :                             NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6231           0 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
    6232           0 :                             (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6233             :                     }
    6234             :                 }
    6235             :             }
    6236             :         } // loop over zones
    6237             :     }
    6238     1081251 : }
    6239             : 
    6240       19092 : void ReportCO2Resilience(EnergyPlusData &state)
    6241             : {
    6242       19092 :     if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
    6243         675 :         int NoBins = 3;
    6244        4215 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6245        3543 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6246           3 :                 state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6247           3 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6248           3 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6249             :             }
    6250             :         }
    6251         675 :         state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
    6252         675 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    6253         660 :             if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
    6254           0 :                 ShowWarningError(state,
    6255             :                                  "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
    6256             :                                  "Zone Air CO2 Concentration output is required, "
    6257             :                                  "but no ZoneAirContaminantBalance object is defined.");
    6258             :             }
    6259         660 :             state.dataOutRptTab->displayCO2ResilienceSummary = false;
    6260         660 :             return;
    6261             :         }
    6262             :     }
    6263             : 
    6264       18432 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6265           0 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    6266           0 :             int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
    6267           0 :             state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
    6268           0 :                 state.dataHeatBal->People(iPeople).NumberOfPeople *
    6269           0 :                 ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatBal->People(iPeople).NumberOfPeoplePtr);
    6270             :         }
    6271             : 
    6272           0 :         Array1D_bool reportPeriodFlags;
    6273           0 :         if (state.dataWeather->TotReportPers > 0) {
    6274           0 :             reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
    6275           0 :             General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
    6276             :         }
    6277             : 
    6278           0 :         auto &ort = state.dataOutRptTab;
    6279           0 :         for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6280           0 :             if (reportPeriodFlags(i)) {
    6281           0 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6282           0 :                 state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6283             :             }
    6284             :         }
    6285             : 
    6286           0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6287           0 :             Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
    6288             : 
    6289           0 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6290           0 :             if (ZoneAirCO2 <= 1000) {
    6291           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6292           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6293           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6294           0 :             } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6295           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6296           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6297           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6298             :             } else {
    6299           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6300           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6301           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6302             :             }
    6303           0 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6304           0 :                 if (reportPeriodFlags(i)) {
    6305           0 :                     int ReportPeriodIdx = i;
    6306           0 :                     if (ZoneAirCO2 <= 1000) {
    6307           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6308           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6309           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6310           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6311           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6312           0 :                     } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6313           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6314           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6315           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6316           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6317           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6318             :                     } else {
    6319           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6320           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6321           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6322           0 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6323           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6324             :                     }
    6325             :                 }
    6326             :             }
    6327             :         }
    6328           0 :     } // loop over zones
    6329             : }
    6330             : 
    6331       91820 : void ReportVisualResilience(EnergyPlusData &state)
    6332             : {
    6333       91820 :     if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
    6334         675 :         int NoBins = 4;
    6335        4215 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6336        3543 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6337           3 :                 state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6338           3 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6339           3 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6340             :             }
    6341             :         }
    6342         675 :         state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
    6343         675 :         if ((int)state.dataDayltg->daylightControl.size() == 0) {
    6344         620 :             if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
    6345           0 :                 ShowWarningError(state,
    6346             :                                  "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
    6347             :                                  "Zone Average Daylighting Reference Point Illuminance output is required, "
    6348             :                                  "but no Daylighting Control Object is defined.");
    6349             :             }
    6350         620 :             state.dataOutRptTab->displayVisualResilienceSummary = false;
    6351         620 :             return;
    6352             :         }
    6353             :     }
    6354             : 
    6355       91200 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6356           0 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    6357           0 :             int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
    6358           0 :             state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
    6359           0 :                 state.dataHeatBal->People(iPeople).NumberOfPeople *
    6360           0 :                 ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatBal->People(iPeople).NumberOfPeoplePtr);
    6361             :         }
    6362             :         // Accumulate across daylighting controls first
    6363           0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6364           0 :             state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
    6365             :         }
    6366           0 :         for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
    6367           0 :             auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
    6368           0 :             if (thisDaylightControl.PowerReductionFactor > 0) {
    6369           0 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6370           0 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
    6371             :                 }
    6372             :             } else {
    6373           0 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6374           0 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
    6375           0 :                         thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
    6376             :                 }
    6377             :             }
    6378             :         }
    6379             : 
    6380           0 :         Array1D_bool reportPeriodFlags;
    6381           0 :         if (state.dataWeather->TotReportPers > 0) {
    6382           0 :             reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
    6383           0 :             General::findReportPeriodIdx(
    6384           0 :                 state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
    6385             :         }
    6386             : 
    6387           0 :         auto &ort = state.dataOutRptTab;
    6388           0 :         for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6389           0 :             if (reportPeriodFlags(i)) {
    6390           0 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6391           0 :                 state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6392             :             }
    6393             :         }
    6394             : 
    6395           0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6396           0 :             if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) continue;
    6397             :             // Now divide by total reference points to get average
    6398           0 :             Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
    6399             : 
    6400           0 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6401           0 :             if (avgZoneIllum <= 100) {
    6402           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6403           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6404           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6405           0 :             } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6406           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6407           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6408           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6409           0 :             } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6410           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6411           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6412           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6413             :             } else {
    6414           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
    6415           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6416           0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6417             :             }
    6418           0 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6419           0 :                 if (reportPeriodFlags(i)) {
    6420           0 :                     int ReportPeriodIdx = i;
    6421           0 :                     if (avgZoneIllum <= 100) {
    6422           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6423           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6424           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6425           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6426           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6427           0 :                     } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6428           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6429           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6430           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6431           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6432           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6433           0 :                     } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6434           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6435           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6436           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6437           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6438           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6439             :                     } else {
    6440           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6441           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6442           0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6443           0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6444           0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6445             :                     }
    6446             :                 }
    6447             :             }
    6448             :         }
    6449           0 :     } // loop over zones
    6450             : }
    6451             : 
    6452     2804482 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
    6453             : {
    6454             : 
    6455             :     // SUBROUTINE INFORMATION:
    6456             :     //       AUTHOR         Linda Lawrie
    6457             :     //       DATE WRITTEN   Oct 2000
    6458             : 
    6459             :     // PURPOSE OF THIS SUBROUTINE:
    6460             :     // This subroutine puts the reporting part of the HBSurface Module in one area.
    6461             : 
    6462     2804482 :     SolarShading::ReportSurfaceShading(state);
    6463             : 
    6464     2804482 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    6465         687 :         ReportNonRepresentativeSurfaceResults(state);
    6466             :     }
    6467             : 
    6468             :     // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
    6469             : 
    6470             :     // Opaque or window surfaces
    6471    22670650 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6472    39780936 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6473    19914768 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6474    19914768 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6475    19914768 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6476   191522568 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6477   171607800 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6478             :                 // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
    6479   171607800 :                 state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
    6480   171607800 :                 state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
    6481   171607800 :                     state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6482             : 
    6483   171607800 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6484   171607800 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
    6485   171607800 :                     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6486             : 
    6487   171607800 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
    6488   171607800 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
    6489   171607800 :                     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6490             : 
    6491   171607800 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
    6492   171607800 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
    6493   171607800 :                     state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6494             : 
    6495   171607800 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
    6496             : 
    6497   171607800 :                 state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
    6498   171607800 :                     state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6499             : 
    6500   171607800 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
    6501   171607800 :                 state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
    6502   171607800 :                     state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6503             : 
    6504             :                 // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
    6505   171607800 :                 state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
    6506   171607800 :                     surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
    6507   171607800 :                     (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
    6508             : 
    6509             :                 // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
    6510   171607800 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
    6511   171607800 :                     state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
    6512             :             }
    6513    19866168 :         }
    6514             :     }
    6515             : 
    6516     2804482 :     if (state.dataOutRptTab->displayHeatEmissionsSummary) {
    6517     1077315 :         state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
    6518    46380375 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6519    45303060 :             if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    6520    21077133 :                 state.dataHeatBalSurf->SumSurfaceHeatEmission +=
    6521    21077133 :                     state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    6522             :             }
    6523             :         }
    6524             :     }
    6525             : 
    6526             :     // Window surfaces
    6527    22670650 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6528    39780936 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6529    19914768 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6530    19914768 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    6531    19914768 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    6532    43136754 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6533    23221986 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6534    23221986 :                 state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
    6535    23221986 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
    6536             : 
    6537             :                 // Absorbed short wave radiation
    6538             :                 int TotGlassLayers;
    6539    23221986 :                 int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    6540    23221986 :                 auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
    6541    23221986 :                 int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
    6542    23221986 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
    6543    23221986 :                 if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
    6544        8109 :                     TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
    6545    23213877 :                 } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
    6546       39540 :                     TotGlassLayers = thisConstruct.TotSolidLayers;
    6547    23174337 :                 } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    6548    22985379 :                     TotGlassLayers = thisConstruct.TotGlassLayers;
    6549             :                 } else {
    6550             :                     // Interior, exterior or between-glass shade, screen or blind in place
    6551      188958 :                     TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
    6552             :                 }
    6553    23221986 :                 state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
    6554    23221986 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
    6555    23221986 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
    6556    53233956 :                 for (int lay = 1; lay <= TotGlassLayers; ++lay) {
    6557             :                     // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6558    30011970 :                     state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
    6559    30011970 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
    6560             :                     // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6561    30011970 :                     state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6562             :                     // Total Shortwave Absorbed:All solid Layers[W]
    6563    30011970 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6564             :                 }
    6565             : 
    6566             :                 // Window heat gain/loss
    6567    23221986 :                 if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
    6568     7910461 :                     state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
    6569     7910461 :                     state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
    6570     7910461 :                         state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6571             :                 } else {
    6572    15311525 :                     state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
    6573    15311525 :                     state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
    6574    15311525 :                         state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6575             :                 }
    6576    23221986 :                 state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
    6577    23221986 :                     state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6578    23221986 :                 if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    6579        4050 :                     int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    6580        4050 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
    6581        4050 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
    6582             :                 }
    6583             :             }
    6584    19866168 :         }
    6585             :     }
    6586             : 
    6587     2804482 :     if (state.dataSurface->AnyMovableInsulation) ReportIntMovInsInsideSurfTemp(state);
    6588             : 
    6589             :     // Opaque heat transfer surfaces
    6590    22670650 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6591    39780936 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6592    19914768 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6593    19914768 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6594    19914768 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6595   168300582 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6596   148385814 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6597             : 
    6598   148385814 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
    6599   148385814 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
    6600   148385814 :                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6601             : 
    6602   148385814 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
    6603   148385814 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
    6604   148385814 :                     state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6605             : 
    6606   148385814 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
    6607   148385814 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
    6608   148385814 :                     state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6609             : 
    6610             :                 // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6611   148385814 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
    6612             :                 // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6613   148385814 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
    6614             : 
    6615             :                 // inside face conduction updates
    6616   148385814 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
    6617   148385814 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
    6618   148385814 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6619   148385814 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
    6620   148385814 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
    6621   148385814 :                 if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
    6622    71804478 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6623             :                 } else {
    6624    76581336 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6625             :                 }
    6626             : 
    6627             :                 // outside face conduction updates
    6628   148385814 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
    6629   148385814 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
    6630   148385814 :                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6631   148385814 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
    6632   148385814 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
    6633   148385814 :                 if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
    6634    91271820 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6635             :                 } else {
    6636    57113994 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6637             :                 }
    6638             :             }
    6639   168300582 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6640             :                 // do average surface conduction updates
    6641             : 
    6642   148385814 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
    6643   148385814 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
    6644   148385814 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
    6645   148385814 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
    6646   148385814 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
    6647   148385814 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6648   148385814 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
    6649   148385814 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
    6650   148385814 :                 if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
    6651    64726230 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6652             :                 } else {
    6653    83659584 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6654             :                 }
    6655             : 
    6656             :                 // do surface storage rate updates
    6657   148385814 :                 state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
    6658   148385814 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
    6659   148385814 :                 state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
    6660   148385814 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
    6661   148385814 :                 state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
    6662   148385814 :                     state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6663   148385814 :                 state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
    6664   148385814 :                 state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
    6665   148385814 :                 if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
    6666    64388961 :                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6667             :                 } else {
    6668    83996853 :                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6669             :                 }
    6670             :             }
    6671    19866168 :         }
    6672             :     }
    6673             : 
    6674     2804482 :     if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
    6675       73122 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour + state.dataGlobal->TimeStep;
    6676      674988 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6677     1236060 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6678      634194 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6679      634194 :                 int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6680      634194 :                 int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6681     5032314 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6682     4398120 :                     state.dataOutRptTab->lightSWRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) =
    6683     4398120 :                         state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
    6684     4398120 :                     state.dataOutRptTab->feneSolarRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) =
    6685     4398120 :                         state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
    6686             :                 }
    6687      634194 :                 firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6688      634194 :                 lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6689     5588010 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6690     4953816 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6691     4953816 :                     if (!state.dataGlobal->WarmupFlag) {
    6692      677376 :                         if (state.dataGlobal->isPulseZoneSizing) {
    6693      338688 :                             state.dataOutRptTab->loadConvectedWithPulse(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) =
    6694      338688 :                                 state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6695             :                         } else {
    6696      338688 :                             state.dataOutRptTab->loadConvectedNormal(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) =
    6697      338688 :                                 state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6698      338688 :                             state.dataOutRptTab->netSurfRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) =
    6699      338688 :                                 state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6700             :                         }
    6701             :                     }
    6702             :                 }
    6703      601866 :             }
    6704             :         }
    6705             :     }
    6706             : 
    6707     2804482 :     if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6708      514302 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6709      777210 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6710      388605 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6711      388605 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6712      388605 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6713     3186792 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6714     2798187 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6715     2798187 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6716             :                 }
    6717      388605 :                 if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
    6718      177212 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6719      177212 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
    6720      177212 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6721             :                 } else {
    6722      211393 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6723      211393 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
    6724      211393 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6725             :                 }
    6726             : 
    6727      388605 :                 if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
    6728      256629 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6729      256629 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
    6730      256629 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6731             :                 } else {
    6732      131976 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6733      131976 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
    6734      131976 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6735             :                 }
    6736      388605 :             }
    6737             :         }
    6738             :     }
    6739     2804482 : }
    6740             : 
    6741         687 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
    6742             : {
    6743       32289 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6744       63204 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6745       31602 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6746             :             // Heat transfer surfaces
    6747       31602 :             int firstSurf = thisSpace.HTSurfaceFirst;
    6748       31602 :             int lastSurf = thisSpace.HTSurfaceLast;
    6749      429375 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6750      397773 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6751      397773 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    6752      397773 :                 if (surfNum != repSurfNum) {
    6753       89997 :                     state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
    6754       89997 :                     state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
    6755             :                 }
    6756             :             }
    6757             : 
    6758             :             // Windows
    6759       31602 :             if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6760           0 :                 firstSurf = thisSpace.WindowSurfaceFirst;
    6761           0 :                 lastSurf = thisSpace.WindowSurfaceLast;
    6762           0 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6763           0 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6764           0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    6765           0 :                     if (surfNum != repSurfNum) {
    6766           0 :                         Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    6767           0 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    6768           0 :                             state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    6769           0 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    6770           0 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    6771           0 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    6772           0 :                             state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
    6773             :                     }
    6774             :                 }
    6775             :             }
    6776       31602 :         }
    6777             :     }
    6778         687 : }
    6779             : 
    6780       10122 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
    6781             : {
    6782       10122 :     state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
    6783       20244 :     for (int SurfNum : state.dataHeatBalSurf->SurfMovInsulIndexList) {
    6784       10122 :         if (state.dataHeatBalSurf->SurfMovInsulIntPresent(SurfNum)) {
    6785        6075 :             state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    6786             :         }
    6787       10122 :     }
    6788       10122 : }
    6789             : // End of Reporting subroutines for the HB Module
    6790             : // *****************************************************************************
    6791             : 
    6792             : // *****************************************************************************
    6793             : // *****************************************************************************
    6794             : // *****************************************************************************
    6795             : // *****************************************************************************
    6796             : 
    6797             : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
    6798             : 
    6799     3703058 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
    6800             :                                 ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    6801             : {
    6802             : 
    6803             :     // SUBROUTINE INFORMATION:
    6804             :     //       AUTHOR         George Walton
    6805             :     //       DATE WRITTEN   December 1979
    6806             :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays);
    6807             :     //                      Aug 2000 (RJL for MTF moisture calculations)
    6808             :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    6809             :     //                      Dec 2000 (RKS for radiant system model addition)
    6810             :     //                      Apr 2002 (COP removed denominator from OSC calculation
    6811             :     //                      Jul 2008 (P.Biddulph include calls to HAMT)
    6812             :     //                      Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
    6813             :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    6814             :     //       RE-ENGINEERED  Mar 1998 (RKS)
    6815             : 
    6816             :     // PURPOSE OF THIS SUBROUTINE:
    6817             :     // This subroutine performs a heat balance on the outside face of each
    6818             :     // surface in the building.
    6819             : 
    6820             :     // METHODOLOGY EMPLOYED:
    6821             :     // Various boundary conditions are set and additional parameters are set-
    6822             :     // up.  Then, the proper heat balance equation is selected based on the
    6823             :     // presence of movable insulation, thermal mass of the surface construction,
    6824             :     // and convection model being used.
    6825             : 
    6826             :     // REFERENCES:
    6827             :     // (I)BLAST legacy routine HBOUT
    6828             :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    6829             : 
    6830             :     //    // Using/Aliasing
    6831             :     //    using namespace DataEnvironment;
    6832             :     //    using namespace DataHeatBalance;
    6833             :     //    using namespace DataHeatBalSurface;
    6834             :     //    using namespace DataSurfaces;
    6835             :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
    6836             :     //    using ScheduleManager::GetCurrentScheduleValue;
    6837             :     //    using ScheduleManager::GetScheduleIndex;
    6838             :     //    using namespace Psychrometrics;
    6839             :     //    using EcoRoofManager::CalcEcoRoof;
    6840             :     //
    6841             :     //    // Locals
    6842             :     //    // SUBROUTINE ARGUMENT DEFINITIONS:
    6843             :     //
    6844             :     //>>>>>>> origin/develop
    6845             :     // SUBROUTINE PARAMETER DEFINITIONS:
    6846     3703058 :     constexpr const char *RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
    6847     3703058 :     constexpr const char *RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
    6848     3703058 :     constexpr const char *RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
    6849     3703058 :     constexpr const char *RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
    6850     3703058 :     constexpr const char *RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
    6851     3703058 :     constexpr const char *RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
    6852     3703058 :     constexpr const char *RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
    6853     3703058 :     constexpr const char *RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
    6854     3703058 :     constexpr const char *RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
    6855     3703058 :     constexpr const char *RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
    6856     3703058 :     constexpr const char *HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
    6857     3703058 :     constexpr const char *HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
    6858     3703058 :     constexpr const char *HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
    6859     3703058 :     constexpr const char *Outside("Outside");
    6860             : 
    6861     3703058 :     bool MovInsulErrorFlag = false; // Movable Insulation error flag
    6862             : 
    6863             :     // set ground surfaces average temperature
    6864     3703058 :     GetGroundSurfacesTemperatureAverage(state);
    6865             : 
    6866             :     // set surrounding surfaces average temperature
    6867     3703058 :     GetSurroundingSurfacesTemperatureAverage(state);
    6868             : 
    6869     3703058 :     auto &Surface = state.dataSurface->Surface;
    6870             : 
    6871     3703058 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    6872    23747690 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6873             :             // Need to transfer any source/sink for a surface to the local array.  Note that
    6874             :             // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
    6875             :             // This must be done at this location so that this is always updated correctly.
    6876    22778640 :             if (Surface(SurfNum).Area > 0.0)
    6877    22778640 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
    6878    22778640 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6879             : 
    6880             :             // next we add source (actually a sink) from any integrated PV
    6881    22778640 :             if (Surface(SurfNum).Area > 0.0)
    6882    22778640 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
    6883    22778640 :                     state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6884             :         }
    6885             :     }
    6886             : 
    6887     3703058 :     if (present(ZoneToResimulate)) {
    6888     1590246 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6889      795123 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
    6890             :     } else {
    6891     5815870 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6892     2907935 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
    6893             :     }
    6894             : 
    6895             :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    6896     3715631 :     for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
    6897       12573 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
    6898       12573 :             EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, Surface(surfNum).OutsideHeatSourceTermSchedule);
    6899     3703058 :     }
    6900    26743425 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
    6901    46129334 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6902    23088967 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    6903   217994983 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    6904   194906016 :                 if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) continue;
    6905   169798748 :                 if (present(ZoneToResimulate)) {
    6906    18677604 :                     if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
    6907    11477699 :                         continue; // skip surfaces that are not associated with this zone
    6908             :                     }
    6909             :                 }
    6910             :                 // Interior windows in partitions use "normal" heat balance calculations
    6911             :                 // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
    6912             :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
    6913             : 
    6914             :                 // Initializations for this surface
    6915   158321049 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    6916   158321049 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    6917   158321049 :                 Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
    6918   158321049 :                 Real64 HSky = 0.0;      // "Convection" coefficient from sky to surface
    6919   158321049 :                 Real64 HGround = 0.0;   // "Convection" coefficient from ground to surface
    6920   158321049 :                 Real64 HAir = 0.0;      // "Convection" coefficient from air to surface (radiation)
    6921   158321049 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    6922   158321049 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    6923   158321049 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    6924   158321049 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    6925   158321049 :                 state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
    6926             : 
    6927             :                 // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
    6928             :                 // various different boundary conditions
    6929   158321049 :                 switch (Surface(SurfNum).ExtBoundCond) {
    6930     9770860 :                 case DataSurfaces::Ground: { // Surface in contact with ground
    6931     9770860 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    6932     9770860 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    6933             : 
    6934             :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    6935     9770860 :                     if (thisConstruct.SourceSinkPresent)
    6936     1374524 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    6937             : 
    6938             :                     // start HAMT
    6939     9770860 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    6940             :                         // Set variables used in the HAMT moisture balance
    6941       26913 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    6942       26913 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    6943       53826 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    6944       26913 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
    6945       26913 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    6946             : 
    6947       26913 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    6948       26913 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    6949       80739 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    6950             :                                   state,
    6951       26913 :                                   state.dataEnvrn->OutBaroPress,
    6952       26913 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6953       26913 :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    6954       26913 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6955             :                                                                 1.0,
    6956       26913 :                                                                 state.dataEnvrn->OutBaroPress,
    6957       26913 :                                                                 RoutineNameGroundTemp)) +
    6958       53826 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    6959       26913 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    6960             : 
    6961       26913 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    6962       26913 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    6963       26913 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    6964             :                     }
    6965             :                     // end HAMT
    6966             : 
    6967     9770860 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    6968             :                         // Set variables used in the FD moisture balance
    6969      415738 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    6970      415738 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    6971      415738 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    6972      415738 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
    6973      415738 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    6974      415738 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    6975      415738 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    6976     1247214 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    6977             :                                   state,
    6978      415738 :                                   state.dataEnvrn->OutBaroPress,
    6979      415738 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6980      415738 :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    6981      415738 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    6982             :                                                                 1.0,
    6983      415738 :                                                                 state.dataEnvrn->OutBaroPress,
    6984      415738 :                                                                 RoutineNameGroundTemp)) +
    6985      831476 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    6986      415738 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    6987      415738 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    6988      415738 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    6989      415738 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    6990             :                     }
    6991             :                     // Added for FCfactor grounds
    6992     9770860 :                 } break;
    6993      576756 :                 case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
    6994      576756 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    6995      576756 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    6996             : 
    6997             :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    6998      576756 :                     if (thisConstruct.SourceSinkPresent)
    6999           0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7000             : 
    7001      576756 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7002             :                         // Set variables used in the HAMT moisture balance
    7003           0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7004           0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7005           0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    7006           0 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
    7007           0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7008             : 
    7009           0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7010           0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7011           0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7012             :                                   state,
    7013           0 :                                   state.dataEnvrn->OutBaroPress,
    7014           0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7015           0 :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7016           0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7017             :                                                                 1.0,
    7018           0 :                                                                 state.dataEnvrn->OutBaroPress,
    7019           0 :                                                                 RoutineNameGroundTempFC)) +
    7020           0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7021           0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7022             : 
    7023           0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7024           0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7025           0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7026             :                     }
    7027             : 
    7028      576756 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7029             :                         // Set variables used in the FD moisture balance
    7030           0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7031           0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7032           0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    7033           0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
    7034           0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7035           0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7036           0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7037           0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7038             :                                   state,
    7039           0 :                                   state.dataEnvrn->OutBaroPress,
    7040           0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7041           0 :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7042           0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7043             :                                                                 1.0,
    7044           0 :                                                                 state.dataEnvrn->OutBaroPress,
    7045           0 :                                                                 RoutineNameGroundTempFC)) +
    7046           0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7047           0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7048           0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7049           0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7050           0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7051             :                     }
    7052      576756 :                 } break;
    7053       79287 :                 case DataSurfaces::OtherSideCoefNoCalcExt: {
    7054             :                     // Use Other Side Coefficients to determine the surface film coefficient and
    7055             :                     // the exterior boundary condition temperature
    7056             : 
    7057       79287 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7058             :                     // Set surface temp from previous timestep
    7059       79287 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7060       79037 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7061             :                     }
    7062             : 
    7063       79287 :                     if (state.dataSurface->OSC(OPtr).ConstTempScheduleIndex != 0) { // Determine outside temperature from schedule
    7064       71763 :                         state.dataSurface->OSC(OPtr).ConstTemp =
    7065       71763 :                             ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->OSC(OPtr).ConstTempScheduleIndex);
    7066             :                     }
    7067             : 
    7068             :                     //  Allow for modification of TemperatureCoefficient with unitary sine wave.
    7069             :                     Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
    7070       79287 :                     if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
    7071        3465 :                         ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
    7072             :                     } else {
    7073       75822 :                         ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
    7074             :                     }
    7075             : 
    7076       79287 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7077       79287 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7078       79287 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7079       79287 :                          ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7080       79287 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7081       79287 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7082       79287 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7083       79287 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7084       79287 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7085             : 
    7086             :                     // Enforce max/min limits if applicable
    7087       79287 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent)
    7088       33255 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7089       33255 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7090       79287 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent)
    7091       33255 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7092       33255 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7093             : 
    7094       79287 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7095             : 
    7096             :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7097       79287 :                     if (thisConstruct.SourceSinkPresent)
    7098           0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7099             : 
    7100      158574 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7101       79287 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7102             :                         // Set variables used in the FD moisture balance and HAMT
    7103           0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7104           0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7105           0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7106           0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7107           0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7108           0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7109           0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7110           0 :                                                                 state.dataEnvrn->OutBaroPress,
    7111           0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7112           0 :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7113           0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7114             :                                                                                               1.0,
    7115           0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7116           0 :                                                                                               RoutineNameOtherSideCoefNoCalcExt)) +
    7117           0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7118           0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7119           0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7120           0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7121           0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7122             :                     }
    7123             :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7124       79287 :                 } break;
    7125        1353 :                 case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
    7126             :                     // First, set up the outside convection coefficient and the exterior temperature
    7127             :                     // boundary condition for the surface
    7128        1353 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7129             :                     // Set surface temp from previous timestep
    7130        1353 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7131        1347 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7132             :                     }
    7133             : 
    7134        1353 :                     if (state.dataSurface->OSC(OPtr).ConstTempScheduleIndex != 0) { // Determine outside temperature from schedule
    7135           0 :                         state.dataSurface->OSC(OPtr).ConstTemp =
    7136           0 :                             ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->OSC(OPtr).ConstTempScheduleIndex);
    7137             :                     }
    7138             : 
    7139        1353 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
    7140             : 
    7141        1353 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7142        1353 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7143        1353 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7144        1353 :                          state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7145        1353 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7146        1353 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7147        1353 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7148        1353 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7149        1353 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7150             : 
    7151             :                     // Enforce max/min limits if applicable
    7152        1353 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent)
    7153           0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7154           0 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7155        1353 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent)
    7156           0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7157           0 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7158             : 
    7159        1353 :                     Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7160             : 
    7161             :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7162        1353 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent)
    7163           0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7164             : 
    7165        2706 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7166        1353 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7167             :                         // Set variables used in the FD moisture balance and HAMT
    7168           0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7169           0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7170           0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7171           0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7172           0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7173           0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7174           0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7175           0 :                                                                 state.dataEnvrn->OutBaroPress,
    7176           0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7177           0 :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7178           0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7179             :                                                                                               1.0,
    7180           0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7181           0 :                                                                                               RoutineNameOtherSideCoefCalcExt)) +
    7182           0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7183           0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7184           0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7185           0 :                         state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7186           0 :                         state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7187             :                     }
    7188             : 
    7189             :                     // Call the outside surface temp calculation and pass the necessary terms
    7190        1353 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7191           0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7192        1353 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7193        1353 :                         if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7194             :                     }
    7195             :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7196        1353 :                 } break;
    7197      211815 :                 case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from seperate, dynamic component
    7198             :                     // modeling that defines the "outside environment"
    7199             :                     // First, set up the outside convection coefficient and the exterior temperature
    7200             :                     // boundary condition for the surface
    7201      211815 :                     int OPtr = Surface(SurfNum).OSCMPtr;
    7202             :                     // EMS overrides
    7203      211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv)
    7204           0 :                         state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
    7205      211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv)
    7206           0 :                         state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
    7207      211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad)
    7208           0 :                         state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
    7209      211815 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad)
    7210           0 :                         state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
    7211      211815 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
    7212             : 
    7213      211815 :                     Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
    7214             : 
    7215             :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7216      211815 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent)
    7217           0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7218             : 
    7219      423630 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7220      211815 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7221             :                         // Set variables used in the FD moisture balance and HAMT
    7222           0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7223           0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7224           0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7225           0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7226           0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7227           0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7228           0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7229             :                                   state,
    7230           0 :                                   state.dataEnvrn->OutBaroPress,
    7231           0 :                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7232           0 :                                   Psychrometrics::PsyWFnTdbRhPb(
    7233           0 :                                       state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
    7234           0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7235           0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7236           0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
    7237           0 :                         state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
    7238           0 :                         state.dataMstBal->HAirFD(SurfNum) = 0.0;  // CR 8046, null out and use only sky term for surface to baffle IR
    7239             :                     }
    7240             : 
    7241             :                     // Call the outside surface temp calculation and pass the necessary terms
    7242      211815 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7243           0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7244             : 
    7245      211815 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7246        8124 :                             CalcExteriorVentedCavity(state, SurfNum);
    7247             :                         }
    7248             : 
    7249      211815 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7250      211815 :                         if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7251             : 
    7252           0 :                     } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7253           0 :                                Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7254           0 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7255           0 :                             CalcExteriorVentedCavity(state, SurfNum);
    7256             :                         }
    7257             :                     }
    7258             :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7259      211815 :                 } break;
    7260    45611218 :                 case DataSurfaces::ExternalEnvironment: {
    7261             :                     // checking the EcoRoof presented in the external environment
    7262             :                     // recompute each load by calling ecoroof
    7263             : 
    7264             :                     Real64 TempExt;
    7265             : 
    7266    45611218 :                     if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
    7267      443820 :                         EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
    7268      443820 :                         continue;
    7269             :                     }
    7270             :                     // Roughness index of the exterior surface
    7271    45167398 :                     Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
    7272             :                     // Thermal absoptance of the exterior surface
    7273    45167398 :                     Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
    7274    45167398 :                     HMovInsul = 0;
    7275             :                     // Check for outside movable insulation
    7276    45167398 :                     if (state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum)) {
    7277        4047 :                         HMovInsul = state.dataHeatBalSurf->SurfMovInsulHExt(SurfNum);
    7278             :                     }
    7279             : 
    7280             :                     // Check for exposure to wind (exterior environment)
    7281    45167398 :                     if (Surface(SurfNum).ExtWind) {
    7282             : 
    7283             :                         // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
    7284    44990581 :                         Convect::InitExtConvCoeff(state,
    7285             :                                                   SurfNum,
    7286             :                                                   HMovInsul,
    7287             :                                                   RoughSurf,
    7288             :                                                   AbsThermSurf,
    7289    44990581 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7290    44990581 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7291    44990581 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7292    44990581 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7293    44990581 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7294    44990581 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7295             : 
    7296    44990581 :                         if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
    7297             : 
    7298       11907 :                             if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
    7299       11907 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
    7300             :                             } else { // User set
    7301           0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    7302             :                             }
    7303             : 
    7304       11907 :                             TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
    7305             : 
    7306             :                             // start HAMT
    7307       11907 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7308             :                                 // Set variables used in the HAMT moisture balance
    7309           0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7310           0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7311           0 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
    7312           0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7313           0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7314           0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7315           0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7316           0 :                                                                         state.dataEnvrn->OutBaroPress,
    7317           0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7318           0 :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7319           0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7320             :                                                                                                       1.0,
    7321           0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7322           0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7323           0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7324           0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7325           0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7326           0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7327           0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7328             :                             }
    7329             :                             // end HAMT
    7330       11907 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7331             :                                 // Set variables used in the FD moisture balance
    7332           0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7333           0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7334           0 :                                     Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
    7335           0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7336           0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7337           0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7338           0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7339           0 :                                                                         state.dataEnvrn->OutBaroPress,
    7340           0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7341           0 :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7342           0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7343             :                                                                                                       1.0,
    7344           0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7345           0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7346           0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7347           0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7348           0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7349           0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7350           0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7351             :                             }
    7352             : 
    7353             :                         } else { // Surface is dry, use the normal correlation
    7354             : 
    7355    44978674 :                             TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7356             : 
    7357    88069506 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7358    43090832 :                                 Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7359             :                                 // Set variables used in the FD moisture balance and HAMT
    7360     2032493 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7361     2032493 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7362     2032493 :                                     state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7363     2032493 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7364     2032493 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7365     2032493 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7366     4064986 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7367     2032493 :                                                                         state.dataEnvrn->OutBaroPress,
    7368     2032493 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7369     2032493 :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7370     2032493 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7371             :                                                                                                       1.0,
    7372     2032493 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7373     2032493 :                                                                                                       RoutineNameExtEnvDrySurf)) +
    7374     4064986 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7375     2032493 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7376             :                                 //  check for saturation conditions of air
    7377             :                                 // Local temporary saturated vapor density for checking
    7378             :                                 Real64 RhoVaporSat =
    7379     2032493 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
    7380     2032493 :                                 if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
    7381     2032493 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7382     2032493 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7383     2032493 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7384             :                             }
    7385             :                         }
    7386             : 
    7387             :                     } else { // No wind
    7388             : 
    7389             :                         // Calculate exterior heat transfer coefficients for windspeed = 0
    7390      176817 :                         Convect::InitExtConvCoeff(state,
    7391             :                                                   SurfNum,
    7392             :                                                   HMovInsul,
    7393             :                                                   RoughSurf,
    7394             :                                                   AbsThermSurf,
    7395      176817 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7396      176817 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7397      176817 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7398      176817 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7399      176817 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7400      176817 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7401             : 
    7402      176817 :                         TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7403             : 
    7404      346908 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7405      170091 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7406             :                             // Set variables used in the FD moisture balance and HAMT
    7407        6726 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7408        6726 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7409        6726 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7410        6726 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7411        6726 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7412        6726 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7413       13452 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7414        6726 :                                                                     state.dataEnvrn->OutBaroPress,
    7415        6726 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7416        6726 :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7417        6726 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7418             :                                                                                                   1.0,
    7419        6726 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7420        6726 :                                                                                                   RoutineNameNoWind)) +
    7421       13452 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7422        6726 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7423        6726 :                             state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7424        6726 :                             state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7425        6726 :                             state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7426             :                         }
    7427             :                     }
    7428             :                     // Calculate LWR from surrounding surfaces if defined for an exterior surface
    7429    45167398 :                     if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
    7430        5412 :                         int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
    7431             :                         // Absolute temperature of the outside surface of an exterior surface
    7432        5412 :                         Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
    7433       13530 :                         for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
    7434             :                              SrdSurfNum++) {
    7435             :                             // View factor of a surrounding surface
    7436        8118 :                             Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
    7437             :                             // Absolute temperature of a surrounding surface
    7438             :                             Real64 SrdSurfTempAbs =
    7439       16236 :                                 ScheduleManager::GetCurrentScheduleValue(
    7440        8118 :                                     state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).TempSchNum) +
    7441        8118 :                                 Constant::Kelvin;
    7442        8118 :                             state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
    7443        8118 :                                 Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
    7444             :                         }
    7445             :                     }
    7446             : 
    7447    45167398 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7448    47210667 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
    7449     2043269 :                         Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7450    43128179 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7451    43128179 :                         if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7452             :                     }
    7453    45167398 :                 } break;
    7454      100578 :                 case DataSurfaces::KivaFoundation: {
    7455      100578 :                     auto const *thisMaterial = dynamic_cast<const Material::MaterialChild *>(
    7456      100578 :                         state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)));
    7457      100578 :                     assert(thisMaterial != nullptr);
    7458      100578 :                     Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
    7459      100578 :                     Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
    7460             : 
    7461             :                     // Set Kiva exterior convection algorithms
    7462      100578 :                     Convect::InitExtConvCoeff(state,
    7463             :                                               SurfNum,
    7464             :                                               HMovInsul,
    7465             :                                               RoughSurf,
    7466             :                                               AbsThermSurf,
    7467      100578 :                                               state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7468      100578 :                                               state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7469      100578 :                                               state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7470      100578 :                                               state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7471      100578 :                                               state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7472      100578 :                                               state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7473      100578 :                 } break;
    7474   101969182 :                 default: { // for interior or other zone surfaces
    7475             : 
    7476   101969182 :                     if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
    7477             : 
    7478    30392928 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7479             : 
    7480             :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7481             : 
    7482    60640788 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7483    30247860 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7484             :                             // Set variables used in the FD moisture balance HAMT
    7485      145068 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7486      145068 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
    7487      145068 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7488      145068 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7489      145068 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7490      290136 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7491             :                                       state,
    7492      145068 :                                       state.dataEnvrn->OutBaroPress,
    7493      145068 :                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7494      145068 :                                       Psychrometrics::PsyWFnTdbRhPb(
    7495      145068 :                                           state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
    7496      290136 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7497      145068 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7498      145068 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7499      145068 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7500      145068 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7501             :                         }
    7502             : 
    7503             :                     } else { // Interzone partition
    7504             : 
    7505    71576254 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7506    71576254 :                             state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7507             : 
    7508             :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7509             : 
    7510   142009276 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7511    70433022 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7512             :                             // Set variables used in the FD moisture balance and HAMT
    7513     1143232 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7514     1143232 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
    7515     1143232 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
    7516     1143232 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7517     1143232 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7518     2286464 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7519     1143232 :                                                                     state.dataEnvrn->OutBaroPress,
    7520     1143232 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7521     1143232 :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7522     1143232 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7523             :                                                                                                   1.0,
    7524     1143232 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7525     1143232 :                                                                                                   RoutineNameIZPart)) +
    7526     2286464 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7527     1143232 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7528     1143232 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7529     1143232 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7530     1143232 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7531             :                         }
    7532             :                     }
    7533             :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7534   101969182 :                 } break;
    7535             :                 }
    7536             : 
    7537   157877229 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
    7538             :             }
    7539    23040367 :         }
    7540             :     } // ...end of DO loop over all surface (actually heat transfer surfaces)
    7541     3703058 : }
    7542             : 
    7543   157877229 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
    7544             : {
    7545   157877229 :     auto const &surface = state.dataSurface->Surface(SurfNum);
    7546   157877229 :     int OPtr = surface.OSCMPtr;
    7547   157877229 :     if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
    7548      211815 :         return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
    7549             :     } else {
    7550   157665414 :         if (state.dataEnvrn->IsRain) {
    7551       43093 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7552       43093 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
    7553             :         } else {
    7554   157622321 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7555   157622321 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
    7556             :         }
    7557             :     }
    7558             : }
    7559             : 
    7560     3735792 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
    7561             :                                ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    7562             : {
    7563     3735792 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
    7564         796 :         if (state.dataHeatBal->AnyEMPD) {
    7565           2 :             state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
    7566             :         }
    7567         796 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    7568          44 :             SetupOutputVariable(state,
    7569             :                                 "Surface Inside Face Heat Balance Calculation Iteration Count",
    7570             :                                 Constant::Units::None,
    7571          22 :                                 state.dataHeatBal->InsideSurfIterations,
    7572             :                                 OutputProcessor::TimeStepType::Zone,
    7573             :                                 OutputProcessor::StoreType::Sum,
    7574             :                                 "Simulation");
    7575             :         }
    7576             :         // Precompute whether CTF temperature limits will be needed
    7577         796 :         state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
    7578        5852 :         for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
    7579       10124 :             for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
    7580        5068 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    7581       49173 :                 for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
    7582       44152 :                     DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
    7583       44152 :                     if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
    7584             :                         (alg == DataSurfaces::HeatTransferModel::Kiva)) {
    7585          47 :                         state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
    7586          47 :                         break;
    7587             :                     }
    7588             :                 }
    7589        5056 :             }
    7590             :         }
    7591         796 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
    7592             :     }
    7593             : 
    7594     3735792 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
    7595        6443 :         state.dataHeatBalSurf->SurfTempInsOld = 23.0;
    7596        6443 :         state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
    7597        6443 :         state.dataHeatBal->SurfTempEffBulkAir = 23.0;
    7598        6443 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
    7599        6443 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
    7600             : 
    7601             :         // Initialize Kiva instances ground temperatures
    7602        6443 :         if (state.dataHeatBal->AnyKiva) {
    7603          59 :             state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
    7604             :         }
    7605             :     }
    7606     3735792 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    7607     3726850 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
    7608             :     }
    7609             : 
    7610     3735792 :     sumSurfQdotRadHVAC(state);
    7611             : 
    7612             :     // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
    7613     3735792 :     bool const PartialResimulate(present(ZoneToResimulate));
    7614             : 
    7615     3735792 :     if (!PartialResimulate) {
    7616     2940669 :         if (state.dataHeatBal->AllCTF) {
    7617     2706511 :             CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
    7618             :         } else {
    7619      468316 :             CalcHeatBalanceInsideSurf2(state,
    7620      234158 :                                        state.dataSurface->AllHTSurfaceList,
    7621      234158 :                                        state.dataSurface->AllIZSurfaceList,
    7622      234158 :                                        state.dataSurface->AllHTNonWindowSurfaceList,
    7623      234158 :                                        state.dataSurface->AllHTWindowSurfaceList);
    7624             :         }
    7625             :     } else {
    7626      795123 :         auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
    7627      795123 :         auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
    7628      795123 :         auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
    7629      795123 :         auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
    7630             :         // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
    7631      795123 :         CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
    7632             :     }
    7633     3735792 :     CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
    7634     3735792 :     UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
    7635     3735792 : }
    7636             : 
    7637     1029281 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
    7638             :                                 const std::vector<int> &HTSurfs,          // Heat transfer surfaces to simulate (opaque and windows)
    7639             :                                 const std::vector<int> &IZSurfs,          // Interzone heat transfer surfaces to simulate
    7640             :                                 const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
    7641             :                                 const std::vector<int> &HTWindowSurfs,    // Window heat transfer surfaces to simulate
    7642             :                                 ObjexxFCL::Optional_int_const ZoneToResimulate)
    7643             : {
    7644             :     // SUBROUTINE INFORMATION:
    7645             :     //       AUTHOR         George Walton
    7646             :     //       DATE WRITTEN   December 1979
    7647             :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    7648             :     //                      Dec 1999 (FCW for window calculation)
    7649             :     //                      May 2000 (FCW for window frame and dividers)
    7650             :     //                      Aug 2000 (RJL for MTF moisture calculations)
    7651             :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    7652             :     //                      Dec 2000 (RKS for radiant system model addition)
    7653             :     //                      Jul 2003 (CC) set the reference temperatures for inside surface heat balance
    7654             :     //                                    depending on convection algorithms and/or air models used
    7655             :     //                      May 2006 (RR  account for exterior window screen)
    7656             :     //                      Jul 2008 (P. Biddulph include calls to HAMT)
    7657             :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    7658             :     //       RE-ENGINEERED  Mar 1998 (RKS)
    7659             : 
    7660             :     // PURPOSE OF THIS SUBROUTINE:
    7661             :     // This subroutine performs a heat balance on the inside face of each
    7662             :     // surface in the building.
    7663             : 
    7664             :     // METHODOLOGY EMPLOYED:
    7665             :     // Various boundary conditions are set and additional parameters are set-
    7666             :     // up.  Then, the proper heat balance equation is selected based on whether
    7667             :     // the surface is a partition or not and on whether or not movable
    7668             :     // insulation is present on the inside face.
    7669             : 
    7670             :     // REFERENCES:
    7671             :     // (I)BLAST legacy routine HBSRF
    7672             : 
    7673     1029281 :     constexpr const char *rhoAirZone("RhoAirZone");
    7674     1029281 :     constexpr const char *wsurf("Wsurf");
    7675     1029281 :     constexpr const char *HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
    7676     1029281 :     constexpr const char *Inside("Inside");
    7677             : 
    7678             :     Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
    7679             :     Real64 SurfTempInSat;  // Local temporary surface dew point temperature
    7680             : 
    7681             :     Real64 Wsurf;         // Moisture ratio for HAMT
    7682             :     Real64 RhoAirZone;    // Zone moisture density for HAMT
    7683             :     int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
    7684             : 
    7685             :     // determine reference air temperatures
    7686    13275389 :     for (int SurfNum : HTSurfs) {
    7687             : 
    7688             :         // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
    7689    12246108 :         if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome)
    7690           0 :             continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7691    12246108 :         Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
    7692    12246108 :         state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
    7693    12246108 :         state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
    7694     1029281 :     }
    7695             : 
    7696             :     // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    7697             :     // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    7698             :     // CalcWindowHeatBalance.
    7699             :     // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    7700     1917276 :     for (int surfNum : HTWindowSurfs) {
    7701      887995 :         state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    7702      887995 :         state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    7703      887995 :         state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    7704      887995 :         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    7705      887995 :         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    7706      887995 :         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    7707      887995 :         state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    7708      887995 :         state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    7709      887995 :         state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    7710      887995 :         state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    7711      887995 :         state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    7712      887995 :         state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    7713      887995 :         state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    7714     1029281 :     }
    7715             : 
    7716     1029281 :     state.dataHeatBal->InsideSurfIterations = 0;
    7717             : 
    7718             :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    7719     1029281 :     for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    7720           0 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    7721           0 :             EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->Surface(surfNum).InsideHeatSourceTermSchedule);
    7722     1029281 :     }
    7723             : 
    7724             :     // Calculate Kiva instances
    7725     1029281 :     if (state.dataHeatBal->AnyKiva) {
    7726       21897 :         if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
    7727       21897 :               state.dataGlobal->TimeStep == 1) ||
    7728       43794 :              state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
    7729        4222 :             !state.dataGlobal->WarmupFlag) {
    7730         576 :             state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
    7731             :         }
    7732             :     }
    7733             : 
    7734     1029281 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    7735     4015745 :     while (!Converged) {    // Start of main inside heat balance DO loop...
    7736             : 
    7737     2986464 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    7738             : 
    7739     2986464 :         if (state.dataHeatBal->AnyKiva) {
    7740      546989 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7741      450680 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
    7742       96309 :             }
    7743             :         }
    7744             : 
    7745     5972928 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    7746     2986464 :                                                            state.dataHeatBalSurf->SurfTempIn,
    7747     2986464 :                                                            state.dataHeatBal->InsideSurfIterations,
    7748     2986464 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    7749             :                                                            ZoneToResimulate,
    7750             :                                                            Inside); // Update the radiation balance
    7751             : 
    7752     2986464 :         if (state.dataHeatBal->AnyKiva) {
    7753      546989 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7754      450680 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
    7755       96309 :             }
    7756             :         }
    7757             : 
    7758             :         // Every 30 iterations, recalculate the inside convection coefficients in case
    7759             :         // there has been a significant drift in the surface temperatures predicted.
    7760             :         // This is not fool-proof and it basically means that the outside surface
    7761             :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    7762             :         // The choice of 30 is not significant--just want to do this a couple of
    7763             :         // times before the iteration limit is hit.
    7764     4943647 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    7765     1957183 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    7766          67 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    7767             :         }
    7768             : 
    7769     2986464 :         if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    7770     1432649 :             for (int SurfNum : HTSurfs) {
    7771     1325130 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    7772     1325130 :                 if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)
    7773           0 :                     continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7774             : 
    7775             :                 // Calculate the inside surface moisture quantities
    7776             :                 // calculate the inside surface moisture transfer conditions
    7777             :                 // check for saturation conditions of air
    7778     1325130 :                 if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
    7779      625991 :                     (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
    7780     1052500 :                     int ZoneNum = surface.Zone;
    7781     1052500 :                     Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    7782     1052500 :                     Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
    7783     1052500 :                     Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    7784             : 
    7785     1052500 :                     state.dataMstBal->RhoVaporAirIn(SurfNum) =
    7786     1052500 :                         min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
    7787     1052500 :                             Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
    7788     1052500 :                     state.dataMstBal->HMassConvInFD(SurfNum) =
    7789     2105000 :                         HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
    7790     1052500 :                                         Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
    7791             :                 }
    7792      107519 :             }
    7793             :         }
    7794             : 
    7795    39790351 :         for (int SurfNum : HTNonWindowSurfs) {
    7796             :             // Perform heat balance on the inside face of the surface ...
    7797             :             // The following are possibilities here:
    7798             :             //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    7799             :             //   (b) the surface is a partition, in which case the temperature of both sides are the same
    7800             :             //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    7801             :             //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    7802             :             //   (e) standard opaque surface with movable insulation, special two-part equation
    7803             :             // In the surface calculation there are the following Algorithm types for opaque surfaces that
    7804             :             // do not have movable insulation:
    7805             :             //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    7806             :             //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    7807             :             //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    7808             :             //   (d) the HAMT calc (solutionalgo = UseHAMT).
    7809             : 
    7810    36803887 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    7811    36803887 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    7812           0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    7813           0 :                 if (SurfNum != repSurfNum) continue;
    7814             :             }
    7815    36803887 :             int const ZoneNum = surface.Zone;
    7816    36803887 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7817    36803887 :             int const ConstrNum = surface.Construction;
    7818    36803887 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    7819    36803887 :             Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    7820    36803887 :             Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7821             : 
    7822    36803887 :             if (surface.ExtBoundCond == SurfNum) {
    7823             :                 // CR6869 -- let Window HB take care of it      IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
    7824             :                 // Surface is adiabatic
    7825     1207934 :                 if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7826      295824 :                     surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    7827             : 
    7828      912110 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7829           0 :                         MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    7830           0 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    7831             :                     }
    7832             :                     // Pre-calculate a few terms
    7833             :                     Real64 const TempTerm(
    7834      912110 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    7835      912110 :                         state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    7836      912110 :                         HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    7837      912110 :                         state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    7838      912110 :                         (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    7839      912110 :                     Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    7840             :                     // Calculate the current inside surface temperature
    7841      912110 :                     if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    7842           0 :                         ((state.dataSurface->SurfIsPool(SurfNum)) &&
    7843           0 :                          (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    7844           0 :                          (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    7845      912110 :                         if (construct.SourceSinkPresent) {
    7846           0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7847           0 :                                 (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    7848           0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7849             :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7850             :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7851             :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7852             :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7853             :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7854             :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7855             :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7856             :                         } else {
    7857      912110 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7858      912110 :                                 (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7859             :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7860             :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7861             :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7862             :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7863             :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7864             :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7865             :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7866             :                         }
    7867             :                     } else { // this is a pool and it has been simulated this time step
    7868           0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7869           0 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    7870           0 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
    7871           0 :                             (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    7872             :                              DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
    7873             :                         // non-pool equation for details) | Iterative damping term (for stability) |
    7874             :                         // Conduction term (both partition sides same temp) | Pool and damping term
    7875             :                     }
    7876      912110 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7877           0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    7878           0 :                             state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
    7879             :                         // Conduction term (both partition sides same temp) |
    7880             :                         // Convection and damping term
    7881           0 :                         if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    7882           0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    7883             :                         }
    7884             :                     }
    7885             :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    7886      912110 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
    7887      341437 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7888      341437 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    7889      341437 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    7890      341437 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    7891             : 
    7892      912110 :                     if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    7893             : 
    7894             :                         // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
    7895           0 :                         Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
    7896           0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    7897           0 :                             TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
    7898             :                         // radiation from internal sources | Convection from surface to zone air | Radiant flux from
    7899             :                         // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
    7900             :                         // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
    7901             :                         // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
    7902             :                         // term (both partition sides same temp) | Convection and damping term
    7903           0 :                         state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    7904             :                             0.0; // The outside temp is assumed to be equal to the inside temp for a partition
    7905           0 :                         state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    7906           0 :                             construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
    7907             :                         // term (both partition sides same temp) | Convection and damping term
    7908             :                     }
    7909             : 
    7910     1207934 :                 } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7911           0 :                            surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7912             : 
    7913      295824 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)
    7914           0 :                         HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
    7915             :                                                                   SurfNum,
    7916           0 :                                                                   state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
    7917             :                                                                   TempSurfOutTmp); // HAMT
    7918             : 
    7919      295824 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7920      591648 :                         HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    7921      295824 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    7922             :                     }
    7923             : 
    7924      295824 :                     TH11 = TempSurfOutTmp;
    7925             :                 }
    7926             : 
    7927     1207934 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    7928             : 
    7929             :             } else { // Standard surface or interzone surface
    7930    35595953 :                 bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulIntPresent(SurfNum);
    7931    35595953 :                 if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
    7932             : 
    7933    35595953 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7934    11446992 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    7935             : 
    7936    24848100 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7937      699139 :                             MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    7938      699139 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    7939             :                         }
    7940             :                         // Pre-calculate a few terms
    7941             :                         Real64 const TempTerm(
    7942    24848100 :                             state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    7943    24848100 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    7944    24848100 :                             HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    7945    24848100 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    7946    24848100 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    7947    24848100 :                         Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    7948             :                         // Calculate the current inside surface temperature
    7949    24848100 :                         if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    7950           0 :                             ((state.dataSurface->SurfIsPool(SurfNum)) &&
    7951           0 :                              (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    7952           0 :                              (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    7953    24848100 :                             if (construct.SourceSinkPresent) {
    7954     1678303 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7955     1678303 :                                     (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    7956     1678303 :                                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    7957     1678303 :                                      construct.CTFCross[0] * TH11) *
    7958             :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    7959             :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    7960             :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    7961             :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    7962             :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    7963             :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    7964             :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    7965             :                                 // Radiation from AFN ducts
    7966             :                             } else {
    7967    23169797 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7968    23169797 :                                     (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    7969    23169797 :                                      construct.CTFCross[0] * TH11) *
    7970             :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    7971             :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    7972             :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    7973             :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    7974             :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    7975             :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    7976             :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    7977             :                                 // Radiation from AFN ducts
    7978             :                             }
    7979             :                         } else { // surface is a pool and the pool has been simulated this time step
    7980           0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7981           0 :                                 (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    7982           0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
    7983           0 :                                 (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    7984             :                                  DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
    7985             :                             // (see non-pool equation for details) | Iterative damping term (for
    7986             :                             // stability) | Current conduction from | the outside surface |
    7987             :                             // Coefficient for conduction (current time) | Pool and damping term
    7988             :                         }
    7989    24848100 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7990      699139 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    7991      699139 :                                 state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
    7992             :                                 TempDiv; // Coefficient for conduction (current time) | Convection and damping term
    7993      699139 :                             if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    7994           0 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    7995             :                             }
    7996             :                         }
    7997             :                         // if any mixed heat transfer models in zone, apply limits to CTF result
    7998    24848100 :                         if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
    7999     2054148 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
    8000             :                                 DataHeatBalSurface::MinSurfaceTempLimit,
    8001     2054148 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8002     2054148 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8003             : 
    8004    24848100 :                         if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    8005             : 
    8006             :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8007     1678303 :                             Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
    8008     1678303 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    8009     1678303 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8010             :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8011             :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8012             :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8013             :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8014             :                             // sides same temp) | Convection and damping term
    8015     1678303 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    8016     1678303 :                                 construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
    8017             :                             // Cond term (both partition sides same temp) |
    8018             :                             // Convection and damping term
    8019     1678303 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    8020     1678303 :                                 construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
    8021             :                             // partition sides same temp) | Convection and
    8022             :                             // damping term
    8023             : 
    8024     1678303 :                             if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8025             :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8026             :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8027             :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8028             :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8029      270256 :                                 if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
    8030      135128 :                                     int OtherSideSurfNum = surface.ExtBoundCond;
    8031      135128 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8032      135128 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    8033      135128 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8034      135128 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    8035      135128 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8036      135128 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    8037      135128 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    8038      135128 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8039      135128 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
    8040      135128 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8041      135128 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
    8042      135128 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8043             :                                 }
    8044             :                             }
    8045             :                         }
    8046             : 
    8047    35595953 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    8048      804041 :                                surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8049             : 
    8050    10297173 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8051      353361 :                             if (surface.ExtBoundCond > 0) {
    8052             :                                 // HAMT get the correct other side zone zone air temperature --
    8053           0 :                                 int OtherSideSurfNum = surface.ExtBoundCond;
    8054             :                                 // ZoneNum = surface.Zone;
    8055           0 :                                 OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
    8056           0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) =
    8057           0 :                                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
    8058             :                             }
    8059      353361 :                             HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8060             :                         }
    8061             : 
    8062    10297173 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD)
    8063    19887624 :                             HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    8064     9943812 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8065             : 
    8066    10297173 :                         TH11 = TempSurfOutTmp;
    8067             : 
    8068    10747853 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
    8069             :                         // Read Kiva results for each surface
    8070      450680 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8071      450680 :                             state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
    8072             : 
    8073      450680 :                         TH11 = 0.0;
    8074             :                     }
    8075             : 
    8076    35595953 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8077             : 
    8078             :                 } else { // Movable insulation present
    8079           0 :                     Real64 HMovInsul = state.dataHeatBalSurf->SurfMovInsulHInt(SurfNum);
    8080           0 :                     if (construct.SourceSinkPresent) {
    8081             : 
    8082           0 :                         ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
    8083           0 :                         ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    8084           0 :                         ShowContinueError(state,
    8085           0 :                                           format("interior movable insulation {} for a surface with that construction.",
    8086           0 :                                                  state.dataMaterial->Material(state.dataSurface->SurfMaterialMovInsulInt(SurfNum))->Name));
    8087           0 :                         ShowContinueError(state,
    8088             :                                           "This is not currently allowed because the heat balance equations do not currently accommodate "
    8089             :                                           "this combination.");
    8090           0 :                         ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    8091             :                     }
    8092             : 
    8093           0 :                     Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
    8094             : 
    8095           0 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) =
    8096           0 :                         (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    8097           0 :                          construct.CTFCross[0] * TH11 +
    8098           0 :                          F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    8099           0 :                                HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8100           0 :                                state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    8101           0 :                                state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    8102           0 :                                DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
    8103           0 :                         (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8104             : 
    8105           0 :                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8106           0 :                         (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    8107           0 :                          HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
    8108           0 :                          state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
    8109             :                         (HMovInsul);
    8110             :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    8111           0 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum])
    8112           0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8113           0 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    8114           0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8115           0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8116             :                 }
    8117             :             }
    8118     2986464 :         }
    8119     5922479 :         for (int SurfNum : HTWindowSurfs) {
    8120     2936015 :             auto &surface = state.dataSurface->Surface(SurfNum);
    8121     2936015 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8122           0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    8123           0 :                 if (SurfNum != repSurfNum) continue;
    8124             :             }
    8125     2936015 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8126     2936015 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
    8127     2936015 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8128     2936015 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8129             :                 // Lookup up the TDD:DOME object
    8130           0 :                 int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8131           0 :                 int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8132             :                 // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8133           0 :                 Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8134             : 
    8135             :                 // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8136             :                 // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8137             :                 //   = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
    8138           0 :                 Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    8139           0 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8140           0 :                     (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    8141           0 :                      state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8142           0 :                      state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    8143           0 :                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8144           0 :                      Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8145           0 :                     (Ueff + HConvIn_surf +
    8146             :                      DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8147             :                                                          // solar | Convection from surface to zone air | Net radiant exchange with
    8148             :                                                          // other zone surfaces | Iterative damping term (for stability) | Current
    8149             :                                                          // conduction from the outside surface | Coefficient for conduction (current
    8150             :                                                          // time) | Convection and damping term
    8151           0 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8152             : 
    8153           0 :                 Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
    8154             : 
    8155             :                 // fill out report vars for components of Window Heat Gain
    8156           0 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
    8157           0 :                     HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
    8158           0 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
    8159           0 :                     state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8160           0 :                     (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
    8161           0 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
    8162           0 :                     state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8163           0 :                         (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8164           0 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
    8165             : 
    8166             :                 // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8167           0 :                 state.dataSurface->SurfWinHeatGain(SurfNum) =
    8168           0 :                     state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
    8169           0 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
    8170           0 :                     surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
    8171             :                 // Net transmitted solar | Convection | IR exchange | IR
    8172             :                 // Zone diffuse interior shortwave reflected back into the TDD
    8173             : 
    8174             :             } else {                                                // Regular window
    8175     2936015 :                 if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8176             :                     // Get outside convection coeff for exterior window here to avoid calling
    8177             :                     // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8178             :                     // (HeatBalanceSurfaceManager USEing and WindowManager and
    8179             :                     // WindowManager USEing HeatBalanceSurfaceManager)
    8180      887995 :                     if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8181      887995 :                         auto const *thisMaterial = dynamic_cast<Material::MaterialChild *>(state.dataMaterial->Material(construct.LayerPoint(1)));
    8182      887995 :                         assert(thisMaterial != nullptr);
    8183      887995 :                         Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8184      887995 :                         Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8185      887995 :                         DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
    8186      887995 :                         if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8187             :                             // Exterior shade in place
    8188           0 :                             int const ConstrNumSh = surface.activeShadedConstruction;
    8189           0 :                             if (ConstrNumSh != 0) {
    8190           0 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    8191             :                                 auto const *thisMaterial2 =
    8192           0 :                                     dynamic_cast<Material::MaterialChild *>(state.dataMaterial->Material(constructionSh.LayerPoint(1)));
    8193           0 :                                 assert(thisMaterial2 != nullptr);
    8194           0 :                                 RoughSurf = thisMaterial2->Roughness;
    8195           0 :                                 EmisOut = thisMaterial2->AbsorpThermal;
    8196             :                             }
    8197             :                         }
    8198             : 
    8199             :                         // Get the outside effective emissivity for Equivalent layer model
    8200      887995 :                         if (construct.WindowTypeEQL) {
    8201           0 :                             EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    8202             :                         }
    8203             :                         // Set Exterior Convection Coefficient...
    8204      887995 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8205             : 
    8206           0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8207             : 
    8208      887995 :                         } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    8209             : 
    8210             :                             // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    8211             :                             // subroutine)
    8212      887995 :                             Convect::InitExtConvCoeff(state,
    8213             :                                                       SurfNum,
    8214             :                                                       0.0,
    8215             :                                                       RoughSurf,
    8216             :                                                       EmisOut,
    8217             :                                                       TH11,
    8218      887995 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8219      887995 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8220      887995 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8221      887995 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8222      887995 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8223             : 
    8224      887995 :                             if (state.dataEnvrn->IsRain) {                             // Raining: since wind exposed, outside window surface gets wet
    8225           0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
    8226             :                             }
    8227             : 
    8228             :                         } else { // Not Wind exposed
    8229             : 
    8230             :                             // Calculate exterior heat transfer coefficients for windspeed = 0
    8231           0 :                             Convect::InitExtConvCoeff(state,
    8232             :                                                       SurfNum,
    8233             :                                                       0.0,
    8234             :                                                       RoughSurf,
    8235             :                                                       EmisOut,
    8236             :                                                       TH11,
    8237           0 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8238           0 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8239           0 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8240           0 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8241           0 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8242             :                         }
    8243             :                     } else { // Interior Surface
    8244             : 
    8245           0 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8246           0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8247             :                         } else {
    8248             :                             // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    8249             :                             // same
    8250           0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    8251             :                         }
    8252             :                     }
    8253             : 
    8254             :                     // Following call determines inside surface temperature of glazing, and of
    8255             :                     // frame and/or divider, if present
    8256      887995 :                     Window::CalcWindowHeatBalance(
    8257      887995 :                         state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
    8258      887995 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8259             :                 }
    8260             :             }
    8261     2986464 :         } // ...end of inside surface heat balance equation selection
    8262             : 
    8263    42726366 :         for (int SurfNum : HTSurfs) {
    8264    39739902 :             int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
    8265    39739902 :             auto &zone = state.dataHeatBal->Zone(ZoneNum);
    8266    39739902 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8267    39739902 :             Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    8268    39739902 :             TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8269    39739902 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
    8270    39739902 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) continue;
    8271    39739902 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8272             :                 // Tubular daylighting devices are treated as one big object with an effective R value.
    8273             :                 // The outside face temperature of the TDD:DOME and the inside face temperature of the
    8274             :                 // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    8275             :                 // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    8276             :                 // and the outside face of the TDD:DIFFUSER for reporting.
    8277             : 
    8278             :                 // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    8279           0 :                 int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    8280           0 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    8281           0 :                     state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8282             : 
    8283             :                 // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    8284             :                 // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    8285           0 :                 TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    8286           0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    8287             :             }
    8288             : 
    8289    39739902 :             if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8290           0 :                 TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    8291             :             }
    8292             : 
    8293     2986464 :         } // ...end of main loops over all surfaces for inside heat balances
    8294             : 
    8295             :         // Interzone surface updating: interzone surfaces have other side temperatures
    8296             :         // which can vary as the simulation iterates through the inside heat
    8297             :         // balance.  This block is intended to "lock" the opposite side (outside)
    8298             :         // temperatures to the correct value, namely the value calculated by the
    8299             :         // inside surface heat balance for the other side.
    8300             :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    8301             :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    8302    21902638 :         for (int SurfNum : IZSurfs) {
    8303    18916174 :             int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
    8304             :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    8305             :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    8306             :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    8307             :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    8308    18916174 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    8309    18916174 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    8310     2986464 :         }
    8311             : 
    8312     2986464 :         ++state.dataHeatBal->InsideSurfIterations;
    8313             : 
    8314             :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    8315     2986464 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    8316    39790351 :         for (int SurfNum : HTNonWindowSurfs) {
    8317    36803887 :             MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
    8318    36803887 :             if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8319             :                 // also check all internal nodes as well as surface faces
    8320    10239636 :                 MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
    8321             :             }
    8322     2986464 :         } // ...end of loop to check for convergence
    8323             : 
    8324     2986464 :         if (!state.dataHeatBal->AnyCondFD) {
    8325     1975431 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) Converged = true;
    8326             :         } else {
    8327     1011033 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) Converged = true;
    8328             : 
    8329             :             // resets relaxation factor to speed up iterations when under-relaxation is not needed.
    8330     1011033 :             if (state.dataHeatBal->InsideSurfIterations <= 1) {
    8331      351690 :                 state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    8332             :             }
    8333     1011033 :             if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
    8334             :                 // adjust relaxation factor down, assume large number of iterations is result of instability
    8335        1739 :                 state.dataHeatBal->CondFDRelaxFactor *= 0.9;
    8336        1739 :                 if (state.dataHeatBal->CondFDRelaxFactor < 0.1) state.dataHeatBal->CondFDRelaxFactor = 0.1;
    8337             :             }
    8338             :         }
    8339             : 
    8340             : #ifdef EP_Count_Calls
    8341             :         state.dataTimingsData->NumMaxInsideSurfIterations =
    8342             :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    8343             : #endif
    8344             : 
    8345     2986464 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) Converged = false;
    8346             : 
    8347     2986464 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    8348           0 :             if (!state.dataGlobal->WarmupFlag) {
    8349           0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    8350           0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    8351           0 :                     if (!state.dataHeatBal->AnyCondFD) {
    8352           0 :                         ShowWarningError(state,
    8353           0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8354             :                                                 "Allowed Temp Diff [C] ={:.3R}",
    8355             :                                                 MaxDelTemp,
    8356           0 :                                                 state.dataHeatBal->MaxAllowedDelTemp));
    8357           0 :                         ShowContinueErrorTimeStamp(state, "");
    8358             :                     } else {
    8359           0 :                         ShowWarningError(state,
    8360           0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8361             :                                                 "Allowed Temp Diff [C] ={:.6R}",
    8362             :                                                 MaxDelTemp,
    8363           0 :                                                 state.dataHeatBal->MaxAllowedDelTempCondFD));
    8364           0 :                         ShowContinueErrorTimeStamp(state, "");
    8365             :                     }
    8366             :                 } else {
    8367           0 :                     ShowRecurringWarningErrorAtEnd(state,
    8368             :                                                    "Inside surface heat balance convergence problem continues",
    8369           0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    8370             :                                                    MaxDelTemp,
    8371             :                                                    MaxDelTemp,
    8372             :                                                    _,
    8373             :                                                    "[C]",
    8374             :                                                    "[C]");
    8375             :                 }
    8376             :             }
    8377           0 :             break; // iteration loop
    8378             :         }
    8379             : 
    8380             :     } // ...end of main inside heat balance DO loop (ends when Converged)
    8381             : 
    8382             :     // Update SumHmXXXX for non-window EMPD or HAMT surfaces
    8383     1029281 :     if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    8384             : 
    8385             :         // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
    8386       94956 :         for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
    8387       54963 :             thisZoneHB.SumHmAW = 0.0;
    8388       54963 :             thisZoneHB.SumHmARa = 0.0;
    8389       54963 :             thisZoneHB.SumHmARaW = 0.0;
    8390       39993 :         }
    8391             : 
    8392      381747 :         for (int SurfNum : HTNonWindowSurfs) {
    8393      341754 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    8394      341754 :             int ZoneNum = surface.Zone;
    8395      341754 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    8396             : 
    8397      341754 :             if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8398      171564 :                 HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
    8399             : 
    8400      171564 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8401             : 
    8402      171564 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8403             : 
    8404      171564 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
    8405      514692 :                 RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
    8406             :                     state,
    8407      171564 :                     state.dataEnvrn->OutBaroPress,
    8408             :                     MAT_zone,
    8409      171564 :                     Psychrometrics::PsyWFnTdbRhPb(
    8410             :                         state,
    8411             :                         MAT_zone,
    8412      171564 :                         Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
    8413      171564 :                         state.dataEnvrn->OutBaroPress));
    8414             : 
    8415      171564 :                 Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
    8416             :                 Wsurf =
    8417      343128 :                     Psychrometrics::PsyWFnTdbRhPb(state,
    8418             :                                                   surfInTemp,
    8419      171564 :                                                   Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
    8420      171564 :                                                   state.dataEnvrn->OutBaroPress);
    8421             : 
    8422      171564 :                 thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
    8423             : 
    8424      171564 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
    8425             : 
    8426      170190 :             } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8427             :                 // need to calculate the amount of moisture that is entering or
    8428             :                 // leaving the zone  Qm [kg/sec] = hmi * Area * (Del Rhov)
    8429             :                 // {Hmi [m/sec];     Area [m2];    Rhov [kg moist/m3]  }
    8430             :                 // Positive values are into the zone and negative values are
    8431             :                 // leaving the zone.  SumHmAw is the sum of the moisture entering or
    8432             :                 // leaving the zone from all of the surfaces and is a rate.  Multiply
    8433             :                 // by time to get the actual amount affecting the zone volume of air.
    8434             : 
    8435      150018 :                 MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
    8436      150018 :                 state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
    8437      150018 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8438      150018 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8439      150018 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    8440      150018 :                 thisZoneHB.SumHmARa +=
    8441      150018 :                     FD_Area_fac *
    8442      450054 :                     Psychrometrics::PsyRhoAirFnPbTdbW(
    8443             :                         state,
    8444      150018 :                         state.dataEnvrn->OutBaroPress,
    8445             :                         MAT_zone,
    8446      150018 :                         Psychrometrics::PsyWFnTdbRhPb(state,
    8447             :                                                       MAT_zone,
    8448      150018 :                                                       Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
    8449      150018 :                                                       state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
    8450             :                 // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
    8451      150018 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
    8452             :             }
    8453       39993 :         }
    8454             :     }
    8455     1029281 : }
    8456             : 
    8457     2706511 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
    8458             :                                        const int FirstZone,             // First zone to simulate
    8459             :                                        const int LastZone,              // Last zone to simulate
    8460             :                                        const std::vector<int> &IZSurfs, // Last zone to simulate
    8461             :                                        ObjexxFCL::Optional_int_const ZoneToResimulate)
    8462             : {
    8463             : 
    8464             :     // This function performs a heat balance on the inside face of each
    8465             :     // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
    8466             :     // simplified for CTF surfaces only.
    8467             : 
    8468             :     // REFERENCES:
    8469             :     // (I)BLAST legacy routine HBSRF
    8470     2706511 :     auto &Surface = state.dataSurface->Surface;
    8471             : 
    8472     2706511 :     constexpr std::string_view Inside("Inside");
    8473             : 
    8474     2706511 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
    8475             :         // Set up coefficient arrays that never change - loop over non-window HT surfaces
    8476        5743 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8477        9954 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8478        4983 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8479        4983 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8480        4983 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8481       42523 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8482       37540 :                     int const ConstrNum = Surface(surfNum).Construction;
    8483       37540 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8484       37540 :                     if (Surface(surfNum).ExtBoundCond == surfNum) {
    8485        6219 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
    8486             :                     } else {
    8487       31321 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
    8488             :                     }
    8489       37540 :                     if (construct.SourceSinkPresent) {
    8490         127 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
    8491             :                     } else {
    8492       37413 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
    8493             :                     }
    8494             :                 }
    8495        4971 :             }
    8496             :         }
    8497             : 
    8498         772 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
    8499             :     }
    8500             : 
    8501    22580154 :     for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8502    39795886 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8503    19922243 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8504             :             // loop over all heat transfer surface except TDD Dome.
    8505    19922243 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    8506    19922243 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    8507             :             // determine reference air temperatures and other variable terms - loop over all surfaces
    8508   191508577 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8509   171586334 :                 auto const &surface = Surface(surfNum);
    8510   171586334 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8511      397773 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8512      397773 :                     if (surfNum != repSurfNum) continue;
    8513             :                 }
    8514             : 
    8515   171496337 :                 int const ConstrNum = Surface(surfNum).Construction;
    8516   171496337 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8517   171496337 :                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
    8518   171496337 :                 state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
    8519   171496337 :                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
    8520   171496337 :                 state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    8521   171496337 :                 if (construct.SourceSinkPresent) {
    8522      790918 :                     state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
    8523             :                 }
    8524             : 
    8525             :                 // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
    8526   171496337 :                 if (state.dataSurface->SurfIsPool(surfNum)) {
    8527       51624 :                     if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
    8528        8092 :                         (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
    8529       35440 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
    8530             :                     } else {
    8531        8092 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
    8532             :                     }
    8533             :                 }
    8534   171496337 :                 Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
    8535   171496337 :                 state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
    8536   171496337 :                 state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
    8537             :             }
    8538             : 
    8539             :             // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    8540             :             // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    8541             :             // CalcWindowHeatBalance.
    8542             :             // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    8543    19922243 :             int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8544    19922243 :             int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8545    43240331 :             for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8546    23318088 :                 state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    8547    23318088 :                 state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    8548    23318088 :                 state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    8549    23318088 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    8550    23318088 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    8551    23318088 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    8552    23318088 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    8553    23318088 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    8554    23318088 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    8555    23318088 :                 state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    8556    23318088 :                 state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    8557    23318088 :                 state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    8558    23318088 :                 state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    8559             :             }
    8560             : 
    8561             :             // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    8562    19947389 :             for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    8563       25146 :                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    8564       25146 :                     EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->Surface(surfNum).InsideHeatSourceTermSchedule);
    8565    19922243 :             }
    8566             : 
    8567             :             // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
    8568    19922243 :             int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8569    19922243 :             int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8570    19922243 :             Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8571    19922243 :             Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8572             :             // this loop auto-vectorizes
    8573   168190489 :             for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8574   148268246 :                 auto const &surface = Surface(surfNum);
    8575   148268246 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8576      275487 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8577      275487 :                     if (surfNum != repSurfNum) continue;
    8578             :                 }
    8579             : 
    8580             :                 // Pre-calculate a few terms before the iteration loop
    8581   148256567 :                 state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8582   148256567 :                     state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8583   148256567 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8584   148256567 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8585   148256567 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8586   148256567 :                     (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8587   148256567 :                 state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8588   148256567 :                     1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8589   148256567 :                            state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8590   148256567 :                            state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8591   148256567 :                            (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
    8592             :             }
    8593    19873643 :         }
    8594             :     }
    8595             : 
    8596     2706511 :     state.dataHeatBal->InsideSurfIterations = 0;
    8597     2706511 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    8598    13733987 :     while (!Converged) {    // Start of main inside heat balance iteration loop...
    8599             : 
    8600    11027476 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    8601             : 
    8602    22054952 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    8603    11027476 :                                                            state.dataHeatBalSurf->SurfTempIn,
    8604    11027476 :                                                            state.dataHeatBal->InsideSurfIterations,
    8605    11027476 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    8606             :                                                            ZoneToResimulate,
    8607             :                                                            Inside); // Update the radiation balance
    8608             : 
    8609             :         // Every 30 iterations, recalculate the inside convection coefficients in case
    8610             :         // there has been a significant drift in the surface temperatures predicted.
    8611             :         // This is not fool-proof and it basically means that the outside surface
    8612             :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    8613             :         // The choice of 30 is not significant--just want to do this a couple of
    8614             :         // times before the iteration limit is hit.
    8615    19348441 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    8616     8320965 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    8617        1786 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    8618             :             // Since HConvIn has changed re-calculate a few terms - non-window surfaces
    8619       13680 :             for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8620       23788 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8621       11894 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8622       11894 :                     int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8623       11894 :                     int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8624             : 
    8625       11894 :                     Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8626       11894 :                     Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8627             :                     // this loop auto-vectorizes
    8628      103770 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8629       91876 :                         auto const &surface = Surface(surfNum);
    8630       91876 :                         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8631           0 :                             int repSurfNum = surface.RepresentativeCalcSurfNum;
    8632           0 :                             if (surfNum != repSurfNum) continue;
    8633             :                         }
    8634             : 
    8635       91876 :                         state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8636       91876 :                             state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8637       91876 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8638       91876 :                             state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8639       91876 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8640       91876 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8641       91876 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8642       91876 :                             1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8643       91876 :                                    state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8644       91876 :                                    state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8645       91876 :                                    (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
    8646             :                                    iterDampConstant);
    8647             :                     }
    8648       11894 :                 }
    8649             :             }
    8650             :         }
    8651             : 
    8652             :         // Loop over non-window surfaces
    8653   103550757 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8654   185272782 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8655    92749501 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    8656    92749501 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8657    92749501 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8658    92749501 :                 Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
    8659             :                 // this loop auto-vectorizes
    8660   788768575 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8661             :                     // Perform heat balance on the inside face of the surface ...
    8662             :                     // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
    8663             :                     //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    8664             :                     //   (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
    8665             :                     //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    8666             :                     //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    8667             :                     //   (e) standard opaque surface with movable insulation, special two-part equation
    8668             :                     // In the surface calculation there are the following Algorithm types for opaque surfaces that
    8669             :                     // do not have movable insulation:
    8670             :                     //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    8671             :                     //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    8672             :                     //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    8673             :                     //   (d) the HAMT calc (solutionalgo = UseHAMT).
    8674             : 
    8675             :                     // For adiabatic surface:
    8676             :                     // Adiabatic:   TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
    8677             :                     // Adiabatic:   SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8678             :                     // Ad+Source:   SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
    8679             :                     // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool:     TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
    8680             :                     // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool:     SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
    8681             :                     // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8682             : 
    8683             :                     // For standard or interzone surface:
    8684             :                     // Standard:    TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
    8685             :                     // Standard:    SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
    8686             :                     // TempDiv; Std+Source:  SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
    8687             :                     // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool:    TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
    8688             :                     // IterDampConst); Std+Pool:    SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
    8689             :                     // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
    8690             : 
    8691             :                     // Composite with Adiabatic/Source/Pool flags:
    8692             :                     //              TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
    8693             :                     //              SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
    8694             :                     //              SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
    8695             :                     //              SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
    8696             :                     //                                        + IterDampConst * SurfTempInsOld(SurfNum)+
    8697             :                     //                                        IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
    8698             :                     //                                        * TH11) * TempDiv;
    8699             : 
    8700             :                     // Calculate the current inside surface temperature
    8701   696019074 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8702   696019074 :                         ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
    8703   696019074 :                              (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
    8704   696019074 :                          state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
    8705   696019074 :                              state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
    8706   696019074 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
    8707   696019074 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
    8708   696019074 :                          iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8709   696019074 :                          (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
    8710   696019074 :                              state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
    8711   696019074 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum);
    8712             :                     // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8713             :                     // radiation from internal sources | Convection from surface to zone air | Net radiant
    8714             :                     // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
    8715             :                     // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
    8716             :                     // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
    8717             :                     // an electric baseboard heater | Iterative damping term (for stability) | Current
    8718             :                     // conduction from | the outside surface | Coefficient for conduction (current time) |
    8719             :                     // Convection and damping term | Radiation from AFN ducts
    8720             : 
    8721   696019074 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8722             :                 }
    8723             : 
    8724             :                 // Loop over non-window surfaces (includes TubularDaylightingDomes)
    8725   788768575 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8726   696019074 :                     bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulIntPresent(surfNum);
    8727   696019074 :                     if (movableInsulPresent) { // Movable insulation present, recalc surface temps
    8728       16981 :                         Real64 HMovInsul = state.dataHeatBalSurf->SurfMovInsulHInt(surfNum);
    8729       16981 :                         Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
    8730       16981 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) =
    8731       16981 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8732       16981 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
    8733       16981 :                              F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8734       16981 :                                    state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8735       16981 :                                    state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8736       16981 :                                    state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8737       16981 :                                    state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8738       16981 :                                    DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
    8739       16981 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8740             : 
    8741       16981 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8742       16981 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
    8743       16981 :                              HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
    8744       16981 :                              state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
    8745       16981 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
    8746             :                             (HMovInsul);
    8747             :                     }
    8748             : 
    8749   696019074 :                     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    8750    12263940 :                         if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
    8751             :                             // Set the appropriate parameters for the radiant system
    8752             :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8753             :                             Real64 const RadSysDiv(1.0 /
    8754     2443758 :                                                    (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    8755             :                             Real64 const TempTerm(
    8756     2443758 :                                 state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8757     2443758 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8758     2443758 :                                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8759     2443758 :                                 state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8760     2443758 :                                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8761     2443758 :                                 (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
    8762     2443758 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
    8763     2443758 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8764             :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8765             :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8766             :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8767             :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8768             :                             // sides same temp) | Convection and damping term
    8769     2443758 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
    8770     2443758 :                                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
    8771             :                             // Cond term (both partition sides same temp) |
    8772             :                             // Convection and damping term
    8773     2443758 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
    8774     2443758 :                                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
    8775             :                             // partition sides same temp) | Convection and
    8776             :                             // damping term
    8777             : 
    8778     2443758 :                             if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8779             :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8780             :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8781             :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8782             :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8783      967402 :                                 if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
    8784      483701 :                                     int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
    8785      483701 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8786      483701 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
    8787      483701 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8788      483701 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
    8789      483701 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8790      483701 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
    8791      483701 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
    8792      483701 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8793      483701 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
    8794      483701 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8795      483701 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
    8796      483701 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8797             :                                 }
    8798             :                             }
    8799             :                         }
    8800             :                     }
    8801             :                 }
    8802             : 
    8803             :                 // Loop over window surfaces
    8804    92749501 :                 int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8805    92749501 :                 int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8806   199735502 :                 for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8807   106986001 :                     auto &surface = state.dataSurface->Surface(surfNum);
    8808   106986001 :                     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8809      400322 :                         int repSurfNum = surface.RepresentativeCalcSurfNum;
    8810      400322 :                         if (surfNum != repSurfNum) continue;
    8811             :                     }
    8812   106729615 :                     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
    8813   106729615 :                     int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    8814   106729615 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8815   106729615 :                     if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8816             :                         // Lookup up the TDD:DOME object
    8817       20832 :                         int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    8818       20832 :                         int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8819             :                         // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8820       20832 :                         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8821             : 
    8822             :                         // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8823             :                         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8824             :                         //   = SurfWinQRadSWwinAbs(surfNum,1)/2.0
    8825       20832 :                         Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
    8826       20832 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8827       20832 :                             (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
    8828       20832 :                              state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8829       20832 :                              HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8830       20832 :                              state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8831       20832 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8832       20832 :                              Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8833       20832 :                             (Ueff + HConvIn_surf +
    8834             :                              DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8835             :                                                                  // solar | Convection from surface to zone air | Net radiant exchange with
    8836             :                                                                  // other zone surfaces | Iterative damping term (for stability) | Current
    8837             :                                                                  // conduction from the outside surface | Coefficient for conduction (current
    8838             :                                                                  // time) | Convection and damping term
    8839       20832 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8840       20832 :                         Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
    8841             : 
    8842             :                         // fill out report vars for components of Window Heat Gain
    8843       20832 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    8844       41664 :                             HConvIn_surf * surface.Area *
    8845       20832 :                             (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    8846       20832 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    8847       20832 :                             state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8848       20832 :                             (Sigma_Temp_4 -
    8849       20832 :                              (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
    8850       20832 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    8851       20832 :                             state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8852       20832 :                                 (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8853       20832 :                             state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
    8854             : 
    8855             :                         // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8856       20832 :                         state.dataSurface->SurfWinHeatGain(surfNum) =
    8857       20832 :                             state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
    8858       20832 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
    8859       20832 :                             surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
    8860             :                         // Net transmitted solar | Convection | IR exchange | IR
    8861             :                         // Zone diffuse interior shortwave reflected back into the TDD
    8862             :                     } else {                                                // Regular window
    8863   106708783 :                         if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8864             :                             // Get outside convection coeff for exterior window here to avoid calling
    8865             :                             // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8866             :                             // (HeatBalanceSurfaceManager USEing and WindowManager and
    8867             :                             // WindowManager USEing HeatBalanceSurfaceManager)
    8868    23235720 :                             if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8869    23208528 :                                 auto const *thisMaterial = state.dataMaterial->Material(construct.LayerPoint(1));
    8870    23208528 :                                 assert(thisMaterial != nullptr);
    8871    23208528 :                                 Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8872    23208528 :                                 Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8873    23208528 :                                 DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
    8874    23208528 :                                 if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8875             :                                     // Exterior shade in place
    8876       31645 :                                     int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
    8877       31645 :                                     if (ConstrNumSh != 0) {
    8878       21502 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    8879       21502 :                                         auto const *thisMaterial2 = state.dataMaterial->Material(constructionSh.LayerPoint(1));
    8880       21502 :                                         RoughSurf = thisMaterial2->Roughness;
    8881       21502 :                                         EmisOut = thisMaterial2->AbsorpThermal;
    8882             :                                     }
    8883             :                                 }
    8884             : 
    8885             :                                 // Get the outside effective emissivity for Equivalent layer model
    8886    23208528 :                                 if (construct.WindowTypeEQL) {
    8887        8109 :                                     EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    8888             :                                 }
    8889             :                                 // Set Exterior Convection Coefficient...
    8890    23208528 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    8891             : 
    8892           0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    8893             : 
    8894    23208528 :                                 } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    8895             : 
    8896             :                                     // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    8897             :                                     // subroutine)
    8898    23208528 :                                     Convect::InitExtConvCoeff(state,
    8899             :                                                               surfNum,
    8900             :                                                               0.0,
    8901             :                                                               RoughSurf,
    8902             :                                                               EmisOut,
    8903             :                                                               TH11,
    8904    23208528 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    8905    23208528 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    8906    23208528 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    8907    23208528 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    8908    23208528 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    8909             : 
    8910    23208528 :                                     if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    8911        5882 :                                         state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
    8912             :                                     }
    8913             : 
    8914             :                                 } else { // Not Wind exposed
    8915             : 
    8916             :                                     // Calculate exterior heat transfer coefficients for windspeed = 0
    8917           0 :                                     Convect::InitExtConvCoeff(state,
    8918             :                                                               surfNum,
    8919             :                                                               0.0,
    8920             :                                                               RoughSurf,
    8921             :                                                               EmisOut,
    8922             :                                                               TH11,
    8923           0 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    8924           0 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    8925           0 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    8926           0 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    8927           0 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    8928             :                                 }
    8929             : 
    8930             :                             } else { // Interior Surface
    8931             : 
    8932       27192 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    8933           0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    8934             :                                 } else {
    8935             :                                     // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    8936             :                                     // same
    8937       27192 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    8938             :                                 }
    8939             :                             }
    8940             : 
    8941             :                             // Following call determines inside surface temperature of glazing, and of
    8942             :                             // frame and/or divider, if present
    8943    23235720 :                             Window::CalcWindowHeatBalance(
    8944    23235720 :                                 state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
    8945    23235720 :                             state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8946             :                         }
    8947             :                     }
    8948             :                 }
    8949             : 
    8950    92749501 :                 int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    8951    92749501 :                 int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    8952   895754576 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8953   803005075 :                     auto &zone = state.dataHeatBal->Zone(zoneNum);
    8954             : 
    8955   803005075 :                     Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    8956   803005075 :                     Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
    8957   803005075 :                     TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
    8958   803005075 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11;                                                  // For reporting
    8959   803005075 :                     if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8960             :                         // Tubular daylighting devices are treated as one big object with an effective R value.
    8961             :                         // The outside face temperature of the TDD:DOME and the inside face temperature of the
    8962             :                         // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    8963             :                         // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    8964             :                         // and the outside face of the TDD:DIFFUSER for reporting.
    8965             : 
    8966             :                         // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    8967       20832 :                         int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
    8968       20832 :                         state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    8969       20832 :                             state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
    8970             : 
    8971             :                         // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    8972             :                         // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    8973       20832 :                         TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    8974       20832 :                             state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    8975             :                     }
    8976             : 
    8977   803005075 :                     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8978           0 :                         TestSurfTempCalcHeatBalanceInsideSurf(
    8979           0 :                             state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    8980             :                     }
    8981             :                 }
    8982    92523281 :             }
    8983             :         } // ...end of main loops over all surfaces for inside heat balances
    8984             : 
    8985             :         // Interzone surface updating: interzone surfaces have other side temperatures
    8986             :         // which can vary as the simulation iterates through the inside heat
    8987             :         // balance.  This block is intended to "lock" the opposite side (outside)
    8988             :         // temperatures to the correct value, namely the value calculated by the
    8989             :         // inside surface heat balance for the other side.
    8990             :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    8991             :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    8992   336877590 :         for (int SurfNum : IZSurfs) {
    8993   325850114 :             int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
    8994             :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    8995             :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    8996             :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    8997             :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    8998   325850114 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    8999   325850114 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    9000   325850114 :             state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
    9001    11027476 :         }
    9002             : 
    9003    11027476 :         ++state.dataHeatBal->InsideSurfIterations;
    9004             : 
    9005             :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    9006    11027476 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    9007   103550757 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    9008   185272782 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    9009    92749501 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    9010    92749501 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    9011    92749501 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    9012   788768575 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    9013   696019074 :                     Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
    9014   696019074 :                     Real64 absDif = std::abs(delta);
    9015   696019074 :                     MaxDelTemp = std::max(absDif, MaxDelTemp);
    9016             :                 }
    9017    92523281 :             }
    9018             :         } // ...end of loop to check for convergence
    9019             : 
    9020    11027476 :         if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) Converged = true;
    9021             : 
    9022             : #ifdef EP_Count_Calls
    9023             :         state.dataTimingsData->NumMaxInsideSurfIterations =
    9024             :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    9025             : #endif
    9026             : 
    9027    11027476 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) Converged = false;
    9028             : 
    9029    11027476 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    9030           0 :             if (!state.dataGlobal->WarmupFlag) {
    9031           0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    9032           0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    9033           0 :                     ShowWarningError(state,
    9034           0 :                                      format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
    9035             :                                             "Temp Diff [C] ={:.6R}",
    9036             :                                             MaxDelTemp,
    9037           0 :                                             state.dataHeatBal->MaxAllowedDelTempCondFD));
    9038           0 :                     ShowContinueErrorTimeStamp(state, "");
    9039             :                 } else {
    9040           0 :                     ShowRecurringWarningErrorAtEnd(state,
    9041             :                                                    "Inside surface heat balance convergence problem continues",
    9042           0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    9043             :                                                    MaxDelTemp,
    9044             :                                                    MaxDelTemp,
    9045             :                                                    _,
    9046             :                                                    "[C]",
    9047             :                                                    "[C]");
    9048             :                 }
    9049             :             }
    9050           0 :             break; // iteration loop
    9051             :         }
    9052             : 
    9053             :     } // ...end of main inside heat balance iteration loop (ends when Converged)
    9054     2706511 : }
    9055             : 
    9056     3735792 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
    9057             : {
    9058     6866842 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
    9059     3131050 :         auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
    9060     3131050 :         state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
    9061     3131050 :                                                                    thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
    9062     3131050 :                                                                    thisSurfQRadFromHVAC.CoolingPanel;
    9063     3735792 :     }
    9064     3735792 : }
    9065             : 
    9066           0 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
    9067             : {
    9068           0 :     std::string surfName = state.dataSurface->Surface(SurfNum).Name;
    9069             : 
    9070           0 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    9071           0 :         if (state.dataGlobal->WarmupFlag) ++WarmupSurfTemp;
    9072           0 :         if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
    9073           0 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
    9074           0 :                 if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
    9075           0 :                     ShowSevereMessage(
    9076           0 :                         state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9077           0 :                     ShowContinueErrorTimeStamp(state, "");
    9078           0 :                     if (!zone.TempOutOfBoundsReported) {
    9079           0 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9080           0 :                         if (zone.FloorArea > 0.0) {
    9081           0 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9082             :                         } else {
    9083           0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9084             :                         }
    9085           0 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9086           0 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9087           0 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9088             :                         } else {
    9089           0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9090             :                         }
    9091           0 :                         if (zone.IsControlled) {
    9092           0 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9093             :                         } else {
    9094           0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9095             :                         }
    9096           0 :                         zone.TempOutOfBoundsReported = true;
    9097             :                     }
    9098           0 :                     ShowRecurringSevereErrorAtEnd(state,
    9099           0 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9100           0 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9101             :                                                   TH12,
    9102             :                                                   TH12,
    9103             :                                                   _,
    9104             :                                                   "C",
    9105             :                                                   "C");
    9106             :                 } else {
    9107           0 :                     ShowRecurringSevereErrorAtEnd(state,
    9108           0 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9109           0 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9110             :                                                   TH12,
    9111             :                                                   TH12,
    9112             :                                                   _,
    9113             :                                                   "C",
    9114             :                                                   "C");
    9115             :                 }
    9116             :             } else {
    9117           0 :                 if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
    9118           0 :                     ShowSevereMessage(
    9119           0 :                         state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9120           0 :                     ShowContinueErrorTimeStamp(state, "");
    9121           0 :                     if (!zone.TempOutOfBoundsReported) {
    9122           0 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9123           0 :                         if (zone.FloorArea > 0.0) {
    9124           0 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9125             :                         } else {
    9126           0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9127             :                         }
    9128           0 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9129           0 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9130           0 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9131             :                         } else {
    9132           0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9133             :                         }
    9134           0 :                         if (zone.IsControlled) {
    9135           0 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9136             :                         } else {
    9137           0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9138             :                         }
    9139           0 :                         zone.TempOutOfBoundsReported = true;
    9140             :                     }
    9141           0 :                     ShowRecurringSevereErrorAtEnd(state,
    9142           0 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9143           0 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9144             :                                                   TH12,
    9145             :                                                   TH12,
    9146             :                                                   _,
    9147             :                                                   "C",
    9148             :                                                   "C");
    9149             :                 } else {
    9150           0 :                     ShowRecurringSevereErrorAtEnd(state,
    9151           0 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9152           0 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9153             :                                                   TH12,
    9154             :                                                   TH12,
    9155             :                                                   _,
    9156             :                                                   "C",
    9157             :                                                   "C");
    9158             :                 }
    9159             :             }
    9160           0 :             if (zone.EnforcedReciprocity) {
    9161           0 :                 if (WarmupSurfTemp > 3) {
    9162           0 :                     ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
    9163           0 :                     ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
    9164           0 :                     ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9165             :                 }
    9166           0 :             } else if (WarmupSurfTemp > 10) {
    9167           0 :                 ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9168             :             }
    9169             :         }
    9170             :     }
    9171           0 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
    9172           0 :         if (!state.dataGlobal->WarmupFlag) {
    9173           0 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
    9174           0 :                 ShowSevereError(state,
    9175           0 :                                 format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9176           0 :                 ShowContinueErrorTimeStamp(state, "");
    9177           0 :                 if (!zone.TempOutOfBoundsReported) {
    9178           0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9179           0 :                     if (zone.FloorArea > 0.0) {
    9180           0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9181             :                     } else {
    9182           0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9183             :                     }
    9184           0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9185           0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9186           0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9187             :                     } else {
    9188           0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9189             :                     }
    9190           0 :                     if (zone.IsControlled) {
    9191           0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9192             :                     } else {
    9193           0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9194             :                     }
    9195           0 :                     zone.TempOutOfBoundsReported = true;
    9196             :                 }
    9197           0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9198             :             } else {
    9199           0 :                 ShowSevereError(state,
    9200           0 :                                 format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9201           0 :                 ShowContinueErrorTimeStamp(state, "");
    9202           0 :                 if (!zone.TempOutOfBoundsReported) {
    9203           0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9204           0 :                     if (zone.FloorArea > 0.0) {
    9205           0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9206             :                     } else {
    9207           0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9208             :                     }
    9209           0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9210           0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9211           0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9212             :                     } else {
    9213           0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9214             :                     }
    9215           0 :                     if (zone.IsControlled) {
    9216           0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9217             :                     } else {
    9218           0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9219             :                     }
    9220           0 :                     zone.TempOutOfBoundsReported = true;
    9221             :                 }
    9222           0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9223             :             }
    9224             :         } else {
    9225           0 :             if (TH12 < -10000. || TH12 > 10000.) {
    9226           0 :                 ShowSevereError(
    9227             :                     state,
    9228           0 :                     format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9229           0 :                 ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
    9230           0 :                 ShowContinueErrorTimeStamp(state, "");
    9231           0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9232             :             }
    9233             :         }
    9234             :     }
    9235           0 : }
    9236             : 
    9237    43341347 : void CalcOutsideSurfTemp(EnergyPlusData &state,
    9238             :                          int const SurfNum,      // Surface number DO loop counter
    9239             :                          int const spaceNum,     // Space number the current surface is attached to
    9240             :                          int const ConstrNum,    // Construction index for the current surface
    9241             :                          Real64 const HMovInsul, // "Convection" coefficient of movable insulation
    9242             :                          Real64 const TempExt,   // Exterior temperature boundary condition
    9243             :                          bool &ErrorFlag         // Error flag for movable insulation problem
    9244             : )
    9245             : {
    9246             : 
    9247             :     // SUBROUTINE INFORMATION:
    9248             :     //       AUTHOR         George Walton
    9249             :     //       DATE WRITTEN   December 1979
    9250             :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    9251             :     //                      Jul 2000 (RJL for Moisture algorithms)
    9252             :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    9253             :     //                      Dec 2000 (RKS for radiant system model addition)
    9254             :     //                      Aug 2010 (BG added radiant heat flow rate reporting)
    9255             :     //       RE-ENGINEERED  Mar 1998 (RKS)
    9256             : 
    9257             :     // PURPOSE OF THIS SUBROUTINE:
    9258             :     // This subroutine performs a heat balance on the outside face of each
    9259             :     // surface in the building.  NOTE that this also sets some coefficients
    9260             :     // that are needed for radiant system modeling.  Thus, it is extremely
    9261             :     // important that if someone makes changes to the heat balance equations
    9262             :     // at a later date that they must also make changes to the coefficient
    9263             :     // setting portion of this subroutine as well.
    9264             : 
    9265             :     // METHODOLOGY EMPLOYED:
    9266             :     // Various boundary conditions are set and additional parameters are set-
    9267             :     // up.  Then, the proper heat balance equation is selected based on the
    9268             :     // presence of movable insulation, thermal mass of the surface construction,
    9269             :     // and convection model being used.
    9270             : 
    9271             :     // REFERENCES:
    9272             :     // (I)BLAST legacy routine HBOUT
    9273             :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    9274             : 
    9275             :     // Determine whether or not movable insulation is present
    9276    43341347 :     bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
    9277             :     bool QuickConductionSurf;                 // .TRUE. if the cross CTF term is relatively large
    9278             :     Real64 F1;                                // Intermediate calculation variable
    9279             :     Real64 F2;                                // Intermediate calculation variable
    9280             :     // Determine whether this surface is a "slow conductive" or "quick conductive"
    9281             :     // surface.  Designates are inherited from BLAST.  Basically, a "quick" surface
    9282             :     // requires the inside heat balance to be accounted for in the heat balance
    9283             :     // while a "slow" surface can used the last time step's value for inside
    9284             :     // surface temperature.
    9285    43341347 :     auto &surface = state.dataSurface->Surface(SurfNum);
    9286    43341347 :     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    9287    43341347 :     if (construct.CTFCross[0] > 0.01) {
    9288     4797660 :         QuickConductionSurf = true;
    9289     4797660 :         F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    9290             :     } else {
    9291    38543687 :         QuickConductionSurf = false;
    9292             :     }
    9293             : 
    9294    43341347 :     Real64 TSky = state.dataEnvrn->SkyTemp;
    9295    43341347 :     Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
    9296    43341347 :     Real64 TSrdSurfs = 0.0;
    9297             : 
    9298    43341347 :     if (surface.SurfHasSurroundingSurfProperty) {
    9299        5412 :         int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
    9300        5412 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyTempSchNum != 0) {
    9301           0 :             TSky = ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyTempSchNum);
    9302             :         }
    9303        5412 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundTempSchNum != 0) {
    9304           0 :             TGround = ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundTempSchNum);
    9305             :         }
    9306        5412 :         TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
    9307             :     }
    9308    43341347 :     if (surface.UseSurfPropertyGndSurfTemp) {
    9309        8118 :         TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
    9310             :     }
    9311             : 
    9312             :     // Now, calculate the outside surface temperature using the proper heat balance equation.
    9313             :     // Each case has been separated out into its own IF-THEN block for clarity.  Additional
    9314             :     // cases can simply be added anywhere in the following section.  This is the last step
    9315             :     // in the main loop.  Once the proper heat balance is done, the simulation goes on to
    9316             :     // the next SurfNum.
    9317             : 
    9318             :     // Outside heat balance case: Tubular daylighting device
    9319    43341347 :     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
    9320    43341347 :     if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    9321             : 
    9322             :         // Lookup up the TDD:DIFFUSER object
    9323        4050 :         int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    9324        4050 :         int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
    9325        4050 :         int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
    9326        4050 :         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    9327        4050 :         F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
    9328             : 
    9329             :         // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
    9330             :         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    9331             :         //   SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
    9332             :         //+Construct(ConstrNum)%CTFSourceOut[0]     &   TDDs cannot be radiant systems
    9333             :         // *SurfQsrcHist(1,SurfNum)                     &
    9334             :         //+Construct(ConstrNum)%CTFSourceIn[0] &   TDDs cannot be radiant systems
    9335             :         // *SurfQsrcHist(1,SurfNum)                &
    9336        4050 :         TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    9337        4050 :                 (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9338        4050 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
    9339        4050 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9340        4050 :                 F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
    9341        4050 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
    9342        4050 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
    9343        4050 :                (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9344        4050 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9345        4050 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9346        4050 :                 F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
    9347             :                             // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
    9348             : 
    9349             :         // Outside heat balance case: No movable insulation, slow conduction
    9350    43337297 :     } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
    9351             :         // Add LWR from surrounding surfaces
    9352    38535590 :         if (surface.OSCMPtr == 0) {
    9353    38393975 :             if (construct.SourceSinkPresent) {
    9354       83175 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9355       83175 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9356       83175 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9357       83175 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9358       83175 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9359       83175 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9360       83175 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9361       83175 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9362       83175 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9363             :             } else {
    9364    38310800 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9365    38310800 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9366    38310800 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9367    38310800 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9368    38310800 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9369    38310800 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9370    38310800 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9371    38310800 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9372             :             }
    9373             :             // Outside Heat Balance case: Other Side Conditions Model
    9374             :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9375             :             // local copies of variables for clarity in radiation terms
    9376             :             // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
    9377             :             Real64 RadTemp =
    9378      141615 :                 state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
    9379      141615 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
    9380             : 
    9381             :             // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
    9382      141615 :             if (construct.SourceSinkPresent) {
    9383           0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9384           0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9385           0 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9386           0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9387           0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9388             :             } else {
    9389      141615 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9390      141615 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9391      141615 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9392      141615 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9393             :             }
    9394             :         }
    9395             :         // Outside heat balance case: No movable insulation, quick conduction
    9396    43337297 :     } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
    9397     4797660 :         if (surface.OSCMPtr == 0) {
    9398     4727460 :             if (construct.SourceSinkPresent) {
    9399       24140 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9400       24140 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9401       24140 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9402       24140 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9403       24140 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9404       24140 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9405       24140 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9406       24140 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9407       24140 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9408       24140 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9409       24140 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9410       24140 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9411       24140 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9412       24140 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9413             :             } else {
    9414     4703320 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9415     4703320 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9416     4703320 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9417     4703320 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9418     4703320 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9419     4703320 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9420     4703320 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9421     4703320 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9422     4703320 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9423     4703320 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9424     4703320 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9425     4703320 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9426     4703320 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9427             :             }
    9428             :             // Outside Heat Balance case: Other Side Conditions Model
    9429             :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9430             :             // local copies of variables for clarity in radiation terms
    9431       70200 :             Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
    9432       70200 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
    9433             :             // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
    9434       70200 :             if (construct.SourceSinkPresent) {
    9435           0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9436           0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9437           0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9438           0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9439           0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9440           0 :                               construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9441           0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9442           0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9443           0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9444           0 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9445             :             } else {
    9446       70200 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9447       70200 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9448       70200 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9449       70200 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9450       70200 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9451       70200 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9452       70200 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9453       70200 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9454             :             }
    9455             :         }
    9456             :         // Outside heat balance case: Movable insulation, slow conduction
    9457     4801707 :     } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
    9458             : 
    9459        4047 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9460        4047 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9461        4047 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9462             : 
    9463        4047 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9464        4047 :                 construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9465        4047 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9466        4047 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9467        4047 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9468        4047 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9469        4047 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
    9470             : 
    9471             :         // Outside heat balance case: Movable insulation, quick conduction
    9472           0 :     } else if ((MovInsulPresent) && (QuickConductionSurf)) {
    9473             : 
    9474           0 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9475           0 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9476           0 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9477             : 
    9478           0 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9479           0 :                 F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9480           0 :                       state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9481           0 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9482           0 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
    9483           0 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9484           0 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9485           0 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9486           0 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9487           0 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
    9488             : 
    9489             :     } // ...end of outside heat balance cases IF-THEN block
    9490             : 
    9491             :     // multiply out linearized radiation coeffs for reporting
    9492             :     Real64 const HExtSurf_fac(
    9493    43341347 :         -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
    9494    43341347 :           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
    9495    43341347 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
    9496             : 
    9497             :     // Set the radiant system heat balance coefficients if this surface is also a radiant system
    9498    43341347 :     if (construct.SourceSinkPresent) {
    9499             : 
    9500      107315 :         if (MovInsulPresent) {
    9501             :             // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
    9502           0 :             ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
    9503           0 :             ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    9504           0 :             ShowContinueError(state,
    9505           0 :                               format("exterior movable insulation {} for a surface with that construction.",
    9506           0 :                                      state.dataMaterial->Material(state.dataSurface->SurfMaterialMovInsulExt(SurfNum))->Name));
    9507           0 :             ShowContinueError(state,
    9508             :                               "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
    9509           0 :             ErrorFlag = true;
    9510           0 :             return;
    9511             : 
    9512             :         } else {
    9513      107315 :             Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
    9514      107315 :                                           state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
    9515      107315 :                                           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
    9516      107315 :                                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
    9517             : 
    9518      107315 :             state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    9519      107315 :                 (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9520      107315 :                  state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9521      107315 :                  (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9522      107315 :                  state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
    9523             :                 RadSysDiv; // ODB used to approx ground surface temp
    9524             : 
    9525      107315 :             state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
    9526             : 
    9527      107315 :             state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
    9528             :         }
    9529             :     }
    9530             : }
    9531             : 
    9532        8124 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
    9533             : {
    9534             : 
    9535             :     // SUBROUTINE INFORMATION:
    9536             :     //       AUTHOR         B Griffith
    9537             :     //       DATE WRITTEN   January 2005
    9538             : 
    9539             :     // PURPOSE OF THIS SUBROUTINE:
    9540             :     // manages calculating the temperatures of baffle and air cavity for
    9541             :     // multi-skin configuration.
    9542             : 
    9543             :     // METHODOLOGY EMPLOYED:
    9544             :     // derived from CalcPassiveTranspiredCollector
    9545             : 
    9546             :     // local working variables
    9547             :     Real64 HrPlen;
    9548             :     Real64 HcPlen;
    9549             :     Real64 Isc;
    9550             :     Real64 MdotVent;
    9551             :     Real64 VdotWind;
    9552             :     Real64 VdotThermal;
    9553             : 
    9554        8124 :     int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
    9555        8124 :     Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    9556        8124 :     Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
    9557        8124 :         state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
    9558        8124 :     Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
    9559        8124 :     Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
    9560             :     // Aspect Ratio of gap
    9561        8124 :     Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
    9562        8124 :     Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
    9563        8124 :     Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
    9564             : 
    9565             :     // all the work is done in this routine located in GeneralRoutines.cc
    9566             : 
    9567       32496 :     for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
    9568             : 
    9569       48744 :         TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
    9570       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
    9571             :                                                           holeArea,
    9572       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
    9573       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
    9574       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
    9575       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
    9576       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
    9577       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
    9578             :                                                           AspRat,
    9579       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
    9580       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
    9581       24372 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
    9582             :                                                           TmpTscoll,
    9583             :                                                           TmpTaPlen,
    9584             :                                                           HcPlen,
    9585             :                                                           HrPlen,
    9586             :                                                           Isc,
    9587             :                                                           MdotVent,
    9588             :                                                           VdotWind,
    9589             :                                                           VdotThermal);
    9590             : 
    9591             :     } // sequential solution
    9592             :     // now fill results into derived types
    9593        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
    9594        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
    9595        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
    9596        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
    9597        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
    9598        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
    9599       16248 :         (MdotVent / RhoAir) *
    9600        8124 :         (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) * Constant::SecInHour;
    9601        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
    9602        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
    9603        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
    9604             : 
    9605             :     // now do some updates
    9606        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9607        8124 :     state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9608             : 
    9609             :     // update the OtherSideConditionsModel coefficients.
    9610        8124 :     int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
    9611             : 
    9612        8124 :     state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9613        8124 :     state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
    9614        8124 :     state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9615        8124 :     state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
    9616        8124 : }
    9617             : 
    9618      818667 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
    9619             : {
    9620             :     // SUBROUTINE INFORMATION:
    9621             :     //       AUTHOR         Jason Glazer
    9622             :     //       DATE WRITTEN   September 2012
    9623             : 
    9624             :     // PURPOSE OF THIS SUBROUTINE:
    9625             :     //   Gather values during sizing used for surface absorption factors
    9626             : 
    9627             :     // METHODOLOGY EMPLOYED:
    9628             :     //   Save sequence of values for report during sizing.
    9629             : 
    9630      818667 :     if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
    9631       36642 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour + state.dataGlobal->TimeStep;
    9632      336870 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
    9633      300228 :             state.dataOutRptTab->TMULTseq(state.dataSize->CurOverallSimDay, TimeStepInDay, enclosureNum) =
    9634      300228 :                 state.dataViewFactor->EnclRadInfo(enclosureNum).radThermAbsMult;
    9635             :         }
    9636     2683542 :         for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
    9637     2646900 :             auto const &surface = state.dataSurface->Surface(jSurf);
    9638     2646900 :             if (!surface.HeatTransSurf || surface.Zone == 0) continue;           // Skip non-heat transfer surfaces
    9639     2482200 :             if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) continue; // Skip tubular daylighting device domes
    9640     2482200 :             state.dataOutRptTab->ITABSFseq(state.dataSize->CurOverallSimDay, TimeStepInDay, jSurf) = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
    9641             :         }
    9642             :     }
    9643      818667 : }
    9644             : 
    9645    56101773 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
    9646             : {
    9647    56101773 :     if (state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
    9648        2408 :         if (state.dataSurface->SurfIncSolMultiplier(SurfNum).SchedPtr > 0) {
    9649        2408 :             return ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->SurfIncSolMultiplier(SurfNum).SchedPtr) *
    9650        2408 :                    state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9651             :         } else {
    9652           0 :             return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9653             :         }
    9654             :     } else {
    9655    56099365 :         return 1.0;
    9656             :     }
    9657             : }
    9658             : 
    9659         796 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
    9660             : {
    9661             : 
    9662             :     // purpuse:
    9663             :     //   Initializes sky and ground surfaces view factors of exterior surfaces
    9664             :     //   used by SurfaceProperty:LocalEnvironment
    9665             :     //   view factors are constant hence should be set only once
    9666             : 
    9667         796 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9668         792 :         return;
    9669             :     }
    9670           4 :     if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    9671           0 :         return;
    9672             :     }
    9673             : 
    9674         414 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9675         410 :         auto &Surface = state.dataSurface->Surface(SurfNum);
    9676         410 :         if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
    9677             : 
    9678          18 :             int GndSurfsNum = 0;
    9679          18 :             int SrdSurfsNum = 0;
    9680          18 :             Real64 SrdSurfsViewFactor = 0.0;
    9681          18 :             Real64 SurfsSkyViewFactor = 0.0;
    9682          18 :             Real64 GroundSurfsViewFactor = 0.0;
    9683          18 :             bool IsSkyViewFactorSet = false;
    9684          18 :             bool IsGroundViewFactorSet = false;
    9685          18 :             bool SetGroundViewFactorObject = false;
    9686          18 :             if (Surface.SurfHasSurroundingSurfProperty) {
    9687           6 :                 SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
    9688           6 :                 auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
    9689           6 :                 SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
    9690           6 :                 IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
    9691           6 :                 if (SurfsSkyViewFactor > 0.0) {
    9692           4 :                     SrdSurfsViewFactor += SurfsSkyViewFactor;
    9693             :                 }
    9694           6 :                 if (!Surface.IsSurfPropertyGndSurfacesDefined) {
    9695           5 :                     SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
    9696           5 :                     IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
    9697           5 :                     GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
    9698             :                 }
    9699          14 :                 for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    9700           8 :                     SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
    9701             :                 }
    9702             :             }
    9703          18 :             if (Surface.IsSurfPropertyGndSurfacesDefined) {
    9704          13 :                 GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
    9705          13 :                 IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
    9706          13 :                 GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
    9707          13 :                 SrdSurfsViewFactor += GroundSurfsViewFactor;
    9708             :             }
    9709             : 
    9710             :             // Check if the sum of all defined view factors > 1.0
    9711          18 :             if (SrdSurfsViewFactor > 1.0) {
    9712           0 :                 ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
    9713           0 :                 ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
    9714             :             }
    9715          18 :             if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9716             :                 // If both surface sky and ground view factor defined, overwrite with the defined value
    9717           4 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9718           4 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9719          14 :             } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
    9720             :                 // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
    9721           2 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9722           2 :                 Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
    9723           2 :                 if (GndSurfsNum > 0) {
    9724           0 :                     SetGroundViewFactorObject = true;
    9725           0 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9726             :                 } else {
    9727           2 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9728             :                 }
    9729          12 :             } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9730             :                 // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
    9731          12 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9732          12 :                 Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
    9733          12 :                 if (SrdSurfsNum > 0) {
    9734           0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9735           0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9736             :                 }
    9737             :             } else {
    9738             :                 // If neither ground nor sky view factor specified, continue to use the original proportion.
    9739           0 :                 Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
    9740           0 :                 Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
    9741           0 :                 if (SrdSurfsNum > 0) {
    9742           0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9743           0 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9744           0 :                     if (GndSurfsNum == 0) {
    9745           0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9746           0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
    9747             :                     }
    9748             :                 }
    9749           0 :                 if (GndSurfsNum > 0) {
    9750           0 :                     SetGroundViewFactorObject = true;
    9751           0 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9752             :                 }
    9753             :             }
    9754          18 :             if (SetGroundViewFactorObject) {
    9755           0 :                 ReSetGroundSurfacesViewFactor(state, SurfNum);
    9756             :             }
    9757             :         }
    9758             :     }
    9759             : }
    9760             : 
    9761     3703058 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
    9762             : {
    9763             :     //  returns ground surfaces average temperature (deg C)
    9764             :     //  ground surfaces viewed by a building exterior surface
    9765             :     //  ground surfaces temperature weighed using view factors
    9766             : 
    9767     3703058 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9768     3695622 :         return;
    9769             :     }
    9770             : 
    9771      620862 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9772      613426 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) continue;
    9773       17589 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9774       17589 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9775           0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9776           0 :             continue;
    9777             :         }
    9778       17589 :         Real64 GndSurfaceTemp = 0.0;
    9779       17589 :         Real64 GndSurfViewFactor = 0.0;
    9780       17589 :         Real64 GndSurfaceTempSum = 0.0;
    9781       59532 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9782       41943 :             GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
    9783       41943 :             if (GndSurfViewFactor == 0.0) continue;
    9784       41943 :             if (GndSurfsProperty.GndSurfs(gSurfNum).TempSchPtr == 0) continue;
    9785       40590 :             GndSurfaceTemp = ScheduleManager::GetCurrentScheduleValue(state, GndSurfsProperty.GndSurfs(gSurfNum).TempSchPtr);
    9786       40590 :             GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
    9787             :         }
    9788       17589 :         if (GndSurfaceTempSum == 0.0) {
    9789        1353 :             GndSurfsProperty.SurfsTempAvg = 0.0;
    9790        1353 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9791        1353 :             continue;
    9792             :         }
    9793       16236 :         GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
    9794             :     }
    9795             : }
    9796             : 
    9797     2804678 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
    9798             : {
    9799             :     //  returns ground surfaces average reflectance (dimenssionless)
    9800             :     //  ground reflectance viewed by a building exterior surface
    9801             :     //  ground surfaces reflectance weighed using view factors
    9802             : 
    9803     2804678 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9804     2797242 :         return;
    9805             :     }
    9806      620862 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9807             : 
    9808      613426 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) continue;
    9809       17589 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9810       17589 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9811           0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9812           0 :             continue;
    9813             :         }
    9814       17589 :         Real64 GndSurfRefl = 0.0;
    9815       17589 :         Real64 GndSurfsReflSum = 0.0;
    9816       59532 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9817       41943 :             if (GndSurfsProperty.GndSurfs(gSurfNum).ReflSchPtr == 0) continue;
    9818       40590 :             GndSurfRefl = ScheduleManager::GetCurrentScheduleValue(state, GndSurfsProperty.GndSurfs(gSurfNum).ReflSchPtr);
    9819       40590 :             GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
    9820             :         }
    9821       17589 :         if (GndSurfsReflSum == 0.0) {
    9822        1353 :             GndSurfsProperty.SurfsReflAvg = 0.0;
    9823        1353 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9824        1353 :             continue;
    9825             :         }
    9826       16236 :         GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
    9827             :     }
    9828             : }
    9829             : 
    9830           0 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
    9831             : {
    9832             :     //  resets ground veiew factors based on view factors identity
    9833             :     //  the ground view factor value is set to the first element
    9834             :     //  when the ground view factor input field is blank
    9835             : 
    9836           0 :     if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) return;
    9837           0 :     auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9838           0 :     GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
    9839             : 
    9840           0 :     if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9841           0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9842           0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9843           0 :         return;
    9844             :     }
    9845           0 :     GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
    9846             : }
    9847             : 
    9848     3703058 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
    9849             : {
    9850             :     //  returns surrounding surfaces average temperature (deg C)
    9851             :     //  surrounding surfaces viewed by an exterior surface
    9852             :     //  surrounding surfaces temperature weighed using view factors
    9853             : 
    9854     3703058 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9855     3695622 :         return;
    9856             :     }
    9857             : 
    9858      620862 :     for (auto &surface : state.dataSurface->Surface) {
    9859      613426 :         if (!surface.SurfHasSurroundingSurfProperty) continue;
    9860             :         // local vars
    9861        8118 :         Real64 SrdSurfaceTemp = 0.0;
    9862        8118 :         Real64 SrdSurfaceTempSum = 0.0;
    9863        8118 :         auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
    9864       18942 :         for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    9865       10824 :             SrdSurfaceTemp =
    9866       10824 :                 ScheduleManager::GetCurrentScheduleValue(state, SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).TempSchNum) + Constant::Kelvin;
    9867       10824 :             SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
    9868             :         }
    9869        8118 :         surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
    9870        7436 :     }
    9871             : }
    9872             : } // namespace EnergyPlus::HeatBalanceSurfaceManager

Generated by: LCOV version 1.14