LCOV - code coverage report
Current view: top level - EnergyPlus - SolarShading.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 4064 6192 65.6 %
Date: 2023-01-17 19:17:23 Functions: 52 63 82.5 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, 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 <cassert>
      50             : #include <cmath>
      51             : #include <memory>
      52             : 
      53             : // ObjexxFCL Headers
      54             : #include <ObjexxFCL/Array.functions.hh>
      55             : #include <ObjexxFCL/Fmath.hh>
      56             : #include <ObjexxFCL/Vector3.hh>
      57             : #include <ObjexxFCL/member.functions.hh>
      58             : 
      59             : // EnergyPlus Headers
      60             : #include <EnergyPlus/CommandLineInterface.hh>
      61             : #include <EnergyPlus/Construction.hh>
      62             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      63             : #include <EnergyPlus/DataDaylightingDevices.hh>
      64             : #include <EnergyPlus/DataEnvironment.hh>
      65             : #include <EnergyPlus/DataErrorTracking.hh>
      66             : #include <EnergyPlus/DataHeatBalSurface.hh>
      67             : #include <EnergyPlus/DataHeatBalance.hh>
      68             : #include <EnergyPlus/DataIPShortCuts.hh>
      69             : #include <EnergyPlus/DataReportingFlags.hh>
      70             : #include <EnergyPlus/DataShadowingCombinations.hh>
      71             : #include <EnergyPlus/DataStringGlobals.hh>
      72             : #include <EnergyPlus/DataSurfaces.hh>
      73             : #include <EnergyPlus/DataSystemVariables.hh>
      74             : #include <EnergyPlus/DataViewFactorInformation.hh>
      75             : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
      76             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      77             : #include <EnergyPlus/DaylightingDevices.hh>
      78             : #include <EnergyPlus/DaylightingManager.hh>
      79             : #include <EnergyPlus/DisplayRoutines.hh>
      80             : #include <EnergyPlus/General.hh>
      81             : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      82             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      83             : #include <EnergyPlus/OutputProcessor.hh>
      84             : #include <EnergyPlus/OutputReportPredefined.hh>
      85             : #include <EnergyPlus/ScheduleManager.hh>
      86             : #include <EnergyPlus/SolarReflectionManager.hh>
      87             : #include <EnergyPlus/SolarShading.hh>
      88             : #include <EnergyPlus/UtilityRoutines.hh>
      89             : #include <EnergyPlus/Vectors.hh>
      90             : #include <EnergyPlus/WindowComplexManager.hh>
      91             : #include <EnergyPlus/WindowEquivalentLayer.hh>
      92             : #include <EnergyPlus/WindowManager.hh>
      93             : #include <EnergyPlus/WindowManagerExteriorData.hh>
      94             : #include <EnergyPlus/WindowModel.hh>
      95             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      96             : #include <WCEMultiLayerOptics.hpp>
      97             : 
      98             : namespace EnergyPlus::SolarShading {
      99             : 
     100             : // MODULE INFORMATION:
     101             : //       AUTHOR         Rick Strand
     102             : //       DATE WRITTEN   March 1997
     103             : //       MODIFIED       December 1998, FCW
     104             : //       MODIFIED       July 1999, Linda Lawrie, eliminate shadefl.scr,
     105             : //                      do shadowing calculations during simulation
     106             : //       MODIFIED       June 2001, FCW, handle window blinds
     107             : //       MODIFIED       May 2004, LKL, Polygons > 4 sides (not subsurfaces)
     108             : //       MODIFIED       January 2007, LKL, Taking parameters back to original integer (HC)
     109             : //       MODIFIED       August 2011, JHK, Including Complex Fenestration optical calculations
     110             : //       MODIFIED       November 2012, BG, Timestep solar and daylighting calculations
     111             : //       RE-ENGINEERED  na
     112             : 
     113             : // PURPOSE OF THIS MODULE:
     114             : // The purpose of this module is to encompass the routines and data
     115             : // which are need to perform the solar calculations in EnergyPlus.
     116             : // This also requires that shading and geometry routines and data
     117             : // which are used by the solar calculations be included in this module.
     118             : 
     119             : // METHODOLOGY EMPLOYED:
     120             : // Many of the methods used in this module have been carried over from the
     121             : // (I)BLAST program.  As such, there is not much documentation on the
     122             : // methodology used.  The original code was written mainly by George
     123             : // Walton and requires coordinate transformations.  It calculates
     124             : // shading using an overlapping polygon approach.
     125             : 
     126             : // REFERENCES:
     127             : // TARP Manual, NIST Publication.
     128             : // Passive Solar Extension of the BLAST Program, CERL/UIUC Publication.
     129             : 
     130             : using namespace DataEnvironment;
     131             : using namespace DataHeatBalance;
     132             : using namespace DataSurfaces;
     133             : using namespace DataShadowingCombinations;
     134             : using namespace SolarReflectionManager;
     135             : using namespace DataVectorTypes;
     136             : using namespace WindowManager;
     137             : using namespace FenestrationCommon;
     138             : using namespace SingleLayerOptics;
     139             : 
     140             : int constexpr NPhi = 6;                                           // Number of altitude angle steps for sky integration
     141             : int constexpr NTheta = 24;                                        // Number of azimuth angle steps for sky integration
     142             : Real64 constexpr Eps = 1.e-10;                                    // Small number
     143             : Real64 constexpr DPhi = DataGlobalConstants::PiOvr2 / NPhi;       // Altitude step size
     144             : Real64 constexpr DTheta = 2.0 * DataGlobalConstants::Pi / NTheta; // Azimuth step size
     145             : Real64 constexpr DThetaDPhi = DTheta * DPhi;                      // Product of DTheta and DPhi
     146             : Real64 constexpr PhiMin = 0.5 * DPhi;                             // Minimum altitude
     147             : 
     148             : Real64 constexpr HCMULT = 100000.0; // Multiplier used to change meters to .01 millimeters for homogeneous coordinates.
     149             :                                     // Homogeneous Coordinates are represented in integers (64 bit). This changes the surface coordinates from meters
     150             :                                     // to .01 millimeters -- making that the resolution for shadowing, polygon clipping, etc.
     151             : Real64 const sqHCMULT = (HCMULT * HCMULT);    // Square of HCMult used in Homogeneous coordinates
     152             : Real64 const sqHCMULT_fac = (0.5 / sqHCMULT); // ( 0.5 / sqHCMULT ) factor
     153             : 
     154             : // Parameters for use with the variable OverlapStatus...
     155             : int constexpr NoOverlap = 1;
     156             : int constexpr FirstSurfWithinSecond = 2;
     157             : int constexpr SecondSurfWithinFirst = 3;
     158             : int constexpr PartialOverlap = 4;
     159             : int constexpr TooManyVertices = 5;
     160             : int constexpr TooManyFigures = 6;
     161             : 
     162         771 : void InitSolarCalculations(EnergyPlusData &state)
     163             : {
     164             : 
     165             :     // SUBROUTINE INFORMATION:
     166             :     //       AUTHOR         George Walton
     167             :     //       DATE WRITTEN   September 1977
     168             :     //       MODIFIED       na
     169             :     //       RE-ENGINEERED  Mar97, RKS, Initial EnergyPlus Version
     170             : 
     171             :     // PURPOSE OF THIS SUBROUTINE:
     172             :     // This routine controls the computation of the solar flux multipliers.
     173             : 
     174             :     // METHODOLOGY EMPLOYED:
     175             :     // All shadowing calculations have been grouped under this routine to
     176             :     // allow segmentation separating it from the hourly loads calculation.
     177             : 
     178             : #ifdef EP_Count_Calls
     179             :     ++state.dataTimingsData->NumInitSolar_Calls;
     180             : #endif
     181         771 :     if (state.dataGlobal->BeginSimFlag) {
     182         771 :         if (state.files.outputControl.shd) {
     183        1540 :             state.dataSolarShading->shd_stream =
     184        2310 :                 std::make_unique<std::fstream>(state.dataStrGlobals->outputShdFilePath, std::ios_base::out | std::ios_base::trunc);
     185         770 :             if (!state.dataSolarShading->shd_stream) {
     186           0 :                 ShowFatalError(state,
     187           0 :                                "InitSolarCalculations: Could not open file \"" + state.dataStrGlobals->outputShdFilePath.string() +
     188             :                                    "\" for output (write).");
     189             :             }
     190             :         } else {
     191           1 :             state.dataSolarShading->shd_stream = std::make_unique<std::iostream>(nullptr);
     192             :         }
     193             : 
     194         771 :         if (state.dataSolarShading->GetInputFlag) {
     195         771 :             GetShadowingInput(state);
     196         771 :             state.dataSolarShading->GetInputFlag = false;
     197         771 :             state.dataSolarShading->MaxHCV =
     198         771 :                 (((max(15, state.dataSurface->MaxVerticesPerSurface) + 16) / 16) * 16) - 1; // Assure MaxHCV+1 is multiple of 16 for 128 B alignment
     199         771 :             assert((state.dataSolarShading->MaxHCV + 1) % 16 == 0);
     200             :         }
     201             : 
     202         771 :         if (state.dataSolarShading->firstTime) DisplayString(state, "Allocate Solar Module Arrays");
     203         771 :         AllocateModuleArrays(state);
     204             : 
     205         771 :         if (state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::FullInteriorExterior) {
     206         331 :             if (state.dataSolarShading->firstTime) DisplayString(state, "Computing Interior Solar Absorption Factors");
     207         331 :             ComputeIntSolarAbsorpFactors(state);
     208             :         }
     209             : 
     210         771 :         if (state.dataSolarShading->firstTime) DisplayString(state, "Determining Shadowing Combinations");
     211         771 :         DetermineShadowingCombinations(state);
     212         771 :         state.dataSolarShading->shd_stream.reset(); // Done writing to shd file
     213             : 
     214         771 :         if (state.dataSolarShading->firstTime) DisplayString(state, "Computing Window Shade Absorption Factors");
     215         771 :         ComputeWinShadeAbsorpFactors(state);
     216             : 
     217         771 :         if (state.dataSurface->CalcSolRefl) {
     218           9 :             DisplayString(state, "Initializing Solar Reflection Factors");
     219           9 :             InitSolReflRecSurf(state);
     220             :         }
     221             : 
     222         771 :         if (state.dataSolarShading->firstTime) DisplayString(state, "Proceeding with Initializing Solar Calculations");
     223             :     }
     224             : 
     225         771 :     if (state.dataGlobal->BeginEnvrnFlag) {
     226         771 :         state.dataSolarShading->SurfSunCosTheta = 0.0;
     227         771 :         state.dataSolarShading->SurfSunlitArea = 0.0;
     228         771 :         state.dataSurface->SurfSunlitArea = 0.0;
     229         771 :         state.dataSurface->SurfSunlitFrac = 0.0;
     230         771 :         state.dataHeatBal->SurfSunlitFracHR = 0.0;
     231         771 :         state.dataHeatBal->SurfSunlitFrac = 0.0;
     232         771 :         state.dataHeatBal->SurfSunlitFracWithoutReveal = 0.0;
     233         771 :         state.dataHeatBal->SurfWinBackSurfaces = 0;
     234         771 :         state.dataHeatBal->SurfWinOverlapAreas = 0.0;
     235         771 :         state.dataHeatBal->SurfCosIncAngHR = 0.0;
     236         771 :         state.dataHeatBal->SurfCosIncAng = 0.0;
     237         771 :         state.dataSolarShading->SurfAnisoSkyMult = 1.0; // For isotropic sky; recalculated in AnisoSkyViewFactors if anisotropic radiance
     238             :         //    WithShdgIsoSky=0.0
     239             :         //    WoShdgIsoSky=0.0
     240             :         //    WithShdgHoriz=0.0
     241             :         //    WoShdgHoriz=0.0
     242             :         //    DifShdgRatioIsoSky=0.0
     243             :         //    DifShdgRatioHoriz=0.0
     244         771 :         state.dataSolarShading->SurfMultIsoSky = 0.0;
     245         771 :         state.dataSolarShading->SurfMultCircumSolar = 0.0;
     246         771 :         state.dataSolarShading->SurfMultHorizonZenith = 0.0;
     247         771 :         state.dataSolarShading->SurfWinRevealStatus = 0;
     248             : 
     249        5585 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     250        4814 :             state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
     251        4814 :             state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
     252        4814 :             state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
     253        4814 :             state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
     254        4814 :             state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
     255        4814 :             state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
     256        4814 :             state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
     257        4814 :             state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
     258        4814 :             state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
     259        4814 :             state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
     260             :         }
     261        5582 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
     262        4811 :             state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
     263        4811 :             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
     264        4811 :             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
     265        4811 :             state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
     266        4811 :             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
     267        4811 :             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
     268        4811 :             state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
     269        4811 :             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
     270        4811 :             state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
     271        4811 :             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
     272        4811 :             state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
     273             :         }
     274       44533 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     275       43762 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
     276       43762 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
     277       43762 :             state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
     278       43762 :             state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
     279       43762 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
     280       43762 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
     281       43762 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
     282       43762 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
     283       43762 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
     284       43762 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
     285       43762 :             state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
     286       43762 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
     287       43762 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
     288       43762 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
     289       43762 :             state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
     290       43762 :             state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
     291       43762 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
     292       43762 :             state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
     293             :         }
     294        5585 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     295        9632 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     296        4818 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
     297        4818 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
     298        4818 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
     299       10792 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
     300             : 
     301        5974 :                     state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
     302        5974 :                     state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
     303        5974 :                     state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
     304        5974 :                     state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
     305        5974 :                     state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
     306             : 
     307        5974 :                     state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
     308        5974 :                     state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
     309        5974 :                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
     310        5974 :                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
     311             : 
     312        5974 :                     state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
     313        5974 :                     state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
     314        5974 :                     state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
     315             :                 }
     316       10792 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
     317        5974 :                     state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
     318        5974 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
     319        5974 :                     state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
     320        5974 :                     state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
     321        5974 :                     state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
     322        5974 :                     state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
     323        5974 :                     state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
     324        5974 :                     state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
     325             : 
     326        5974 :                     state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
     327        5974 :                     state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
     328        5974 :                     state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
     329             :                 }
     330       10792 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
     331        5974 :                     state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
     332        5974 :                     state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
     333        5974 :                     state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
     334        5974 :                     state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
     335        5974 :                     state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
     336             : 
     337        5974 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
     338        5974 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
     339        5974 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
     340        5974 :                     state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
     341             : 
     342        5974 :                     state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0;
     343        5974 :                     state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 0;
     344        5974 :                     state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 0;
     345             :                 }
     346             :             }
     347             :         }
     348             :     }
     349             : 
     350             :     // Initialize these once
     351        5397 :     for (int IPhi = 1; IPhi <= NPhi; ++IPhi) {   // Loop over patch altitude values
     352        4626 :         Real64 Phi = PhiMin + (IPhi - 1) * DPhi; // 7.5,22.5,37.5,52.5,67.5,82.5 for NPhi = 6
     353        4626 :         state.dataSolarShading->sin_Phi.push_back(std::sin(Phi));
     354        4626 :         state.dataSolarShading->cos_Phi.push_back(std::cos(Phi));
     355             :     }
     356             : 
     357       19275 :     for (int ITheta = 1; ITheta <= NTheta; ++ITheta) { // Loop over patch azimuth values
     358       18504 :         Real64 Theta = (ITheta - 1) * DTheta;          // 0,15,30,....,330,345 for NTheta = 24
     359       18504 :         state.dataSolarShading->sin_Theta.push_back(std::sin(Theta));
     360       18504 :         state.dataSolarShading->cos_Theta.push_back(std::cos(Theta));
     361             :     }
     362             : 
     363         771 :     state.dataSolarShading->firstTime = false;
     364         771 : }
     365             : 
     366         771 : void GetShadowingInput(EnergyPlusData &state)
     367             : {
     368             :     // SUBROUTINE INFORMATION:
     369             :     //       AUTHOR         Linda K. Lawrie
     370             :     //       DATE WRITTEN   July 1999
     371             :     //       MODIFIED       B. Griffith, Nov 2012, add calculation method
     372             : 
     373             :     // PURPOSE OF THIS SUBROUTINE:
     374             :     // This subroutine gets the Shadowing Calculation object.
     375             : 
     376             :     // Using/Aliasing
     377             :     using DataSystemVariables::ShadingMethod;
     378             : 
     379             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     380             :     int NumItems;
     381             :     int NumNumbers;
     382             :     int NumAlphas;
     383             :     int IOStat;
     384         771 :     int Found = 0;
     385         771 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     386         771 :     state.dataIPShortCut->rNumericArgs({1, 4}) = 0.0; // so if nothing gotten, defaults will be maintained.
     387         771 :     state.dataIPShortCut->cAlphaArgs(1) = "";
     388         771 :     state.dataIPShortCut->cAlphaArgs(2) = "";
     389         771 :     cCurrentModuleObject = "ShadowCalculation";
     390         771 :     NumItems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     391         771 :     NumAlphas = 0;
     392         771 :     NumNumbers = 0;
     393         771 :     if (NumItems > 1) {
     394           0 :         ShowWarningError(state, cCurrentModuleObject + ": More than 1 occurrence of this object found, only first will be used.");
     395             :     }
     396             : 
     397         771 :     if (NumItems != 0) {
     398        1036 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     399             :                                                                  cCurrentModuleObject,
     400             :                                                                  1,
     401         148 :                                                                  state.dataIPShortCut->cAlphaArgs,
     402             :                                                                  NumAlphas,
     403         148 :                                                                  state.dataIPShortCut->rNumericArgs,
     404             :                                                                  NumNumbers,
     405             :                                                                  IOStat,
     406         148 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     407         148 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     408         148 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     409         148 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     410         148 :         state.dataSolarShading->ShadowingCalcFrequency = state.dataIPShortCut->rNumericArgs(1);
     411             :     }
     412             : 
     413         771 :     if (state.dataSolarShading->ShadowingCalcFrequency <= 0) {
     414             :         //  Set to default value
     415         623 :         state.dataSolarShading->ShadowingCalcFrequency = 20;
     416             :     }
     417         771 :     if (state.dataSolarShading->ShadowingCalcFrequency > 31) {
     418           0 :         ShowWarningError(state, cCurrentModuleObject + ": suspect " + state.dataIPShortCut->cNumericFieldNames(1));
     419           0 :         ShowContinueError(state, format("Value entered=[{:.0R}], Shadowing Calculations will be inaccurate.", state.dataIPShortCut->rNumericArgs(1)));
     420             :     }
     421             : 
     422         771 :     if (state.dataIPShortCut->rNumericArgs(2) > 199.0) {
     423         104 :         state.dataSolarShading->MaxHCS = state.dataIPShortCut->rNumericArgs(2);
     424             :     } else {
     425         667 :         state.dataSolarShading->MaxHCS = 15000;
     426             :     }
     427             : 
     428         771 :     int aNum = 1;
     429         771 :     unsigned pixelRes = 512u;
     430         771 :     if (NumAlphas >= aNum) {
     431         148 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Scheduled")) {
     432           1 :             state.dataSysVars->shadingMethod = ShadingMethod::Scheduled;
     433           1 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Scheduled";
     434         147 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Imported")) {
     435           1 :             if (state.dataScheduleMgr->ScheduleFileShadingProcessed) {
     436           1 :                 state.dataSysVars->shadingMethod = ShadingMethod::Imported;
     437           1 :                 state.dataIPShortCut->cAlphaArgs(aNum) = "Imported";
     438             :             } else {
     439           0 :                 ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     440           0 :                 ShowContinueError(state,
     441           0 :                                   "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) +
     442             :                                       "\" while no Schedule:File:Shading object is defined, InternalCalculation will be used.");
     443             :             }
     444         146 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "PolygonClipping")) {
     445         145 :             state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
     446         145 :             state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
     447           1 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "PixelCounting")) {
     448           1 :             state.dataSysVars->shadingMethod = ShadingMethod::PixelCounting;
     449           1 :             state.dataIPShortCut->cAlphaArgs(aNum) = "PixelCounting";
     450           1 :             if (NumNumbers >= 3) {
     451           1 :                 pixelRes = (unsigned)state.dataIPShortCut->rNumericArgs(3);
     452             :             }
     453             : #ifdef EP_NO_OPENGL
     454             :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     455             :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\"");
     456             :             ShowContinueError(state, "This version of EnergyPlus was not compiled to use OpenGL (required for PixelCounting)");
     457             :             ShowContinueError(state, "PolygonClipping will be used instead");
     458             :             state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
     459             :             state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
     460             : #else
     461           1 :             auto error_callback = [](const int messageType, const std::string &message, void *contextPtr) {
     462           0 :                 auto *state = (EnergyPlusData *)contextPtr;
     463           0 :                 if (messageType == Pumbra::MSG_ERR) {
     464           0 :                     ShowSevereError(*state, message);
     465           0 :                 } else if (messageType == Pumbra::MSG_WARN) {
     466           0 :                     ShowWarningError(*state, message);
     467             :                 } else { // if (messageType == MSG_INFO)
     468           0 :                     ShowMessage(*state, message);
     469             :                 }
     470           1 :             };
     471           1 :             if (Pumbra::Penumbra::isValidContext()) {
     472           1 :                 state.dataSolarShading->penumbra = std::make_unique<Pumbra::Penumbra>(error_callback, &state, pixelRes);
     473             :             } else {
     474           0 :                 ShowWarningError(state, "No GPU found (required for PixelCounting)");
     475           0 :                 ShowContinueError(state, "PolygonClipping will be used instead");
     476           0 :                 state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
     477           0 :                 state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
     478             :             }
     479             : #endif
     480             :         } else {
     481           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     482           0 :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", PolygonClipping will be used.");
     483             :         }
     484             :     } else {
     485         623 :         state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
     486         623 :         state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
     487             :     }
     488             : 
     489         772 :     if ((state.dataSysVars->shadingMethod == DataSystemVariables::ShadingMethod::PixelCounting) &&
     490           1 :         state.dataSolarShading->anyScheduledShadingSurface) {
     491           1 :         ShowSevereError(state, "The Shading Calculation Method of choice is \"PixelCounting\"; ");
     492           1 :         ShowContinueError(state, "and there is at least one shading surface of type ");
     493           1 :         ShowContinueError(state, "Shading:Site:Detailed, Shading:Building:Detailed, or Shading:Zone:Detailed, ");
     494           1 :         ShowContinueError(state, "that has an active transmittance schedule value greater than zero.");
     495           1 :         ShowContinueError(state, "With \"PixelCounting\" Shading Calculation Method, the shading surfaces will be treated as ");
     496           1 :         ShowContinueError(state, "completely opaque (transmittance = 0) during the shading calculation, ");
     497           1 :         ShowContinueError(state, "which may result in inaccurate or unexpected results.");
     498           1 :         ShowContinueError(state, "It is suggested switching to another Shading Calculation Method, such as \"PolygonClipping\".");
     499             :     }
     500             : 
     501         771 :     aNum++;
     502         771 :     if (NumAlphas >= aNum) {
     503         148 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Periodic")) {
     504         146 :             state.dataSysVars->DetailedSolarTimestepIntegration = false;
     505         146 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Periodic";
     506           2 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Timestep")) {
     507           2 :             state.dataSysVars->DetailedSolarTimestepIntegration = true;
     508           2 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Timestep";
     509             :         } else {
     510           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     511           0 :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", Periodic will be used.");
     512           0 :             state.dataSysVars->DetailedSolarTimestepIntegration = false;
     513           0 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Periodic";
     514             :         }
     515             :     } else {
     516         623 :         state.dataSysVars->DetailedSolarTimestepIntegration = false;
     517         623 :         state.dataIPShortCut->cAlphaArgs(aNum) = "Periodic";
     518             :     }
     519             : 
     520         771 :     aNum++;
     521         771 :     if (NumAlphas >= aNum) {
     522           7 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "SutherlandHodgman")) {
     523           7 :             state.dataSysVars->SutherlandHodgman = true;
     524           7 :             state.dataIPShortCut->cAlphaArgs(aNum) = "SutherlandHodgman";
     525           0 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "ConvexWeilerAtherton")) {
     526           0 :             state.dataSysVars->SutherlandHodgman = false;
     527           0 :             state.dataIPShortCut->cAlphaArgs(aNum) = "ConvexWeilerAtherton";
     528           0 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "SlaterBarskyandSutherlandHodgman")) {
     529           0 :             state.dataSysVars->SutherlandHodgman = true;
     530           0 :             state.dataSysVars->SlaterBarsky = true;
     531           0 :             state.dataIPShortCut->cAlphaArgs(aNum) = "SlaterBarskyandSutherlandHodgman";
     532           0 :         } else if (state.dataIPShortCut->lAlphaFieldBlanks(aNum)) {
     533           0 :             if (!state.dataSysVars->SutherlandHodgman) { // if already set.
     534           0 :                 state.dataIPShortCut->cAlphaArgs(aNum) = "ConvexWeilerAtherton";
     535             :             } else {
     536           0 :                 if (!state.dataSysVars->SlaterBarsky) {
     537           0 :                     state.dataIPShortCut->cAlphaArgs(aNum) = "SutherlandHodgman";
     538             :                 } else {
     539           0 :                     state.dataIPShortCut->cAlphaArgs(aNum) = "SlaterBarskyandSutherlandHodgman";
     540             :                 }
     541             :             }
     542             :         } else {
     543           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     544           0 :             if (!state.dataSysVars->SutherlandHodgman) {
     545           0 :                 ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", ConvexWeilerAtherton will be used.");
     546             :             } else {
     547           0 :                 if (!state.dataSysVars->SlaterBarsky) {
     548           0 :                     ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", SutherlandHodgman will be used.");
     549             :                 } else {
     550           0 :                     ShowContinueError(
     551           0 :                         state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", SlaterBarskyandSutherlandHodgman will be used.");
     552             :                 }
     553             :             }
     554             :         }
     555             :     } else {
     556         764 :         if (!state.dataSysVars->SutherlandHodgman) {
     557           0 :             state.dataIPShortCut->cAlphaArgs(aNum) = "ConvexWeilerAtherton";
     558             :         } else {
     559         764 :             if (!state.dataSysVars->SlaterBarsky) {
     560         764 :                 state.dataIPShortCut->cAlphaArgs(aNum) = "SutherlandHodgman";
     561             :             } else {
     562           0 :                 state.dataIPShortCut->cAlphaArgs(aNum) = "SlaterBarskyandSutherlandHodgman";
     563             :             }
     564             :         }
     565             :     }
     566             : 
     567         771 :     aNum++;
     568         771 :     if (NumAlphas >= aNum) {
     569           5 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "SimpleSkyDiffuseModeling")) {
     570           5 :             state.dataSysVars->DetailedSkyDiffuseAlgorithm = false;
     571           5 :             state.dataIPShortCut->cAlphaArgs(aNum) = "SimpleSkyDiffuseModeling";
     572           0 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "DetailedSkyDiffuseModeling")) {
     573           0 :             state.dataSysVars->DetailedSkyDiffuseAlgorithm = true;
     574           0 :             state.dataIPShortCut->cAlphaArgs(aNum) = "DetailedSkyDiffuseModeling";
     575           0 :         } else if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
     576           0 :             state.dataSysVars->DetailedSkyDiffuseAlgorithm = false;
     577           0 :             state.dataIPShortCut->cAlphaArgs(aNum) = "SimpleSkyDiffuseModeling";
     578             :         } else {
     579           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     580           0 :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", SimpleSkyDiffuseModeling will be used.");
     581             :         }
     582             :     } else {
     583         766 :         state.dataIPShortCut->cAlphaArgs(aNum) = "SimpleSkyDiffuseModeling";
     584         766 :         state.dataSysVars->DetailedSkyDiffuseAlgorithm = false;
     585             :     }
     586             : 
     587         771 :     aNum++;
     588         771 :     if (NumAlphas >= aNum) {
     589           5 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Yes")) {
     590           1 :             state.dataSysVars->ReportExtShadingSunlitFrac = true;
     591           1 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Yes";
     592           4 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "No")) {
     593           4 :             state.dataSysVars->ReportExtShadingSunlitFrac = false;
     594           4 :             state.dataIPShortCut->cAlphaArgs(aNum) = "No";
     595             :         } else {
     596           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     597           0 :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", InternalCalculation will be used.");
     598             :         }
     599             :     } else {
     600         766 :         state.dataIPShortCut->cAlphaArgs(aNum) = "No";
     601         766 :         state.dataSysVars->ReportExtShadingSunlitFrac = false;
     602             :     }
     603         771 :     if (state.dataSysVars->shadingMethod == ShadingMethod::Imported) {
     604             :         int ExtShadingSchedNum;
     605         114 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     606         113 :             ExtShadingSchedNum = ScheduleManager::GetScheduleIndex(state, state.dataSurface->Surface(SurfNum).Name + "_shading");
     607         113 :             if (ExtShadingSchedNum != 0) {
     608         113 :                 state.dataSurface->Surface(SurfNum).SurfSchedExternalShadingFrac = true;
     609         113 :                 state.dataSurface->Surface(SurfNum).SurfExternalShadingSchInd = ExtShadingSchedNum;
     610             :             } else {
     611           0 :                 ShowWarningError(state,
     612           0 :                                  cCurrentModuleObject + ": sunlit fraction schedule not found for " + state.dataSurface->Surface(SurfNum).Name +
     613             :                                      " when using ImportedShading.");
     614           0 :                 ShowContinueError(state, "These values are set to 1.0.");
     615             :             }
     616             :         }
     617             :     }
     618             : 
     619         771 :     bool DisableSelfShadingWithinGroup = false;
     620         771 :     bool DisableSelfShadingBetweenGroup = false;
     621             : 
     622         771 :     aNum++;
     623         771 :     if (NumAlphas >= aNum) {
     624           3 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Yes")) {
     625           2 :             DisableSelfShadingWithinGroup = true;
     626           2 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Yes";
     627           1 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "No")) {
     628           1 :             state.dataIPShortCut->cAlphaArgs(aNum) = "No";
     629             :         } else {
     630           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     631           0 :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", all shading effects would be considered.");
     632             :         }
     633             :     } else {
     634         768 :         state.dataIPShortCut->cAlphaArgs(aNum) = "No";
     635             :     }
     636             : 
     637         771 :     aNum++;
     638         771 :     if (NumAlphas >= aNum) {
     639           3 :         if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Yes")) {
     640           1 :             DisableSelfShadingBetweenGroup = true;
     641           1 :             state.dataIPShortCut->cAlphaArgs(aNum) = "Yes";
     642           2 :         } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "No")) {
     643           2 :             state.dataIPShortCut->cAlphaArgs(aNum) = "No";
     644             :         } else {
     645           0 :             ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
     646           0 :             ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", all shading effects would be considered.");
     647             :         }
     648             :     } else {
     649         768 :         state.dataIPShortCut->cAlphaArgs(aNum) = "No";
     650             :     }
     651             : 
     652         771 :     if (DisableSelfShadingBetweenGroup && DisableSelfShadingWithinGroup) {
     653           1 :         state.dataSysVars->DisableAllSelfShading = true;
     654         770 :     } else if (DisableSelfShadingBetweenGroup || DisableSelfShadingWithinGroup) {
     655           1 :         state.dataSysVars->DisableGroupSelfShading = true;
     656             :     }
     657             : 
     658         771 :     aNum++;
     659             :     int SurfZoneGroup, CurZoneGroup;
     660         771 :     if (state.dataSysVars->DisableGroupSelfShading) {
     661           2 :         Array1D_int DisableSelfShadingGroups;
     662             :         int NumOfShadingGroups;
     663           1 :         if (NumAlphas >= aNum) {
     664             :             // Read all shading groups
     665           1 :             NumOfShadingGroups = NumAlphas - (aNum - 1);
     666           1 :             DisableSelfShadingGroups.allocate(NumOfShadingGroups);
     667           2 :             for (int i = 1; i <= NumOfShadingGroups; i++) {
     668           3 :                 Found = UtilityRoutines::FindItemInList(
     669           3 :                     state.dataIPShortCut->cAlphaArgs(i + (aNum - 1)), state.dataHeatBal->ZoneList, state.dataHeatBal->NumOfZoneLists);
     670           1 :                 if (Found != 0) DisableSelfShadingGroups(i) = Found;
     671             :             }
     672             : 
     673         114 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
     674         113 :                 if (state.dataSurface->Surface(SurfNum).ExtBoundCond == 0) { // Loop through all exterior surfaces
     675          89 :                     SurfZoneGroup = 0;
     676             :                     // Check the shading zone group of each exterior surface
     677         178 :                     for (int ZoneGroupLoop = 1; ZoneGroupLoop <= NumOfShadingGroups; ZoneGroupLoop++) { // Loop through all defined shading groups
     678          89 :                         CurZoneGroup = DisableSelfShadingGroups(ZoneGroupLoop);
     679         425 :                         for (int ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(CurZoneGroup).NumOfZones;
     680             :                              ZoneNum++) { // Loop through all zones in the zone list
     681         375 :                             if (state.dataSurface->Surface(SurfNum).Zone == state.dataHeatBal->ZoneList(CurZoneGroup).Zone(ZoneNum)) {
     682          39 :                                 SurfZoneGroup = CurZoneGroup;
     683          39 :                                 break;
     684             :                             }
     685             :                         }
     686             :                     }
     687             :                     // if a surface is not in any zone group, no self shading is disabled for this surface
     688          89 :                     if (SurfZoneGroup != 0) {
     689             :                         // if DisableSelfShadingWithinGroup, add all zones in the same zone group to the surface's disabled zone list
     690             :                         // if DisableSelfShadingBetweenGroups, add all zones in all other zone groups to the surface's disabled zone list
     691          78 :                         for (int ZoneGroupLoop = 1; ZoneGroupLoop <= NumOfShadingGroups; ZoneGroupLoop++) { // Loop through all defined shading groups
     692          39 :                             CurZoneGroup = DisableSelfShadingGroups(ZoneGroupLoop);
     693          39 :                             if (SurfZoneGroup == CurZoneGroup && DisableSelfShadingWithinGroup) {
     694         234 :                                 for (int ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(CurZoneGroup).NumOfZones;
     695             :                                      ZoneNum++) { // Loop through all zones in the zone list
     696         390 :                                     state.dataSurface->SurfShadowDisabledZoneList(SurfNum).push_back(
     697         195 :                                         state.dataHeatBal->ZoneList(CurZoneGroup).Zone(ZoneNum));
     698          39 :                                 }
     699           0 :                             } else if (SurfZoneGroup != CurZoneGroup && DisableSelfShadingBetweenGroup) {
     700           0 :                                 for (int ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(CurZoneGroup).NumOfZones; ZoneNum++) {
     701           0 :                                     state.dataSurface->SurfShadowDisabledZoneList(SurfNum).push_back(
     702           0 :                                         state.dataHeatBal->ZoneList(CurZoneGroup).Zone(ZoneNum));
     703             :                                 }
     704             :                             }
     705             :                         }
     706             :                     }
     707             :                 }
     708             :             }
     709             :         } else {
     710           0 :             ShowFatalError(state, "No Shading groups are defined when disabling grouped self shading.");
     711             :         }
     712             :     }
     713             : 
     714         771 :     if (!state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
     715           0 :         state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) {
     716             : 
     717           0 :         ShowWarningError(state,
     718             :                          "GetShadowingInput: The shading transmittance for shading devices changes throughout the year. Choose "
     719           0 :                          "DetailedSkyDiffuseModeling in the " +
     720           0 :                              cCurrentModuleObject + " object to remove this warning.");
     721           0 :         ShowContinueError(state, "Simulation has been reset to use DetailedSkyDiffuseModeling. Simulation continues.");
     722           0 :         state.dataSysVars->DetailedSkyDiffuseAlgorithm = true;
     723           0 :         state.dataIPShortCut->cAlphaArgs(2) = "DetailedSkyDiffuseModeling";
     724           0 :         if (state.dataSolarShading->ShadowingCalcFrequency > 1) {
     725           0 :             ShowContinueError(state,
     726           0 :                               "Better accuracy may be gained by setting the " + state.dataIPShortCut->cNumericFieldNames(1) + " to 1 in the " +
     727           0 :                                   cCurrentModuleObject + " object.");
     728             :         }
     729         771 :     } else if (state.dataSysVars->DetailedSkyDiffuseAlgorithm) {
     730           0 :         if (!state.dataSurface->ShadingTransmittanceVaries || state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
     731           0 :             ShowWarningError(state,
     732             :                              "GetShadowingInput: DetailedSkyDiffuseModeling is chosen but not needed as either the shading transmittance for "
     733             :                              "shading devices does not change throughout the year");
     734           0 :             ShowContinueError(state, " or MinimalShadowing has been chosen.");
     735           0 :             ShowContinueError(state, "Simulation should be set to use SimpleSkyDiffuseModeling, but is left at Detailed for simulation.");
     736           0 :             ShowContinueError(state, "Choose SimpleSkyDiffuseModeling in the " + cCurrentModuleObject + " object to reduce computation time.");
     737             :         }
     738             :     }
     739             : 
     740         771 :     print(state.files.eio,
     741             :           "{}",
     742             :           "! <Shadowing/Sun Position Calculations Annual Simulations>, Shading Calculation Method, "
     743             :           "Shading Calculation Update Frequency Method, Shading Calculation Update Frequency {days}, "
     744             :           "Maximum Figures in Shadow Overlap Calculations {}, Polygon Clipping Algorithm, Pixel Counting Resolution, Sky Diffuse Modeling "
     745             :           "Algorithm, Output External Shading Calculation Results, Disable "
     746         771 :           "Self-Shading Within Shading Zone Groups, Disable Self-Shading From Shading Zone Groups to Other Zones\n");
     747        7710 :     print(state.files.eio,
     748             :           "Shadowing/Sun Position Calculations Annual Simulations,{},{},{},{},{},{},{},{},{},{}\n",
     749         771 :           state.dataIPShortCut->cAlphaArgs(1),
     750         771 :           state.dataIPShortCut->cAlphaArgs(2),
     751         771 :           state.dataSolarShading->ShadowingCalcFrequency,
     752         771 :           state.dataSolarShading->MaxHCS,
     753         771 :           state.dataIPShortCut->cAlphaArgs(3),
     754             :           pixelRes,
     755         771 :           state.dataIPShortCut->cAlphaArgs(4),
     756         771 :           state.dataIPShortCut->cAlphaArgs(5),
     757         771 :           state.dataIPShortCut->cAlphaArgs(6),
     758        1542 :           state.dataIPShortCut->cAlphaArgs(7));
     759         771 : }
     760             : 
     761         771 : void AllocateModuleArrays(EnergyPlusData &state)
     762             : {
     763             : 
     764             :     // SUBROUTINE INFORMATION:
     765             :     //       AUTHOR         Rick Strand
     766             :     //       DATE WRITTEN   February 1998
     767             :     //       MODIFIED       August 2005 JG - Added output variables for energy in J
     768             : 
     769             :     // PURPOSE OF THIS SUBROUTINE:
     770             :     // This routine allocates all of the arrays at the module level which
     771             :     // require allocation.
     772             : 
     773             :     // METHODOLOGY EMPLOYED:
     774             :     // Allocation is dependent on the user input file.
     775             : 
     776             :     int SurfLoop;
     777             :     int I;
     778             :     int NumOfLayers;
     779         771 :     int constexpr HoursInDay(24);
     780             : 
     781         771 :     state.dataSolarShading->SurfSunCosTheta.dimension(state.dataSurface->TotSurfaces, 0.0);
     782         771 :     state.dataSolarShading->SurfSunlitArea.dimension(state.dataSurface->TotSurfaces, 0.0);
     783         771 :     if (!state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() || !state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
     784         769 :         state.dataSolarShading->SurfWinIntBeamAbsByShadFac.allocate(state.dataSurface->TotSurfaces);
     785         769 :         state.dataSolarShading->SurfWinExtBeamAbsByShadFac.allocate(state.dataSurface->TotSurfaces);
     786         769 :         state.dataSolarShading->SurfWinTransBmSolar.allocate(state.dataSurface->TotSurfaces);
     787         769 :         state.dataSolarShading->SurfWinTransDifSolar.allocate(state.dataSurface->TotSurfaces);
     788         769 :         state.dataSolarShading->SurfWinTransDifSolarGnd.allocate(state.dataSurface->TotSurfaces);
     789         769 :         state.dataSolarShading->SurfWinTransDifSolarSky.allocate(state.dataSurface->TotSurfaces);
     790         769 :         state.dataSolarShading->SurfWinTransBmBmSolar.allocate(state.dataSurface->TotSurfaces);
     791         769 :         state.dataSolarShading->SurfWinTransBmDifSolar.allocate(state.dataSurface->TotSurfaces);
     792             :     }
     793         771 :     state.dataSolarShading->SurfAnisoSkyMult.dimension(state.dataSurface->TotSurfaces, 1.0);
     794         771 :     state.dataSolarShading->SurfIntAbsFac.dimension(state.dataSurface->TotSurfaces, 0.0);
     795             :     // For isotropic sky: recalculated in AnisoSkyViewFactors if anisotropic radiance
     796             :     //  ALLOCATE(WithShdgIsoSky(TotSurfaces))
     797             :     //  WithShdgIsoSky=0.0
     798             :     //  ALLOCATE(WoShdgIsoSky(TotSurfaces))
     799             :     //  WoShdgIsoSky=0.0
     800             :     //  ALLOCATE(WithShdgHoriz(TotSurfaces))
     801             :     //  WithShdgHoriz=0.0
     802             :     //  ALLOCATE(WoShdgHoriz(TotSurfaces))
     803             :     //  WoShdgHoriz=0.0
     804             :     //  ALLOCATE(DifShdgRatioIsoSky(TotSurfaces))
     805             :     //  DifShdgRatioIsoSky=0.0
     806             :     //  ALLOCATE(DifShdgRatioHoriz(TotSurfaces))
     807             :     //  DifShdgRatioHoriz=0.0
     808         771 :     state.dataSolarShading->SurfMultIsoSky.dimension(state.dataSurface->TotSurfaces, 0.0);
     809         771 :     state.dataSolarShading->SurfMultCircumSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     810         771 :     state.dataSolarShading->SurfMultHorizonZenith.dimension(state.dataSurface->TotSurfaces, 0.0);
     811         771 :     state.dataSolarShading->SurfWinRevealStatus.dimension(24, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0);
     812             : 
     813             :     // Weiler-Atherton
     814         771 :     state.dataSolarShading->MAXHCArrayBounds = 2 * (state.dataSurface->MaxVerticesPerSurface + 1);
     815         771 :     state.dataSolarShading->MAXHCArrayIncrement = state.dataSurface->MaxVerticesPerSurface + 1;
     816         771 :     state.dataSolarShading->XTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     817         771 :     state.dataSolarShading->YTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     818         771 :     state.dataSolarShading->XVC.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
     819         771 :     state.dataSolarShading->XVS.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
     820         771 :     state.dataSolarShading->YVC.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
     821         771 :     state.dataSolarShading->YVS.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
     822         771 :     state.dataSolarShading->ZVC.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
     823             : 
     824             :     // Sutherland-Hodgman
     825         771 :     state.dataSolarShading->ATEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     826         771 :     state.dataSolarShading->BTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     827         771 :     state.dataSolarShading->CTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     828         771 :     state.dataSolarShading->XTEMP1.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     829         771 :     state.dataSolarShading->YTEMP1.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
     830             : 
     831         771 :     state.dataSurface->SurfSunCosHourly.allocate(HoursInDay);
     832       19275 :     for (int hour = 1; hour <= HoursInDay; hour++) {
     833       18504 :         state.dataSurface->SurfSunCosHourly(hour) = 0.0;
     834             :     }
     835         771 :     state.dataSurface->SurfSunlitArea.dimension(state.dataSurface->TotSurfaces, 0.0);
     836         771 :     state.dataSurface->SurfSunlitFrac.dimension(state.dataSurface->TotSurfaces, 0.0);
     837         771 :     state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
     838         771 :     state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
     839         771 :     state.dataSurface->SurfBmToBmReflFacObs.dimension(state.dataSurface->TotSurfaces, 0.0);
     840         771 :     state.dataSurface->SurfBmToDiffReflFacObs.dimension(state.dataSurface->TotSurfaces, 0.0);
     841         771 :     state.dataSurface->SurfBmToDiffReflFacGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
     842         771 :     state.dataSurface->SurfSkyDiffReflFacGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
     843         771 :     state.dataSurface->SurfOpaqAI.dimension(state.dataSurface->TotSurfaces, 0.0);
     844         771 :     state.dataSurface->SurfOpaqAO.dimension(state.dataSurface->TotSurfaces, 0.0);
     845         771 :     state.dataSurface->SurfWinTransSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     846         771 :     state.dataSurface->SurfWinBmSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     847         771 :     state.dataSurface->SurfWinBmBmSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     848         771 :     state.dataSurface->SurfWinBmDifSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     849         771 :     state.dataSurface->SurfWinDifSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     850         771 :     state.dataSurface->SurfWinHeatGain.dimension(state.dataSurface->TotSurfaces, 0.0);
     851         771 :     state.dataSurface->SurfWinHeatGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     852         771 :     state.dataSurface->SurfWinHeatLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     853         771 :     state.dataSurface->SurfWinGainConvGlazToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     854         771 :     state.dataSurface->SurfWinGainIRGlazToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     855         771 :     state.dataSurface->SurfWinLossSWZoneToOutWinRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     856         771 :     state.dataSurface->SurfWinGainFrameDividerToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     857         771 :     state.dataSurface->SurfWinGainConvShadeToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     858         771 :     state.dataSurface->SurfWinGainIRShadeToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     859         771 :     state.dataSurface->SurfWinGapConvHtFlowRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     860         771 :     state.dataSurface->SurfWinShadingAbsorbedSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
     861         771 :     state.dataSurface->SurfWinSysSolTransmittance.dimension(state.dataSurface->TotSurfaces, 0.0);
     862         771 :     state.dataSurface->SurfWinSysSolReflectance.dimension(state.dataSurface->TotSurfaces, 0.0);
     863         771 :     state.dataSurface->SurfWinSysSolAbsorptance.dimension(state.dataSurface->TotSurfaces, 0.0);
     864         771 :     state.dataSurface->SurfWinInsideGlassCondensationFlag.dimension(state.dataSurface->TotSurfaces, 0);
     865         771 :     state.dataSurface->SurfWinInsideFrameCondensationFlag.dimension(state.dataSurface->TotSurfaces, 0);
     866         771 :     state.dataSurface->SurfWinInsideDividerCondensationFlag.dimension(state.dataSurface->TotSurfaces, 0);
     867             : 
     868         771 :     state.dataHeatBal->SurfSunlitFracHR.dimension(HoursInDay, state.dataSurface->TotSurfaces, 0.0);
     869         771 :     state.dataHeatBal->SurfSunlitFrac.dimension(HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0.0);
     870         771 :     state.dataHeatBal->SurfSunlitFracWithoutReveal.dimension(HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0.0);
     871        1542 :     state.dataHeatBal->SurfWinBackSurfaces.dimension(
     872        1542 :         HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataBSDFWindow->MaxBkSurf, state.dataSurface->TotSurfaces, 0);
     873        1542 :     state.dataHeatBal->SurfWinOverlapAreas.dimension(
     874        1542 :         HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataBSDFWindow->MaxBkSurf, state.dataSurface->TotSurfaces, 0.0);
     875         771 :     state.dataHeatBal->SurfCosIncAngHR.dimension(HoursInDay, state.dataSurface->TotSurfaces, 0.0);
     876         771 :     state.dataHeatBal->SurfCosIncAng.dimension(HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0.0);
     877             : 
     878         771 :     state.dataHeatBal->ZoneTransSolar.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     879         771 :     state.dataHeatBal->ZoneBmSolFrExtWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     880         771 :     state.dataHeatBal->ZoneBmSolFrIntWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     881         771 :     state.dataHeatBal->EnclSolInitialDifSolReflW.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     882         771 :     state.dataHeatBal->ZoneDifSolFrExtWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     883         771 :     state.dataHeatBal->ZoneDifSolFrIntWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     884         771 :     state.dataHeatBal->ZoneWinHeatGain.dimension(state.dataGlobal->NumOfZones, 0.0);
     885         771 :     state.dataHeatBal->ZoneWinHeatGainRep.dimension(state.dataGlobal->NumOfZones, 0.0);
     886         771 :     state.dataHeatBal->ZoneWinHeatLossRep.dimension(state.dataGlobal->NumOfZones, 0.0);
     887         771 :     state.dataHeatBal->ZoneOpaqSurfInsFaceCond.dimension(state.dataGlobal->NumOfZones, 0.0);
     888         771 :     state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep.dimension(state.dataGlobal->NumOfZones, 0.0);
     889         771 :     state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep.dimension(state.dataGlobal->NumOfZones, 0.0);
     890         771 :     state.dataHeatBal->ZoneOpaqSurfExtFaceCond.dimension(state.dataGlobal->NumOfZones, 0.0);
     891         771 :     state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep.dimension(state.dataGlobal->NumOfZones, 0.0);
     892         771 :     state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep.dimension(state.dataGlobal->NumOfZones, 0.0);
     893             : 
     894         771 :     state.dataHeatBal->SurfQRadSWOutIncident.dimension(state.dataSurface->TotSurfaces, 0.0);
     895         771 :     state.dataHeatBal->SurfQRadSWOutIncidentBeam.dimension(state.dataSurface->TotSurfaces, 0.0);
     896         771 :     state.dataHeatBal->SurfBmIncInsSurfIntensRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     897         771 :     state.dataHeatBal->SurfBmIncInsSurfAmountRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     898             :     //  ALLOCATE(DifIncInsSurfIntensRep(TotSurfaces))
     899             :     //  DifIncInsSurfIntensRep=0.0
     900             :     //  ALLOCATE(DifIncInsSurfAmountRep(TotSurfaces))
     901             :     //  DifIncInsSurfAmountRep=0.0
     902         771 :     state.dataHeatBal->SurfIntBmIncInsSurfIntensRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     903         771 :     state.dataHeatBal->SurfIntBmIncInsSurfAmountRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     904             :     //  ALLOCATE(IntDifIncInsSurfIntensRep(TotSurfaces))
     905             :     //  IntDifIncInsSurfIntensRep=0.0
     906             :     //  ALLOCATE(IntDifIncInsSurfAmountRep(TotSurfaces))
     907             :     //  IntDifIncInsSurfAmountRep=0.0
     908         771 :     state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse.dimension(state.dataSurface->TotSurfaces, 0.0);
     909         771 :     state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse.dimension(state.dataSurface->TotSurfaces, 0.0);
     910         771 :     state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
     911         771 :     state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
     912         771 :     state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs.dimension(state.dataSurface->TotSurfaces, 0.0);
     913         771 :     state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs.dimension(state.dataSurface->TotSurfaces, 0.0);
     914         771 :     state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs.dimension(state.dataSurface->TotSurfaces, 0.0);
     915         771 :     state.dataHeatBal->SurfCosIncidenceAngle.dimension(state.dataSurface->TotSurfaces, 0.0);
     916             : 
     917         771 :     state.dataHeatBal->SurfWinBSDFBeamDirectionRep.dimension(state.dataSurface->TotSurfaces, 0);
     918         771 :     state.dataHeatBal->SurfWinBSDFBeamThetaRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     919         771 :     state.dataHeatBal->SurfWinBSDFBeamPhiRep.dimension(state.dataSurface->TotSurfaces, 0.0);
     920         771 :     state.dataHeatBal->SurfWinQRadSWwinAbsTot.dimension(state.dataSurface->TotSurfaces, 0.0);
     921         771 :     state.dataHeatBal->SurfWinQRadSWwinAbsLayer.dimension(state.dataSurface->TotSurfaces, state.dataHeatBal->MaxSolidWinLayers, 0.0);
     922         771 :     state.dataHeatBal->SurfWinFenLaySurfTempFront.dimension(state.dataSurface->TotSurfaces, state.dataHeatBal->MaxSolidWinLayers, 0.0);
     923         771 :     state.dataHeatBal->SurfWinFenLaySurfTempBack.dimension(state.dataSurface->TotSurfaces, state.dataHeatBal->MaxSolidWinLayers, 0.0);
     924             : 
     925         771 :     state.dataHeatBal->SurfWinSWwinAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
     926         771 :     state.dataHeatBal->SurfInitialDifSolInAbsReport.dimension(state.dataSurface->TotSurfaces, 0.0);
     927         771 :     state.dataHeatBal->SurfWinInitialDifSolInTransReport.dimension(state.dataSurface->TotSurfaces, 0.0);
     928         771 :     state.dataHeatBal->SurfSWInAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
     929             : 
     930             :     // energy
     931         771 :     state.dataSurface->SurfWinTransSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     932         771 :     state.dataSurface->SurfWinBmSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     933         771 :     state.dataSurface->SurfWinBmBmSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     934         771 :     state.dataSurface->SurfWinBmDifSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     935             : 
     936         771 :     state.dataSurface->SurfWinDifSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     937         771 :     state.dataSurface->SurfWinHeatGainRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     938         771 :     state.dataSurface->SurfWinHeatLossRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     939         771 :     state.dataSurface->SurfWinGapConvHtFlowRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     940         771 :     state.dataSurface->SurfWinHeatTransferRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     941         771 :     state.dataSurface->SurfWinShadingAbsorbedSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     942             : 
     943         771 :     state.dataHeatBal->ZoneTransSolarEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     944         771 :     state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     945         771 :     state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     946         771 :     state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     947         771 :     state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
     948         771 :     state.dataHeatBal->ZoneWinHeatGainRepEnergy.dimension(state.dataGlobal->NumOfZones, 0.0);
     949         771 :     state.dataHeatBal->ZoneWinHeatLossRepEnergy.dimension(state.dataGlobal->NumOfZones, 0.0);
     950             : 
     951         771 :     state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
     952         771 :     state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
     953         771 :     state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
     954         771 :     state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
     955             :     //  ALLOCATE(DifIncInsSurfAmountRepEnergy(TotSurfaces))
     956             :     //  DifIncInsSurfAmountRepEnergy=0.0
     957         771 :     state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     958         771 :     state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     959             :     //  ALLOCATE(IntDifIncInsSurfAmountRepEnergy(TotSurfaces))
     960             :     //  IntDifIncInsSurfAmountRepEnergy=0.0
     961         771 :     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
     962             : 
     963       44533 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
     964       43762 :         state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
     965       43762 :         state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
     966       43762 :         state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
     967       43762 :         state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
     968       43762 :         state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
     969       43762 :         state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
     970       43762 :         state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
     971       43762 :         state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
     972       43762 :         state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
     973       43762 :         state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
     974             :     }
     975             : 
     976             :     // Added report variables for inside reveal to debug CR 7596. TH 5/26/2009
     977       44533 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
     978       43762 :         state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
     979       43762 :         state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
     980       43762 :         state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
     981       43762 :         state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
     982             :     }
     983             : 
     984         771 :     DisplayString(state, "Initializing Zone and Enclosure Report Variables");
     985        5582 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
     986        4811 :         auto &thisEnclosureName = state.dataViewFactor->EnclSolInfo(enclosureNum).Name;
     987        9622 :         SetupOutputVariable(state,
     988             :                             "Zone Windows Total Transmitted Solar Radiation Rate",
     989             :                             OutputProcessor::Unit::W,
     990        4811 :                             state.dataHeatBal->ZoneTransSolar(enclosureNum),
     991             :                             OutputProcessor::SOVTimeStepType::Zone,
     992             :                             OutputProcessor::SOVStoreType::Average,
     993        4811 :                             thisEnclosureName);
     994        9622 :         SetupOutputVariable(state,
     995             :                             "Zone Exterior Windows Total Transmitted Beam Solar Radiation Rate",
     996             :                             OutputProcessor::Unit::W,
     997        4811 :                             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum),
     998             :                             OutputProcessor::SOVTimeStepType::Zone,
     999             :                             OutputProcessor::SOVStoreType::Average,
    1000        4811 :                             thisEnclosureName);
    1001        9622 :         SetupOutputVariable(state,
    1002             :                             "Zone Interior Windows Total Transmitted Beam Solar Radiation Rate",
    1003             :                             OutputProcessor::Unit::W,
    1004        4811 :                             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum),
    1005             :                             OutputProcessor::SOVTimeStepType::Zone,
    1006             :                             OutputProcessor::SOVStoreType::Average,
    1007        4811 :                             thisEnclosureName);
    1008        9622 :         SetupOutputVariable(state,
    1009             :                             "Zone Exterior Windows Total Transmitted Diffuse Solar Radiation Rate",
    1010             :                             OutputProcessor::Unit::W,
    1011        4811 :                             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum),
    1012             :                             OutputProcessor::SOVTimeStepType::Zone,
    1013             :                             OutputProcessor::SOVStoreType::Average,
    1014        4811 :                             thisEnclosureName);
    1015        9622 :         SetupOutputVariable(state,
    1016             :                             "Zone Interior Windows Total Transmitted Diffuse Solar Radiation Rate",
    1017             :                             OutputProcessor::Unit::W,
    1018        4811 :                             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum),
    1019             :                             OutputProcessor::SOVTimeStepType::Zone,
    1020             :                             OutputProcessor::SOVStoreType::Average,
    1021        4811 :                             thisEnclosureName);
    1022             :         // Energy variables
    1023        9622 :         SetupOutputVariable(state,
    1024             :                             "Zone Windows Total Transmitted Solar Radiation Energy",
    1025             :                             OutputProcessor::Unit::J,
    1026        4811 :                             state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum),
    1027             :                             OutputProcessor::SOVTimeStepType::Zone,
    1028             :                             OutputProcessor::SOVStoreType::Summed,
    1029        4811 :                             thisEnclosureName);
    1030        9622 :         SetupOutputVariable(state,
    1031             :                             "Zone Exterior Windows Total Transmitted Beam Solar Radiation Energy",
    1032             :                             OutputProcessor::Unit::J,
    1033        4811 :                             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum),
    1034             :                             OutputProcessor::SOVTimeStepType::Zone,
    1035             :                             OutputProcessor::SOVStoreType::Summed,
    1036        4811 :                             thisEnclosureName);
    1037        9622 :         SetupOutputVariable(state,
    1038             :                             "Zone Interior Windows Total Transmitted Beam Solar Radiation Energy",
    1039             :                             OutputProcessor::Unit::J,
    1040        4811 :                             state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclosureNum),
    1041             :                             OutputProcessor::SOVTimeStepType::Zone,
    1042             :                             OutputProcessor::SOVStoreType::Summed,
    1043        4811 :                             thisEnclosureName);
    1044        9622 :         SetupOutputVariable(state,
    1045             :                             "Zone Exterior Windows Total Transmitted Diffuse Solar Radiation Energy",
    1046             :                             OutputProcessor::Unit::J,
    1047        4811 :                             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum),
    1048             :                             OutputProcessor::SOVTimeStepType::Zone,
    1049             :                             OutputProcessor::SOVStoreType::Summed,
    1050        4811 :                             thisEnclosureName);
    1051        9622 :         SetupOutputVariable(state,
    1052             :                             "Zone Interior Windows Total Transmitted Diffuse Solar Radiation Energy",
    1053             :                             OutputProcessor::Unit::J,
    1054        4811 :                             state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum),
    1055             :                             OutputProcessor::SOVTimeStepType::Zone,
    1056             :                             OutputProcessor::SOVStoreType::Summed,
    1057        4811 :                             thisEnclosureName);
    1058             :     }
    1059        5585 :     for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) {
    1060       14442 :         SetupOutputVariable(state,
    1061             :                             "Zone Windows Total Heat Gain Rate",
    1062             :                             OutputProcessor::Unit::W,
    1063        4814 :                             state.dataHeatBal->ZoneWinHeatGainRep(ZoneLoop),
    1064             :                             OutputProcessor::SOVTimeStepType::Zone,
    1065             :                             OutputProcessor::SOVStoreType::Average,
    1066        9628 :                             state.dataHeatBal->Zone(ZoneLoop).Name);
    1067       14442 :         SetupOutputVariable(state,
    1068             :                             "Zone Windows Total Heat Loss Rate",
    1069             :                             OutputProcessor::Unit::W,
    1070        4814 :                             state.dataHeatBal->ZoneWinHeatLossRep(ZoneLoop),
    1071             :                             OutputProcessor::SOVTimeStepType::Zone,
    1072             :                             OutputProcessor::SOVStoreType::Average,
    1073        9628 :                             state.dataHeatBal->Zone(ZoneLoop).Name);
    1074       14442 :         SetupOutputVariable(state,
    1075             :                             "Zone Windows Total Heat Gain Energy",
    1076             :                             OutputProcessor::Unit::J,
    1077        4814 :                             state.dataHeatBal->ZoneWinHeatGainRepEnergy(ZoneLoop),
    1078             :                             OutputProcessor::SOVTimeStepType::Zone,
    1079             :                             OutputProcessor::SOVStoreType::Summed,
    1080        9628 :                             state.dataHeatBal->Zone(ZoneLoop).Name);
    1081       14442 :         SetupOutputVariable(state,
    1082             :                             "Zone Windows Total Heat Loss Energy",
    1083             :                             OutputProcessor::Unit::J,
    1084        4814 :                             state.dataHeatBal->ZoneWinHeatLossRepEnergy(ZoneLoop),
    1085             :                             OutputProcessor::SOVTimeStepType::Zone,
    1086             :                             OutputProcessor::SOVStoreType::Summed,
    1087        9628 :                             state.dataHeatBal->Zone(ZoneLoop).Name);
    1088        4814 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    1089             :             // CurrentModuleObject='Zone(Advanced)'
    1090         171 :             SetupOutputVariable(state,
    1091             :                                 "Zone Opaque Surface Inside Faces Total Conduction Heat Gain Rate",
    1092             :                                 OutputProcessor::Unit::W,
    1093          57 :                                 state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(ZoneLoop),
    1094             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1095             :                                 OutputProcessor::SOVStoreType::Average,
    1096         114 :                                 state.dataHeatBal->Zone(ZoneLoop).Name);
    1097         171 :             SetupOutputVariable(state,
    1098             :                                 "Zone Opaque Surface Inside Faces Total Conduction Heat Loss Rate",
    1099             :                                 OutputProcessor::Unit::W,
    1100          57 :                                 state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(ZoneLoop),
    1101             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1102             :                                 OutputProcessor::SOVStoreType::Average,
    1103         114 :                                 state.dataHeatBal->Zone(ZoneLoop).Name);
    1104             :             // Energy variables
    1105         171 :             SetupOutputVariable(state,
    1106             :                                 "Zone Opaque Surface Inside Faces Total Conduction Heat Gain Energy",
    1107             :                                 OutputProcessor::Unit::J,
    1108          57 :                                 state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(ZoneLoop),
    1109             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1110             :                                 OutputProcessor::SOVStoreType::Summed,
    1111         114 :                                 state.dataHeatBal->Zone(ZoneLoop).Name);
    1112         171 :             SetupOutputVariable(state,
    1113             :                                 "Zone Opaque Surface Inside Faces Total Conduction Heat Loss Energy",
    1114             :                                 OutputProcessor::Unit::J,
    1115          57 :                                 state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(ZoneLoop),
    1116             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1117             :                                 OutputProcessor::SOVStoreType::Summed,
    1118         114 :                                 state.dataHeatBal->Zone(ZoneLoop).Name);
    1119             :         }
    1120             :     }
    1121             : 
    1122         771 :     DisplayString(state, "Initializing Surface (Shading) Report Variables");
    1123             :     // CurrentModuleObject='Surfaces'
    1124       44533 :     for (SurfLoop = 1; SurfLoop <= state.dataSurface->TotSurfaces; ++SurfLoop) {
    1125      175048 :         SetupOutputVariable(state,
    1126             :                             "Surface Outside Normal Azimuth Angle",
    1127             :                             OutputProcessor::Unit::deg,
    1128       43762 :                             state.dataSurface->Surface(SurfLoop).Azimuth,
    1129             :                             OutputProcessor::SOVTimeStepType::Zone,
    1130             :                             OutputProcessor::SOVStoreType::Average,
    1131       87524 :                             state.dataSurface->Surface(SurfLoop).Name);
    1132       43762 :         if (state.dataSurface->Surface(SurfLoop).ExtSolar) {
    1133       55143 :             SetupOutputVariable(state,
    1134             :                                 "Surface Outside Face Sunlit Area",
    1135             :                                 OutputProcessor::Unit::m2,
    1136       18381 :                                 state.dataSurface->SurfSunlitArea(SurfLoop),
    1137             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1138             :                                 OutputProcessor::SOVStoreType::State,
    1139       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1140       55143 :             SetupOutputVariable(state,
    1141             :                                 "Surface Outside Face Sunlit Fraction",
    1142             :                                 OutputProcessor::Unit::None,
    1143       18381 :                                 state.dataSurface->SurfSunlitFrac(SurfLoop),
    1144             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1145             :                                 OutputProcessor::SOVStoreType::State,
    1146       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1147       55143 :             SetupOutputVariable(state,
    1148             :                                 "Surface Outside Face Incident Solar Radiation Rate per Area",
    1149             :                                 OutputProcessor::Unit::W_m2,
    1150       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncident(SurfLoop),
    1151             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1152             :                                 OutputProcessor::SOVStoreType::Average,
    1153       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1154       55143 :             SetupOutputVariable(state,
    1155             :                                 "Surface Outside Face Incident Beam Solar Radiation Rate per Area",
    1156             :                                 OutputProcessor::Unit::W_m2,
    1157       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfLoop),
    1158             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1159             :                                 OutputProcessor::SOVStoreType::Average,
    1160       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1161       55143 :             SetupOutputVariable(state,
    1162             :                                 "Surface Outside Face Incident Sky Diffuse Solar Radiation Rate per Area",
    1163             :                                 OutputProcessor::Unit::W_m2,
    1164       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfLoop),
    1165             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1166             :                                 OutputProcessor::SOVStoreType::Average,
    1167       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1168       55143 :             SetupOutputVariable(state,
    1169             :                                 "Surface Outside Face Incident Ground Diffuse Solar Radiation Rate per Area",
    1170             :                                 OutputProcessor::Unit::W_m2,
    1171       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfLoop),
    1172             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1173             :                                 OutputProcessor::SOVStoreType::Average,
    1174       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1175       55143 :             SetupOutputVariable(state,
    1176             :                                 "Surface Outside Face Beam Solar Incident Angle Cosine Value",
    1177             :                                 OutputProcessor::Unit::None,
    1178       18381 :                                 state.dataHeatBal->SurfCosIncidenceAngle(SurfLoop),
    1179             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1180             :                                 OutputProcessor::SOVStoreType::Average,
    1181       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1182       55143 :             SetupOutputVariable(state,
    1183             :                                 "Surface Outside Face Incident Sky Diffuse Ground Reflected Solar Radiation Rate per Area",
    1184             :                                 OutputProcessor::Unit::W_m2,
    1185       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfLoop),
    1186             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1187             :                                 OutputProcessor::SOVStoreType::Average,
    1188       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1189       55143 :             SetupOutputVariable(state,
    1190             :                                 "Surface Outside Face Incident Sky Diffuse Surface Reflected Solar Radiation Rate per Area",
    1191             :                                 OutputProcessor::Unit::W_m2,
    1192       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfLoop),
    1193             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1194             :                                 OutputProcessor::SOVStoreType::Average,
    1195       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1196       55143 :             SetupOutputVariable(state,
    1197             :                                 "Surface Outside Face Incident Beam To Beam Surface Reflected Solar Radiation Rate per Area",
    1198             :                                 OutputProcessor::Unit::W_m2,
    1199       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfLoop),
    1200             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1201             :                                 OutputProcessor::SOVStoreType::Average,
    1202       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1203       55143 :             SetupOutputVariable(state,
    1204             :                                 "Surface Outside Face Incident Beam To Diffuse Surface Reflected Solar Radiation Rate per Area",
    1205             :                                 OutputProcessor::Unit::W_m2,
    1206       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfLoop),
    1207             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1208             :                                 OutputProcessor::SOVStoreType::Average,
    1209       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1210       55143 :             SetupOutputVariable(state,
    1211             :                                 "Surface Outside Face Incident Beam To Diffuse Ground Reflected Solar Radiation Rate per Area",
    1212             :                                 OutputProcessor::Unit::W_m2,
    1213       18381 :                                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfLoop),
    1214             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1215             :                                 OutputProcessor::SOVStoreType::Average,
    1216       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1217       55143 :             SetupOutputVariable(state,
    1218             :                                 "Surface Anisotropic Sky Multiplier",
    1219             :                                 OutputProcessor::Unit::None,
    1220       18381 :                                 state.dataSolarShading->SurfAnisoSkyMult(SurfLoop),
    1221             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1222             :                                 OutputProcessor::SOVStoreType::Average,
    1223       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1224       73524 :             SetupOutputVariable(state,
    1225             :                                 "Surface Window BSDF Beam Direction Number",
    1226             :                                 OutputProcessor::Unit::None,
    1227       18381 :                                 state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfLoop),
    1228             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1229             :                                 OutputProcessor::SOVStoreType::Average,
    1230       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1231       55143 :             SetupOutputVariable(state,
    1232             :                                 "Surface Window BSDF Beam Theta Angle",
    1233             :                                 OutputProcessor::Unit::rad,
    1234       18381 :                                 state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfLoop),
    1235             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1236             :                                 OutputProcessor::SOVStoreType::Average,
    1237       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1238       55143 :             SetupOutputVariable(state,
    1239             :                                 "Surface Window BSDF Beam Phi Angle",
    1240             :                                 OutputProcessor::Unit::rad,
    1241       18381 :                                 state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfLoop),
    1242             :                                 OutputProcessor::SOVTimeStepType::Zone,
    1243             :                                 OutputProcessor::SOVStoreType::Average,
    1244       36762 :                                 state.dataSurface->Surface(SurfLoop).Name);
    1245             :         }
    1246       43762 :         if (!state.dataSurface->Surface(SurfLoop).HeatTransSurf) continue;
    1247             : 
    1248       42207 :         if (state.dataSurface->Surface(SurfLoop).Class == SurfaceClass::Window) {
    1249             :             // CurrentModuleObject='Windows/GlassDoors'
    1250        5974 :             if (state.dataSurface->Surface(SurfLoop).ExtSolar) {
    1251       17874 :                 SetupOutputVariable(state,
    1252             :                                     "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
    1253             :                                     OutputProcessor::Unit::W,
    1254        5958 :                                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
    1255             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1256             :                                     OutputProcessor::SOVStoreType::Average,
    1257       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1258       17874 :                 SetupOutputVariable(state,
    1259             :                                     "Surface Window Total Glazing Layers Absorbed Shortwave Radiation Rate",
    1260             :                                     OutputProcessor::Unit::W,
    1261        5958 :                                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfLoop),
    1262             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1263             :                                     OutputProcessor::SOVStoreType::Average,
    1264       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1265             : 
    1266        5958 :                 if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF) {
    1267          24 :                     NumOfLayers = state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).TotSolidLayers;
    1268             :                 } else {
    1269        5934 :                     NumOfLayers = state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).TotLayers;
    1270             :                 }
    1271       15910 :                 for (I = 1; I <= NumOfLayers; ++I) {
    1272        9952 :                     if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF) {
    1273         340 :                         SetupOutputVariable(state,
    1274         136 :                                             format("Surface Window Total Absorbed Shortwave Radiation Rate Layer {}", I),
    1275             :                                             OutputProcessor::Unit::W,
    1276         136 :                                             state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfLoop, I),
    1277             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1278             :                                             OutputProcessor::SOVStoreType::Average,
    1279          68 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1280             :                     }
    1281        9952 :                     if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF || (I == 1)) {
    1282       30010 :                         SetupOutputVariable(state,
    1283       12004 :                                             format("Surface Window Front Face Temperature Layer {}", I),
    1284             :                                             OutputProcessor::Unit::C,
    1285       12004 :                                             state.dataHeatBal->SurfWinFenLaySurfTempFront(SurfLoop, I),
    1286             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1287             :                                             OutputProcessor::SOVStoreType::Average,
    1288        6002 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1289             :                     }
    1290        9952 :                     if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF || (I == NumOfLayers)) {
    1291       30010 :                         SetupOutputVariable(state,
    1292       12004 :                                             format("Surface Window Back Face Temperature Layer {}", I),
    1293             :                                             OutputProcessor::Unit::C,
    1294       12004 :                                             state.dataHeatBal->SurfWinFenLaySurfTempBack(SurfLoop, I),
    1295             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1296             :                                             OutputProcessor::SOVStoreType::Average,
    1297        6002 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1298             :                     }
    1299             :                 }
    1300             : 
    1301       17874 :                 SetupOutputVariable(state,
    1302             :                                     "Surface Window Transmitted Solar Radiation Rate",
    1303             :                                     OutputProcessor::Unit::W,
    1304        5958 :                                     state.dataSurface->SurfWinTransSolar(SurfLoop),
    1305             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1306             :                                     OutputProcessor::SOVStoreType::Average,
    1307       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1308       17874 :                 SetupOutputVariable(state,
    1309             :                                     "Surface Window Transmitted Beam Solar Radiation Rate",
    1310             :                                     OutputProcessor::Unit::W,
    1311        5958 :                                     state.dataSurface->SurfWinBmSolar(SurfLoop),
    1312             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1313             :                                     OutputProcessor::SOVStoreType::Average,
    1314       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1315             : 
    1316             :                 // added TH 12/9/2009
    1317       17874 :                 SetupOutputVariable(state,
    1318             :                                     "Surface Window Transmitted Beam To Beam Solar Radiation Rate",
    1319             :                                     OutputProcessor::Unit::W,
    1320        5958 :                                     state.dataSurface->SurfWinBmBmSolar(SurfLoop),
    1321             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1322             :                                     OutputProcessor::SOVStoreType::Average,
    1323       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1324       17874 :                 SetupOutputVariable(state,
    1325             :                                     "Surface Window Transmitted Beam To Diffuse Solar Radiation Rate",
    1326             :                                     OutputProcessor::Unit::W,
    1327        5958 :                                     state.dataSurface->SurfWinBmDifSolar(SurfLoop),
    1328             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1329             :                                     OutputProcessor::SOVStoreType::Average,
    1330       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1331             : 
    1332       17874 :                 SetupOutputVariable(state,
    1333             :                                     "Surface Window Transmitted Diffuse Solar Radiation Rate",
    1334             :                                     OutputProcessor::Unit::W,
    1335        5958 :                                     state.dataSurface->SurfWinDifSolar(SurfLoop),
    1336             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1337             :                                     OutputProcessor::SOVStoreType::Average,
    1338       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1339       17874 :                 SetupOutputVariable(state,
    1340             :                                     "Surface Window Heat Gain Rate",
    1341             :                                     OutputProcessor::Unit::W,
    1342        5958 :                                     state.dataSurface->SurfWinHeatGainRep(SurfLoop),
    1343             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1344             :                                     OutputProcessor::SOVStoreType::Average,
    1345       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1346       17874 :                 SetupOutputVariable(state,
    1347             :                                     "Surface Window Heat Loss Rate",
    1348             :                                     OutputProcessor::Unit::W,
    1349        5958 :                                     state.dataSurface->SurfWinHeatLossRep(SurfLoop),
    1350             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1351             :                                     OutputProcessor::SOVStoreType::Average,
    1352       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1353       17874 :                 SetupOutputVariable(state,
    1354             :                                     "Surface Window Gap Convective Heat Transfer Rate",
    1355             :                                     OutputProcessor::Unit::W,
    1356        5958 :                                     state.dataSurface->SurfWinGapConvHtFlowRep(SurfLoop),
    1357             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1358             :                                     OutputProcessor::SOVStoreType::Average,
    1359       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1360       17874 :                 SetupOutputVariable(state,
    1361             :                                     "Surface Window Shading Device Absorbed Solar Radiation Rate",
    1362             :                                     OutputProcessor::Unit::W,
    1363        5958 :                                     state.dataSurface->SurfWinShadingAbsorbedSolar(SurfLoop),
    1364             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1365             :                                     OutputProcessor::SOVStoreType::Average,
    1366       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1367       17874 :                 SetupOutputVariable(state,
    1368             :                                     "Surface Window Net Heat Transfer Rate",
    1369             :                                     OutputProcessor::Unit::W,
    1370        5958 :                                     state.dataSurface->SurfWinHeatGain(SurfLoop),
    1371             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1372             :                                     OutputProcessor::SOVStoreType::Average,
    1373       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1374             : 
    1375        5958 :                 if (state.dataGlobal->DisplayAdvancedReportVariables) {
    1376             :                     // CurrentModuleObject='Windows/GlassDoors(Advanced)'
    1377         378 :                     SetupOutputVariable(state,
    1378             :                                         "Surface Window Inside Face Glazing Zone Convection Heat Gain Rate",
    1379             :                                         OutputProcessor::Unit::W,
    1380         126 :                                         state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfLoop),
    1381             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1382             :                                         OutputProcessor::SOVStoreType::Average,
    1383         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1384         378 :                     SetupOutputVariable(state,
    1385             :                                         "Surface Window Inside Face Glazing Net Infrared Heat Transfer Rate",
    1386             :                                         OutputProcessor::Unit::W,
    1387         126 :                                         state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfLoop),
    1388             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1389             :                                         OutputProcessor::SOVStoreType::Average,
    1390         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1391         378 :                     SetupOutputVariable(state,
    1392             :                                         "Surface Window Shortwave from Zone Back Out Window Heat Transfer Rate",
    1393             :                                         OutputProcessor::Unit::W,
    1394         126 :                                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfLoop),
    1395             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1396             :                                         OutputProcessor::SOVStoreType::Average,
    1397         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1398         378 :                     SetupOutputVariable(state,
    1399             :                                         "Surface Window Inside Face Frame and Divider Zone Heat Gain Rate",
    1400             :                                         OutputProcessor::Unit::W,
    1401         126 :                                         state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfLoop),
    1402             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1403             :                                         OutputProcessor::SOVStoreType::Average,
    1404         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1405         378 :                     SetupOutputVariable(state,
    1406             :                                         "Surface Window Inside Face Gap between Shade and Glazing Zone Convection Heat Gain Rate",
    1407             :                                         OutputProcessor::Unit::W,
    1408         126 :                                         state.dataSurface->SurfWinConvHeatFlowNatural(SurfLoop),
    1409             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1410             :                                         OutputProcessor::SOVStoreType::Average,
    1411         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1412         378 :                     SetupOutputVariable(state,
    1413             :                                         "Surface Window Inside Face Shade Zone Convection Heat Gain Rate",
    1414             :                                         OutputProcessor::Unit::W,
    1415         126 :                                         state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfLoop),
    1416             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1417             :                                         OutputProcessor::SOVStoreType::Average,
    1418         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1419         378 :                     SetupOutputVariable(state,
    1420             :                                         "Surface Window Inside Face Shade Net Infrared Heat Transfer Rate",
    1421             :                                         OutputProcessor::Unit::W,
    1422         126 :                                         state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfLoop),
    1423             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1424             :                                         OutputProcessor::SOVStoreType::Average,
    1425         252 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1426         126 :                     if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeEQL) {
    1427           0 :                         SetupOutputVariable(state,
    1428             :                                             "Surface Window Inside Face Other Convection Heat Gain Rate",
    1429             :                                             OutputProcessor::Unit::W,
    1430           0 :                                             state.dataSurface->SurfWinOtherConvHeatGain(SurfLoop),
    1431             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1432             :                                             OutputProcessor::SOVStoreType::Average,
    1433           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1434             :                     }
    1435             :                 }
    1436             : 
    1437             :                 // Added TH 12/23/2008 for thermochromic windows
    1438             :                 // CurrentModuleObject='Thermochromic Windows'
    1439        5958 :                 if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).TCFlag == 1) {
    1440           3 :                     SetupOutputVariable(state,
    1441             :                                         "Surface Window Thermochromic Layer Temperature",
    1442             :                                         OutputProcessor::Unit::C,
    1443           1 :                                         state.dataSurface->SurfWinTCLayerTemp(SurfLoop),
    1444             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1445             :                                         OutputProcessor::SOVStoreType::Average,
    1446           2 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1447           3 :                     SetupOutputVariable(state,
    1448             :                                         "Surface Window Thermochromic Layer Property Specification Temperature",
    1449             :                                         OutputProcessor::Unit::C,
    1450           1 :                                         state.dataSurface->SurfWinSpecTemp(SurfLoop),
    1451             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1452             :                                         OutputProcessor::SOVStoreType::Average,
    1453           2 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1454             :                 }
    1455             : 
    1456             :                 // Added TH 5/26/2009 for switchable windows to report switching factor (tinted level)
    1457             :                 // CurrentModuleObject='Switchable Windows'
    1458        5958 :                 if (state.dataSurface->Surface(SurfLoop).HasShadeControl) {
    1459         143 :                     if (state.dataSurface->WindowShadingControl(state.dataSurface->Surface(SurfLoop).activeWindowShadingControl).ShadingType ==
    1460             :                         WinShadingType::SwitchableGlazing) {
    1461             :                         // IF (SurfaceWindow(SurfLoop)%ShadingFlag == WinShadingType::SwitchableGlazing) THEN  !ShadingFlag is not set to
    1462             :                         // WinShadingType::SwitchableGlazing yet!
    1463          90 :                         SetupOutputVariable(state,
    1464             :                                             "Surface Window Switchable Glazing Switching Factor",
    1465             :                                             OutputProcessor::Unit::None,
    1466          30 :                                             state.dataSurface->SurfWinSwitchingFactor(SurfLoop),
    1467             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1468             :                                             OutputProcessor::SOVStoreType::Average,
    1469          60 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1470          90 :                         SetupOutputVariable(state,
    1471             :                                             "Surface Window Switchable Glazing Visible Transmittance",
    1472             :                                             OutputProcessor::Unit::None,
    1473          30 :                                             state.dataSurface->SurfWinVisTransSelected(SurfLoop),
    1474             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1475             :                                             OutputProcessor::SOVStoreType::Average,
    1476          60 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1477             :                     }
    1478             :                 }
    1479             : 
    1480        5958 :                 if (state.dataSurface->SurfWinFrameArea(SurfLoop) > 0.0) {
    1481             :                     // CurrentModuleObject='Window Frames'
    1482         390 :                     SetupOutputVariable(state,
    1483             :                                         "Surface Window Frame Heat Gain Rate",
    1484             :                                         OutputProcessor::Unit::W,
    1485         130 :                                         state.dataSurface->SurfWinFrameHeatGain(SurfLoop),
    1486             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1487             :                                         OutputProcessor::SOVStoreType::Average,
    1488         260 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1489         390 :                     SetupOutputVariable(state,
    1490             :                                         "Surface Window Frame Heat Loss Rate",
    1491             :                                         OutputProcessor::Unit::W,
    1492         130 :                                         state.dataSurface->SurfWinFrameHeatLoss(SurfLoop),
    1493             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1494             :                                         OutputProcessor::SOVStoreType::Average,
    1495         260 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1496         390 :                     SetupOutputVariable(state,
    1497             :                                         "Surface Window Frame Inside Temperature",
    1498             :                                         OutputProcessor::Unit::C,
    1499         130 :                                         state.dataSurface->SurfWinFrameTempIn(SurfLoop),
    1500             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1501             :                                         OutputProcessor::SOVStoreType::Average,
    1502         260 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1503         390 :                     SetupOutputVariable(state,
    1504             :                                         "Surface Window Frame Outside Temperature",
    1505             :                                         OutputProcessor::Unit::C,
    1506         130 :                                         state.dataSurface->SurfWinFrameTempSurfOut(SurfLoop),
    1507             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1508             :                                         OutputProcessor::SOVStoreType::Average,
    1509         260 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1510             :                 }
    1511        5958 :                 if (state.dataSurface->SurfWinDividerArea(SurfLoop) > 0.0) {
    1512             :                     // CurrentModuleObject='Window Dividers'
    1513         192 :                     SetupOutputVariable(state,
    1514             :                                         "Surface Window Divider Heat Gain Rate",
    1515             :                                         OutputProcessor::Unit::W,
    1516          64 :                                         state.dataSurface->SurfWinDividerHeatGain(SurfLoop),
    1517             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1518             :                                         OutputProcessor::SOVStoreType::Average,
    1519         128 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1520         192 :                     SetupOutputVariable(state,
    1521             :                                         "Surface Window Divider Heat Loss Rate",
    1522             :                                         OutputProcessor::Unit::W,
    1523          64 :                                         state.dataSurface->SurfWinDividerHeatLoss(SurfLoop),
    1524             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1525             :                                         OutputProcessor::SOVStoreType::Average,
    1526         128 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1527         192 :                     SetupOutputVariable(state,
    1528             :                                         "Surface Window Divider Inside Temperature",
    1529             :                                         OutputProcessor::Unit::C,
    1530          64 :                                         state.dataSurface->SurfWinDividerTempIn(SurfLoop),
    1531             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1532             :                                         OutputProcessor::SOVStoreType::Average,
    1533         128 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1534         192 :                     SetupOutputVariable(state,
    1535             :                                         "Surface Window Divider Outside Temperature",
    1536             :                                         OutputProcessor::Unit::C,
    1537          64 :                                         state.dataSurface->SurfWinDividerTempSurfOut(SurfLoop),
    1538             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1539             :                                         OutputProcessor::SOVStoreType::Average,
    1540         128 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1541             :                 }
    1542             : 
    1543             :                 // CurrentModuleObject='Windows'
    1544             :                 // Energy
    1545       17874 :                 SetupOutputVariable(state,
    1546             :                                     "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
    1547             :                                     OutputProcessor::Unit::J,
    1548        5958 :                                     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
    1549             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1550             :                                     OutputProcessor::SOVStoreType::Summed,
    1551       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1552       17874 :                 SetupOutputVariable(state,
    1553             :                                     "Surface Window Transmitted Solar Radiation Energy",
    1554             :                                     OutputProcessor::Unit::J,
    1555        5958 :                                     state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
    1556             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1557             :                                     OutputProcessor::SOVStoreType::Summed,
    1558       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1559       17874 :                 SetupOutputVariable(state,
    1560             :                                     "Surface Window Transmitted Beam Solar Radiation Energy",
    1561             :                                     OutputProcessor::Unit::J,
    1562        5958 :                                     state.dataSurface->SurfWinBmSolarEnergy(SurfLoop),
    1563             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1564             :                                     OutputProcessor::SOVStoreType::Summed,
    1565       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1566             : 
    1567             :                 // added TH 12/9/2009
    1568       17874 :                 SetupOutputVariable(state,
    1569             :                                     "Surface Window Transmitted Beam To Beam Solar Radiation Energy",
    1570             :                                     OutputProcessor::Unit::J,
    1571        5958 :                                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfLoop),
    1572             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1573             :                                     OutputProcessor::SOVStoreType::Summed,
    1574       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1575       17874 :                 SetupOutputVariable(state,
    1576             :                                     "Surface Window Transmitted Beam To Diffuse Solar Radiation Energy",
    1577             :                                     OutputProcessor::Unit::J,
    1578        5958 :                                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfLoop),
    1579             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1580             :                                     OutputProcessor::SOVStoreType::Summed,
    1581       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1582             : 
    1583       17874 :                 SetupOutputVariable(state,
    1584             :                                     "Surface Window Transmitted Diffuse Solar Radiation Energy",
    1585             :                                     OutputProcessor::Unit::J,
    1586        5958 :                                     state.dataSurface->SurfWinDifSolarEnergy(SurfLoop),
    1587             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1588             :                                     OutputProcessor::SOVStoreType::Summed,
    1589       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1590       17874 :                 SetupOutputVariable(state,
    1591             :                                     "Surface Window Heat Gain Energy",
    1592             :                                     OutputProcessor::Unit::J,
    1593        5958 :                                     state.dataSurface->SurfWinHeatGainRepEnergy(SurfLoop),
    1594             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1595             :                                     OutputProcessor::SOVStoreType::Summed,
    1596       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1597       17874 :                 SetupOutputVariable(state,
    1598             :                                     "Surface Window Heat Loss Energy",
    1599             :                                     OutputProcessor::Unit::J,
    1600        5958 :                                     state.dataSurface->SurfWinHeatLossRepEnergy(SurfLoop),
    1601             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1602             :                                     OutputProcessor::SOVStoreType::Summed,
    1603       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1604       17874 :                 SetupOutputVariable(state,
    1605             :                                     "Surface Window Gap Convective Heat Transfer Energy",
    1606             :                                     OutputProcessor::Unit::J,
    1607        5958 :                                     state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfLoop),
    1608             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1609             :                                     OutputProcessor::SOVStoreType::Summed,
    1610       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1611       17874 :                 SetupOutputVariable(state,
    1612             :                                     "Surface Window Shading Device Absorbed Solar Radiation Energy",
    1613             :                                     OutputProcessor::Unit::J,
    1614        5958 :                                     state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfLoop),
    1615             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1616             :                                     OutputProcessor::SOVStoreType::Summed,
    1617       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1618       17874 :                 SetupOutputVariable(state,
    1619             :                                     "Surface Window Net Heat Transfer Energy",
    1620             :                                     OutputProcessor::Unit::J,
    1621        5958 :                                     state.dataSurface->SurfWinHeatTransferRepEnergy(SurfLoop),
    1622             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1623             :                                     OutputProcessor::SOVStoreType::Summed,
    1624       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1625             : 
    1626       17874 :                 SetupOutputVariable(state,
    1627             :                                     "Surface Window System Solar Transmittance",
    1628             :                                     OutputProcessor::Unit::None,
    1629        5958 :                                     state.dataSurface->SurfWinSysSolTransmittance(SurfLoop),
    1630             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1631             :                                     OutputProcessor::SOVStoreType::Average,
    1632       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1633       17874 :                 SetupOutputVariable(state,
    1634             :                                     "Surface Window System Solar Reflectance",
    1635             :                                     OutputProcessor::Unit::None,
    1636        5958 :                                     state.dataSurface->SurfWinSysSolReflectance(SurfLoop),
    1637             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1638             :                                     OutputProcessor::SOVStoreType::Average,
    1639       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1640       17874 :                 SetupOutputVariable(state,
    1641             :                                     "Surface Window System Solar Absorptance",
    1642             :                                     OutputProcessor::Unit::None,
    1643        5958 :                                     state.dataSurface->SurfWinSysSolAbsorptance(SurfLoop),
    1644             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1645             :                                     OutputProcessor::SOVStoreType::Average,
    1646       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1647       23832 :                 SetupOutputVariable(state,
    1648             :                                     "Surface Window Inside Face Glazing Condensation Status",
    1649             :                                     OutputProcessor::Unit::None,
    1650        5958 :                                     state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfLoop),
    1651             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1652             :                                     OutputProcessor::SOVStoreType::State,
    1653       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1654       23832 :                 SetupOutputVariable(state,
    1655             :                                     "Surface Window Inside Face Frame Condensation Status",
    1656             :                                     OutputProcessor::Unit::None,
    1657        5958 :                                     state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfLoop),
    1658             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1659             :                                     OutputProcessor::SOVStoreType::State,
    1660       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1661       23832 :                 SetupOutputVariable(state,
    1662             :                                     "Surface Window Inside Face Divider Condensation Status",
    1663             :                                     OutputProcessor::Unit::None,
    1664        5958 :                                     state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfLoop),
    1665             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1666             :                                     OutputProcessor::SOVStoreType::State,
    1667       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1668             : 
    1669             :                 // Outside reveal report variables
    1670             :                 // IF (Surface(SurfLoop)%Reveal > 0.0) THEN
    1671       17874 :                 SetupOutputVariable(state,
    1672             :                                     "Surface Window Outside Reveal Reflected Beam Solar Radiation Rate",
    1673             :                                     OutputProcessor::Unit::W,
    1674        5958 :                                     state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfLoop),
    1675             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1676             :                                     OutputProcessor::SOVStoreType::State,
    1677       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1678             :                 // Energy
    1679       17874 :                 SetupOutputVariable(state,
    1680             :                                     "Surface Window Outside Reveal Reflected Beam Solar Radiation Energy",
    1681             :                                     OutputProcessor::Unit::J,
    1682        5958 :                                     state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfLoop),
    1683             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1684             :                                     OutputProcessor::SOVStoreType::Summed,
    1685       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1686             :                 // ENDIF
    1687             : 
    1688             :                 // Inside reveal report variables
    1689        5958 :                 if (state.dataSurface->SurfWinInsideReveal(SurfLoop) > 0.0 || state.dataSurface->SurfWinInsideSillDepth(SurfLoop) > 0.0) {
    1690           0 :                     SetupOutputVariable(state,
    1691             :                                         "Surface Window Inside Reveal Reflected Beam Solar Radiation Rate",
    1692             :                                         OutputProcessor::Unit::W,
    1693           0 :                                         state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfLoop),
    1694             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1695             :                                         OutputProcessor::SOVStoreType::State,
    1696           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1697             :                     // Energy
    1698           0 :                     SetupOutputVariable(state,
    1699             :                                         "Surface Window Inside Reveal Reflected Beam Solar Radiation Energy",
    1700             :                                         OutputProcessor::Unit::J,
    1701           0 :                                         state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfLoop),
    1702             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1703             :                                         OutputProcessor::SOVStoreType::Summed,
    1704           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1705             : 
    1706             :                     // Added report variables for inside reveal to debug CR 7596. TH 5/26/2009
    1707             :                     // All reflected solar by the inside reveal is turned into diffuse
    1708           0 :                     SetupOutputVariable(state,
    1709             :                                         "Surface Window Inside Reveal Absorbed Beam Solar Radiation Rate",
    1710             :                                         OutputProcessor::Unit::W,
    1711           0 :                                         state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfLoop),
    1712             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1713             :                                         OutputProcessor::SOVStoreType::State,
    1714           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1715           0 :                     SetupOutputVariable(state,
    1716             :                                         "Surface Window Inside Reveal Reflected Diffuse Zone Solar Radiation Rate",
    1717             :                                         OutputProcessor::Unit::W,
    1718           0 :                                         state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfLoop),
    1719             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1720             :                                         OutputProcessor::SOVStoreType::State,
    1721           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1722           0 :                     SetupOutputVariable(state,
    1723             :                                         "Surface Window Inside Reveal Reflected Diffuse Frame Solar Radiation Rate",
    1724             :                                         OutputProcessor::Unit::W,
    1725           0 :                                         state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfLoop),
    1726             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1727             :                                         OutputProcessor::SOVStoreType::State,
    1728           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1729           0 :                     SetupOutputVariable(state,
    1730             :                                         "Surface Window Inside Reveal Reflected Diffuse Glazing Solar Radiation Rate",
    1731             :                                         OutputProcessor::Unit::W,
    1732           0 :                                         state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfLoop),
    1733             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1734             :                                         OutputProcessor::SOVStoreType::State,
    1735           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1736             :                 }
    1737             : 
    1738             :                 //     Output blind report variables only when blinds are used
    1739        5958 :                 if (state.dataSurface->SurfWinBlindNumber(SurfLoop) > 0) {
    1740             :                     // CurrentModuleObject='Window Blinds'
    1741         102 :                     SetupOutputVariable(state,
    1742             :                                         "Surface Window Blind Beam to Beam Solar Transmittance",
    1743             :                                         OutputProcessor::Unit::None,
    1744          34 :                                         state.dataSurface->SurfWinBlTsolBmBm(SurfLoop),
    1745             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1746             :                                         OutputProcessor::SOVStoreType::State,
    1747          68 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1748         102 :                     SetupOutputVariable(state,
    1749             :                                         "Surface Window Blind Beam to Diffuse Solar Transmittance",
    1750             :                                         OutputProcessor::Unit::None,
    1751          34 :                                         state.dataSurface->SurfWinBlTsolBmDif(SurfLoop),
    1752             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1753             :                                         OutputProcessor::SOVStoreType::State,
    1754          68 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1755         102 :                     SetupOutputVariable(state,
    1756             :                                         "Surface Window Blind Diffuse to Diffuse Solar Transmittance",
    1757             :                                         OutputProcessor::Unit::None,
    1758          34 :                                         state.dataSurface->SurfWinBlTsolDifDif(SurfLoop),
    1759             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1760             :                                         OutputProcessor::SOVStoreType::State,
    1761          68 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1762         102 :                     SetupOutputVariable(state,
    1763             :                                         "Surface Window Blind and Glazing System Beam Solar Transmittance",
    1764             :                                         OutputProcessor::Unit::None,
    1765          34 :                                         state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfLoop),
    1766             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1767             :                                         OutputProcessor::SOVStoreType::State,
    1768          68 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1769         102 :                     SetupOutputVariable(state,
    1770             :                                         "Surface Window Blind and Glazing System Diffuse Solar Transmittance",
    1771             :                                         OutputProcessor::Unit::None,
    1772          34 :                                         state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfLoop),
    1773             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1774             :                                         OutputProcessor::SOVStoreType::State,
    1775          68 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1776             :                 }
    1777             : 
    1778             :                 //     Output screen report variables only when screens are used
    1779        5958 :                 if (state.dataSurface->SurfWinScreenNumber(SurfLoop) > 0) {
    1780             :                     // CurrentModuleObject='Window Screens'
    1781          24 :                     SetupOutputVariable(state,
    1782             :                                         "Surface Window Screen Beam to Beam Solar Transmittance",
    1783             :                                         OutputProcessor::Unit::None,
    1784           8 :                                         state.dataSurface->SurfWinScTsolBmBm(SurfLoop),
    1785             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1786             :                                         OutputProcessor::SOVStoreType::State,
    1787          16 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1788          24 :                     SetupOutputVariable(state,
    1789             :                                         "Surface Window Screen Beam to Diffuse Solar Transmittance",
    1790             :                                         OutputProcessor::Unit::None,
    1791           8 :                                         state.dataSurface->SurfWinScTsolBmDif(SurfLoop),
    1792             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1793             :                                         OutputProcessor::SOVStoreType::State,
    1794          16 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1795          24 :                     SetupOutputVariable(state,
    1796             :                                         "Surface Window Screen Diffuse to Diffuse Solar Transmittance",
    1797             :                                         OutputProcessor::Unit::None,
    1798           8 :                                         state.dataSurface->SurfWinScTsolDifDif(SurfLoop),
    1799             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1800             :                                         OutputProcessor::SOVStoreType::State,
    1801          16 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1802          24 :                     SetupOutputVariable(state,
    1803             :                                         "Surface Window Screen and Glazing System Beam Solar Transmittance",
    1804             :                                         OutputProcessor::Unit::None,
    1805           8 :                                         state.dataSurface->SurfWinScGlSysTsolBmBm(SurfLoop),
    1806             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1807             :                                         OutputProcessor::SOVStoreType::State,
    1808          16 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1809          24 :                     SetupOutputVariable(state,
    1810             :                                         "Surface Window Screen and Glazing System Diffuse Solar Transmittance",
    1811             :                                         OutputProcessor::Unit::None,
    1812           8 :                                         state.dataSurface->SurfWinScGlSysTsolDifDif(SurfLoop),
    1813             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1814             :                                         OutputProcessor::SOVStoreType::State,
    1815          16 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1816             :                 }
    1817             : 
    1818             :                 // CurrentModuleObject='Windows'
    1819       17874 :                 SetupOutputVariable(state,
    1820             :                                     "Surface Window Solar Horizontal Profile Angle",
    1821             :                                     OutputProcessor::Unit::deg,
    1822        5958 :                                     state.dataSurface->SurfWinProfileAngHor(SurfLoop),
    1823             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1824             :                                     OutputProcessor::SOVStoreType::State,
    1825       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1826       17874 :                 SetupOutputVariable(state,
    1827             :                                     "Surface Window Solar Vertical Profile Angle",
    1828             :                                     OutputProcessor::Unit::deg,
    1829        5958 :                                     state.dataSurface->SurfWinProfileAngVert(SurfLoop),
    1830             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1831             :                                     OutputProcessor::SOVStoreType::State,
    1832       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1833       17874 :                 SetupOutputVariable(state,
    1834             :                                     "Surface Window Glazing Beam to Beam Solar Transmittance",
    1835             :                                     OutputProcessor::Unit::None,
    1836        5958 :                                     state.dataSurface->SurfWinGlTsolBmBm(SurfLoop),
    1837             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1838             :                                     OutputProcessor::SOVStoreType::State,
    1839       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1840       17874 :                 SetupOutputVariable(state,
    1841             :                                     "Surface Window Glazing Beam to Diffuse Solar Transmittance",
    1842             :                                     OutputProcessor::Unit::None,
    1843        5958 :                                     state.dataSurface->SurfWinGlTsolBmDif(SurfLoop),
    1844             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1845             :                                     OutputProcessor::SOVStoreType::State,
    1846       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1847       17874 :                 SetupOutputVariable(state,
    1848             :                                     "Surface Window Glazing Diffuse to Diffuse Solar Transmittance",
    1849             :                                     OutputProcessor::Unit::None,
    1850        5958 :                                     state.dataSurface->SurfWinGlTsolDifDif(SurfLoop),
    1851             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1852             :                                     OutputProcessor::SOVStoreType::State,
    1853       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1854       23832 :                 SetupOutputVariable(state,
    1855             :                                     "Surface Window Model Solver Iteration Count",
    1856             :                                     OutputProcessor::Unit::None,
    1857        5958 :                                     state.dataSurface->SurfWinWindowCalcIterationsRep(SurfLoop),
    1858             :                                     OutputProcessor::SOVTimeStepType::Zone,
    1859             :                                     OutputProcessor::SOVStoreType::State,
    1860       11916 :                                     state.dataSurface->Surface(SurfLoop).Name);
    1861             :             } else { // Not ExtSolar
    1862          16 :                 if (state.dataGlobal->DisplayAdvancedReportVariables) {
    1863             :                     // CurrentModuleObject='InteriorWindows(Advanced)'
    1864           0 :                     if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
    1865           0 :                         SetupOutputVariable(state,
    1866             :                                             "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
    1867             :                                             OutputProcessor::Unit::W,
    1868           0 :                                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
    1869             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1870             :                                             OutputProcessor::SOVStoreType::Average,
    1871           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1872             :                     }
    1873           0 :                     SetupOutputVariable(state,
    1874             :                                         "Surface Window Total Glazing Layers Absorbed Shortwave Radiation Rate",
    1875             :                                         OutputProcessor::Unit::W,
    1876           0 :                                         state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfLoop),
    1877             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1878             :                                         OutputProcessor::SOVStoreType::Average,
    1879           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1880             : 
    1881           0 :                     if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
    1882           0 :                         SetupOutputVariable(state,
    1883             :                                             "Surface Window Transmitted Solar Radiation Rate",
    1884             :                                             OutputProcessor::Unit::W,
    1885           0 :                                             state.dataSurface->SurfWinTransSolar(SurfLoop),
    1886             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1887             :                                             OutputProcessor::SOVStoreType::Average,
    1888           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1889             :                     }
    1890           0 :                     SetupOutputVariable(state,
    1891             :                                         "Surface Window Transmitted Beam Solar Radiation Rate",
    1892             :                                         OutputProcessor::Unit::W,
    1893           0 :                                         state.dataSurface->SurfWinBmSolar(SurfLoop),
    1894             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1895             :                                         OutputProcessor::SOVStoreType::Average,
    1896           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1897             : 
    1898             :                     // added TH 12/9/2009
    1899           0 :                     SetupOutputVariable(state,
    1900             :                                         "Surface Window Transmitted Beam To Beam Solar Radiation Rate",
    1901             :                                         OutputProcessor::Unit::W,
    1902           0 :                                         state.dataSurface->SurfWinBmBmSolar(SurfLoop),
    1903             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1904             :                                         OutputProcessor::SOVStoreType::Average,
    1905           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1906           0 :                     SetupOutputVariable(state,
    1907             :                                         "Surface Window Transmitted Beam To Diffuse Solar Radiation Rate",
    1908             :                                         OutputProcessor::Unit::W,
    1909           0 :                                         state.dataSurface->SurfWinBmDifSolar(SurfLoop),
    1910             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1911             :                                         OutputProcessor::SOVStoreType::Average,
    1912           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1913             : 
    1914           0 :                     SetupOutputVariable(state,
    1915             :                                         "Surface Window Transmitted Diffuse Solar Radiation Rate",
    1916             :                                         OutputProcessor::Unit::W,
    1917           0 :                                         state.dataSurface->SurfWinDifSolar(SurfLoop),
    1918             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1919             :                                         OutputProcessor::SOVStoreType::Average,
    1920           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1921           0 :                     SetupOutputVariable(state,
    1922             :                                         "Surface Window Heat Gain Rate",
    1923             :                                         OutputProcessor::Unit::W,
    1924           0 :                                         state.dataSurface->SurfWinHeatGainRep(SurfLoop),
    1925             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1926             :                                         OutputProcessor::SOVStoreType::Average,
    1927           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1928           0 :                     SetupOutputVariable(state,
    1929             :                                         "Surface Window Heat Loss Rate",
    1930             :                                         OutputProcessor::Unit::W,
    1931           0 :                                         state.dataSurface->SurfWinHeatLossRep(SurfLoop),
    1932             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1933             :                                         OutputProcessor::SOVStoreType::Average,
    1934           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1935           0 :                     SetupOutputVariable(state,
    1936             :                                         "Surface Window Gap Convective Heat Transfer Rate",
    1937             :                                         OutputProcessor::Unit::W,
    1938           0 :                                         state.dataSurface->SurfWinGapConvHtFlowRep(SurfLoop),
    1939             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1940             :                                         OutputProcessor::SOVStoreType::Average,
    1941           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1942           0 :                     SetupOutputVariable(state,
    1943             :                                         "Surface Window Shading Device Absorbed Solar Radiation Rate",
    1944             :                                         OutputProcessor::Unit::W,
    1945           0 :                                         state.dataSurface->SurfWinShadingAbsorbedSolar(SurfLoop),
    1946             :                                         OutputProcessor::SOVTimeStepType::Zone,
    1947             :                                         OutputProcessor::SOVStoreType::Average,
    1948           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    1949           0 :                     if (state.dataSurface->SurfWinFrameArea(SurfLoop) > 0.0) {
    1950           0 :                         SetupOutputVariable(state,
    1951             :                                             "Surface Window Frame Heat Gain Rate",
    1952             :                                             OutputProcessor::Unit::W,
    1953           0 :                                             state.dataSurface->SurfWinFrameHeatGain(SurfLoop),
    1954             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1955             :                                             OutputProcessor::SOVStoreType::Average,
    1956           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1957           0 :                         SetupOutputVariable(state,
    1958             :                                             "Surface Window Frame Heat Loss Rate",
    1959             :                                             OutputProcessor::Unit::W,
    1960           0 :                                             state.dataSurface->SurfWinFrameHeatLoss(SurfLoop),
    1961             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1962             :                                             OutputProcessor::SOVStoreType::Average,
    1963           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1964           0 :                         SetupOutputVariable(state,
    1965             :                                             "Surface Window Frame Inside Temperature",
    1966             :                                             OutputProcessor::Unit::C,
    1967           0 :                                             state.dataSurface->SurfWinFrameTempIn(SurfLoop),
    1968             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1969             :                                             OutputProcessor::SOVStoreType::Average,
    1970           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1971           0 :                         SetupOutputVariable(state,
    1972             :                                             "Surface Window Frame Outside Temperature",
    1973             :                                             OutputProcessor::Unit::C,
    1974           0 :                                             state.dataSurface->SurfWinFrameTempSurfOut(SurfLoop),
    1975             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1976             :                                             OutputProcessor::SOVStoreType::Average,
    1977           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1978             :                     }
    1979           0 :                     if (state.dataSurface->SurfWinDividerArea(SurfLoop) > 0.0) {
    1980           0 :                         SetupOutputVariable(state,
    1981             :                                             "Surface Window Divider Heat Gain Rate",
    1982             :                                             OutputProcessor::Unit::W,
    1983           0 :                                             state.dataSurface->SurfWinDividerHeatGain(SurfLoop),
    1984             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1985             :                                             OutputProcessor::SOVStoreType::Average,
    1986           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1987           0 :                         SetupOutputVariable(state,
    1988             :                                             "Surface Window Divider Heat Loss Rate",
    1989             :                                             OutputProcessor::Unit::W,
    1990           0 :                                             state.dataSurface->SurfWinDividerHeatLoss(SurfLoop),
    1991             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1992             :                                             OutputProcessor::SOVStoreType::Average,
    1993           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    1994           0 :                         SetupOutputVariable(state,
    1995             :                                             "Surface Window Divider Inside Temperature",
    1996             :                                             OutputProcessor::Unit::C,
    1997           0 :                                             state.dataSurface->SurfWinDividerTempIn(SurfLoop),
    1998             :                                             OutputProcessor::SOVTimeStepType::Zone,
    1999             :                                             OutputProcessor::SOVStoreType::Average,
    2000           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2001           0 :                         SetupOutputVariable(state,
    2002             :                                             "Surface Window Divider Outside Temperature",
    2003             :                                             OutputProcessor::Unit::C,
    2004           0 :                                             state.dataSurface->SurfWinDividerTempSurfOut(SurfLoop),
    2005             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2006             :                                             OutputProcessor::SOVStoreType::Average,
    2007           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2008             :                     }
    2009             :                     // Energy
    2010             : 
    2011           0 :                     if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
    2012           0 :                         SetupOutputVariable(state,
    2013             :                                             "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
    2014             :                                             OutputProcessor::Unit::J,
    2015           0 :                                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
    2016             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2017             :                                             OutputProcessor::SOVStoreType::Summed,
    2018           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2019             :                     }
    2020             : 
    2021           0 :                     if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
    2022           0 :                         SetupOutputVariable(state,
    2023             :                                             "Surface Window Transmitted Solar Radiation Energy",
    2024             :                                             OutputProcessor::Unit::J,
    2025           0 :                                             state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
    2026             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2027             :                                             OutputProcessor::SOVStoreType::Summed,
    2028           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2029             :                     }
    2030           0 :                     SetupOutputVariable(state,
    2031             :                                         "Surface Window Transmitted Beam Solar Radiation Energy",
    2032             :                                         OutputProcessor::Unit::J,
    2033           0 :                                         state.dataSurface->SurfWinBmSolarEnergy(SurfLoop),
    2034             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2035             :                                         OutputProcessor::SOVStoreType::Summed,
    2036           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2037             : 
    2038           0 :                     SetupOutputVariable(state,
    2039             :                                         "Surface Window Transmitted Beam To Beam Solar Radiation Energy",
    2040             :                                         OutputProcessor::Unit::J,
    2041           0 :                                         state.dataSurface->SurfWinBmBmSolarEnergy(SurfLoop),
    2042             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2043             :                                         OutputProcessor::SOVStoreType::Summed,
    2044           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2045           0 :                     SetupOutputVariable(state,
    2046             :                                         "Surface Window Transmitted Beam To Diffuse Solar Radiation Energy",
    2047             :                                         OutputProcessor::Unit::J,
    2048           0 :                                         state.dataSurface->SurfWinBmDifSolarEnergy(SurfLoop),
    2049             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2050             :                                         OutputProcessor::SOVStoreType::Summed,
    2051           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2052             : 
    2053           0 :                     SetupOutputVariable(state,
    2054             :                                         "Surface Window Transmitted Diffuse Solar Radiation Energy",
    2055             :                                         OutputProcessor::Unit::J,
    2056           0 :                                         state.dataSurface->SurfWinDifSolarEnergy(SurfLoop),
    2057             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2058             :                                         OutputProcessor::SOVStoreType::Summed,
    2059           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2060           0 :                     SetupOutputVariable(state,
    2061             :                                         "Surface Window Heat Gain Energy",
    2062             :                                         OutputProcessor::Unit::J,
    2063           0 :                                         state.dataSurface->SurfWinHeatGainRepEnergy(SurfLoop),
    2064             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2065             :                                         OutputProcessor::SOVStoreType::Summed,
    2066           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2067           0 :                     SetupOutputVariable(state,
    2068             :                                         "Surface Window Heat Loss Energy",
    2069             :                                         OutputProcessor::Unit::J,
    2070           0 :                                         state.dataSurface->SurfWinHeatLossRepEnergy(SurfLoop),
    2071             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2072             :                                         OutputProcessor::SOVStoreType::Summed,
    2073           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2074           0 :                     SetupOutputVariable(state,
    2075             :                                         "Surface Window Gap Convective Heat Transfer Energy",
    2076             :                                         OutputProcessor::Unit::J,
    2077           0 :                                         state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfLoop),
    2078             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2079             :                                         OutputProcessor::SOVStoreType::Summed,
    2080           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2081           0 :                     SetupOutputVariable(state,
    2082             :                                         "Surface Window Shading Device Absorbed Solar Radiation Energy",
    2083             :                                         OutputProcessor::Unit::J,
    2084           0 :                                         state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfLoop),
    2085             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2086             :                                         OutputProcessor::SOVStoreType::Summed,
    2087           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2088             : 
    2089           0 :                     SetupOutputVariable(state,
    2090             :                                         "Surface Window System Solar Transmittance",
    2091             :                                         OutputProcessor::Unit::None,
    2092           0 :                                         state.dataSurface->SurfWinSysSolTransmittance(SurfLoop),
    2093             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2094             :                                         OutputProcessor::SOVStoreType::Average,
    2095           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2096           0 :                     SetupOutputVariable(state,
    2097             :                                         "Surface Window System Solar Reflectance",
    2098             :                                         OutputProcessor::Unit::None,
    2099           0 :                                         state.dataSurface->SurfWinSysSolReflectance(SurfLoop),
    2100             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2101             :                                         OutputProcessor::SOVStoreType::Average,
    2102           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2103           0 :                     SetupOutputVariable(state,
    2104             :                                         "Surface Window System Solar Absorptance",
    2105             :                                         OutputProcessor::Unit::None,
    2106           0 :                                         state.dataSurface->SurfWinSysSolAbsorptance(SurfLoop),
    2107             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2108             :                                         OutputProcessor::SOVStoreType::Average,
    2109           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2110           0 :                     SetupOutputVariable(state,
    2111             :                                         "Surface Window Inside Face Glazing Condensation Status",
    2112             :                                         OutputProcessor::Unit::None,
    2113           0 :                                         state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfLoop),
    2114             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2115             :                                         OutputProcessor::SOVStoreType::State,
    2116           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2117           0 :                     SetupOutputVariable(state,
    2118             :                                         "Surface Window Inside Face Frame Condensation Status",
    2119             :                                         OutputProcessor::Unit::None,
    2120           0 :                                         state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfLoop),
    2121             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2122             :                                         OutputProcessor::SOVStoreType::State,
    2123           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2124           0 :                     SetupOutputVariable(state,
    2125             :                                         "Surface Window Inside Face Divider Condensation Status",
    2126             :                                         OutputProcessor::Unit::None,
    2127           0 :                                         state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfLoop),
    2128             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2129             :                                         OutputProcessor::SOVStoreType::State,
    2130           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2131           0 :                     SetupOutputVariable(state,
    2132             :                                         "Surface Window Outside Reveal Reflected Beam Solar Radiation Rate",
    2133             :                                         OutputProcessor::Unit::W,
    2134           0 :                                         state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfLoop),
    2135             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2136             :                                         OutputProcessor::SOVStoreType::State,
    2137           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2138           0 :                     SetupOutputVariable(state,
    2139             :                                         "Surface Window Inside Reveal Reflected Beam Solar Radiation Rate",
    2140             :                                         OutputProcessor::Unit::W,
    2141           0 :                                         state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfLoop),
    2142             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2143             :                                         OutputProcessor::SOVStoreType::State,
    2144           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2145             :                     // Energy
    2146           0 :                     SetupOutputVariable(state,
    2147             :                                         "Surface Window Outside Reveal Reflected Beam Solar Radiation Energy",
    2148             :                                         OutputProcessor::Unit::J,
    2149           0 :                                         state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfLoop),
    2150             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2151             :                                         OutputProcessor::SOVStoreType::Summed,
    2152           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2153           0 :                     SetupOutputVariable(state,
    2154             :                                         "Surface Window Inside Reveal Reflected Beam Solar Radiation Energy",
    2155             :                                         OutputProcessor::Unit::J,
    2156           0 :                                         state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfLoop),
    2157             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2158             :                                         OutputProcessor::SOVStoreType::Summed,
    2159           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2160             : 
    2161             :                     //     Output blind report variables only when blinds are used
    2162           0 :                     if (state.dataSurface->SurfWinBlindNumber(SurfLoop) > 0) {
    2163           0 :                         SetupOutputVariable(state,
    2164             :                                             "Surface Window Blind Beam to Beam Solar Transmittance",
    2165             :                                             OutputProcessor::Unit::None,
    2166           0 :                                             state.dataSurface->SurfWinBlTsolBmBm(SurfLoop),
    2167             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2168             :                                             OutputProcessor::SOVStoreType::State,
    2169           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2170           0 :                         SetupOutputVariable(state,
    2171             :                                             "Surface Window Blind Beam to Diffuse Solar Transmittance",
    2172             :                                             OutputProcessor::Unit::None,
    2173           0 :                                             state.dataSurface->SurfWinBlTsolBmDif(SurfLoop),
    2174             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2175             :                                             OutputProcessor::SOVStoreType::State,
    2176           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2177           0 :                         SetupOutputVariable(state,
    2178             :                                             "Surface Window Blind Diffuse to Diffuse Solar Transmittance",
    2179             :                                             OutputProcessor::Unit::None,
    2180           0 :                                             state.dataSurface->SurfWinBlTsolDifDif(SurfLoop),
    2181             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2182             :                                             OutputProcessor::SOVStoreType::State,
    2183           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2184           0 :                         SetupOutputVariable(state,
    2185             :                                             "Surface Window Blind and Glazing System Beam Solar Transmittance",
    2186             :                                             OutputProcessor::Unit::None,
    2187           0 :                                             state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfLoop),
    2188             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2189             :                                             OutputProcessor::SOVStoreType::State,
    2190           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2191           0 :                         SetupOutputVariable(state,
    2192             :                                             "Surface Window Blind and Glazing System Diffuse Solar Transmittance",
    2193             :                                             OutputProcessor::Unit::None,
    2194           0 :                                             state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfLoop),
    2195             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2196             :                                             OutputProcessor::SOVStoreType::State,
    2197           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2198             :                     }
    2199             : 
    2200             :                     //     Output screen report variables only when screens are used
    2201           0 :                     if (state.dataSurface->SurfWinScreenNumber(SurfLoop) > 0) {
    2202           0 :                         SetupOutputVariable(state,
    2203             :                                             "Surface Window Screen Beam to Beam Solar Transmittance",
    2204             :                                             OutputProcessor::Unit::None,
    2205           0 :                                             state.dataSurface->SurfWinScTsolBmBm(SurfLoop),
    2206             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2207             :                                             OutputProcessor::SOVStoreType::State,
    2208           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2209           0 :                         SetupOutputVariable(state,
    2210             :                                             "Surface Window Screen Beam to Diffuse Solar Transmittance",
    2211             :                                             OutputProcessor::Unit::None,
    2212           0 :                                             state.dataSurface->SurfWinScTsolBmDif(SurfLoop),
    2213             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2214             :                                             OutputProcessor::SOVStoreType::State,
    2215           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2216           0 :                         SetupOutputVariable(state,
    2217             :                                             "Surface Window Screen Diffuse to Diffuse Solar Transmittance",
    2218             :                                             OutputProcessor::Unit::None,
    2219           0 :                                             state.dataSurface->SurfWinScTsolDifDif(SurfLoop),
    2220             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2221             :                                             OutputProcessor::SOVStoreType::State,
    2222           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2223           0 :                         SetupOutputVariable(state,
    2224             :                                             "Surface Window Screen and Glazing System Beam Solar Transmittance",
    2225             :                                             OutputProcessor::Unit::None,
    2226           0 :                                             state.dataSurface->SurfWinScGlSysTsolBmBm(SurfLoop),
    2227             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2228             :                                             OutputProcessor::SOVStoreType::State,
    2229           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2230           0 :                         SetupOutputVariable(state,
    2231             :                                             "Surface Window Screen and Glazing System Diffuse Solar Transmittance",
    2232             :                                             OutputProcessor::Unit::None,
    2233           0 :                                             state.dataSurface->SurfWinScGlSysTsolDifDif(SurfLoop),
    2234             :                                             OutputProcessor::SOVTimeStepType::Zone,
    2235             :                                             OutputProcessor::SOVStoreType::State,
    2236           0 :                                             state.dataSurface->Surface(SurfLoop).Name);
    2237             :                     }
    2238             : 
    2239           0 :                     SetupOutputVariable(state,
    2240             :                                         "Surface Window Solar Horizontal Profile Angle",
    2241             :                                         OutputProcessor::Unit::deg,
    2242           0 :                                         state.dataSurface->SurfWinProfileAngHor(SurfLoop),
    2243             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2244             :                                         OutputProcessor::SOVStoreType::State,
    2245           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2246           0 :                     SetupOutputVariable(state,
    2247             :                                         "Surface Window Solar Vertical Profile Angle",
    2248             :                                         OutputProcessor::Unit::deg,
    2249           0 :                                         state.dataSurface->SurfWinProfileAngVert(SurfLoop),
    2250             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2251             :                                         OutputProcessor::SOVStoreType::State,
    2252           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2253           0 :                     SetupOutputVariable(state,
    2254             :                                         "Surface Window Glazing Beam to Beam Solar Transmittance",
    2255             :                                         OutputProcessor::Unit::None,
    2256           0 :                                         state.dataSurface->SurfWinGlTsolBmBm(SurfLoop),
    2257             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2258             :                                         OutputProcessor::SOVStoreType::State,
    2259           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2260           0 :                     SetupOutputVariable(state,
    2261             :                                         "Surface Window Glazing Beam to Diffuse Solar Transmittance",
    2262             :                                         OutputProcessor::Unit::None,
    2263           0 :                                         state.dataSurface->SurfWinGlTsolBmDif(SurfLoop),
    2264             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2265             :                                         OutputProcessor::SOVStoreType::State,
    2266           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2267           0 :                     SetupOutputVariable(state,
    2268             :                                         "Surface Window Glazing Diffuse to Diffuse Solar Transmittance",
    2269             :                                         OutputProcessor::Unit::None,
    2270           0 :                                         state.dataSurface->SurfWinGlTsolDifDif(SurfLoop),
    2271             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2272             :                                         OutputProcessor::SOVStoreType::State,
    2273           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2274           0 :                     SetupOutputVariable(state,
    2275             :                                         "Surface Window Model Solver Iteration Count",
    2276             :                                         OutputProcessor::Unit::None,
    2277           0 :                                         state.dataSurface->SurfWinWindowCalcIterationsRep(SurfLoop),
    2278             :                                         OutputProcessor::SOVTimeStepType::Zone,
    2279             :                                         OutputProcessor::SOVStoreType::State,
    2280           0 :                                         state.dataSurface->Surface(SurfLoop).Name);
    2281             :                 }
    2282             :             } // end non extsolar reporting as advanced variables
    2283             :         }     // Window Reporting
    2284       42221 :         if (state.dataSurface->Surface(SurfLoop).Class == SurfaceClass::Window && state.dataSurface->Surface(SurfLoop).ExtBoundCond > 0 &&
    2285          14 :             state.dataSurface->Surface(SurfLoop).ExtBoundCond != SurfLoop) { // Interzone window
    2286             :                                                                              // CurrentModuleObject='InterzoneWindows'
    2287          42 :             SetupOutputVariable(state,
    2288             :                                 "Surface Window Transmitted Beam Solar Radiation Rate",
    2289             :                                 OutputProcessor::Unit::W,
    2290          14 :                                 state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfLoop),
    2291             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2292             :                                 OutputProcessor::SOVStoreType::State,
    2293          28 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2294             :             // energy
    2295          42 :             SetupOutputVariable(state,
    2296             :                                 "Surface Window Transmitted Beam Solar Radiation Energy",
    2297             :                                 OutputProcessor::Unit::J,
    2298          14 :                                 state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfLoop),
    2299             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2300             :                                 OutputProcessor::SOVStoreType::Summed,
    2301          28 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2302             :         }
    2303       42207 :         if (state.dataSurface->Surface(SurfLoop).Class == SurfaceClass::TDD_Dome && state.dataSurface->Surface(SurfLoop).ExtSolar) {
    2304             :             // CurrentModuleObject='TDD Domes'
    2305           6 :             SetupOutputVariable(state,
    2306             :                                 "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
    2307             :                                 OutputProcessor::Unit::W,
    2308           2 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
    2309             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2310             :                                 OutputProcessor::SOVStoreType::Average,
    2311           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2312           6 :             SetupOutputVariable(state,
    2313             :                                 "Surface Window Transmitted Solar Radiation Rate",
    2314             :                                 OutputProcessor::Unit::W,
    2315           2 :                                 state.dataSurface->SurfWinTransSolar(SurfLoop),
    2316             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2317             :                                 OutputProcessor::SOVStoreType::Average,
    2318           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2319             :             // energy
    2320           6 :             SetupOutputVariable(state,
    2321             :                                 "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
    2322             :                                 OutputProcessor::Unit::J,
    2323           2 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
    2324             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2325             :                                 OutputProcessor::SOVStoreType::Summed,
    2326           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2327           6 :             SetupOutputVariable(state,
    2328             :                                 "Surface Window Transmitted Solar Radiation Energy",
    2329             :                                 OutputProcessor::Unit::J,
    2330           2 :                                 state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
    2331             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2332             :                                 OutputProcessor::SOVStoreType::Summed,
    2333           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2334             :         }
    2335       42207 :         if (state.dataSurface->SurfWinOriginalClass(SurfLoop) == SurfaceClass::TDD_Diffuser) {
    2336             :             // CurrentModuleObject='TDD Diffusers'
    2337           6 :             SetupOutputVariable(state,
    2338             :                                 "Surface Outside Face Incident Solar Radiation Rate per Area",
    2339             :                                 OutputProcessor::Unit::W_m2,
    2340           2 :                                 state.dataHeatBal->SurfQRadSWOutIncident(SurfLoop),
    2341             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2342             :                                 OutputProcessor::SOVStoreType::Average,
    2343           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2344           6 :             SetupOutputVariable(state,
    2345             :                                 "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
    2346             :                                 OutputProcessor::Unit::W,
    2347           2 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
    2348             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2349             :                                 OutputProcessor::SOVStoreType::Average,
    2350           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2351           6 :             SetupOutputVariable(state,
    2352             :                                 "Surface Window Transmitted Solar Radiation Rate",
    2353             :                                 OutputProcessor::Unit::W,
    2354           2 :                                 state.dataSurface->SurfWinTransSolar(SurfLoop),
    2355             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2356             :                                 OutputProcessor::SOVStoreType::Average,
    2357           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2358             :             // energy
    2359           6 :             SetupOutputVariable(state,
    2360             :                                 "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
    2361             :                                 OutputProcessor::Unit::J,
    2362           2 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
    2363             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2364             :                                 OutputProcessor::SOVStoreType::Summed,
    2365           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2366           6 :             SetupOutputVariable(state,
    2367             :                                 "Surface Window Transmitted Solar Radiation Energy",
    2368             :                                 OutputProcessor::Unit::J,
    2369           2 :                                 state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
    2370             :                                 OutputProcessor::SOVTimeStepType::Zone,
    2371             :                                 OutputProcessor::SOVStoreType::Summed,
    2372           4 :                                 state.dataSurface->Surface(SurfLoop).Name);
    2373             :         }
    2374             :     }
    2375             : 
    2376       44533 :     for (SurfLoop = 1; SurfLoop <= state.dataSurface->TotSurfaces; ++SurfLoop) {
    2377       43762 :         if (!state.dataSurface->Surface(SurfLoop).HeatTransSurf) continue;
    2378             :         // CurrentModuleObject='Surfaces'
    2379      126621 :         SetupOutputVariable(state,
    2380             :                             "Surface Inside Face Exterior Windows Incident Beam Solar Radiation Rate per Area",
    2381             :                             OutputProcessor::Unit::W_m2,
    2382       42207 :                             state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfLoop),
    2383             :                             OutputProcessor::SOVTimeStepType::Zone,
    2384             :                             OutputProcessor::SOVStoreType::Average,
    2385       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2386      126621 :         SetupOutputVariable(state,
    2387             :                             "Surface Inside Face Exterior Windows Incident Beam Solar Radiation Rate",
    2388             :                             OutputProcessor::Unit::W,
    2389       42207 :                             state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfLoop),
    2390             :                             OutputProcessor::SOVTimeStepType::Zone,
    2391             :                             OutputProcessor::SOVStoreType::Average,
    2392       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2393      126621 :         SetupOutputVariable(state,
    2394             :                             "Surface Inside Face Interior Windows Incident Beam Solar Radiation Rate per Area",
    2395             :                             OutputProcessor::Unit::W_m2,
    2396       42207 :                             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfLoop),
    2397             :                             OutputProcessor::SOVTimeStepType::Zone,
    2398             :                             OutputProcessor::SOVStoreType::Average,
    2399       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2400      126621 :         SetupOutputVariable(state,
    2401             :                             "Surface Inside Face Interior Windows Incident Beam Solar Radiation Rate",
    2402             :                             OutputProcessor::Unit::W,
    2403       42207 :                             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfLoop),
    2404             :                             OutputProcessor::SOVTimeStepType::Zone,
    2405             :                             OutputProcessor::SOVStoreType::Average,
    2406       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2407      126621 :         SetupOutputVariable(state,
    2408             :                             "Surface Inside Face Initial Transmitted Diffuse Absorbed Solar Radiation Rate",
    2409             :                             OutputProcessor::Unit::W,
    2410       42207 :                             state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfLoop),
    2411             :                             OutputProcessor::SOVTimeStepType::Zone,
    2412             :                             OutputProcessor::SOVStoreType::Average,
    2413       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2414      126621 :         SetupOutputVariable(state,
    2415             :                             "Surface Inside Face Initial Transmitted Diffuse Transmitted Out Window Solar Radiation Rate",
    2416             :                             OutputProcessor::Unit::W,
    2417       42207 :                             state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfLoop),
    2418             :                             OutputProcessor::SOVTimeStepType::Zone,
    2419             :                             OutputProcessor::SOVStoreType::Average,
    2420       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2421      126621 :         SetupOutputVariable(state,
    2422             :                             "Surface Inside Face Absorbed Shortwave Radiation Rate",
    2423             :                             OutputProcessor::Unit::W,
    2424       42207 :                             state.dataHeatBal->SurfSWInAbsTotalReport(SurfLoop),
    2425             :                             OutputProcessor::SOVTimeStepType::Zone,
    2426             :                             OutputProcessor::SOVStoreType::Average,
    2427       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2428             :         // energy
    2429      126621 :         SetupOutputVariable(state,
    2430             :                             "Surface Inside Face Exterior Windows Incident Beam Solar Radiation Energy",
    2431             :                             OutputProcessor::Unit::J,
    2432       42207 :                             state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfLoop),
    2433             :                             OutputProcessor::SOVTimeStepType::Zone,
    2434             :                             OutputProcessor::SOVStoreType::Summed,
    2435       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2436      126621 :         SetupOutputVariable(state,
    2437             :                             "Surface Inside Face Interior Windows Incident Beam Solar Radiation Energy",
    2438             :                             OutputProcessor::Unit::J,
    2439       42207 :                             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfLoop),
    2440             :                             OutputProcessor::SOVTimeStepType::Zone,
    2441             :                             OutputProcessor::SOVStoreType::Summed,
    2442       84414 :                             state.dataSurface->Surface(SurfLoop).Name);
    2443             :     }
    2444         771 : }
    2445             : 
    2446      821926 : void AnisoSkyViewFactors(EnergyPlusData &state)
    2447             : {
    2448             : 
    2449             :     // SUBROUTINE INFORMATION:
    2450             :     //       AUTHOR         Fred Winkelmann
    2451             :     //       DATE WRITTEN   April 1999
    2452             :     //       MODIFIED       LKL; Dec 2002 -- Anisotropic is only sky radiance option
    2453             :     //       RE-ENGINEERED  na
    2454             : 
    2455             :     // PURPOSE OF THIS SUBROUTINE:
    2456             :     // Calculates view factor multiplier, SurfAnisoSkyMult, for diffuse
    2457             :     // sky irradiance on exterior surfaces taking into account
    2458             :     // anisotropic radiance of the sky. Called by InitSurfaceHeatBalance
    2459             :     // In this case the diffuse sky irradiance on a surface is given by
    2460             :     //  SurfAnisoSkyMult(SurfNum) * DifSolarRad
    2461             :     // SurfAnisoSkyMult accounts not only for the sky radiance distribution but
    2462             :     // also for the effects of shading of sky diffuse radiation by
    2463             :     // shadowing surfaces such as overhangs. It does not account for reflection
    2464             :     // of sky diffuse radiation from shadowing surfaces.
    2465             :     // Based on an empirical model described in
    2466             :     // R. Perez, P. Ineichen, R. Seals, J. Michalsky and R. Stewart,
    2467             :     // "Modeling Daylight Availability and Irradiance Components from Direct
    2468             :     // and Global Irradiance," Solar Energy 44, 271-289, 1990.
    2469             :     // In this model the radiance of the sky consists of three distributions
    2470             :     // that are superimposed:
    2471             : 
    2472             :     // (1) An isotropic distribution that covers the entire sky dome;
    2473             :     // (2) A circumsolar brightening centered around the position of the sun;
    2474             :     // (3) A horizon brightening
    2475             :     // The circumsolar brightening is assumed to be concentrated at a point
    2476             :     // source at the center of the sun although this region actually begins at the
    2477             :     // periphery of the solar disk and falls off in intensity with increasing
    2478             :     // angular distance from the periphery.
    2479             :     // The horizon brightening is assumed to be concentrated at the horizon and
    2480             :     // to be independent of azimuth. In actuality, for clear skies, the horizon
    2481             :     // brightening is highest at the horizon and decreases in intensity away from
    2482             :     // the horizon. For overcast skies the horizon brightening has a negative value
    2483             :     // since for such skies the sky radiance increases rather than decreases away
    2484             :     // from the horizon.
    2485             :     // The F11R, F12R, etc. values were provided by R. Perez, private communication,
    2486             :     // 5/21/99. These values have higher precision than those listed in the above
    2487             :     // paper.
    2488             : 
    2489             :     // Using/Aliasing
    2490             : 
    2491             :     // Locals
    2492             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2493             :     static constexpr std::array<Real64, 7> EpsilonLimit = {
    2494             :         1.065, 1.23, 1.5, 1.95, 2.8, 4.5, 6.2}; // Upper limit of bins of the sky clearness parameter, Epsilon
    2495             :     // Circumsolar brightening coefficients; index corresponds to range of Epsilon, the sky clearness parameter
    2496             :     static constexpr std::array<Real64, 8> F11R = {-0.0083117, 0.1299457, 0.3296958, 0.5682053, 0.8730280, 1.1326077, 1.0601591, 0.6777470};
    2497             :     static constexpr std::array<Real64, 8> F12R = {0.5877285, 0.6825954, 0.4868735, 0.1874525, -0.3920403, -1.2367284, -1.5999137, -0.3272588};
    2498             :     static constexpr std::array<Real64, 8> F13R = {-0.0620636, -0.1513752, -0.2210958, -0.2951290, -0.3616149, -0.4118494, -0.3589221, -0.2504286};
    2499             :     // Horizon/zenith brightening coefficient array; index corresponds to range of Epsilon, the sky clearness parameter
    2500             :     static constexpr std::array<Real64, 8> F21R = {-0.0596012, -0.0189325, 0.0554140, 0.1088631, 0.2255647, 0.2877813, 0.2642124, 0.1561313};
    2501             :     static constexpr std::array<Real64, 8> F22R = {0.0721249, 0.0659650, -0.0639588, -0.1519229, -0.4620442, -0.8230357, -1.1272340, -1.3765031};
    2502             :     static constexpr std::array<Real64, 8> F23R = {-0.0220216, -0.0288748, -0.0260542, -0.0139754, 0.0012448, 0.0558651, 0.1310694, 0.2506212};
    2503             : 
    2504             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2505             : 
    2506             :     Real64 CosZenithAng;           // Cosine of solar zenith angle
    2507             :     Real64 ZenithAng;              // Solar zenith angle (radians)
    2508             :     Real64 ZenithAngDeg;           // Solar zenith angle (degrees)
    2509             :     Real64 F1;                     // Circumsolar brightening coefficient
    2510             :     Real64 F2;                     // Horizon/zenith brightening coefficient
    2511             :     Real64 Epsilon;                // Sky clearness parameter
    2512             :     Real64 Delta;                  // Sky brightness parameter
    2513             :     Real64 CosIncAngBeamOnSurface; // Cosine of incidence angle of beam solar on surface
    2514             :     Real64 IncAng;                 // Incidence angle of beam solar on surface (radians)
    2515             :     int EpsilonBin;                // Sky clearness (Epsilon) bin index
    2516             :     Real64 AirMass;                // Relative air mass
    2517             :     Real64 AirMassH;               // Intermediate variable for relative air mass calculation
    2518             :     Real64 CircumSolarFac;         // Ratio of cosine of incidence angle to cosine of zenith angle
    2519             :     Real64 KappaZ3;                // Intermediate variable
    2520             :     Real64 ViewFactorSkyGeom;      // Geometrical sky view factor
    2521      821926 :     Real64 constexpr cosine_tolerance(0.0001);
    2522             : 
    2523             : #ifdef EP_Count_Calls
    2524             :     ++state.dataTimingsData->NumAnisoSky_Calls;
    2525             : #endif
    2526             : 
    2527      821926 :     CosZenithAng = state.dataEnvrn->SOLCOS(3);
    2528      821926 :     ZenithAng = std::acos(CosZenithAng);
    2529      821926 :     ZenithAngDeg = ZenithAng / DataGlobalConstants::DegToRadians;
    2530             : 
    2531      821926 :     state.dataSolarShading->SurfAnisoSkyMult = 0.0;
    2532             : 
    2533             :     //           Relative air mass
    2534      821926 :     AirMassH = (1.0 - 0.1 * state.dataEnvrn->Elevation / 1000.0);
    2535      821926 :     if (ZenithAngDeg <= 75.0) {
    2536      657406 :         AirMass = AirMassH / CosZenithAng;
    2537             :     } else {
    2538      164520 :         AirMass = AirMassH / (CosZenithAng + 0.15 * std::pow(93.9 - ZenithAngDeg, -1.253));
    2539             :     }
    2540      821926 :     KappaZ3 = 1.041 * pow_3(ZenithAng);
    2541      821926 :     Epsilon = ((state.dataEnvrn->BeamSolarRad + state.dataEnvrn->DifSolarRad) / state.dataEnvrn->DifSolarRad + KappaZ3) / (1.0 + KappaZ3);
    2542      821926 :     Delta = state.dataEnvrn->DifSolarRad * AirMass / 1353.0; // 1353 is average extraterrestrial irradiance (W/m2)
    2543             :     //           Circumsolar (F1) and horizon/zenith (F2) brightening coefficients
    2544     5499554 :     for (EpsilonBin = 0; EpsilonBin < 8; ++EpsilonBin) {
    2545     5499554 :         if (EpsilonBin == 7) break;
    2546     5205994 :         if (Epsilon < EpsilonLimit[EpsilonBin]) break;
    2547             :     }
    2548      821926 :     F1 = max(0.0, F11R[EpsilonBin] + F12R[EpsilonBin] * Delta + F13R[EpsilonBin] * ZenithAng);
    2549      821926 :     F2 = F21R[EpsilonBin] + F22R[EpsilonBin] * Delta + F23R[EpsilonBin] * ZenithAng;
    2550             : 
    2551    21722407 :     for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
    2552             : 
    2553    62701443 :         CosIncAngBeamOnSurface = state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
    2554    41800962 :                                  state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
    2555    20900481 :                                  state.dataEnvrn->SOLCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
    2556             : 
    2557             :         // So I believe this should only be a diagnostic error...the calcs should always be within -1,+1; it's just round-off that we need to trap
    2558             :         // for
    2559    20900481 :         if (CosIncAngBeamOnSurface > 1.0) {
    2560           0 :             if (CosIncAngBeamOnSurface > (1.0 + cosine_tolerance)) {
    2561           0 :                 ShowSevereError(state, "Cosine of incident angle of beam solar on surface out of range...too high");
    2562           0 :                 ShowContinueError(state, "This is a diagnostic error that should not be encountered under normal circumstances");
    2563           0 :                 ShowContinueError(state, "Occurs on surface: " + state.dataSurface->Surface(SurfNum).Name);
    2564           0 :                 ShowContinueError(state, format("Current value = {} ... should be within [-1, +1]", CosIncAngBeamOnSurface));
    2565           0 :                 ShowFatalError(state, "Anisotropic solar calculation causes fatal error");
    2566             :             }
    2567           0 :             CosIncAngBeamOnSurface = 1.0;
    2568    20900481 :         } else if (CosIncAngBeamOnSurface < -1.0) {
    2569           0 :             if (CosIncAngBeamOnSurface < (-1.0 - cosine_tolerance)) {
    2570           0 :                 ShowSevereError(state, "Cosine of incident angle of beam solar on surface out of range...too low");
    2571           0 :                 ShowContinueError(state, "This is a diagnostic error that should not be encountered under normal circumstances");
    2572           0 :                 ShowContinueError(state, "Occurs on surface: " + state.dataSurface->Surface(SurfNum).Name);
    2573           0 :                 ShowContinueError(state, format("Current value = {} ... should be within [-1, +1]", CosIncAngBeamOnSurface));
    2574           0 :                 ShowFatalError(state, "Anisotropic solar calculation causes fatal error");
    2575             :             }
    2576           0 :             CosIncAngBeamOnSurface = -1.0;
    2577             :         }
    2578             : 
    2579    20900481 :         IncAng = std::acos(CosIncAngBeamOnSurface);
    2580             : 
    2581    20900481 :         ViewFactorSkyGeom = state.dataSurface->Surface(SurfNum).ViewFactorSky;
    2582    20900481 :         state.dataSolarShading->SurfMultIsoSky(SurfNum) = ViewFactorSkyGeom * (1.0 - F1);
    2583             :         //           0.0871557 below corresponds to a zenith angle of 85 deg
    2584    20900481 :         CircumSolarFac = max(0.0, CosIncAngBeamOnSurface) / max(0.0871557, CosZenithAng);
    2585             :         //           For near-horizontal roofs, model has an inconsistency that gives sky diffuse
    2586             :         //           irradiance significantly different from DifSolarRad when zenith angle is
    2587             :         //           above 85 deg. The following forces irradiance to be very close to DifSolarRad
    2588             :         //           in this case.
    2589    20900481 :         if (CircumSolarFac > 0.0 && CosZenithAng < 0.0871557 && state.dataSurface->Surface(SurfNum).Tilt < 2.0) CircumSolarFac = 1.0;
    2590    20900481 :         state.dataSolarShading->SurfMultCircumSolar(SurfNum) = F1 * CircumSolarFac;
    2591    20900481 :         state.dataSolarShading->SurfMultHorizonZenith(SurfNum) = F2 * state.dataSurface->Surface(SurfNum).SinTilt;
    2592             : 
    2593    20900481 :         if (!state.dataSysVars->DetailedSkyDiffuseAlgorithm || !state.dataSurface->ShadingTransmittanceVaries ||
    2594           0 :             state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
    2595    20900481 :             state.dataSolarShading->SurfAnisoSkyMult(SurfNum) =
    2596    41800962 :                 state.dataSolarShading->SurfMultIsoSky(SurfNum) * state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum) +
    2597    41800962 :                 state.dataSolarShading->SurfMultCircumSolar(SurfNum) *
    2598    41800962 :                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) +
    2599    20900481 :                 state.dataSolarShading->SurfMultHorizonZenith(SurfNum) * state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum);
    2600             :         } else {
    2601           0 :             state.dataSolarShading->SurfAnisoSkyMult(SurfNum) =
    2602           0 :                 state.dataSolarShading->SurfMultIsoSky(SurfNum) *
    2603           0 :                     state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, SurfNum) +
    2604           0 :                 state.dataSolarShading->SurfMultCircumSolar(SurfNum) *
    2605           0 :                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) +
    2606           0 :                 state.dataSolarShading->SurfMultHorizonZenith(SurfNum) *
    2607           0 :                     state.dataSolarShading->SurfDifShdgRatioHorizHRTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, SurfNum);
    2608           0 :             state.dataSolarShading->SurfCurDifShdgRatioIsoSky(SurfNum) =
    2609           0 :                 state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, SurfNum);
    2610             :         }
    2611    20900481 :         state.dataSolarShading->SurfAnisoSkyMult(SurfNum) = max(0.0, state.dataSolarShading->SurfAnisoSkyMult(SurfNum)); // make sure not negative.
    2612             :     }
    2613      821926 : }
    2614             : 
    2615       17490 : void CHKBKS(EnergyPlusData &state,
    2616             :             int const NBS, // Surface Number of the potential back surface
    2617             :             int const NRS  // Surface Number of the potential shadow receiving surface
    2618             : )
    2619             : {
    2620             : 
    2621             :     // SUBROUTINE INFORMATION:
    2622             :     //       AUTHOR         Legacy Code
    2623             :     //       DATE WRITTEN
    2624             :     //       MODIFIED       Nov 2001, FW: Reverse subroutine arguments NRS and NBS to
    2625             :     //                                    correspond to how CHKBKS is called
    2626             :     //                      Jan 2002, FW: change error message
    2627             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    2628             :     //       Sep 2020: Revised the vector computation method to reliabily produce CVec,
    2629             :     //                 and simplified the warning messages.
    2630             : 
    2631             :     // PURPOSE OF THIS SUBROUTINE:
    2632             :     // Determines whether a any vertices of the back surface are in front of the receiving surface;
    2633             :     // if so, gives severe error.  Only base heat transfer surfaces are checked.
    2634             : 
    2635             :     // METHODOLOGY EMPLOYED:
    2636             :     // na
    2637             : 
    2638             :     // REFERENCES:
    2639             :     // BLAST/IBLAST code, original author George Walton
    2640             : 
    2641             :     // Using/Aliasing
    2642             :     using namespace Vectors;
    2643             : 
    2644             :     int N;       // Loop Control (vertex counter)
    2645             :     int NVRS;    // Number of vertices of the receiving surface
    2646             :     int NVBS;    // Number of vertices of the back surface
    2647             :     Real64 DOTP; // Dot product of C and D
    2648             : 
    2649             :     // Object Data
    2650       34980 :     Vector CVec(0.0); // Vector perpendicular to surface at vertex 1
    2651       34980 :     Vector DVec(0.0); // Vector from vertex 1 of first surface to vertex 'n' of second surface
    2652             : 
    2653       17490 :     NVRS = state.dataSurface->Surface(NRS).Sides;
    2654       17490 :     NVBS = state.dataSurface->Surface(NBS).Sides;
    2655             : 
    2656             :     // SEE IF ANY VERTICES OF THE back surface ARE IN FRONT OF THE receiving surface
    2657             : 
    2658       52530 :     for (N = 2; N < NVRS; N++) {
    2659       35040 :         CVec += cross(state.dataSurface->Surface(NRS).Vertex(N) - state.dataSurface->Surface(NRS).Vertex(1),
    2660       70080 :                       state.dataSurface->Surface(NRS).Vertex((N + 1)) - state.dataSurface->Surface(NRS).Vertex(1));
    2661             :     }
    2662       17490 :     CVec /= (NVRS >= 3 ? NVRS : 3);
    2663             : 
    2664       87906 :     for (N = 1; N <= NVBS; ++N) {
    2665       70416 :         DVec = state.dataSurface->Surface(NBS).Vertex(N) - state.dataSurface->Surface(NRS).Vertex(1);
    2666       70416 :         DOTP = dot(CVec, DVec);
    2667       70416 :         if (DOTP > 0.0009) {
    2668           0 :             ShowSevereError(state, "Problem in interior solar distribution calculation (CHKBKS)");
    2669           0 :             ShowContinueError(state,
    2670           0 :                               "   Solar Distribution = FullInteriorExterior will not work in Zone=" + state.dataSurface->Surface(NRS).ZoneName);
    2671           0 :             ShowContinueError(state,
    2672           0 :                               format("   because one or more of vertices, such as Vertex {} of back surface={}, is in front of receiving surface={}",
    2673             :                                      N,
    2674           0 :                                      state.dataSurface->Surface(NBS).Name,
    2675           0 :                                      state.dataSurface->Surface(NRS).Name));
    2676           0 :             ShowContinueError(state, format("   (Dot Product indicator={:20.4F})", DOTP));
    2677           0 :             ShowContinueError(state,
    2678             :                               "   Check surface geometry; if OK, use Solar Distribution = FullExterior instead. Use Output:Diagnostics, "
    2679             :                               "DisplayExtraWarnings; for more details.");
    2680           0 :             if (!state.dataGlobal->DisplayExtraWarnings) break;
    2681             :         }
    2682             :     }
    2683       17490 : }
    2684             : 
    2685      370193 : void CHKGSS(EnergyPlusData &state,
    2686             :             int const NRS,     // Surface number of the potential shadow receiving surface
    2687             :             int const NSS,     // Surface number of the potential shadow casting surface
    2688             :             Real64 const ZMIN, // Lowest point of the receiving surface
    2689             :             bool &CannotShade  // TRUE if shadow casting surface cannot shade receiving surface.
    2690             : )
    2691             : {
    2692             : 
    2693             :     // SUBROUTINE INFORMATION:
    2694             :     //       AUTHOR         Legacy Code
    2695             :     //       DATE WRITTEN
    2696             :     //       MODIFIED       na
    2697             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    2698             : 
    2699             :     // PURPOSE OF THIS SUBROUTINE:
    2700             :     // Determines the possible shadowing combinations.  The
    2701             :     // routine checks detached shadowing or base heat transfer surfaces
    2702             :     // for the possibility that they cannot shade a given base heat transfer surface.
    2703             : 
    2704             :     // METHODOLOGY EMPLOYED:
    2705             :     // Shadowing is not possible if:
    2706             :     // 1.  The lowest point of the shadow receiving surface (receiving surface)
    2707             :     //     Is higher than the highest point of the shadow casting surface (s.s.)
    2708             :     // 2.  The shadow casting surface Faces up (e.g. A flat roof)
    2709             :     // 3.  The shadow casting surface Is behind the receiving surface
    2710             :     // 4.  The receiving surface is behind the shadow casting surface
    2711             : 
    2712             :     // REFERENCES:
    2713             :     // BLAST/IBLAST code, original author George Walton
    2714             : 
    2715             :     // Using/Aliasing
    2716             :     using namespace Vectors;
    2717             : 
    2718             :     // Object Data
    2719             : 
    2720      370193 :     CannotShade = true;
    2721             : 
    2722             :     // see if no point of shadow casting surface is above low point of receiving surface
    2723             : 
    2724      370193 :     auto const &surface_C(state.dataSurface->Surface(NSS));
    2725      559602 :     if (surface_C.OutNormVec(3) > 0.9999) return; // Shadow Casting Surface is horizontal and facing upward
    2726      286035 :     auto const &vertex_C(surface_C.Vertex);
    2727      286035 :     Real64 ZMAX(vertex_C(1).z);
    2728     1139822 :     for (int i = 2, e = surface_C.Sides; i <= e; ++i) {
    2729      853787 :         ZMAX = std::max(ZMAX, vertex_C(i).z);
    2730             :     }
    2731      286035 :     if (ZMAX <= ZMIN) return;
    2732             : 
    2733             :     // SEE IF ANY VERTICES OF THE Shadow Casting Surface ARE ABOVE THE PLANE OF THE receiving surface
    2734             : 
    2735      180784 :     auto const &surface_R(state.dataSurface->Surface(NRS));
    2736      180784 :     auto const &vertex_R(surface_R.Vertex);
    2737      361568 :     auto const vertex_R_2(vertex_R(2));
    2738      361568 :     Vector const AVec(vertex_R(1) - vertex_R_2); // Vector from vertex 2 to vertex 1 of receiving surface
    2739      361568 :     Vector const BVec(vertex_R(3) - vertex_R_2); // Vector from vertex 2 to vertex 3 of receiving surface
    2740             : 
    2741      361568 :     Vector const CVec(cross(BVec, AVec)); // Vector perpendicular to surface at vertex 2
    2742             : 
    2743      180784 :     int const NVSS = surface_C.Sides; // Number of vertices of the shadow casting surface
    2744      180784 :     Real64 DOTP(0.0);                 // Dot Product
    2745      706222 :     for (int I = 1; I <= NVSS; ++I) {
    2746      578009 :         DOTP = dot(CVec, vertex_C(I) - vertex_R_2);
    2747      578009 :         if (DOTP > state.dataSolarShading->TolValue) break; // DO loop
    2748             :     }
    2749             : 
    2750             :     // SEE IF ANY VERTICES OF THE receiving surface ARE ABOVE THE PLANE OF THE S.S.
    2751             : 
    2752      180784 :     if (DOTP > state.dataSolarShading->TolValue) {
    2753             : 
    2754      105142 :         auto const vertex_C_2(vertex_C(2));
    2755      105142 :         Vector const AVec(vertex_C(1) - vertex_C_2);
    2756      105142 :         Vector const BVec(vertex_C(3) - vertex_C_2);
    2757             : 
    2758      105142 :         Vector const CVec(cross(BVec, AVec));
    2759             : 
    2760       52571 :         int const NVRS = surface_R.Sides; // Number of vertices of the receiving surface
    2761      169800 :         for (int I = 1; I <= NVRS; ++I) {
    2762      142222 :             DOTP = dot(CVec, vertex_R(I) - vertex_C_2);
    2763      142222 :             if (DOTP > state.dataSolarShading->TolValue) {
    2764       24993 :                 CannotShade = false;
    2765       24993 :                 break; // DO loop
    2766             :             }
    2767             :         }
    2768             :     }
    2769             : }
    2770             : 
    2771        6337 : void CHKSBS(EnergyPlusData &state,
    2772             :             int const HTS,   // Heat transfer surface number of the general receiving surf
    2773             :             int const GRSNR, // Surface number of general receiving surface
    2774             :             int const SBSNR  // Surface number of subsurface
    2775             : )
    2776             : {
    2777             : 
    2778             :     // SUBROUTINE INFORMATION:
    2779             :     //       AUTHOR         Legacy Code
    2780             :     //       DATE WRITTEN
    2781             :     //       MODIFIED       na
    2782             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    2783             : 
    2784             :     // PURPOSE OF THIS SUBROUTINE:
    2785             :     // Checks that a subsurface is completely
    2786             :     // enclosed by its base surface.
    2787             : 
    2788             :     // REFERENCES:
    2789             :     // BLAST/IBLAST code, original author George Walton
    2790             : 
    2791             :     // 3D Planar Polygons
    2792             :     // In 3D applications, one sometimes wants to test a point and polygon that are in the same plane.
    2793             :     // For example, one may have the intersection point of a ray with the plane of a polyhedron's face,
    2794             :     // and want to test if it is inside the face.  Or one may want to know if the base of a 3D perpendicular
    2795             :     // dropped from a point is inside a planar polygon.
    2796             : 
    2797             :     // 3D inclusion is easily determined by projecting the point and polygon into 2D.  To do this, one simply
    2798             :     // ignores one of the 3D coordinates and uses the other two.  To optimally select the coordinate to ignore,
    2799             :     // compute a normal vector to the plane, and select the coordinate with the largest absolute value [Snyder & Barr, 1987].
    2800             :     // This gives the projection of the polygon with maximum area, and results in robust computations.
    2801             :     // John M. Snyder & Alan H. Barr, "Ray Tracing Complex Models Containing Surface Tessellations",
    2802             :     // Computer Graphics 21(4), 119-126 (1987) [also in the Proceedings of SIGGRAPH 1987]
    2803             :     //--- using adapted routine from Triangulation code -- EnergyPlus.
    2804             : 
    2805             :     // MSG - for error message
    2806        6337 :     static Array1D_string const MSG(4, {"misses", "", "within", "overlaps"});
    2807             : 
    2808             :     int N;   // Loop Control
    2809             :     int NVT; // Number of vertices
    2810             :     int NS1; // Number of the figure being overlapped
    2811             :     int NS2; // Number of the figure doing overlapping
    2812             :     int NS3; // Location to place results of overlap
    2813             : 
    2814             :     bool inside;
    2815             : 
    2816             :     bool Out;
    2817             :     Real64 X1; // ,SX,SY,SZ
    2818             :     Real64 Y1;
    2819             :     Real64 Z1;
    2820             :     Real64 X2;
    2821             :     Real64 Y2;
    2822             :     Real64 Z2;
    2823             :     Real64 BX;
    2824             :     Real64 BY;
    2825             :     Real64 BZ;
    2826             :     Real64 BMAX;
    2827             :     //  INTEGER M
    2828             : 
    2829        6337 :     if (state.dataSolarShading->CHKSBSOneTimeFlag) {
    2830         677 :         state.dataSolarShading->XVT.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    2831         677 :         state.dataSolarShading->YVT.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    2832         677 :         state.dataSolarShading->ZVT.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    2833         677 :         state.dataSolarShading->XVT = 0.0;
    2834         677 :         state.dataSolarShading->YVT = 0.0;
    2835         677 :         state.dataSolarShading->ZVT = 0.0;
    2836         677 :         state.dataSolarShading->CHKSBSOneTimeFlag = false;
    2837             :     }
    2838             : 
    2839        6337 :     NS1 = 1;
    2840        6337 :     NS2 = 2;
    2841        6337 :     NS3 = 3;
    2842        6337 :     state.dataSolarShading->HCT(1) = 0.0;
    2843        6337 :     state.dataSolarShading->HCT(2) = 0.0;
    2844             : 
    2845             :     // Put coordinates of base surface into clockwise sequence on the x'-y' plane.
    2846             : 
    2847        6337 :     state.dataSolarShading->XVT = 0.0;
    2848        6337 :     state.dataSolarShading->YVT = 0.0;
    2849        6337 :     state.dataSolarShading->ZVT = 0.0;
    2850        6337 :     state.dataSolarShading->XVS = 0.0;
    2851        6337 :     state.dataSolarShading->YVS = 0.0;
    2852        6337 :     CTRANS(state, GRSNR, HTS, NVT, state.dataSolarShading->XVT, state.dataSolarShading->YVT, state.dataSolarShading->ZVT);
    2853       31749 :     for (N = 1; N <= NVT; ++N) {
    2854       25412 :         state.dataSolarShading->XVS(N) = state.dataSolarShading->XVT(NVT + 1 - N);
    2855       25412 :         state.dataSolarShading->YVS(N) = state.dataSolarShading->YVT(NVT + 1 - N);
    2856             :     }
    2857             : 
    2858        6337 :     HTRANS1(state, NS2, NVT);
    2859             : 
    2860             :     // Put coordinates of the subsurface into clockwise sequence.
    2861             : 
    2862        6337 :     state.dataSolarShading->NVS = state.dataSurface->Surface(SBSNR).Sides;
    2863       31683 :     for (N = 1; N <= state.dataSolarShading->NVS; ++N) {
    2864       25346 :         state.dataSolarShading->XVS(N) = state.dataSurface->ShadeV(SBSNR).XV(state.dataSolarShading->NVS + 1 - N);
    2865       25346 :         state.dataSolarShading->YVS(N) = state.dataSurface->ShadeV(SBSNR).YV(state.dataSolarShading->NVS + 1 - N);
    2866             :     }
    2867        6337 :     HTRANS1(state, NS1, state.dataSolarShading->NVS);
    2868             : 
    2869             :     // Determine the overlap condition.
    2870             : 
    2871        6337 :     DeterminePolygonOverlap(state, NS1, NS2, NS3);
    2872             : 
    2873             :     // Print error condition if necessary.
    2874             : 
    2875        6337 :     if (state.dataSolarShading->OverlapStatus != FirstSurfWithinSecond) {
    2876          19 :         Out = false;
    2877             :         // C                            COMPUTE COMPONENTS OF VECTOR
    2878             :         // C                            NORMAL TO BASE SURFACE.
    2879          19 :         X1 = state.dataSurface->Surface(GRSNR).Vertex(1).x - state.dataSurface->Surface(GRSNR).Vertex(2).x; // XV(1,GRSNR)-XV(2,GRSNR)
    2880          19 :         Y1 = state.dataSurface->Surface(GRSNR).Vertex(1).y - state.dataSurface->Surface(GRSNR).Vertex(2).y; // YV(1,GRSNR)-YV(2,GRSNR)
    2881          19 :         Z1 = state.dataSurface->Surface(GRSNR).Vertex(1).z - state.dataSurface->Surface(GRSNR).Vertex(2).z; // ZV(1,GRSNR)-ZV(2,GRSNR)
    2882          19 :         X2 = state.dataSurface->Surface(GRSNR).Vertex(3).x - state.dataSurface->Surface(GRSNR).Vertex(2).x; // XV(3,GRSNR)-XV(2,GRSNR)
    2883          19 :         Y2 = state.dataSurface->Surface(GRSNR).Vertex(3).y - state.dataSurface->Surface(GRSNR).Vertex(2).y; // YV(3,GRSNR)-YV(2,GRSNR)
    2884          19 :         Z2 = state.dataSurface->Surface(GRSNR).Vertex(3).z - state.dataSurface->Surface(GRSNR).Vertex(2).z; // ZV(3,GRSNR)-ZV(2,GRSNR)
    2885          19 :         BX = Y1 * Z2 - Y2 * Z1;
    2886          19 :         BY = Z1 * X2 - Z2 * X1;
    2887          19 :         BZ = X1 * Y2 - X2 * Y1;
    2888             :         // C                            FIND LARGEST COMPONENT.
    2889          19 :         BMAX = max(std::abs(BX), std::abs(BY), std::abs(BZ));
    2890             :         // C
    2891          19 :         if (std::abs(BX) == BMAX) {
    2892             :             //        write(outputfiledebug,*) ' looking bx-bmax',bmax
    2893          10 :             for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) { // NV(SBSNR)
    2894           8 :                 inside = polygon_contains_point(state.dataSurface->Surface(GRSNR).Sides,
    2895           8 :                                                 state.dataSurface->Surface(GRSNR).Vertex,
    2896           8 :                                                 state.dataSurface->Surface(SBSNR).Vertex(N),
    2897             :                                                 true,
    2898             :                                                 false,
    2899             :                                                 false);
    2900           8 :                 if (!inside) {
    2901           0 :                     Out = true;
    2902             :                     //            do m=1,surface(grsnr)%sides
    2903             :                     //            write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
    2904             :                     //            write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
    2905             :                     //            enddo
    2906             :                     //            EXIT
    2907             :                 }
    2908             :                 //          Y1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(NV(GRSNR),GRSNR)-YV(N,SBSNR)
    2909             :                 //          Z1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(NV(GRSNR),GRSNR)-ZV(N,SBSNR)
    2910             :                 //          DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
    2911             :                 //            Y2 = Y1
    2912             :                 //            Z2 = Z1
    2913             :                 //            Y1 = Surface(GRSNR)%Vertex(M)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(M,GRSNR)-YV(N,SBSNR)
    2914             :                 //            Z1 = Surface(GRSNR)%Vertex(M)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(M,GRSNR)-ZV(N,SBSNR)
    2915             :                 //            SX = Y1*Z2-Y2*Z1
    2916             :                 //            IF(SX*BX.LT.-1.0d-6) THEN
    2917             :                 //              OUT=.TRUE.
    2918             :                 //              write(outputfiledebug,*) 'sx*bx=',sx*bx
    2919             :                 //              write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
    2920             :                 //              write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
    2921             :                 //            endif
    2922             :                 //          ENDDO
    2923             :                 //          IF (OUT) EXIT
    2924             :             }
    2925          17 :         } else if (std::abs(BY) == BMAX) {
    2926             :             //        write(outputfiledebug,*) ' looking by-bmax',bmax
    2927           5 :             for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) { // NV(SBSNR)
    2928           4 :                 inside = polygon_contains_point(state.dataSurface->Surface(GRSNR).Sides,
    2929           4 :                                                 state.dataSurface->Surface(GRSNR).Vertex,
    2930           4 :                                                 state.dataSurface->Surface(SBSNR).Vertex(N),
    2931             :                                                 false,
    2932             :                                                 true,
    2933             :                                                 false);
    2934           4 :                 if (!inside) {
    2935           0 :                     Out = true;
    2936             :                     //            do m=1,surface(grsnr)%sides
    2937             :                     //            write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
    2938             :                     //            write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
    2939             :                     //            enddo
    2940             :                     //            EXIT
    2941             :                 }
    2942             :                 //          Z1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(NV(GRSNR),GRSNR)-ZV(N,SBSNR)
    2943             :                 //          X1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%X-Surface(SBSNR)%Vertex(N)%X !XV(NV(GRSNR),GRSNR)-XV(N,SBSNR)
    2944             :                 //          DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
    2945             :                 //            Z2 = Z1
    2946             :                 //            X2 = X1
    2947             :                 //            Z1 = Surface(GRSNR)%Vertex(M)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(M,GRSNR)-ZV(N,SBSNR)
    2948             :                 //            X1 = Surface(GRSNR)%Vertex(M)%X-Surface(SBSNR)%Vertex(N)%X !XV(M,GRSNR)-XV(N,SBSNR)
    2949             :                 //            SY = Z1*X2-Z2*X1
    2950             :                 //            IF(SY*BY.LT.-1.0d-6) THEN
    2951             :                 //              OUT=.TRUE.
    2952             :                 //              write(outputfiledebug,*) 'sy*by=',sy*by
    2953             :                 //              write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
    2954             :                 //              write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
    2955             :                 //            ENDIF
    2956             :                 //          ENDDO
    2957             :                 //          IF (OUT) EXIT
    2958             :             }
    2959             :         } else {
    2960             :             //        write(outputfiledebug,*) ' looking bz-bmax',bmax
    2961          80 :             for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) { // NV(SBSNR)
    2962          64 :                 inside = polygon_contains_point(state.dataSurface->Surface(GRSNR).Sides,
    2963          64 :                                                 state.dataSurface->Surface(GRSNR).Vertex,
    2964          64 :                                                 state.dataSurface->Surface(SBSNR).Vertex(N),
    2965             :                                                 false,
    2966             :                                                 false,
    2967             :                                                 true);
    2968          64 :                 if (!inside) {
    2969           0 :                     Out = true;
    2970             :                     //            do m=1,surface(grsnr)%sides
    2971             :                     //            write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
    2972             :                     //            write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
    2973             :                     //            enddo
    2974             :                     //            EXIT
    2975             :                 }
    2976             :                 //          X1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%X-Surface(SBSNR)%Vertex(N)%X !XV(NV(GRSNR),GRSNR)-XV(N,SBSNR)
    2977             :                 //          Y1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(NV(GRSNR),GRSNR)-YV(N,SBSNR)
    2978             :                 //          DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
    2979             :                 //            X2 = X1
    2980             :                 //            Y2 = Y1
    2981             :                 //            X1 = Surface(GRSNR)%Vertex(M)%X-Surface(SBSNR)%Vertex(N)%X !XV(M,GRSNR)-XV(N,SBSNR)
    2982             :                 //            Y1 = Surface(GRSNR)%Vertex(M)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(M,GRSNR)-YV(N,SBSNR)
    2983             :                 //            SZ = X1*Y2-X2*Y1
    2984             :                 //            IF(SZ*BZ.LT.-1.0d-6) THEN
    2985             :                 //              OUT=.TRUE.
    2986             :                 //              write(outputfiledebug,*) 'sz*bz=',sz*bz
    2987             :                 //              write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
    2988             :                 //              write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
    2989             :                 //            ENDIF
    2990             :                 //          ENDDO
    2991             :                 //          IF (OUT) EXIT
    2992             :             }
    2993             :         }
    2994             :         //    CALL ShowWarningError(state, 'Base surface does not surround subsurface (CHKSBS), Overlap Status='//  &
    2995             :         //                           TRIM(cOverLapStatus(OverlapStatus)))
    2996             :         //    CALL ShowContinueError(state, 'Surface "'//TRIM(Surface(GRSNR)%Name)//'" '//TRIM(MSG(OverlapStatus))//  &
    2997             :         //                     ' SubSurface "'//TRIM(Surface(SBSNR)%Name)//'"')
    2998             :         //    IF (FirstSurroundError) THEN
    2999             :         //      CALL ShowWarningError(state, 'Base Surface does not surround subsurface errors occuring...'//  &
    3000             :         //                     'Check that the SurfaceGeometry object is expressing the proper starting corner and '//  &
    3001             :         //                     'direction [CounterClockwise/Clockwise]')
    3002             :         //      FirstSurroundError=.FALSE.
    3003             :         //    ENDIF
    3004          19 :         if (Out) {
    3005           0 :             state.dataSolarShading->TrackBaseSubSurround.redimension(++state.dataSolarShading->NumBaseSubSurround);
    3006           0 :             state.dataSolarShading->TrackBaseSubSurround(state.dataSolarShading->NumBaseSubSurround).SurfIndex1 = GRSNR;
    3007           0 :             state.dataSolarShading->TrackBaseSubSurround(state.dataSolarShading->NumBaseSubSurround).SurfIndex2 = SBSNR;
    3008           0 :             state.dataSolarShading->TrackBaseSubSurround(state.dataSolarShading->NumBaseSubSurround).MiscIndex =
    3009           0 :                 state.dataSolarShading->OverlapStatus;
    3010             :             //    CALL ShowRecurringWarningErrorAtEnd(state, 'Base surface does not surround subsurface (CHKSBS), Overlap Status='//  &
    3011             :             //                       TRIM(cOverLapStatus(OverlapStatus)), &
    3012             :             //                       TrackBaseSubSurround(GRSNR)%ErrIndex1)
    3013             :             //    CALL ShowRecurringContinueErrorAtEnd(state, 'Surface "'//TRIM(Surface(GRSNR)%Name)//'" '//TRIM(MSG(OverlapStatus))//  &
    3014             :             //                       ' SubSurface "'//TRIM(Surface(SBSNR)%Name)//'"',  &
    3015             :             //                      TrackBaseSubSurround(SBSNR)%ErrIndex2)
    3016           0 :             if (state.dataSolarShading->shd_stream) {
    3017           0 :                 *state.dataSolarShading->shd_stream << "==== Base does not Surround subsurface details ====\n";
    3018           0 :                 *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(GRSNR).Name << ' '
    3019           0 :                                                     << state.dataSolarShading->cOverLapStatus(state.dataSolarShading->OverlapStatus) << '\n';
    3020           0 :                 *state.dataSolarShading->shd_stream << "Surface#=" << std::setw(5) << GRSNR << " NSides=" << std::setw(5)
    3021           0 :                                                     << state.dataSurface->Surface(GRSNR).Sides << '\n';
    3022           0 :                 *state.dataSolarShading->shd_stream << std::fixed << std::setprecision(2);
    3023           0 :                 for (N = 1; N <= state.dataSurface->Surface(GRSNR).Sides; ++N) {
    3024           0 :                     Vector const &v(state.dataSurface->Surface(GRSNR).Vertex(N));
    3025           0 :                     *state.dataSolarShading->shd_stream << "Vertex " << std::setw(5) << N << "=(" << std::setw(15) << v.x << ',' << std::setw(15)
    3026           0 :                                                         << v.y << ',' << std::setw(15) << v.z << ")\n";
    3027             :                 }
    3028           0 :                 *state.dataSolarShading->shd_stream << "SubSurface=" << state.dataSurface->Surface(SBSNR).Name << '\n';
    3029           0 :                 *state.dataSolarShading->shd_stream << "Surface#=" << std::setw(5) << SBSNR << " NSides=" << std::setw(5)
    3030           0 :                                                     << state.dataSurface->Surface(SBSNR).Sides << '\n';
    3031           0 :                 for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) {
    3032           0 :                     Vector const &v(state.dataSurface->Surface(SBSNR).Vertex(N));
    3033           0 :                     *state.dataSolarShading->shd_stream << "Vertex " << std::setw(5) << N << "=(" << std::setw(15) << v.x << ',' << std::setw(15)
    3034           0 :                                                         << v.y << ',' << std::setw(15) << v.z << ")\n";
    3035             :                 }
    3036           0 :                 *state.dataSolarShading->shd_stream << "================================\n";
    3037             :             }
    3038             :         }
    3039             :     }
    3040        6337 : }
    3041             : 
    3042          76 : bool polygon_contains_point(int const nsides,            // number of sides (vertices)
    3043             :                             Array1D<Vector> &polygon_3d, // points of polygon
    3044             :                             Vector const &point_3d,      // point to be tested
    3045             :                             bool const ignorex,
    3046             :                             bool const ignorey,
    3047             :                             bool const ignorez)
    3048             : {
    3049             : 
    3050             :     // Function information:
    3051             :     //       Author         Linda Lawrie
    3052             :     //       Date written   October 2005
    3053             :     //       Modified       na
    3054             :     //       Re-engineered  na
    3055             : 
    3056             :     // Purpose of this function:
    3057             :     // Determine if a point is inside a simple 2d polygon.  For a simple polygon (one whose
    3058             :     // boundary never crosses itself).  The polygon does not need to be convex.
    3059             : 
    3060             :     // References:
    3061             :     // M Shimrat, Position of Point Relative to Polygon, ACM Algorithm 112,
    3062             :     // Communications of the ACM, Volume 5, Number 8, page 434, August 1962.
    3063             : 
    3064             :     // Use statements:
    3065             :     // Using/Aliasing
    3066             :     using namespace DataVectorTypes;
    3067             : 
    3068             :     // Return value
    3069             :     bool inside; // return value, true=inside, false = not inside
    3070             : 
    3071          76 :     EP_SIZE_CHECK(polygon_3d, nsides);
    3072             : 
    3073             :     int i;
    3074             :     int ip1;
    3075             : 
    3076             :     // Object Data
    3077         152 :     Array1D<Vector_2d> polygon(nsides);
    3078         152 :     Vector_2d point;
    3079             : 
    3080          76 :     inside = false;
    3081          76 :     if (ignorex) {
    3082          40 :         for (int i = 1; i <= nsides; ++i) {
    3083          32 :             polygon(i).x = polygon_3d(i).y;
    3084          32 :             polygon(i).y = polygon_3d(i).z;
    3085             :         }
    3086           8 :         point.x = point_3d.y;
    3087           8 :         point.y = point_3d.z;
    3088          68 :     } else if (ignorey) {
    3089          20 :         for (int i = 1; i <= nsides; ++i) {
    3090          16 :             polygon(i).x = polygon_3d(i).x;
    3091          16 :             polygon(i).y = polygon_3d(i).z;
    3092             :         }
    3093           4 :         point.x = point_3d.x;
    3094           4 :         point.y = point_3d.z;
    3095          64 :     } else if (ignorez) {
    3096         576 :         for (int i = 1; i <= nsides; ++i) {
    3097         512 :             polygon(i).x = polygon_3d(i).x;
    3098         512 :             polygon(i).y = polygon_3d(i).y;
    3099             :         }
    3100          64 :         point.x = point_3d.x;
    3101          64 :         point.y = point_3d.y;
    3102             :     } else { // Illegal
    3103           0 :         assert(false);
    3104             :         point.x = point.y = 0.0; // Elim possibly used uninitialized warnings
    3105             :     }
    3106             : 
    3107         636 :     for (i = 1; i <= nsides; ++i) {
    3108             : 
    3109         560 :         if (i < nsides) {
    3110         484 :             ip1 = i + 1;
    3111             :         } else {
    3112          76 :             ip1 = 1;
    3113             :         }
    3114             : 
    3115         560 :         if ((polygon(i).y < point.y && point.y <= polygon(ip1).y) || (point.y <= polygon(i).y && polygon(ip1).y < point.y)) {
    3116         152 :             if ((point.x - polygon(i).x) - (point.y - polygon(i).y) * (polygon(ip1).x - polygon(i).x) / (polygon(ip1).y - polygon(i).y) < 0) {
    3117          76 :                 inside = !inside;
    3118             :             }
    3119             :         }
    3120             :     }
    3121             : 
    3122         152 :     return inside;
    3123             : }
    3124             : 
    3125         331 : void ComputeIntSolarAbsorpFactors(EnergyPlusData &state)
    3126             : {
    3127             : 
    3128             :     // SUBROUTINE INFORMATION:
    3129             :     //       AUTHOR         Legacy Code
    3130             :     //       MODIFIED       B. Griffith, Oct 2010, deal with no floor case
    3131             :     //                      L. Lawrie, Mar 2012, relax >154 tilt even further (>120 considered non-wall by ASHRAE)
    3132             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    3133             : 
    3134             :     // PURPOSE OF THIS SUBROUTINE:
    3135             :     // This routine computes the fractions of diffusely transmitted
    3136             :     // solar energy absorbed by each zone surface.
    3137             : 
    3138             :     // METHODOLOGY EMPLOYED:
    3139             :     // It is assumed that all transmitted solar energy is incident
    3140             :     // on the floors of the zone (or enclosure).  The fraction directly absorbed in
    3141             :     // the floor is given by 'ISABSF'.  It is proportional to the
    3142             :     // area * solar absorptance.  The remaining solar energy is then
    3143             :     // distributed uniformly around the room according to
    3144             :     // area*absorptance product
    3145             : 
    3146             :     // REFERENCES:
    3147             :     // BLAST/IBLAST code, original author George Walton
    3148             : 
    3149             :     using namespace DataWindowEquivalentLayer;
    3150             : 
    3151             :     Real64 AreaSum;       // Intermediate calculation value
    3152             :     int Lay;              // Window glass layer number
    3153             :     Real64 AbsDiffTotWin; // Sum of a window's glass layer solar absorptances
    3154             :     Real64 TestFractSum;
    3155             :     Real64 HorizAreaSum;
    3156             : 
    3157        2324 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3158        1993 :         auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
    3159             : 
    3160        1993 :         AreaSum = 0.0;
    3161        1993 :         TestFractSum = 0.0;
    3162       19085 :         for (int const SurfNum : thisEnclosure.SurfacePtr) {
    3163       34184 :             if (state.dataHeatBal->Zone(state.dataSurface->Surface(SurfNum).Zone).OfType == StandardZone &&
    3164       17092 :                 state.dataSurface->Surface(SurfNum).CosTilt < -0.5) {
    3165        3046 :                 AreaSum += state.dataSurface->Surface(SurfNum).Area;
    3166             :             }
    3167             :         }
    3168             : 
    3169        1993 :         HorizAreaSum = AreaSum;
    3170             : 
    3171        1993 :         if ((thisEnclosure.FloorArea <= 0.0) && (HorizAreaSum > 0.0)) {
    3172             :             // fill floor area even though surfs not called "Floor", they are roughly horizontal and face upwards.
    3173           0 :             thisEnclosure.FloorArea = HorizAreaSum;
    3174           0 :             ShowWarningError(state, "ComputeIntSolarAbsorpFactors: Solar distribution model is set to place solar gains on the zone floor,");
    3175           0 :             ShowContinueError(state, "...Enclosure=\"" + thisEnclosure.Name + "\" has no floor, but has approximate horizontal surfaces.");
    3176           0 :             ShowContinueError(state, format("...these Tilt > 120 degrees, (area=[{:.2R}] m2) will be used.", HorizAreaSum));
    3177             :         }
    3178             : 
    3179             :         // Compute ISABSF
    3180             : 
    3181       19085 :         for (int const SurfNum : thisEnclosure.SurfacePtr) {
    3182             : 
    3183             :             // only horizontal surfaces. !      !CR 8229, relaxed from -0.99 to -0.5  (Tilt > 154)
    3184             :             // only horizontal surfaces. !      !CR8769 use ASHRAE std of >120, -0.9 to -0.5  (Tilt > 120)
    3185       51276 :             if ((state.dataHeatBal->Zone(state.dataSurface->Surface(SurfNum).Zone).OfType != StandardZone ||
    3186       23184 :                  state.dataSurface->Surface(SurfNum).CosTilt < -0.5) &&
    3187        3046 :                 (state.dataHeatBal->Zone(state.dataSurface->Surface(SurfNum).Zone).OfType == StandardZone ||
    3188           0 :                  state.dataSurface->Surface(SurfNum).ExtBoundCond > 0)) {
    3189             : 
    3190        3046 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3191             :                 // last minute V3.1
    3192        3046 :                 if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
    3193        3046 :                     if (AreaSum > 0.0)
    3194        3046 :                         state.dataSolarShading->SurfIntAbsFac(SurfNum) =
    3195        3046 :                             state.dataSurface->Surface(SurfNum).Area * state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar / AreaSum;
    3196             :                 } else { // Window (floor windows are assumed to have no shading device and no divider,
    3197             :                     // and assumed to be non-switchable)
    3198           0 :                     AbsDiffTotWin = 0.0;
    3199           0 :                     if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) {
    3200           0 :                         for (Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNum).TotGlassLayers; ++Lay) {
    3201           0 :                             AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay);
    3202             :                         }
    3203             :                     } else {
    3204           0 :                         for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(ConstrNum).EQLConsPtr).NL; ++Lay) {
    3205           0 :                             AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBackEQL(Lay);
    3206             :                         }
    3207             :                     }
    3208           0 :                     if (AreaSum > 0.0)
    3209           0 :                         state.dataSolarShading->SurfIntAbsFac(SurfNum) = state.dataSurface->Surface(SurfNum).Area * AbsDiffTotWin / AreaSum;
    3210             :                 }
    3211             :             }
    3212             :             // CR 8229  test ISABSF for problems
    3213       17092 :             TestFractSum += state.dataSolarShading->SurfIntAbsFac(SurfNum);
    3214             :         }
    3215             : 
    3216        1993 :         if (TestFractSum <= 0.0) {
    3217           0 :             if (thisEnclosure.ExtWindowArea > 0.0) { // we have a problem, the sun has no floor to go to
    3218           0 :                 if (thisEnclosure.FloorArea <= 0.0) {
    3219           0 :                     ShowSevereError(state, "ComputeIntSolarAbsorpFactors: Solar distribution model is set to place solar gains on the zone floor,");
    3220           0 :                     ShowContinueError(state, "but Zone or Enclosure =\"" + thisEnclosure.Name + "\" does not appear to have any floor surfaces.");
    3221           0 :                     ShowContinueError(state, "Solar gains will be spread evenly on all surfaces in the zone, and the simulation continues...");
    3222             :                 } else { // Floor Area > 0 but still can't absorb
    3223           0 :                     ShowSevereError(state, "ComputeIntSolarAbsorpFactors: Solar distribution model is set to place solar gains on the zone floor,");
    3224           0 :                     ShowContinueError(state, "but Zone or Enclosure =\"" + thisEnclosure.Name + "\" floor cannot absorb any solar gains. ");
    3225           0 :                     ShowContinueError(state, "Check the solar absorptance of the inside layer of the floor surface construction/material.");
    3226           0 :                     ShowContinueError(state, "Solar gains will be spread evenly on all surfaces in the zone, and the simulation continues...");
    3227             :                 }
    3228             : 
    3229             :                 // try again but use an even spread across all the surfaces in the zone, regardless of horizontal
    3230             :                 //  so as to not lose solar energy
    3231           0 :                 AreaSum = 0.0;
    3232           0 :                 for (int SurfNum : thisEnclosure.SurfacePtr) {
    3233           0 :                     AreaSum += state.dataSurface->Surface(SurfNum).Area;
    3234             :                 }
    3235             : 
    3236           0 :                 for (int const SurfNum : thisEnclosure.SurfacePtr) {
    3237           0 :                     int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3238           0 :                     if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
    3239           0 :                         if (AreaSum > 0.0)
    3240           0 :                             state.dataSolarShading->SurfIntAbsFac(SurfNum) =
    3241           0 :                                 state.dataSurface->Surface(SurfNum).Area * state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar / AreaSum;
    3242             :                     } else { // Window (floor windows are assumed to have no shading device and no divider,
    3243             :                         // and assumed to be non-switchable)
    3244           0 :                         AbsDiffTotWin = 0.0;
    3245           0 :                         if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) {
    3246           0 :                             for (Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNum).TotGlassLayers; ++Lay) {
    3247           0 :                                 AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay);
    3248             :                             }
    3249             :                         } else {
    3250           0 :                             for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(ConstrNum).EQLConsPtr).NL; ++Lay) {
    3251           0 :                                 AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBackEQL(Lay);
    3252             :                             }
    3253             :                         }
    3254             : 
    3255           0 :                         if (AreaSum > 0.0)
    3256           0 :                             state.dataSolarShading->SurfIntAbsFac(SurfNum) = state.dataSurface->Surface(SurfNum).Area * AbsDiffTotWin / AreaSum;
    3257             :                     }
    3258             :                 }
    3259             :             }
    3260             :         }
    3261             : 
    3262             :     } // enclosure loop
    3263         331 : }
    3264             : 
    3265     3190118 : void CLIP(EnergyPlusData &state, int const NVT, Array1D<Real64> &XVT, Array1D<Real64> &YVT, Array1D<Real64> &ZVT)
    3266             : {
    3267             : 
    3268             :     // SUBROUTINE INFORMATION:
    3269             :     //       AUTHOR         Legacy Code
    3270             :     //       DATE WRITTEN
    3271             :     //       MODIFIED       na
    3272             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    3273             : 
    3274             :     // PURPOSE OF THIS SUBROUTINE:
    3275             :     // This subroutine 'clips' the shadow casting surface polygon so that
    3276             :     // none of it lies below the plane of the receiving surface polygon.  This
    3277             :     // prevents the casting of 'false' shadows.
    3278             : 
    3279             :     // REFERENCES:
    3280             :     // BLAST/IBLAST code, original author George Walton
    3281             : 
    3282     3190118 :     int NABOVE(0);    // Number of vertices of shadow casting surface. above the plane of receiving surface
    3283     3190118 :     int NEXT(0);      // First vertex above plane of receiving surface
    3284     3190118 :     int NON(0);       // Number of vertices of shadow casting surface. on plane of receiving surface
    3285     3190118 :     Real64 XIN(0.0);  // X of entry point of shadow casting surface. into plane of receiving surface
    3286     3190118 :     Real64 XOUT(0.0); // X of exit point of shadow casting surface. from plane of receiving surface
    3287     3190118 :     Real64 YIN(0.0);  // Y of entry point of shadow casting surface. into plane of receiving surface
    3288     3190118 :     Real64 YOUT(0.0); // Y of exit point of shadow casting surface. from plane of receiving surface
    3289             :     //  INTEGER NVS      ! Number of vertices of the shadow/clipped surface
    3290             : 
    3291             :     // Determine if the shadow casting surface. is above, below, or intersects with the plane of the receiving surface
    3292             : 
    3293     3190118 :     state.dataSolarShading->NumVertInShadowOrClippedSurface = state.dataSolarShading->NVS;
    3294    15883650 :     for (int N = 1; N <= NVT; ++N) {
    3295    12693532 :         Real64 const ZVT_N(ZVT(N));
    3296    12693532 :         if (ZVT_N > 0.0) {
    3297    10078171 :             ++NABOVE;
    3298     2615361 :         } else if (ZVT_N == 0.0) {
    3299     1286696 :             ++NON;
    3300             :         }
    3301             :     }
    3302             : 
    3303     3190118 :     if (NABOVE + NON == NVT) { // Rename the unclipped shadow casting surface.
    3304             : 
    3305     2524049 :         state.dataSolarShading->NVS = NVT;
    3306     2524049 :         state.dataSolarShading->NumVertInShadowOrClippedSurface = NVT;
    3307    12592041 :         for (int N = 1; N <= NVT; ++N) {
    3308    10067992 :             state.dataSolarShading->XVC(N) = XVT(N);
    3309    10067992 :             state.dataSolarShading->YVC(N) = YVT(N);
    3310    10067992 :             state.dataSolarShading->ZVC(N) = ZVT(N);
    3311             :         }
    3312             : 
    3313      666069 :     } else if (NABOVE == 0) { // Totally submerged shadow casting surface.
    3314             : 
    3315           0 :         state.dataSolarShading->NVS = 0;
    3316           0 :         state.dataSolarShading->NumVertInShadowOrClippedSurface = 0;
    3317             : 
    3318             :     } else { // Remove (clip) that portion of the shadow casting surface. which is below the receiving surface
    3319             : 
    3320      666069 :         state.dataSolarShading->NVS = NABOVE + 2;
    3321      666069 :         state.dataSolarShading->NumVertInShadowOrClippedSurface = NABOVE + 2;
    3322      666069 :         Real64 ZVT_N, ZVT_P(ZVT(1));
    3323      666069 :         XVT(NVT + 1) = XVT(1);
    3324      666069 :         YVT(NVT + 1) = YVT(1);
    3325      666069 :         ZVT(NVT + 1) = ZVT_P;
    3326     3291609 :         for (int N = 1, P = 2; N <= NVT; ++N, ++P) {
    3327     2625540 :             ZVT_N = ZVT_P;
    3328     2625540 :             ZVT_P = ZVT(P);
    3329     2625540 :             if (ZVT_N >= 0.0 && ZVT_P < 0.0) { // Line enters plane of receiving surface
    3330      666069 :                 Real64 const ZVT_fac(1.0 / (ZVT_P - ZVT_N));
    3331      666069 :                 XIN = (ZVT_P * XVT(N) - ZVT_N * XVT(P)) * ZVT_fac;
    3332      666069 :                 YIN = (ZVT_P * YVT(N) - ZVT_N * YVT(P)) * ZVT_fac;
    3333     1959471 :             } else if (ZVT_N <= 0.0 && ZVT_P > 0.0) { // Line exits plane of receiving surface
    3334      666069 :                 NEXT = N + 1;
    3335      666069 :                 Real64 const ZVT_fac(1.0 / (ZVT_P - ZVT_N));
    3336      666069 :                 XOUT = (ZVT_P * XVT(N) - ZVT_N * XVT(P)) * ZVT_fac;
    3337      666069 :                 YOUT = (ZVT_P * YVT(N) - ZVT_N * YVT(P)) * ZVT_fac;
    3338             :             }
    3339             :         }
    3340             : 
    3341             :         // Renumber the vertices of the clipped shadow casting surface. so they are still counter-clockwise sequential.
    3342             : 
    3343      666069 :         state.dataSolarShading->XVC(1) = XOUT; //? Verify that the IN and OUT values were ever set?
    3344      666069 :         state.dataSolarShading->YVC(1) = YOUT;
    3345      666069 :         state.dataSolarShading->ZVC(1) = 0.0;
    3346      666069 :         state.dataSolarShading->XVC(state.dataSolarShading->NVS) = XIN;
    3347      666069 :         state.dataSolarShading->YVC(state.dataSolarShading->NVS) = YIN;
    3348      666069 :         state.dataSolarShading->ZVC(state.dataSolarShading->NVS) = 0.0;
    3349     1938253 :         for (int N = 1; N <= NABOVE; ++N) {
    3350     1272184 :             if (NEXT > NVT) NEXT = 1;
    3351     1272184 :             state.dataSolarShading->XVC(N + 1) = XVT(NEXT);
    3352     1272184 :             state.dataSolarShading->YVC(N + 1) = YVT(NEXT);
    3353     1272184 :             state.dataSolarShading->ZVC(N + 1) = ZVT(NEXT);
    3354     1272184 :             ++NEXT;
    3355             :         }
    3356             :     }
    3357     3190118 : }
    3358             : 
    3359     5969245 : void CTRANS(EnergyPlusData &state,
    3360             :             int const NS,         // Surface number whose vertex coordinates are being transformed
    3361             :             int const NGRS,       // Base surface number for surface NS
    3362             :             int &NVT,             // Number of vertices for surface NS
    3363             :             Array1D<Real64> &XVT, // XYZ coordinates of vertices of NS in plane of NGRS
    3364             :             Array1D<Real64> &YVT,
    3365             :             Array1D<Real64> &ZVT)
    3366             : {
    3367             : 
    3368             :     // SUBROUTINE INFORMATION:
    3369             :     //       AUTHOR         Legacy Code
    3370             :     //       DATE WRITTEN
    3371             :     //       MODIFIED       na
    3372             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    3373             : 
    3374             :     // PURPOSE OF THIS SUBROUTINE:
    3375             :     // Transforms the general coordinates of the vertices
    3376             :     // of surface NS to coordinates in the plane of the receiving surface NGRS.
    3377             :     // See subroutine 'CalcCoordinateTransformation' SurfaceGeometry Module.
    3378             : 
    3379             :     // REFERENCES:
    3380             :     // BLAST/IBLAST code, original author George Walton
    3381             :     // NECAP subroutine 'SHADOW'
    3382             : 
    3383             :     Real64 Xdif; // Intermediate Result
    3384             :     Real64 Ydif; // Intermediate Result
    3385             :     Real64 Zdif; // Intermediate Result
    3386             : 
    3387             :     // Tuned
    3388     5969245 :     auto const &surface(state.dataSurface->Surface(NS));
    3389     5969245 :     auto const &base_surface(state.dataSurface->Surface(NGRS));
    3390     5969245 :     auto const &base_lcsx(base_surface.lcsx);
    3391     5969245 :     auto const &base_lcsy(base_surface.lcsy);
    3392     5969245 :     auto const &base_lcsz(base_surface.lcsz);
    3393     5969245 :     Real64 const base_X0(state.dataSurface->X0(NGRS));
    3394     5969245 :     Real64 const base_Y0(state.dataSurface->Y0(NGRS));
    3395     5969245 :     Real64 const base_Z0(state.dataSurface->Z0(NGRS));
    3396             : 
    3397     5969245 :     NVT = surface.Sides;
    3398             : 
    3399             :     // Perform transformation
    3400    29799103 :     for (int N = 1; N <= NVT; ++N) {
    3401    23829858 :         auto const &vertex(surface.Vertex(N));
    3402             : 
    3403    23829858 :         Xdif = vertex.x - base_X0;
    3404    23829858 :         Ydif = vertex.y - base_Y0;
    3405    23829858 :         Zdif = vertex.z - base_Z0;
    3406             : 
    3407    23829858 :         if (std::abs(Xdif) <= 1.E-15) Xdif = 0.0;
    3408    23829858 :         if (std::abs(Ydif) <= 1.E-15) Ydif = 0.0;
    3409    23829858 :         if (std::abs(Zdif) <= 1.E-15) Zdif = 0.0;
    3410             : 
    3411    23829858 :         XVT(N) = base_lcsx.x * Xdif + base_lcsx.y * Ydif + base_lcsx.z * Zdif;
    3412    23829858 :         YVT(N) = base_lcsy.x * Xdif + base_lcsy.y * Ydif + base_lcsy.z * Zdif;
    3413    23829858 :         ZVT(N) = base_lcsz.x * Xdif + base_lcsz.y * Ydif + base_lcsz.z * Zdif;
    3414             :     }
    3415     5969245 : }
    3416             : 
    3417           0 : void HTRANS(EnergyPlusData &state,
    3418             :             int const I,          // Mode selector: 0 - Compute H.C. of sides
    3419             :             int const NS,         // Figure Number
    3420             :             int const NumVertices // Number of vertices
    3421             : )
    3422             : {
    3423             : 
    3424             :     // SUBROUTINE INFORMATION:
    3425             :     //       AUTHOR         Legacy Code
    3426             :     //       DATE WRITTEN
    3427             :     //       MODIFIED       na
    3428             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    3429             : 
    3430             :     // PURPOSE OF THIS SUBROUTINE:
    3431             :     // This subroutine sets up the homogeneous coordinates.
    3432             :     // This routine converts the cartesian coordinates of a surface
    3433             :     // or shadow polygon to homogeneous coordinates.  It also
    3434             :     // computes the area of the polygon.
    3435             : 
    3436             :     // METHODOLOGY EMPLOYED:
    3437             :     // Note: Original legacy code used integer arithmetic (tests in subroutines
    3438             :     // INCLOS and INTCPT are sensitive to round-off error).  However, porting to Fortran 77
    3439             :     // (BLAST/IBLAST) required some variables to become REAL(r64) instead.
    3440             : 
    3441             :     // Notes on homogeneous coordinates:
    3442             :     // A point (X,Y) is represented by a 3-element vector
    3443             :     // (W*X,W*Y,W), where W may be any REAL(r64) number except 0.  a line
    3444             :     // is also represented by a 3-element vector (A,B,C).  The
    3445             :     // directed line (A,B,C) from point (W*X1,W*Y1,W) to point
    3446             :     // (V*X2,V*Y2,V) is given by (A,B,C) = (W*X1,W*Y1,W) cross
    3447             :     // (V*X2,V*Y2,V).  The sequence of the cross product is a
    3448             :     // convention to determine sign.  The condition that a point lie
    3449             :     // on a line is that (A,B,C) dot (W*X,W*Y,W) = 0.  'Normalize'
    3450             :     // the representation of a point by setting W to 1.  Then if
    3451             :     // (A,B,C) dot (X,Y,1) > 0.0, The point is to the left of the
    3452             :     // line, and if it is less than zero, the point is to the right
    3453             :     // of the line.  The intercept of two lines is given by
    3454             :     // (W*X,W*Y,W) = (A1,B1,C1) cross (A2,B2,C3).
    3455             : 
    3456             :     // REFERENCES:
    3457             :     // BLAST/IBLAST code, original author George Walton
    3458             :     // W. M. Newman & R. F. Sproull, 'Principles of Interactive Computer Graphics', Appendix II, McGraw-Hill, 1973.
    3459             :     // 'CRC Math Tables', 22 ED, 'Analytic Geometry', P.369
    3460             : 
    3461             :     // Using/Aliasing
    3462             : 
    3463             :     // Locals
    3464             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    3465             :     //                1 - Compute H.C. of vertices & sides
    3466             : 
    3467           0 :     if (NS > 2 * state.dataSolarShading->MaxHCS) {
    3468           0 :         ShowFatalError(state, format("Solar Shading: HTrans: Too many Figures (>{})", state.dataSolarShading->MaxHCS));
    3469             :     }
    3470             : 
    3471           0 :     state.dataSolarShading->HCNV(NS) = NumVertices;
    3472             : 
    3473             :     // Tuned Linear indexing
    3474             : 
    3475           0 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    3476           0 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
    3477           0 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
    3478           0 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
    3479           0 :     auto const l1(state.dataSolarShading->HCX.index(NS, 1));
    3480           0 :     if (I != 0) { // Transform vertices of figure ns.
    3481             : 
    3482             :         // See comment at top of module regarding HCMULT
    3483           0 :         auto l(l1);
    3484           0 :         for (int N = 1; N <= NumVertices; ++N, ++l) { // [ l ] == ( NS, N )
    3485           0 :             state.dataSolarShading->HCX[l] = nint64(state.dataSolarShading->XVS(N) * HCMULT);
    3486           0 :             state.dataSolarShading->HCY[l] = nint64(state.dataSolarShading->YVS(N) * HCMULT);
    3487             :         }
    3488             :     }
    3489             : 
    3490             :     // Establish extra point for finding lines between points.
    3491             : 
    3492           0 :     auto l(state.dataSolarShading->HCX.index(NS, NumVertices + 1));
    3493           0 :     Int64 HCX_m(state.dataSolarShading->HCX[l] = state.dataSolarShading->HCX[l1]); // [ l ] == ( NS, NumVertices + 1 ), [ l1 ] == ( NS, 1 )
    3494           0 :     Int64 HCY_m(state.dataSolarShading->HCY[l] = state.dataSolarShading->HCY[l1]); // [ l ] == ( NS, NumVertices + 1 ), [ l1 ] == ( NS, 1 )
    3495             : 
    3496             :     // Determine lines between points.
    3497           0 :     l = l1;
    3498           0 :     auto m(l1 + 1u);
    3499             :     Int64 HCX_l;
    3500             :     Int64 HCY_l;
    3501           0 :     Real64 SUM(0.0);                                   // Sum variable
    3502           0 :     for (int N = 1; N <= NumVertices; ++N, ++l, ++m) { // [ l ] == ( NS, N ), [ m ] == ( NS, N + 1 )
    3503           0 :         HCX_l = HCX_m;
    3504           0 :         HCY_l = HCY_m;
    3505           0 :         HCX_m = state.dataSolarShading->HCX[m];
    3506           0 :         HCY_m = state.dataSolarShading->HCY[m];
    3507           0 :         state.dataSolarShading->HCA[l] = HCY_l - HCY_m;
    3508           0 :         state.dataSolarShading->HCB[l] = HCX_m - HCX_l;
    3509           0 :         SUM += state.dataSolarShading->HCC[l] = (HCY_m * HCX_l) - (HCX_m * HCY_l);
    3510             :     }
    3511             : 
    3512             :     // Compute area of polygon.
    3513             :     //  SUM=0.0D0
    3514             :     //  DO N = 1, NumVertices
    3515             :     //    SUM = SUM + HCX(N,NS)*HCY(N+1,NS) - HCY(N,NS)*HCX(N+1,NS) ! Since HCX and HCY integerized, value of SUM should be ok
    3516             :     //  END DO
    3517           0 :     state.dataSolarShading->HCAREA(NS) = SUM * sqHCMULT_fac;
    3518             :     //  HCAREA(NS)=0.5d0*SUM*(kHCMULT)
    3519           0 : }
    3520             : 
    3521    12482904 : void HTRANS0(EnergyPlusData &state,
    3522             :              int const NS,         // Figure Number
    3523             :              int const NumVertices // Number of vertices
    3524             : )
    3525             : {
    3526             :     // Using/Aliasing
    3527             : 
    3528             :     // Locals
    3529             : 
    3530    12482904 :     if (NS > 2 * state.dataSolarShading->MaxHCS) {
    3531           0 :         ShowFatalError(state, format("Solar Shading: HTrans0: Too many Figures (>{})", state.dataSolarShading->MaxHCS));
    3532             :     }
    3533             : 
    3534    12482904 :     state.dataSolarShading->HCNV(NS) = NumVertices;
    3535             : 
    3536             :     // Tuned Linear indexing
    3537             : 
    3538    12482904 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    3539    12482904 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
    3540    12482904 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
    3541    12482904 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
    3542             : 
    3543    12482904 :     auto const l1(state.dataSolarShading->HCX.index(NS, 1));
    3544             : 
    3545    12482904 :     auto l(state.dataSolarShading->HCX.index(NS, NumVertices + 1));
    3546    12482904 :     Int64 HCX_m(state.dataSolarShading->HCX[l] = state.dataSolarShading->HCX[l1]); // [ l1 ] == ( NS, 1 )
    3547    12482904 :     Int64 HCY_m(state.dataSolarShading->HCY[l] = state.dataSolarShading->HCY[l1]); // [ l1 ] == ( NS, 1 )
    3548             : 
    3549    12482904 :     l = l1;
    3550    12482904 :     auto m(l1 + 1u);
    3551             :     Int64 HCX_l;
    3552             :     Int64 HCY_l;
    3553    12482904 :     Real64 SUM(0.0);
    3554    43217562 :     for (int N = 1; N <= NumVertices; ++N, ++l, ++m) { // [ l ] == ( NS, N ), [ m ] == ( NS, N + 1 )
    3555    30734658 :         HCX_l = HCX_m;
    3556    30734658 :         HCY_l = HCY_m;
    3557    30734658 :         HCX_m = state.dataSolarShading->HCX[m];
    3558    30734658 :         HCY_m = state.dataSolarShading->HCY[m];
    3559    30734658 :         state.dataSolarShading->HCA[l] = HCY_l - HCY_m;
    3560    30734658 :         state.dataSolarShading->HCB[l] = HCX_m - HCX_l;
    3561    30734658 :         SUM += state.dataSolarShading->HCC[l] = (HCY_m * HCX_l) - (HCX_m * HCY_l);
    3562             :     }
    3563             : 
    3564    12482904 :     state.dataSolarShading->HCAREA(NS) = SUM * sqHCMULT_fac;
    3565    12482904 : }
    3566             : 
    3567     7320027 : void HTRANS1(EnergyPlusData &state,
    3568             :              int const NS,         // Figure Number
    3569             :              int const NumVertices // Number of vertices
    3570             : )
    3571             : {
    3572             :     // Using/Aliasing
    3573             : 
    3574     7320027 :     if (NS > 2 * state.dataSolarShading->MaxHCS) {
    3575           0 :         ShowFatalError(state, format("Solar Shading: HTrans1: Too many Figures (>{})", state.dataSolarShading->MaxHCS));
    3576             :     }
    3577             : 
    3578     7320027 :     state.dataSolarShading->HCNV(NS) = NumVertices;
    3579             : 
    3580             :     // Tuned Linear indexing
    3581             : 
    3582     7320027 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    3583     7320027 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
    3584     7320027 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
    3585     7320027 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
    3586             : 
    3587     7320027 :     auto const l1(state.dataSolarShading->HCX.index(NS, 1));
    3588             : 
    3589             :     // only in HTRANS1
    3590     7320027 :     auto l(l1);
    3591    36531443 :     for (int N = 1; N <= NumVertices; ++N, ++l) { // [ l ] == ( NS, N )
    3592    29211416 :         state.dataSolarShading->HCX[l] = nint64(state.dataSolarShading->XVS(N) * HCMULT);
    3593    29211416 :         state.dataSolarShading->HCY[l] = nint64(state.dataSolarShading->YVS(N) * HCMULT);
    3594             :     }
    3595             : 
    3596     7320027 :     l = state.dataSolarShading->HCX.index(NS, NumVertices + 1);
    3597     7320027 :     Int64 HCX_m(state.dataSolarShading->HCX[l] = state.dataSolarShading->HCX[l1]); // [ l1 ] == ( NS, 1 )
    3598     7320027 :     Int64 HCY_m(state.dataSolarShading->HCY[l] = state.dataSolarShading->HCY[l1]);
    3599             : 
    3600     7320027 :     l = l1;
    3601     7320027 :     auto m(l1 + 1u);
    3602             :     Int64 HCX_l;
    3603             :     Int64 HCY_l;
    3604     7320027 :     Real64 SUM(0.0);
    3605    36531443 :     for (int N = 1; N <= NumVertices; ++N, ++l, ++m) { // [ l ] == ( NS, N ), [ m ] == ( NS, N + 1 )
    3606    29211416 :         HCX_l = HCX_m;
    3607    29211416 :         HCY_l = HCY_m;
    3608    29211416 :         HCX_m = state.dataSolarShading->HCX[m];
    3609    29211416 :         HCY_m = state.dataSolarShading->HCY[m];
    3610    29211416 :         state.dataSolarShading->HCA[l] = HCY_l - HCY_m;
    3611    29211416 :         state.dataSolarShading->HCB[l] = HCX_m - HCX_l;
    3612    29211416 :         SUM += state.dataSolarShading->HCC[l] = (HCY_m * HCX_l) - (HCX_m * HCY_l);
    3613             :     }
    3614             : 
    3615     7320027 :     state.dataSolarShading->HCAREA(NS) = SUM * sqHCMULT_fac;
    3616     7320027 : }
    3617             : 
    3618           0 : void INCLOS(EnergyPlusData &state,
    3619             :             int const N1,            // Figure number of figure 1
    3620             :             int const N1NumVert,     // Number of vertices of figure 1
    3621             :             int const N2,            // Figure number of figure 2
    3622             :             int const N2NumVert,     // Number of vertices of figure 2
    3623             :             int &NumVerticesOverlap, // Number of vertices which overlap
    3624             :             int &NIN                 // Number of vertices of figure 1 within figure 2
    3625             : )
    3626             : {
    3627             : 
    3628             :     // SUBROUTINE INFORMATION:
    3629             :     //       AUTHOR         Legacy Code
    3630             :     //       DATE WRITTEN
    3631             :     //       MODIFIED       na
    3632             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    3633             : 
    3634             :     // PURPOSE OF THIS SUBROUTINE:
    3635             :     // This subroutine determines which vertices of figure N1 lie within figure N2.
    3636             : 
    3637             :     // METHODOLOGY EMPLOYED:
    3638             :     // For vertex N of figure N1 to lie within figure N2, it must be
    3639             :     // on or to the right of all sides of figure N2, assuming
    3640             :     // figure N2 is convex.
    3641             : 
    3642             :     // REFERENCES:
    3643             :     // BLAST/IBLAST code, original author George Walton
    3644             : 
    3645             :     int K;              // Vertex number of the overlap
    3646             :     int M;              // Side number of figure N2
    3647             :     int N;              // Vertex number of figure N1
    3648             :     bool CycleMainLoop; // Sets when to cycle main loop
    3649             :     Real64 HFunct;
    3650             : 
    3651           0 :     NIN = 0;
    3652             : 
    3653           0 :     for (N = 1; N <= N1NumVert; ++N) {
    3654             : 
    3655           0 :         CycleMainLoop = false;
    3656             : 
    3657             :         // Eliminate cases where vertex N is to the left of side M.
    3658             : 
    3659           0 :         for (M = 1; M <= N2NumVert; ++M) {
    3660           0 :             HFunct = state.dataSolarShading->HCX(N1, N) * state.dataSolarShading->HCA(N2, M) +
    3661           0 :                      state.dataSolarShading->HCY(N1, N) * state.dataSolarShading->HCB(N2, M) + state.dataSolarShading->HCC(N2, M);
    3662           0 :             if (HFunct > 0.0) {
    3663           0 :                 CycleMainLoop = true; // Set to cycle to the next value of N
    3664           0 :                 break;                // M DO loop
    3665             :             }
    3666             :         }
    3667             : 
    3668           0 :         if (CycleMainLoop) continue;
    3669           0 :         ++NIN;
    3670             : 
    3671             :         // Check for duplication of previously determined points.
    3672             : 
    3673           0 :         if (NumVerticesOverlap != 0) {
    3674           0 :             for (K = 1; K <= NumVerticesOverlap; ++K) {
    3675           0 :                 if ((state.dataSolarShading->XTEMP(K) == state.dataSolarShading->HCX(N1, N)) &&
    3676           0 :                     (state.dataSolarShading->YTEMP(K) == state.dataSolarShading->HCY(N1, N))) {
    3677           0 :                     CycleMainLoop = true; // Set to cycle to the next value of N
    3678           0 :                     break;                // K DO loop
    3679             :                 }
    3680             :             }
    3681           0 :             if (CycleMainLoop) continue;
    3682             :         }
    3683             : 
    3684             :         // Record enclosed vertices in temporary arrays.
    3685             : 
    3686           0 :         ++NumVerticesOverlap;
    3687           0 :         state.dataSolarShading->XTEMP(NumVerticesOverlap) = state.dataSolarShading->HCX(N1, N);
    3688           0 :         state.dataSolarShading->YTEMP(NumVerticesOverlap) = state.dataSolarShading->HCY(N1, N);
    3689             :     }
    3690           0 : }
    3691             : 
    3692           0 : void INTCPT(EnergyPlusData &state,
    3693             :             int const NV1, // Number of vertices of figure NS1
    3694             :             int const NV2, // Number of vertices of figure NS2
    3695             :             int &NV3,      // Number of vertices of figure NS3
    3696             :             int const NS1, // Number of the figure being overlapped
    3697             :             int const NS2  // Number of the figure doing overlapping
    3698             : )
    3699             : {
    3700             : 
    3701             :     // SUBROUTINE INFORMATION:
    3702             :     //       AUTHOR         Legacy Code
    3703             :     //       DATE WRITTEN
    3704             :     //       MODIFIED       na
    3705             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    3706             : 
    3707             :     // PURPOSE OF THIS SUBROUTINE:
    3708             :     // This subroutine determines all intercepts between the sides of figure NS1
    3709             :     // and the sides of figure NS2.
    3710             : 
    3711             :     // METHODOLOGY EMPLOYED:
    3712             :     // The requirements for intersection are that the end points of
    3713             :     // line N lie on both sides of line M and vice versa.  Also
    3714             :     // eliminate cases where the end point of one line lies exactly
    3715             :     // on the other to reduce duplication with the enclosed points.
    3716             : 
    3717             :     // REFERENCES:
    3718             :     // BLAST/IBLAST code, original author George Walton
    3719             : 
    3720             :     Real64 W;        // Normalization factor
    3721             :     Real64 XUntrunc; // Untruncated X coordinate
    3722             :     Real64 YUntrunc; // Untruncated Y coordinate
    3723             :     Int64 I1;        // Intermediate result for testing intersection
    3724             :     Int64 I2;        // Intermediate result for testing intersection
    3725             :     int K;
    3726             :     int KK;
    3727             :     int M; // Side number of figure NS2
    3728             :     int N; // Side number of figure NS1
    3729             : 
    3730           0 :     for (N = 1; N <= NV1; ++N) {
    3731           0 :         for (M = 1; M <= NV2; ++M) {
    3732             : 
    3733             :             // Eliminate cases where sides N and M do not intersect.
    3734             : 
    3735           0 :             I1 = state.dataSolarShading->HCA(NS1, N) * state.dataSolarShading->HCX(NS2, M) +
    3736           0 :                  state.dataSolarShading->HCB(NS1, N) * state.dataSolarShading->HCY(NS2, M) + state.dataSolarShading->HCC(NS1, N);
    3737           0 :             I2 = state.dataSolarShading->HCA(NS1, N) * state.dataSolarShading->HCX(NS2, M + 1) +
    3738           0 :                  state.dataSolarShading->HCB(NS1, N) * state.dataSolarShading->HCY(NS2, M + 1) + state.dataSolarShading->HCC(NS1, N);
    3739           0 :             if (I1 >= 0 && I2 >= 0) continue;
    3740           0 :             if (I1 <= 0 && I2 <= 0) continue;
    3741             : 
    3742           0 :             I1 = state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCX(NS1, N) +
    3743           0 :                  state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCY(NS1, N) + state.dataSolarShading->HCC(NS2, M);
    3744           0 :             I2 = state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCX(NS1, N + 1) +
    3745           0 :                  state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCY(NS1, N + 1) + state.dataSolarShading->HCC(NS2, M);
    3746           0 :             if (I1 >= 0 && I2 >= 0) continue;
    3747           0 :             if (I1 <= 0 && I2 <= 0) continue;
    3748             : 
    3749             :             // Determine the point of intersection and record in the temporary array.
    3750             : 
    3751           0 :             KK = NV3;
    3752           0 :             ++NV3;
    3753           0 :             W = state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCA(NS1, N) -
    3754           0 :                 state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCB(NS1, N);
    3755           0 :             XUntrunc = (state.dataSolarShading->HCC(NS2, M) * state.dataSolarShading->HCB(NS1, N) -
    3756           0 :                         state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCC(NS1, N)) /
    3757             :                        W;
    3758           0 :             YUntrunc = (state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCC(NS1, N) -
    3759           0 :                         state.dataSolarShading->HCC(NS2, M) * state.dataSolarShading->HCA(NS1, N)) /
    3760             :                        W;
    3761           0 :             if (NV3 > isize(state.dataSolarShading->XTEMP)) {
    3762           0 :                 state.dataSolarShading->XTEMP.redimension(isize(state.dataSolarShading->XTEMP) + 10, 0.0);
    3763           0 :                 state.dataSolarShading->YTEMP.redimension(isize(state.dataSolarShading->YTEMP) + 10, 0.0);
    3764             :             }
    3765           0 :             state.dataSolarShading->XTEMP(NV3) = nint64(XUntrunc);
    3766           0 :             state.dataSolarShading->YTEMP(NV3) = nint64(YUntrunc);
    3767             : 
    3768             :             // Eliminate near-duplicate points.
    3769             : 
    3770           0 :             if (KK != 0) {
    3771           0 :                 auto const x(state.dataSolarShading->XTEMP(NV3));
    3772           0 :                 auto const y(state.dataSolarShading->YTEMP(NV3));
    3773           0 :                 for (K = 1; K <= KK; ++K) {
    3774           0 :                     if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
    3775           0 :                     if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
    3776           0 :                     NV3 = KK;
    3777           0 :                     break; // K DO loop
    3778             :                 }
    3779             :             }
    3780             :         }
    3781             :     }
    3782           0 : }
    3783             : 
    3784           0 : inline bool neq(Real64 a, Real64 b)
    3785             : {
    3786           0 :     return std::abs(a - b) > 2.0;
    3787             : }
    3788             : 
    3789           0 : inline bool d_eq(Real64 a, Real64 b)
    3790             : {
    3791           0 :     return std::abs(a - b) < 2.0;
    3792             : }
    3793             : 
    3794           0 : void CLIPLINE(Real64 &x1, Real64 &x2, Real64 &y1, Real64 &y2, Real64 maxX, Real64 minX, Real64 maxY, Real64 minY, bool &visible, bool &rev)
    3795             : {
    3796             :     // Line segment clipping
    3797             :     // Reference:
    3798             :     // Slater, M., Barsky, B.A.
    3799             :     // 2D line and polygon clipping based on space subdivision.
    3800             :     // The Visual Computer 10, 407–422 (1994).
    3801             :     Real64 dx, dy, e, xinc, yinc, tempVar;
    3802           0 :     bool needX = true, needY = true;
    3803             :     int c1, c2;
    3804             : 
    3805           0 :     if (x1 > x2) { // reverse for efficiency
    3806           0 :         tempVar = x1;
    3807           0 :         x1 = x2;
    3808           0 :         x2 = tempVar;
    3809           0 :         tempVar = y1;
    3810           0 :         y1 = y2;
    3811           0 :         y2 = tempVar;
    3812           0 :         rev = true;
    3813             :     }
    3814           0 :     if (x1 > maxX || x2 < minX) return; // x is positive
    3815           0 :     if (x1 < minX) {
    3816           0 :         if (y1 < minY) {
    3817           0 :             if (y2 < minY) return;
    3818           0 :             c1 = 0;
    3819           0 :             dx = x2 - x1;
    3820           0 :             dy = y2 - y1;
    3821           0 :             e = dy * (minX - x1) + dx * (y1 - minY);
    3822           0 :         } else if (y1 > maxY) {
    3823           0 :             if (y2 > maxY) return;
    3824           0 :             c1 = 6;
    3825           0 :             dx = x2 - x1;
    3826           0 :             dy = y2 - y1;
    3827           0 :             e = dy * (minX - x1) + dx * (y1 - maxY);
    3828             :         } else {
    3829           0 :             c1 = 3;
    3830           0 :             dx = x2 - x1;
    3831           0 :             dy = y2 - y1;
    3832           0 :             if (dy > 0) {
    3833           0 :                 e = dy * (minX - x1) + dx * (y1 - maxY);
    3834             :             } else {
    3835           0 :                 e = dy * (minX - x1) + dx * (y1 - minY);
    3836             :             }
    3837             :         }
    3838             :     } else {
    3839           0 :         if (y1 < minY) {
    3840           0 :             if (y2 < minY) return;
    3841           0 :             c1 = 1;
    3842           0 :             dx = x2 - x1;
    3843           0 :             dy = y2 - y1;
    3844           0 :             e = dy * (maxX - x1) + dx * (y1 - minY);
    3845           0 :         } else if (y1 > maxY) {
    3846           0 :             if (y2 > maxY) return;
    3847           0 :             c1 = 7;
    3848           0 :             dx = x2 - x1;
    3849           0 :             dy = y2 - y1;
    3850           0 :             e = dy * (maxX - x1) + dx * (y1 - maxY);
    3851             :         } else {
    3852           0 :             visible = true;
    3853           0 :             if (x2 <= maxX && (y2 >= minY && y2 <= maxY)) return;
    3854           0 :             c1 = 4;
    3855           0 :             dx = x2 - x1;
    3856           0 :             dy = y2 - y1;
    3857           0 :             if (dy > 0) {
    3858           0 :                 e = dy * (maxX - x1) + dx * (y1 - maxY);
    3859             :             } else {
    3860           0 :                 e = dy * (maxX - x1) + dx * (y1 - minY);
    3861             :             }
    3862             :         }
    3863             :     }
    3864           0 :     c2 = c1;
    3865           0 :     if (dy > 0) {
    3866             :         while (true) {
    3867           0 :             if (e < 0.0) {
    3868           0 :                 if (c2 == 1)
    3869           0 :                     return;
    3870           0 :                 else if (c2 == 3) {
    3871           0 :                     visible = true;
    3872           0 :                     x1 = minX;
    3873           0 :                     y1 = maxY + e / dx;
    3874           0 :                     if (x2 <= maxX && y2 <= maxY) return;
    3875           0 :                 } else if (c2 == 4) {
    3876           0 :                     x2 = maxX;
    3877           0 :                     y2 = maxY + e / dx;
    3878           0 :                     return;
    3879             :                 }
    3880           0 :                 if (needX) {
    3881           0 :                     xinc = dy * (maxX - minX);
    3882           0 :                     needX = false;
    3883             :                 }
    3884           0 :                 e += xinc;
    3885           0 :                 c2 += 1;
    3886             :             } else {
    3887           0 :                 if (c2 == 3)
    3888           0 :                     return;
    3889           0 :                 else if (c2 == 1) {
    3890           0 :                     visible = true;
    3891           0 :                     x1 = maxX - e / dy;
    3892           0 :                     y1 = minY;
    3893           0 :                     if (x2 <= maxX && y2 <= maxY) return;
    3894           0 :                 } else if (c2 == 4) {
    3895           0 :                     x2 = maxX - e / dy;
    3896           0 :                     y2 = maxY;
    3897           0 :                     return;
    3898             :                 }
    3899           0 :                 if (needY) {
    3900           0 :                     yinc = dx * (maxY - minY);
    3901           0 :                     needY = false;
    3902             :                 }
    3903           0 :                 e -= yinc;
    3904           0 :                 c2 += 3;
    3905             :             }
    3906             :         }
    3907             :     } else {
    3908             :         while (true) {
    3909           0 :             if (e >= 0.0) {
    3910           0 :                 if (c2 == 7)
    3911           0 :                     return;
    3912           0 :                 else if (c2 == 3) {
    3913           0 :                     visible = true;
    3914           0 :                     x1 = minX;
    3915           0 :                     y1 = minY + e / dx;
    3916           0 :                     if (x2 <= maxX && y2 >= minY) return;
    3917           0 :                 } else if (c2 == 4) {
    3918           0 :                     x2 = maxX;
    3919           0 :                     y2 = minY + e / dx;
    3920           0 :                     return;
    3921             :                 }
    3922           0 :                 if (needX) {
    3923           0 :                     xinc = dy * (maxX - minX);
    3924           0 :                     needX = false;
    3925             :                 }
    3926           0 :                 e += xinc;
    3927           0 :                 c2 += 1;
    3928             :             } else {
    3929           0 :                 if (c2 == 3)
    3930           0 :                     return;
    3931           0 :                 else if (c2 == 7) {
    3932           0 :                     visible = true;
    3933           0 :                     x1 = maxX - e / dy;
    3934           0 :                     y1 = maxY;
    3935           0 :                     if (x2 <= maxX && y2 >= minY) return;
    3936           0 :                 } else if (c2 == 4) {
    3937           0 :                     x2 = maxX - e / dy;
    3938           0 :                     y2 = minY;
    3939           0 :                     return;
    3940             :                 }
    3941           0 :                 if (needY) {
    3942           0 :                     yinc = dx * (maxY - minY);
    3943           0 :                     needY = false;
    3944             :                 }
    3945           0 :                 e += yinc;
    3946           0 :                 c2 -= 3;
    3947             :             }
    3948             :         }
    3949             :     }
    3950             : }
    3951             : 
    3952           0 : void CLIPRECT(EnergyPlusData &state, int const NS2, int const NV1, int &NV3)
    3953             : {
    3954             :     // Polygon clipping by line segment clipping for rectangles
    3955             :     // Reference:
    3956             :     // Slater, M., Barsky, B.A.
    3957             :     // 2D line and polygon clipping based on space subdivision.
    3958             :     // The Visual Computer 10, 407–422 (1994).
    3959           0 :     bool INTFLAG = false;
    3960           0 :     auto l(state.dataSolarShading->HCA.index(NS2, 1));
    3961             :     Real64 maxX, minX, maxY, minY;
    3962           0 :     if (state.dataSolarShading->HCX[l] > state.dataSolarShading->HCX[l + 2]) {
    3963           0 :         maxX = state.dataSolarShading->HCX[l];
    3964           0 :         minX = state.dataSolarShading->HCX[l + 2];
    3965             :     } else {
    3966           0 :         maxX = state.dataSolarShading->HCX[l + 2];
    3967           0 :         minX = state.dataSolarShading->HCX[l];
    3968             :     }
    3969           0 :     if (state.dataSolarShading->HCY[l] > state.dataSolarShading->HCY[l + 2]) {
    3970           0 :         maxY = state.dataSolarShading->HCY[l];
    3971           0 :         minY = state.dataSolarShading->HCY[l + 2];
    3972             :     } else {
    3973           0 :         maxY = state.dataSolarShading->HCY[l + 2];
    3974           0 :         minY = state.dataSolarShading->HCY[l];
    3975             :     }
    3976             : 
    3977             :     Real64 arrx[20]; // Temp array for output X
    3978             :     Real64 arry[20]; // Temp array for output Y
    3979           0 :     int arrc = 0;    // Number of items in output
    3980             : 
    3981           0 :     for (int j = 0; j < NV1; ++j) {
    3982           0 :         Real64 x_1 = state.dataSolarShading->XTEMP[j];
    3983           0 :         Real64 y_1 = state.dataSolarShading->YTEMP[j];
    3984           0 :         Real64 x_2 = state.dataSolarShading->XTEMP[(j + 1) % NV1];
    3985           0 :         Real64 y_2 = state.dataSolarShading->YTEMP[(j + 1) % NV1];
    3986           0 :         Real64 x1 = x_1, x2 = x_2, y1 = y_1, y2 = y_2;
    3987             : 
    3988           0 :         bool visible = false;
    3989           0 :         bool rev = false;
    3990           0 :         CLIPLINE(x_1, x_2, y_1, y_2, maxX, minX, maxY, minY, visible, rev);
    3991           0 :         if (visible) {
    3992           0 :             if ((x_1 != x1 || y_1 != y1) || (x_2 != x2 || y_2 != y2)) {
    3993           0 :                 INTFLAG = true;
    3994             :             }
    3995           0 :             if (rev) { // undo reverse
    3996           0 :                 auto tempVar = x_1;
    3997           0 :                 x_1 = x_2;
    3998           0 :                 x_2 = tempVar;
    3999           0 :                 tempVar = y_1;
    4000           0 :                 y_1 = y_2;
    4001           0 :                 y_2 = tempVar;
    4002             :             }
    4003             :             // if line on edge, or inside, add both points
    4004           0 :             if (arrc == 0 || ((neq(arrx[arrc - 1], x_1) || neq(arry[arrc - 1], y_1)) && (neq(arrx[0], x_1) || neq(arry[0], y_1)))) {
    4005           0 :                 arrx[arrc] = x_1;
    4006           0 :                 arry[arrc] = y_1;
    4007           0 :                 arrc += 1;
    4008           0 :                 if ((neq(x_1, x_2) || neq(y_1, y_2)) && (neq(arrx[0], x_2) || neq(arry[0], y_2))) {
    4009           0 :                     arrx[arrc] = x_2;
    4010           0 :                     arry[arrc] = y_2;
    4011           0 :                     arrc += 1;
    4012             :                 }
    4013           0 :             } else if ((neq(arrx[arrc - 1], x_2) || neq(arry[arrc - 1], y_2)) && (neq(arrx[0], x_2) || neq(arry[0], y_2))) {
    4014           0 :                 arrx[arrc] = x_2;
    4015           0 :                 arry[arrc] = y_2;
    4016           0 :                 arrc += 1;
    4017             :             }
    4018             :         }
    4019             :     }
    4020           0 :     NV3 = arrc;
    4021             : 
    4022             :     // Re-populate XTEMP/YTEMP
    4023           0 :     if (NV3 > 1) {
    4024           0 :         int LastEdgeIndex = -1, incr = 0;
    4025           0 :         double cornerXs[4] = {minX, minX, maxX, maxX};
    4026           0 :         double cornerYs[4] = {minY, maxY, maxY, minY};
    4027           0 :         Real64 edges[4] = {minX, maxY, maxX, minY};
    4028             :         Real64 LastEdgeX, LastEdgeY;
    4029           0 :         for (int i = 0; i <= arrc; i++) {
    4030           0 :             int k = i % arrc;
    4031             : 
    4032           0 :             Real64 currX = arrx[k], currY = arry[k];
    4033             : 
    4034           0 :             int edgeCount = 0, EdgeIndex = -1;
    4035           0 :             for (int m = 0; m < 4; m++) {
    4036           0 :                 if (m % 2 == 0 && d_eq(currX, edges[m])) { // MinX or MaxX
    4037           0 :                     edgeCount++;
    4038           0 :                     EdgeIndex = m;
    4039           0 :                 } else if (m % 2 == 1 && d_eq(currY, edges[m])) {
    4040           0 :                     edgeCount++;
    4041           0 :                     EdgeIndex = m;
    4042             :                 }
    4043             :             }
    4044           0 :             if (edgeCount == 0) { // On inside
    4045           0 :                 if (i != arrc) {
    4046           0 :                     state.dataSolarShading->XTEMP[incr] = currX;
    4047           0 :                     state.dataSolarShading->YTEMP[incr] = currY;
    4048           0 :                     incr++;
    4049             :                 }
    4050           0 :                 continue;
    4051           0 :             } else if (edgeCount > 1) { // On corner
    4052           0 :                 if (d_eq(currX, minX)) {
    4053           0 :                     if (d_eq(currY, minY)) {
    4054           0 :                         EdgeIndex = 3;
    4055             :                     } else {
    4056           0 :                         EdgeIndex = 0;
    4057             :                     }
    4058             :                 } else {
    4059           0 :                     if (d_eq(currY, maxY)) {
    4060           0 :                         EdgeIndex = 1;
    4061             :                     } else {
    4062           0 :                         EdgeIndex = 2;
    4063             :                     }
    4064             :                 }
    4065             :             }
    4066           0 :             if ((LastEdgeIndex > -1 && EdgeIndex > -1) && LastEdgeIndex != EdgeIndex) {
    4067           0 :                 int jumpCount = 0;
    4068           0 :                 if ((EdgeIndex == 0 && LastEdgeIndex == 3) || (EdgeIndex - LastEdgeIndex == 1)) {
    4069           0 :                     jumpCount = 1;
    4070           0 :                 } else if (EdgeIndex % 2 == LastEdgeIndex % 2) {
    4071             :                     // Clockwise double jump
    4072           0 :                     jumpCount = 2;
    4073           0 :                 } else if ((EdgeIndex == 3 && LastEdgeIndex == 0) || (LastEdgeIndex - EdgeIndex == 1)) {
    4074             :                     // Clockwise triple jump
    4075           0 :                     jumpCount = 3;
    4076             :                 }
    4077           0 :                 if (jumpCount > 0) {
    4078             :                     Real64 cornerX;
    4079             :                     Real64 cornerY;
    4080           0 :                     int startIndex = (LastEdgeIndex + 1) % 4;
    4081           0 :                     int added = 0;
    4082           0 :                     for (int i1 = startIndex, j1 = 0; j1 < jumpCount; i1 = (i1 + 1) % 4, j1++) {
    4083           0 :                         cornerX = cornerXs[i1];
    4084           0 :                         cornerY = cornerYs[i1];
    4085           0 :                         if (cornerX == LastEdgeX && cornerY == LastEdgeY) continue; // skip if jump started on corner
    4086             : 
    4087           0 :                         bool insideFlag = true;
    4088           0 :                         for (int j = 0; j < NV1; ++j) {
    4089           0 :                             if ((state.dataSolarShading->ATEMP[j] * cornerX) + (cornerY * state.dataSolarShading->BTEMP[j]) +
    4090           0 :                                     state.dataSolarShading->CTEMP[j] >
    4091             :                                 0.0) {
    4092           0 :                                 insideFlag = false;
    4093           0 :                                 break;
    4094             :                             }
    4095             :                         }
    4096             : 
    4097           0 :                         if (insideFlag &&
    4098           0 :                             (incr == 0 ||
    4099           0 :                              ((neq(cornerX, state.dataSolarShading->XTEMP[incr - 1]) || neq(cornerY, state.dataSolarShading->YTEMP[incr - 1])) &&
    4100           0 :                               (neq(cornerX, state.dataSolarShading->XTEMP[0]) || neq(cornerY, state.dataSolarShading->YTEMP[0]))))) {
    4101           0 :                             state.dataSolarShading->XTEMP[incr] = cornerX;
    4102           0 :                             state.dataSolarShading->YTEMP[incr] = cornerY;
    4103           0 :                             incr++;
    4104           0 :                             added++;
    4105             :                         }
    4106             :                     }
    4107           0 :                     if (jumpCount > 2 && (added == jumpCount && edgeCount == 1)) {
    4108           0 :                         if (i != arrc) {
    4109           0 :                             state.dataSolarShading->XTEMP[incr] = currX;
    4110           0 :                             state.dataSolarShading->YTEMP[incr] = currY;
    4111           0 :                             incr++;
    4112             :                         }
    4113           0 :                         break;
    4114             :                     }
    4115             :                 }
    4116             :             }
    4117           0 :             if (i != arrc) {
    4118           0 :                 state.dataSolarShading->XTEMP[incr] = currX;
    4119           0 :                 state.dataSolarShading->YTEMP[incr] = currY;
    4120           0 :                 incr++;
    4121             :             }
    4122           0 :             LastEdgeIndex = EdgeIndex;
    4123           0 :             LastEdgeX = currX;
    4124           0 :             LastEdgeY = currY;
    4125             :         }
    4126           0 :         NV3 = incr;
    4127             : 
    4128             :     } else {
    4129           0 :         if (NV3 == 1) {
    4130           0 :             state.dataSolarShading->XTEMP[0] = arrx[0];
    4131           0 :             state.dataSolarShading->YTEMP[0] = arry[0];
    4132             :         }
    4133           0 :         if (NV3 == 0) {
    4134           0 :             double cornerXs[4] = {minX, minX, maxX, maxX};
    4135           0 :             double cornerYs[4] = {minY, maxY, maxY, minY};
    4136           0 :             Real64 cornerX = cornerXs[0];
    4137           0 :             Real64 cornerY = cornerYs[0];
    4138           0 :             bool insideFlag = true;
    4139           0 :             for (int j = 0; j < NV1; ++j) {
    4140           0 :                 if ((state.dataSolarShading->ATEMP[j] * cornerX) + (cornerY * state.dataSolarShading->BTEMP[j]) + state.dataSolarShading->CTEMP[j] >=
    4141             :                     0.0) {
    4142           0 :                     insideFlag = false;
    4143           0 :                     break;
    4144             :                 }
    4145             :             }
    4146           0 :             if (insideFlag) {
    4147           0 :                 for (int i1 = 0; i1 < 4; i1++) {
    4148           0 :                     state.dataSolarShading->XTEMP[i1] = cornerXs[i1];
    4149           0 :                     state.dataSolarShading->YTEMP[i1] = cornerYs[i1];
    4150             :                 }
    4151           0 :                 NV3 = 4;
    4152           0 :                 INTFLAG = true;
    4153             :             }
    4154             :         }
    4155             :     }
    4156             : 
    4157             :     // update homogenous edges A,B,C
    4158           0 :     if (NV3 > 0) {
    4159           0 :         Real64 const X_0(state.dataSolarShading->XTEMP[0]);
    4160           0 :         Real64 const Y_0(state.dataSolarShading->YTEMP[0]);
    4161           0 :         Real64 XP_0 = X_0, XP_1;
    4162           0 :         Real64 YP_0 = Y_0, YP_1;
    4163           0 :         for (int P = 0; P < NV3 - 1; ++P) {
    4164           0 :             XP_1 = state.dataSolarShading->XTEMP[P + 1];
    4165           0 :             YP_1 = state.dataSolarShading->YTEMP[P + 1];
    4166             : 
    4167           0 :             state.dataSolarShading->ATEMP[P] = YP_0 - YP_1;
    4168           0 :             state.dataSolarShading->BTEMP[P] = XP_1 - XP_0;
    4169           0 :             state.dataSolarShading->CTEMP[P] = XP_0 * YP_1 - YP_0 * XP_1;
    4170           0 :             XP_0 = XP_1;
    4171           0 :             YP_0 = YP_1;
    4172             :         }
    4173             : 
    4174           0 :         state.dataSolarShading->ATEMP[NV3 - 1] = YP_1 - Y_0;
    4175           0 :         state.dataSolarShading->BTEMP[NV3 - 1] = X_0 - XP_1;
    4176           0 :         state.dataSolarShading->CTEMP[NV3 - 1] = XP_1 * Y_0 - YP_1 * X_0;
    4177             :     }
    4178             : 
    4179             :     // Determine overlap status
    4180           0 :     if (NV3 < 3) { // Determine overlap status
    4181           0 :         state.dataSolarShading->OverlapStatus = NoOverlap;
    4182           0 :     } else if (!INTFLAG) {
    4183           0 :         state.dataSolarShading->OverlapStatus = FirstSurfWithinSecond;
    4184             :     }
    4185           0 : }
    4186             : 
    4187     7838123 : void CLIPPOLY(EnergyPlusData &state,
    4188             :               int const NS1, // Figure number of figure 1 (The subject polygon)
    4189             :               int const NS2, // Figure number of figure 2 (The clipping polygon)
    4190             :               int const NV1, // Number of vertices of figure 1
    4191             :               int const NV2, // Number of vertices of figure 2
    4192             :               int &NV3       // Number of vertices of figure 3
    4193             : )
    4194             : {
    4195             : 
    4196             :     // SUBROUTINE INFORMATION:
    4197             :     //       AUTHOR         Tyler Hoyt
    4198             :     //       DATE WRITTEN   May 4, 2010
    4199             :     //       MODIFIED       na
    4200             :     //       RE-ENGINEERED  na
    4201             : 
    4202             :     // PURPOSE OF THIS SUBROUTINE:
    4203             :     // Populate global arrays XTEMP and YTEMP with the vertices
    4204             :     // of the overlap between NS1 and NS2, and determine relevant
    4205             :     // overlap status.
    4206             : 
    4207             :     // METHODOLOGY EMPLOYED:
    4208             :     // The Sutherland-Hodgman algorithm for polygon clipping is employed.
    4209             : 
    4210             :     using General::ReallocateRealArray;
    4211             :     using General::SafeDivide;
    4212             : 
    4213             :     typedef Array2D<Int64>::size_type size_type;
    4214             :     bool INTFLAG; // For overlap status
    4215             :     int S;        // Test vertex
    4216             :     int KK;       // Duplicate test index
    4217             :     int NVOUT;    // Current output length for loops
    4218             :     int NVTEMP;
    4219             : 
    4220             :     Real64 W; // Normalization factor
    4221             :     Real64 HFunct;
    4222             : 
    4223             : #ifdef EP_Count_Calls
    4224             :     ++state.dataTimingsData->NumClipPoly_Calls;
    4225             : #endif
    4226             :     // Tuned Linear indexing
    4227             : 
    4228     7838123 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    4229     7838123 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
    4230     7838123 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
    4231     7838123 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
    4232             : 
    4233             :     // Populate the arrays with the original polygon
    4234    39079868 :     for (size_type j = 0, l = state.dataSolarShading->HCX.index(NS1, 1), e = NV1; j < e; ++j, ++l) {
    4235    31241745 :         state.dataSolarShading->XTEMP[j] = state.dataSolarShading->HCX[l]; // [ l ] == ( NS1, j+1 )
    4236    31241745 :         state.dataSolarShading->YTEMP[j] = state.dataSolarShading->HCY[l];
    4237    31241745 :         state.dataSolarShading->ATEMP[j] = state.dataSolarShading->HCA[l];
    4238    31241745 :         state.dataSolarShading->BTEMP[j] = state.dataSolarShading->HCB[l];
    4239    31241745 :         state.dataSolarShading->CTEMP[j] = state.dataSolarShading->HCC[l];
    4240             :     }
    4241             : 
    4242     7838123 :     NVOUT = NV1; // First point-loop is the length of the subject polygon.
    4243     7838123 :     INTFLAG = false;
    4244     7838123 :     NVTEMP = 0;
    4245     7838123 :     KK = 0;
    4246             : 
    4247             :     // Check if clipping polygon is rectangle
    4248     7838123 :     if (state.dataSysVars->SlaterBarsky) {
    4249           0 :         auto l1(state.dataSolarShading->HCA.index(NS2, 1));
    4250           0 :         bool rectFlag = ((NV2 == 4) && (((((state.dataSolarShading->HCX[l1] == state.dataSolarShading->HCX[l1 + 1] &&
    4251           0 :                                             state.dataSolarShading->HCY[l1] != state.dataSolarShading->HCY[l1 + 1]) &&
    4252           0 :                                            ((state.dataSolarShading->HCY[l1 + 2] == state.dataSolarShading->HCY[l1 + 1] &&
    4253           0 :                                              state.dataSolarShading->HCY[l1 + 3] == state.dataSolarShading->HCY[l1]))) &&
    4254           0 :                                           state.dataSolarShading->HCX[l1 + 2] == state.dataSolarShading->HCX[l1 + 3]) ||
    4255           0 :                                          ((((state.dataSolarShading->HCY[l1] == state.dataSolarShading->HCY[l1 + 1] &&
    4256           0 :                                              state.dataSolarShading->HCX[l1] != state.dataSolarShading->HCX[l1 + 1]) &&
    4257           0 :                                             (state.dataSolarShading->HCX[l1 + 2] == state.dataSolarShading->HCX[l1 + 1] &&
    4258           0 :                                              state.dataSolarShading->HCX[l1 + 3] == state.dataSolarShading->HCX[l1])) &&
    4259           0 :                                            (state.dataSolarShading->HCY[l1 + 2] == state.dataSolarShading->HCY[l1 + 3]))))));
    4260           0 :         if (rectFlag) {
    4261           0 :             CLIPRECT(state, NS2, NV1, NV3);
    4262           0 :             return;
    4263             :         }
    4264             :     }
    4265             : 
    4266     7838123 :     auto l(state.dataSolarShading->HCA.index(NS2, 1));
    4267    25528079 :     for (int E = 1; E <= NV2; ++E, ++l) { // Loop over edges of the clipping polygon
    4268   112363752 :         for (int P = 1; P <= NVOUT; ++P) {
    4269    90069811 :             state.dataSolarShading->XTEMP1(P) = state.dataSolarShading->XTEMP(P);
    4270    90069811 :             state.dataSolarShading->YTEMP1(P) = state.dataSolarShading->YTEMP(P);
    4271             :         }
    4272    22293941 :         S = NVOUT;
    4273    22293941 :         Real64 const HCA_E(state.dataSolarShading->HCA[l]);
    4274    22293941 :         Real64 const HCB_E(state.dataSolarShading->HCB[l]);
    4275    22293941 :         Real64 const HCC_E(state.dataSolarShading->HCC[l]);
    4276    22293941 :         Real64 XTEMP1_S(state.dataSolarShading->XTEMP1(S));
    4277    22293941 :         Real64 YTEMP1_S(state.dataSolarShading->YTEMP1(S));
    4278   112363752 :         for (int P = 1; P <= NVOUT; ++P) {
    4279    90069811 :             Real64 const XTEMP1_P(state.dataSolarShading->XTEMP1(P));
    4280    90069811 :             Real64 const YTEMP1_P(state.dataSolarShading->YTEMP1(P));
    4281    90069811 :             HFunct = XTEMP1_P * HCA_E + YTEMP1_P * HCB_E + HCC_E;
    4282             :             // S is constant within this block
    4283    90069811 :             if (HFunct <= 0.0) { // Vertex is not in the clipping plane
    4284    59752010 :                 HFunct = XTEMP1_S * HCA_E + YTEMP1_S * HCB_E + HCC_E;
    4285    59752010 :                 if (HFunct > 0.0) { // Test vertex is in the clipping plane
    4286             : 
    4287             :                     // Find/store the intersection of the clip edge and the line connecting S and P
    4288     6344248 :                     KK = NVTEMP;
    4289     6344248 :                     ++NVTEMP;
    4290     6344248 :                     Real64 const ATEMP_S(state.dataSolarShading->ATEMP(S));
    4291     6344248 :                     Real64 const BTEMP_S(state.dataSolarShading->BTEMP(S));
    4292     6344248 :                     Real64 const CTEMP_S(state.dataSolarShading->CTEMP(S));
    4293     6344248 :                     W = HCB_E * ATEMP_S - HCA_E * BTEMP_S;
    4294     6344248 :                     if (W != 0.0) {
    4295     6344248 :                         Real64 const W_inv(1.0 / W);
    4296     6344248 :                         state.dataSolarShading->XTEMP(NVTEMP) = nint64((HCC_E * BTEMP_S - HCB_E * CTEMP_S) * W_inv);
    4297     6344248 :                         state.dataSolarShading->YTEMP(NVTEMP) = nint64((HCA_E * CTEMP_S - HCC_E * ATEMP_S) * W_inv);
    4298             :                     } else {
    4299           0 :                         state.dataSolarShading->XTEMP(NVTEMP) = SafeDivide(HCC_E * BTEMP_S - HCB_E * CTEMP_S, W);
    4300           0 :                         state.dataSolarShading->YTEMP(NVTEMP) = SafeDivide(HCA_E * CTEMP_S - HCC_E * ATEMP_S, W);
    4301             :                     }
    4302     6344248 :                     INTFLAG = true;
    4303             : 
    4304     6344248 :                     if (E == NV2) { // Remove near-duplicates on last edge
    4305     1278121 :                         if (KK != 0) {
    4306      494754 :                             auto const x(state.dataSolarShading->XTEMP(NVTEMP));
    4307      494754 :                             auto const y(state.dataSolarShading->YTEMP(NVTEMP));
    4308     1219887 :                             for (int K = 1; K <= KK; ++K) {
    4309      728003 :                                 if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
    4310       38011 :                                 if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
    4311        2870 :                                 NVTEMP = KK;
    4312        2870 :                                 break; // K loop
    4313             :                             }
    4314             :                         }
    4315             :                     }
    4316             :                 }
    4317             : 
    4318    59752010 :                 KK = NVTEMP;
    4319    59752010 :                 ++NVTEMP;
    4320    59752010 :                 if (NVTEMP > state.dataSolarShading->MAXHCArrayBounds) {
    4321           0 :                     int const NewArrayBounds(state.dataSolarShading->MAXHCArrayBounds + state.dataSolarShading->MAXHCArrayIncrement);
    4322           0 :                     state.dataSolarShading->XTEMP.redimension(NewArrayBounds, 0.0);
    4323           0 :                     state.dataSolarShading->YTEMP.redimension(NewArrayBounds, 0.0);
    4324           0 :                     state.dataSolarShading->XTEMP1.redimension(NewArrayBounds, 0.0);
    4325           0 :                     state.dataSolarShading->YTEMP1.redimension(NewArrayBounds, 0.0);
    4326           0 :                     state.dataSolarShading->ATEMP.redimension(NewArrayBounds, 0.0);
    4327           0 :                     state.dataSolarShading->BTEMP.redimension(NewArrayBounds, 0.0);
    4328           0 :                     state.dataSolarShading->CTEMP.redimension(NewArrayBounds, 0.0);
    4329           0 :                     state.dataSolarShading->MAXHCArrayBounds = NewArrayBounds;
    4330             :                 }
    4331             : 
    4332    59752010 :                 state.dataSolarShading->XTEMP(NVTEMP) = XTEMP1_P;
    4333    59752010 :                 state.dataSolarShading->YTEMP(NVTEMP) = YTEMP1_P;
    4334             : 
    4335    59752010 :                 if (E == NV2) { // Remove near-duplicates on last edge
    4336    11056198 :                     if (KK != 0) {
    4337     8899818 :                         auto const x(state.dataSolarShading->XTEMP(NVTEMP));
    4338     8899818 :                         auto const y(state.dataSolarShading->YTEMP(NVTEMP));
    4339    25363640 :                         for (int K = 1; K <= KK; ++K) {
    4340    17768646 :                             if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
    4341     5211454 :                             if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
    4342     1304824 :                             NVTEMP = KK;
    4343     1304824 :                             break; // K loop
    4344             :                         }
    4345             :                     }
    4346             :                 }
    4347             : 
    4348             :             } else {
    4349    30317801 :                 HFunct = XTEMP1_S * HCA_E + YTEMP1_S * HCB_E + HCC_E;
    4350    30317801 :                 if (HFunct <= 0.0) {                                                   // Test vertex is not in the clipping plane
    4351     6344248 :                     if (NVTEMP < 2 * (state.dataSurface->MaxVerticesPerSurface + 1)) { // avoid assigning to element outside of XTEMP array size
    4352     6344248 :                         KK = NVTEMP;
    4353     6344248 :                         ++NVTEMP;
    4354     6344248 :                         Real64 const ATEMP_S(state.dataSolarShading->ATEMP(S));
    4355     6344248 :                         Real64 const BTEMP_S(state.dataSolarShading->BTEMP(S));
    4356     6344248 :                         Real64 const CTEMP_S(state.dataSolarShading->CTEMP(S));
    4357     6344248 :                         W = HCB_E * ATEMP_S - HCA_E * BTEMP_S;
    4358     6344248 :                         if (W != 0.0) {
    4359     6344248 :                             Real64 const W_inv(1.0 / W);
    4360     6344248 :                             state.dataSolarShading->XTEMP(NVTEMP) = nint64((HCC_E * BTEMP_S - HCB_E * CTEMP_S) * W_inv);
    4361     6344248 :                             state.dataSolarShading->YTEMP(NVTEMP) = nint64((HCA_E * CTEMP_S - HCC_E * ATEMP_S) * W_inv);
    4362             :                         } else {
    4363           0 :                             state.dataSolarShading->XTEMP(NVTEMP) = SafeDivide(HCC_E * BTEMP_S - HCB_E * CTEMP_S, W);
    4364           0 :                             state.dataSolarShading->YTEMP(NVTEMP) = SafeDivide(HCA_E * CTEMP_S - HCC_E * ATEMP_S, W);
    4365             :                         }
    4366     6344248 :                         INTFLAG = true;
    4367             : 
    4368     6344248 :                         if (E == NV2) { // Remove near-duplicates on last edge
    4369     1278121 :                             if (KK != 0) {
    4370      983730 :                                 auto const x(state.dataSolarShading->XTEMP(NVTEMP));
    4371      983730 :                                 auto const y(state.dataSolarShading->YTEMP(NVTEMP));
    4372     3417417 :                                 for (int K = 1; K <= KK; ++K) {
    4373     2522781 :                                     if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
    4374      467729 :                                     if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
    4375       89094 :                                     NVTEMP = KK;
    4376       89094 :                                     break; // K loop
    4377             :                                 }
    4378             :                             }
    4379             :                         }
    4380             :                     }
    4381             :                 }
    4382             :             }
    4383    90069811 :             S = P;
    4384    90069811 :             XTEMP1_S = XTEMP1_P;
    4385    90069811 :             YTEMP1_S = YTEMP1_P;
    4386             :         } // end loop over points of subject polygon
    4387             : 
    4388    22293941 :         NVOUT = NVTEMP;
    4389    22293941 :         if (NVOUT == 0) break; // Added to avoid array bounds violation of XTEMP1 and YTEMP1 and wasted looping
    4390    17689956 :         NVTEMP = 0;
    4391             : 
    4392    17689956 :         if (E != NV2) {
    4393    14455818 :             if (NVOUT > 2) { // Compute HC values for edges of output polygon
    4394    14455818 :                 Real64 const X_1(state.dataSolarShading->XTEMP(1));
    4395    14455818 :                 Real64 const Y_1(state.dataSolarShading->YTEMP(1));
    4396    14455818 :                 Real64 X_P(X_1), X_P1;
    4397    14455818 :                 Real64 Y_P(Y_1), Y_P1;
    4398    58828066 :                 for (int P = 1; P < NVOUT; ++P) {
    4399    44372248 :                     X_P1 = state.dataSolarShading->XTEMP(P + 1);
    4400    44372248 :                     Y_P1 = state.dataSolarShading->YTEMP(P + 1);
    4401    44372248 :                     state.dataSolarShading->ATEMP(P) = Y_P - Y_P1;
    4402    44372248 :                     state.dataSolarShading->BTEMP(P) = X_P1 - X_P;
    4403    44372248 :                     state.dataSolarShading->CTEMP(P) = X_P * Y_P1 - Y_P * X_P1;
    4404    44372248 :                     X_P = X_P1;
    4405    44372248 :                     Y_P = Y_P1;
    4406             :                 }
    4407    14455818 :                 state.dataSolarShading->ATEMP(NVOUT) = Y_P1 - Y_1;
    4408    14455818 :                 state.dataSolarShading->BTEMP(NVOUT) = X_1 - X_P1;
    4409    14455818 :                 state.dataSolarShading->CTEMP(NVOUT) = X_P1 * Y_1 - Y_P1 * X_1;
    4410             :             }
    4411             :         }
    4412             : 
    4413             :     } // end loop over edges in NS2
    4414             : 
    4415     7838123 :     NV3 = NVOUT;
    4416             : 
    4417     7838123 :     if (NV3 < 3) { // Determine overlap status
    4418     4785307 :         state.dataSolarShading->OverlapStatus = NoOverlap;
    4419     3052816 :     } else if (!INTFLAG) {
    4420      329008 :         state.dataSolarShading->OverlapStatus = FirstSurfWithinSecond;
    4421             :     }
    4422             : }
    4423             : 
    4424     2168612 : void MULTOL(EnergyPlusData &state,
    4425             :             int const NNN,   // argument
    4426             :             int const LOC0,  // Location in the homogeneous coordinate array
    4427             :             int const NRFIGS // Number of figures overlapped
    4428             : )
    4429             : {
    4430             : 
    4431             :     // SUBROUTINE INFORMATION:
    4432             :     //       AUTHOR         Legacy Code
    4433             :     //       DATE WRITTEN
    4434             :     //       MODIFIED       na
    4435             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    4436             : 
    4437             :     // PURPOSE OF THIS SUBROUTINE:
    4438             :     // This subroutine determines the overlaps of figure 'NS2' with previous figures
    4439             :     // 'LOC0+1' through 'LOC0+NRFIGS'.  For example, if NS2
    4440             :     // is a shadow, overlap with previous shadows.
    4441             : 
    4442             :     // REFERENCES:
    4443             :     // BLAST/IBLAST code, original author George Walton
    4444             : 
    4445             :     int I;   // Loop Control
    4446             :     int NS1; // Number of the figure being overlapped
    4447             :     int NS2; // Number of the figure doing overlapping
    4448             :     int NS3; // Location to place results of overlap
    4449             : 
    4450     2168612 :     state.dataSolarShading->maxNumberOfFigures = max(state.dataSolarShading->maxNumberOfFigures, NRFIGS);
    4451             : 
    4452     2168612 :     NS2 = NNN;
    4453     5343293 :     for (I = 1; I <= NRFIGS; ++I) {
    4454     3174681 :         NS1 = LOC0 + I;
    4455     3174681 :         NS3 = state.dataSolarShading->LOCHCA + 1;
    4456             : 
    4457     3174681 :         DeterminePolygonOverlap(state, NS1, NS2, NS3); // Find overlap of figure NS2 on figure NS1.
    4458             : 
    4459             :         // Process overlap cases:
    4460             : 
    4461     3174681 :         if (state.dataSolarShading->OverlapStatus == NoOverlap) continue;
    4462             : 
    4463     1507952 :         if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures)) break;
    4464             : 
    4465     1507952 :         state.dataSolarShading->LOCHCA = NS3; // Increment h.c. arrays pointer.
    4466             :     }
    4467     2168612 : }
    4468             : 
    4469           0 : void ORDER(EnergyPlusData &state,
    4470             :            int const NV3, // Number of vertices of figure NS3
    4471             :            int const NS3  // Location to place results of overlap
    4472             : )
    4473             : {
    4474             : 
    4475             :     // SUBROUTINE INFORMATION:
    4476             :     //       AUTHOR         Legacy Code
    4477             :     //       DATE WRITTEN
    4478             :     //       MODIFIED       na
    4479             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    4480             : 
    4481             :     // PURPOSE OF THIS SUBROUTINE:
    4482             :     // This subroutine sorts the vertices found by inclosure and
    4483             :     // intercept in to clockwise order so that the overlap polygon
    4484             :     // may be used in computing subsequent overlaps.
    4485             : 
    4486             :     // METHODOLOGY EMPLOYED:
    4487             :     // The slopes of the lines from the left-most vertex to all
    4488             :     // others are found.  The slopes are sorted into descending
    4489             :     // sequence.  This sequence puts the vertices in clockwise order.
    4490             : 
    4491             :     // REFERENCES:
    4492             :     // BLAST/IBLAST code, original author George Walton
    4493             : 
    4494             :     Real64 DELTAX; // Difference between X coordinates of two vertices
    4495             :     Real64 DELTAY; // Difference between Y coordinates of two vertices
    4496             :     Real64 SAVES;  // Temporary location for exchange of variables
    4497             :     Real64 SAVEX;  // Temporary location for exchange of variables
    4498             :     Real64 SAVEY;  // Temporary location for exchange of variables
    4499             :     Real64 XMIN;   // X coordinate of left-most vertex
    4500             :     Real64 YXMIN;
    4501             :     int I;   // Sort index
    4502             :     int IM1; // Sort control
    4503             :     int J;   // Sort index
    4504             :     int M;   // Number of slopes to be sorted
    4505             :     int N;   // Vertex number
    4506             :     int P;   // Location of first slope to be sorted
    4507             : 
    4508           0 :     if (state.dataSolarShading->ORDERFirstTimeFlag) {
    4509           0 :         state.dataSolarShading->SLOPE.allocate(max(10, state.dataSurface->MaxVerticesPerSurface + 1));
    4510           0 :         state.dataSolarShading->ORDERFirstTimeFlag = false;
    4511             :     }
    4512             :     // Determine left-most vertex.
    4513             : 
    4514           0 :     XMIN = state.dataSolarShading->XTEMP(1);
    4515           0 :     YXMIN = state.dataSolarShading->YTEMP(1);
    4516           0 :     for (N = 2; N <= NV3; ++N) {
    4517           0 :         if (state.dataSolarShading->XTEMP(N) >= XMIN) continue;
    4518           0 :         XMIN = state.dataSolarShading->XTEMP(N);
    4519           0 :         YXMIN = state.dataSolarShading->YTEMP(N);
    4520             :     }
    4521             : 
    4522             :     // Determine slopes from left-most vertex to all others.  Identify
    4523             :     // first and second or last points as they occur.
    4524             : 
    4525           0 :     P = 1;
    4526           0 :     M = 0;
    4527           0 :     for (N = 1; N <= NV3; ++N) {
    4528             : 
    4529           0 :         DELTAX = state.dataSolarShading->XTEMP(N) - XMIN;
    4530           0 :         DELTAY = state.dataSolarShading->YTEMP(N) - YXMIN;
    4531             : 
    4532           0 :         if (std::abs(DELTAX) > 0.5) {
    4533             : 
    4534           0 :             ++M;
    4535           0 :             state.dataSolarShading->SLOPE(M) = DELTAY / DELTAX;
    4536           0 :             state.dataSolarShading->XTEMP(M) = state.dataSolarShading->XTEMP(N);
    4537           0 :             state.dataSolarShading->YTEMP(M) = state.dataSolarShading->YTEMP(N);
    4538             : 
    4539           0 :         } else if (DELTAY > 0.5) {
    4540             : 
    4541           0 :             P = 2;
    4542           0 :             state.dataSolarShading->HCX(NS3, 2) = nint64(state.dataSolarShading->XTEMP(N));
    4543           0 :             state.dataSolarShading->HCY(NS3, 2) = nint64(state.dataSolarShading->YTEMP(N));
    4544             : 
    4545           0 :         } else if (DELTAY < -0.5) {
    4546             : 
    4547           0 :             state.dataSolarShading->HCX(NS3, NV3) = nint64(state.dataSolarShading->XTEMP(N));
    4548           0 :             state.dataSolarShading->HCY(NS3, NV3) = nint64(state.dataSolarShading->YTEMP(N));
    4549             : 
    4550             :         } else {
    4551             : 
    4552           0 :             state.dataSolarShading->HCX(NS3, 1) = nint64(XMIN);
    4553           0 :             state.dataSolarShading->HCY(NS3, 1) = nint64(YXMIN);
    4554             :         }
    4555             :     }
    4556             : 
    4557             :     // Sequence the temporary arrays in order of decreasing slopes.(bubble sort)
    4558             : 
    4559           0 :     if (M != 1) {
    4560             : 
    4561           0 :         for (I = 2; I <= M; ++I) {
    4562           0 :             IM1 = I - 1;
    4563           0 :             for (J = 1; J <= IM1; ++J) {
    4564           0 :                 if (state.dataSolarShading->SLOPE(I) <= state.dataSolarShading->SLOPE(J)) continue;
    4565           0 :                 SAVEX = state.dataSolarShading->XTEMP(I);
    4566           0 :                 SAVEY = state.dataSolarShading->YTEMP(I);
    4567           0 :                 SAVES = state.dataSolarShading->SLOPE(I);
    4568           0 :                 state.dataSolarShading->XTEMP(I) = state.dataSolarShading->XTEMP(J);
    4569           0 :                 state.dataSolarShading->YTEMP(I) = state.dataSolarShading->YTEMP(J);
    4570           0 :                 state.dataSolarShading->SLOPE(I) = state.dataSolarShading->SLOPE(J);
    4571           0 :                 state.dataSolarShading->XTEMP(J) = SAVEX;
    4572           0 :                 state.dataSolarShading->YTEMP(J) = SAVEY;
    4573           0 :                 state.dataSolarShading->SLOPE(J) = SAVES;
    4574             :             }
    4575             :         }
    4576             :     }
    4577             : 
    4578             :     // Place sequenced points in the homogeneous coordinate arrays.
    4579             : 
    4580           0 :     for (N = 1; N <= M; ++N) {
    4581           0 :         state.dataSolarShading->HCX(NS3, N + P) = nint64(state.dataSolarShading->XTEMP(N));
    4582           0 :         state.dataSolarShading->HCY(NS3, N + P) = nint64(state.dataSolarShading->YTEMP(N));
    4583             :     }
    4584           0 : }
    4585             : 
    4586     7838123 : void DeterminePolygonOverlap(EnergyPlusData &state,
    4587             :                              int const NS1, // Number of the figure being overlapped
    4588             :                              int const NS2, // Number of the figure doing overlapping
    4589             :                              int const NS3  // Location to place results of overlap
    4590             : )
    4591             : {
    4592             : 
    4593             :     // SUBROUTINE INFORMATION:
    4594             :     //       AUTHOR         Legacy Code
    4595             :     //       DATE WRITTEN
    4596             :     //       MODIFIED       na
    4597             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    4598             : 
    4599             :     // PURPOSE OF THIS SUBROUTINE:
    4600             :     // This subroutine computes the possible overlap of two polygons.
    4601             :     // It uses homogeneous coordinate techniques to determine the overlap area
    4602             :     // between two convex polygons.  Results are stored in the homogeneous coordinate (HC) arrays.
    4603             : 
    4604             :     // METHODOLOGY EMPLOYED:
    4605             :     // The vertices defining the overlap between fig.1 and fig.2
    4606             :     // consist of: the vertices of fig.1 enclosed by fig.2 (A)
    4607             :     // plus the vertices of fig.2 enclosed by fig.1 (B)
    4608             :     // plus the intercepts of fig.1 and fig.2 (C & D)
    4609             : 
    4610             :     //                               +----------------------+
    4611             :     //                               !                      !
    4612             :     //                               !         FIG.2        !
    4613             :     //                               !                      !
    4614             :     //                +--------------C----------A           !
    4615             :     //                !              !         /            !
    4616             :     //                !              !        /             !
    4617             :     //                !              B-------D--------------+
    4618             :     //                !    FIG.1            /
    4619             :     //                !                    /
    4620             :     //                +-------------------+
    4621             : 
    4622             :     // REFERENCES:
    4623             :     // BLAST/IBLAST code, original author George Walton
    4624             : 
    4625             :     // Using/Aliasing
    4626             : 
    4627             :     int N;    // Loop index
    4628             :     int NV1;  // Number of vertices of figure NS1
    4629             :     int NV2;  // Number of vertices of figure NS2
    4630             :     int NV3;  // Number of vertices of figure NS3 (the overlap of NS1 and NS2)
    4631             :     int NIN1; // Number of vertices of NS1 within NS2
    4632             :     int NIN2; // Number of vertices of NS2 within NS1
    4633             : 
    4634             :     // Check for exceeding array limits.
    4635             : #ifdef EP_Count_Calls
    4636             :     ++state.dataTimingsData->NumDetPolyOverlap_Calls;
    4637             : #endif
    4638             : 
    4639     7838123 :     if (NS3 > state.dataSolarShading->MaxHCS) {
    4640             : 
    4641           0 :         state.dataSolarShading->OverlapStatus = TooManyFigures;
    4642             : 
    4643           0 :         if (!state.dataSolarShading->TooManyFiguresMessage && !state.dataGlobal->DisplayExtraWarnings) {
    4644           0 :             ShowWarningError(state,
    4645           0 :                              format("DeterminePolygonOverlap: Too many figures [>{}]  detected in an overlap calculation. Use "
    4646             :                                     "Output:Diagnostics,DisplayExtraWarnings; for more details.",
    4647           0 :                                     state.dataSolarShading->MaxHCS));
    4648           0 :             state.dataSolarShading->TooManyFiguresMessage = true;
    4649             :         }
    4650             : 
    4651           0 :         if (state.dataGlobal->DisplayExtraWarnings) {
    4652           0 :             state.dataSolarShading->TrackTooManyFigures.redimension(++state.dataSolarShading->NumTooManyFigures);
    4653           0 :             state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex1 =
    4654           0 :                 state.dataSolarShading->CurrentShadowingSurface;
    4655           0 :             state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex2 =
    4656           0 :                 state.dataSolarShading->CurrentSurfaceBeingShadowed;
    4657             :         }
    4658             : 
    4659           0 :         return;
    4660             :     }
    4661             : 
    4662     7838123 :     state.dataSolarShading->OverlapStatus = PartialOverlap;
    4663     7838123 :     NV1 = state.dataSolarShading->HCNV(NS1);
    4664     7838123 :     NV2 = state.dataSolarShading->HCNV(NS2);
    4665     7838123 :     NV3 = 0;
    4666             : 
    4667     7838123 :     if (!state.dataSysVars->SutherlandHodgman) {
    4668           0 :         INCLOS(state, NS1, NV1, NS2, NV2, NV3, NIN1); // Find vertices of NS1 within NS2.
    4669             : 
    4670           0 :         if (NIN1 >= NV1) {
    4671             : 
    4672           0 :             state.dataSolarShading->OverlapStatus = FirstSurfWithinSecond;
    4673             : 
    4674             :         } else {
    4675             : 
    4676           0 :             INCLOS(state, NS2, NV2, NS1, NV1, NV3, NIN2); // Find vertices of NS2 within NS1.
    4677             : 
    4678           0 :             if (NIN2 >= NV2) {
    4679             : 
    4680           0 :                 state.dataSolarShading->OverlapStatus = SecondSurfWithinFirst;
    4681             : 
    4682             :             } else {
    4683             : 
    4684           0 :                 INTCPT(state, NV1, NV2, NV3, NS1, NS2); // Find intercepts of NS1 & NS2.
    4685             : 
    4686           0 :                 if (NV3 < 3) { // Overlap must have 3 or more vertices
    4687           0 :                     state.dataSolarShading->OverlapStatus = NoOverlap;
    4688           0 :                     return;
    4689             :                 }
    4690             :             }
    4691             :         }
    4692             : 
    4693             :     } else {
    4694             :         // simple polygon clipping
    4695     7838123 :         CLIPPOLY(state, NS1, NS2, NV1, NV2, NV3);
    4696             :     }
    4697             : 
    4698     7838123 :     if (NV3 < state.dataSolarShading->MaxHCV && NS3 <= state.dataSolarShading->MaxHCS) {
    4699             : 
    4700     7838123 :         if (!state.dataSysVars->SutherlandHodgman) {
    4701           0 :             ORDER(state, NV3, NS3); // Put vertices in clockwise order.
    4702             :         } else {
    4703     7838123 :             assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    4704     7838123 :             auto l(state.dataSolarShading->HCX.index(NS3, 1));
    4705    20053775 :             for (N = 1; N <= NV3; ++N, ++l) {
    4706    12215652 :                 state.dataSolarShading->HCX[l] = nint64(state.dataSolarShading->XTEMP(N)); // [ l ] == ( N, NS3 )
    4707    12215652 :                 state.dataSolarShading->HCY[l] = nint64(state.dataSolarShading->YTEMP(N));
    4708             :             }
    4709             :         }
    4710             : 
    4711     7838123 :         HTRANS0(state, NS3, NV3); // Determine h.c. values of sides.
    4712             :         // Skip overlaps of negligible area.
    4713             : 
    4714     7838123 :         if (std::abs(state.dataSolarShading->HCAREA(NS3)) * HCMULT < std::abs(state.dataSolarShading->HCAREA(NS1))) {
    4715     4788348 :             state.dataSolarShading->OverlapStatus = NoOverlap;
    4716             :         } else {
    4717     3049775 :             if (state.dataSolarShading->HCAREA(NS1) * state.dataSolarShading->HCAREA(NS2) > 0.0)
    4718     1182879 :                 state.dataSolarShading->HCAREA(NS3) = -state.dataSolarShading->HCAREA(NS3); // Determine sign of area of overlap
    4719     3049775 :             Real64 const HCT_1(state.dataSolarShading->HCT(NS1));
    4720     3049775 :             Real64 const HCT_2(state.dataSolarShading->HCT(NS2));
    4721     3049775 :             Real64 HCT_3(HCT_2 * HCT_1); // Determine transmission of overlap
    4722     3049775 :             if (HCT_2 >= 0.5 && HCT_1 >= 0.5) {
    4723     2025590 :                 if (HCT_2 != 1.0 && HCT_1 != 1.0) {
    4724           0 :                     HCT_3 = 1.0 - HCT_3;
    4725             :                 }
    4726             :             }
    4727     3049775 :             state.dataSolarShading->HCT(NS3) = HCT_3;
    4728             :         }
    4729             : 
    4730           0 :     } else if (NV3 > state.dataSolarShading->MaxHCV) {
    4731             : 
    4732           0 :         state.dataSolarShading->OverlapStatus = TooManyVertices;
    4733             : 
    4734           0 :         if (!state.dataSolarShading->TooManyVerticesMessage && !state.dataGlobal->DisplayExtraWarnings) {
    4735           0 :             ShowWarningError(state,
    4736           0 :                              format("DeterminePolygonOverlap: Too many vertices [>{}] detected in an overlap calculation. Use "
    4737             :                                     "Output:Diagnostics,DisplayExtraWarnings; for more details.",
    4738           0 :                                     state.dataSolarShading->MaxHCV));
    4739           0 :             state.dataSolarShading->TooManyVerticesMessage = true;
    4740             :         }
    4741             : 
    4742           0 :         if (state.dataGlobal->DisplayExtraWarnings) {
    4743           0 :             state.dataSolarShading->TrackTooManyVertices.redimension(++state.dataSolarShading->NumTooManyVertices);
    4744           0 :             state.dataSolarShading->TrackTooManyVertices(state.dataSolarShading->NumTooManyVertices).SurfIndex1 =
    4745           0 :                 state.dataSolarShading->CurrentShadowingSurface;
    4746           0 :             state.dataSolarShading->TrackTooManyVertices(state.dataSolarShading->NumTooManyVertices).SurfIndex2 =
    4747           0 :                 state.dataSolarShading->CurrentSurfaceBeingShadowed;
    4748             :         }
    4749             : 
    4750           0 :     } else if (NS3 > state.dataSolarShading->MaxHCS) {
    4751             : 
    4752           0 :         state.dataSolarShading->OverlapStatus = TooManyFigures;
    4753             : 
    4754           0 :         if (!state.dataSolarShading->TooManyFiguresMessage && !state.dataGlobal->DisplayExtraWarnings) {
    4755           0 :             ShowWarningError(state,
    4756           0 :                              format("DeterminePolygonOverlap: Too many figures [>{}]  detected in an overlap calculation. Use "
    4757             :                                     "Output:Diagnostics,DisplayExtraWarnings; for more details.",
    4758           0 :                                     state.dataSolarShading->MaxHCS));
    4759           0 :             state.dataSolarShading->TooManyFiguresMessage = true;
    4760             :         }
    4761             : 
    4762           0 :         if (state.dataGlobal->DisplayExtraWarnings) {
    4763           0 :             state.dataSolarShading->TrackTooManyFigures.redimension(++state.dataSolarShading->NumTooManyFigures);
    4764           0 :             state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex1 =
    4765           0 :                 state.dataSolarShading->CurrentShadowingSurface;
    4766           0 :             state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex2 =
    4767           0 :                 state.dataSolarShading->CurrentSurfaceBeingShadowed;
    4768             :         }
    4769             :     }
    4770             : }
    4771             : 
    4772       14330 : void CalcPerSolarBeam(EnergyPlusData &state,
    4773             :                       Real64 const AvgEqOfTime,       // Average value of Equation of Time for period
    4774             :                       Real64 const AvgSinSolarDeclin, // Average value of Sine of Solar Declination for period
    4775             :                       Real64 const AvgCosSolarDeclin  // Average value of Cosine of Solar Declination for period
    4776             : )
    4777             : {
    4778             : 
    4779             :     // SUBROUTINE INFORMATION:
    4780             :     //       AUTHOR         Legacy Code
    4781             :     //       DATE WRITTEN
    4782             :     //       MODIFIED       BG, Nov 2012 - Timestep solar.  DetailedSolarTimestepIntegration
    4783             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    4784             : 
    4785             :     // PURPOSE OF THIS SUBROUTINE:
    4786             :     // This subroutine manages computation of solar gain multipliers for beam radiation.  These
    4787             :     // are calculated for a period of days depending on the input "Shadowing Calculations".
    4788             : 
    4789             :     // REFERENCES:
    4790             :     // BLAST/IBLAST code, original author George Walton
    4791             : 
    4792             :     // Using/Aliasing
    4793             : 
    4794             :     using ScheduleManager::LookUpScheduleValue;
    4795             :     using WindowComplexManager::InitComplexWindows;
    4796             :     using WindowComplexManager::UpdateComplexWindows;
    4797             : 
    4798             :     int iHour; // Hour index number
    4799             :     int TS;    // TimeStep Loop Countergit
    4800             : 
    4801       14330 :     if (state.dataSolarShading->InitComplexOnce) InitComplexWindows(state);
    4802       14330 :     state.dataSolarShading->InitComplexOnce = false;
    4803             : 
    4804       14330 :     if (state.dataGlobal->KickOffSizing || state.dataGlobal->KickOffSimulation) return; // Skip solar calcs for these Initialization steps.
    4805             : 
    4806             : #ifdef EP_Count_Calls
    4807             :     ++state.dataTimingsData->NumCalcPerSolBeam_Calls;
    4808             : #endif
    4809             : 
    4810             :     // Initialize some values for the appropriate period
    4811       10621 :     if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    4812       21635 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    4813       38180 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4814       19102 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    4815       19102 :                 int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    4816       19102 :                 int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    4817      162518 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4818      143416 :                     state.dataSurface->SurfOpaqAO(surfNum) = 0.0;
    4819             :                 }
    4820       19102 :                 firstSurf = thisSpace.HTSurfaceFirst;
    4821       19102 :                 lastSurf = thisSpace.HTSurfaceLast;
    4822      186371 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4823      167269 :                     state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0;
    4824             :                 }
    4825      477550 :                 for (int hour = 1; hour <= 24; ++hour) {
    4826     4472904 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4827     4014456 :                         state.dataHeatBal->SurfSunlitFracHR(hour, surfNum) = 0.0;
    4828     4014456 :                         state.dataHeatBal->SurfCosIncAngHR(hour, surfNum) = 0.0;
    4829             :                     }
    4830             :                 }
    4831      477550 :                 for (int hour = 1; hour <= 24; ++hour) {
    4832     2850576 :                     for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) {
    4833    23067312 :                         for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4834    20675184 :                             state.dataHeatBal->SurfSunlitFrac(hour, timestep, surfNum) = 0.0;
    4835    20675184 :                             state.dataHeatBal->SurfCosIncAng(hour, timestep, surfNum) = 0.0;
    4836    20675184 :                             state.dataHeatBal->SurfSunlitFracWithoutReveal(hour, timestep, surfNum) = 0.0;
    4837             :                         }
    4838             :                     }
    4839             :                 }
    4840      477550 :                 for (int hour = 1; hour <= 24; ++hour) {
    4841     2850576 :                     for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) {
    4842    50234688 :                         for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) {
    4843   461346240 :                             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4844   413503680 :                                 state.dataHeatBal->SurfWinBackSurfaces(hour, timestep, backSurfNum, surfNum) = 0.0;
    4845   413503680 :                                 state.dataHeatBal->SurfWinOverlapAreas(hour, timestep, backSurfNum, surfNum) = 0.0;
    4846             :                             }
    4847             :                         }
    4848             :                     }
    4849             :                 }
    4850             :             }
    4851             :         }
    4852             : 
    4853      175426 :         for (auto &e : state.dataSurface->SurfaceWindow) {
    4854      172869 :             e.OutProjSLFracMult = 1.0;
    4855      172869 :             e.InOutProjSLFracMult = 1.0;
    4856             :         }
    4857             :     } else {
    4858       56448 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    4859       96768 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4860       48384 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    4861       48384 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    4862       48384 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    4863      604800 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4864      556416 :                     state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0;
    4865      556416 :                     state.dataSurface->SurfOpaqAO(surfNum) = 0.0;
    4866      556416 :                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0;
    4867      556416 :                     state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0;
    4868      556416 :                     state.dataHeatBal->SurfSunlitFracHR(state.dataGlobal->HourOfDay, surfNum) = 0.0;
    4869      556416 :                     state.dataHeatBal->SurfCosIncAngHR(state.dataGlobal->HourOfDay, surfNum) = 0.0;
    4870      556416 :                     state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0;
    4871             :                 }
    4872     1016064 :                 for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) {
    4873    12096000 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4874    11128320 :                         state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0;
    4875    11128320 :                         state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0.0;
    4876             :                     }
    4877             :                 }
    4878             :             }
    4879             :         }
    4880             : 
    4881      564480 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4882      556416 :             state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay) = 1.0;
    4883      556416 :             state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay) = 1.0;
    4884             :         }
    4885             :     }
    4886             : 
    4887       10621 :     if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    4888       63925 :         for (iHour = 1; iHour <= 24; ++iHour) { // Do for all hours
    4889      397704 :             for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
    4890      336336 :                 FigureSunCosines(state, iHour, TS, AvgEqOfTime, AvgSinSolarDeclin, AvgCosSolarDeclin);
    4891             :             }
    4892             :         }
    4893             :     } else {
    4894        8064 :         FigureSunCosines(state, state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, AvgEqOfTime, AvgSinSolarDeclin, AvgCosSolarDeclin);
    4895             :     }
    4896             :     // Initialize/update the Complex Fenestration geometry and optical properties
    4897       10621 :     UpdateComplexWindows(state);
    4898       10621 :     if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    4899       63925 :         for (iHour = 1; iHour <= 24; ++iHour) { // Do for all hours.
    4900      397704 :             for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
    4901      336336 :                 FigureSolarBeamAtTimestep(state, iHour, TS);
    4902             :             } // TimeStep Loop
    4903             :         }     // Hour Loop
    4904             :     } else {
    4905        8064 :         FigureSolarBeamAtTimestep(state, state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
    4906             :     }
    4907             : }
    4908             : 
    4909      344400 : void FigureSunCosines(EnergyPlusData &state,
    4910             :                       int const iHour,
    4911             :                       int const iTimeStep,
    4912             :                       Real64 const EqOfTime,       // value of Equation of Time for period
    4913             :                       Real64 const SinSolarDeclin, // value of Sine of Solar Declination for period
    4914             :                       Real64 const CosSolarDeclin  // value of Cosine of Solar Declination for period
    4915             : )
    4916             : {
    4917             : 
    4918             :     // SUBROUTINE INFORMATION:
    4919             :     //       AUTHOR         B. Griffith
    4920             :     //       DATE WRITTEN   October 2012
    4921             :     //       MODIFIED       na
    4922             :     //       RE-ENGINEERED  na
    4923             : 
    4924             :     // PURPOSE OF THIS SUBROUTINE:
    4925             :     // Determine solar position.  Default for sun below horizon.
    4926             : 
    4927             :     // METHODOLOGY EMPLOYED:
    4928             :     // Given hour, timestep, equation of time, solar declination sine, and solar declination cosine,
    4929             :     // determine sun directions for use elsewhere
    4930             : 
    4931             :     // Using/Aliasing
    4932             : 
    4933             :     Real64 CurrentTime; // Current Time for passing to Solar Position Routine
    4934             : 
    4935      344400 :     if (state.dataGlobal->NumOfTimeStepInHour != 1) {
    4936      343776 :         CurrentTime = double(iHour - 1) + double(iTimeStep) * (state.dataGlobal->TimeStepZone);
    4937             :     } else {
    4938         624 :         CurrentTime = double(iHour) + state.dataEnvrn->TS1TimeOffset;
    4939             :     }
    4940      344400 :     SUN4(state, CurrentTime, EqOfTime, SinSolarDeclin, CosSolarDeclin);
    4941             : 
    4942             :     // Save hourly values for use in DaylightingManager
    4943      344400 :     if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    4944      336336 :         if (iTimeStep == state.dataGlobal->NumOfTimeStepInHour) state.dataSurface->SurfSunCosHourly(iHour) = state.dataSolarShading->SUNCOS;
    4945             :     } else {
    4946        8064 :         state.dataSurface->SurfSunCosHourly(iHour) = state.dataSolarShading->SUNCOS;
    4947             :     }
    4948             :     // Save timestep values for use in WindowComplexManager
    4949      344400 :     state.dataBSDFWindow->SUNCOSTS(iTimeStep, iHour) = state.dataSolarShading->SUNCOS;
    4950      344400 : }
    4951             : 
    4952      344400 : void FigureSolarBeamAtTimestep(EnergyPlusData &state, int const iHour, int const iTimeStep)
    4953             : {
    4954             : 
    4955             :     // SUBROUTINE INFORMATION:
    4956             :     //       AUTHOR         B.Griffith, derived from CalcPerSolarBeam, Legacy and Lawrie.
    4957             :     //       DATE WRITTEN   October 2012
    4958             :     //       MODIFIED       na
    4959             :     //       RE-ENGINEERED  na
    4960             : 
    4961             :     // PURPOSE OF THIS SUBROUTINE:
    4962             :     // This subroutine computes solar gain multipliers for beam solar
    4963             : 
    4964             :     using DataSystemVariables::ShadingMethod;
    4965             :     using ScheduleManager::LookUpScheduleValue;
    4966             : 
    4967             :     Real64 SurfArea;        // Surface area. For walls, includes all window frame areas.
    4968             :     Real64 Fac1WoShdg;      // Intermediate calculation factor, without shading
    4969             :     Real64 Fac1WithShdg;    // Intermediate calculation factor, with shading
    4970             :     Real64 FracIlluminated; // Fraction of surface area illuminated by a sky patch
    4971             : 
    4972             :     // Recover the sun direction from the array stored in previous loop
    4973      344400 :     state.dataSolarShading->SUNCOS = state.dataBSDFWindow->SUNCOSTS(iTimeStep, iHour);
    4974             : 
    4975      344400 :     state.dataSolarShading->SurfSunCosTheta = 0.0;
    4976             : 
    4977      344400 :     if (state.dataSolarShading->SUNCOS(3) < DataEnvironment::SunIsUpValue) return;
    4978             : 
    4979    11218080 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4980    33134031 :         state.dataSolarShading->SurfSunCosTheta(SurfNum) = state.dataSolarShading->SUNCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
    4981    22089354 :                                                            state.dataSolarShading->SUNCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
    4982    11044677 :                                                            state.dataSolarShading->SUNCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
    4983    11044677 :         if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    4984    10766469 :             if (iTimeStep == state.dataGlobal->NumOfTimeStepInHour)
    4985     2093327 :                 state.dataHeatBal->SurfCosIncAngHR(iHour, SurfNum) = state.dataSolarShading->SurfSunCosTheta(SurfNum);
    4986             :         } else {
    4987      278208 :             state.dataHeatBal->SurfCosIncAngHR(iHour, SurfNum) = state.dataSolarShading->SurfSunCosTheta(SurfNum);
    4988             :         }
    4989    11044677 :         state.dataHeatBal->SurfCosIncAng(iHour, iTimeStep, SurfNum) = state.dataSolarShading->SurfSunCosTheta(SurfNum);
    4990             :     }
    4991             : 
    4992      520304 :     if ((state.dataSysVars->shadingMethod == ShadingMethod::Scheduled || state.dataSysVars->shadingMethod == ShadingMethod::Imported) &&
    4993      173783 :         !state.dataGlobal->DoingSizing && state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
    4994           0 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4995           0 :             if (state.dataSurface->Surface(SurfNum).SurfSchedExternalShadingFrac) {
    4996           0 :                 state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) =
    4997           0 :                     LookUpScheduleValue(state, state.dataSurface->Surface(SurfNum).SurfExternalShadingSchInd, iHour, iTimeStep);
    4998             :             } else {
    4999           0 :                 state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = 1.0;
    5000             :             }
    5001             :         }
    5002             :     } else {
    5003      173403 :         SHADOW(state, iHour, iTimeStep); // Determine sunlit areas and solar multipliers for all surfaces.
    5004    11218080 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5005    11044677 :             if (state.dataSurface->Surface(SurfNum).Area >= 1.e-10) {
    5006    11044677 :                 SurfArea = state.dataSurface->Surface(SurfNum).NetAreaShadowCalc;
    5007    11044677 :                 if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    5008    10766469 :                     if (iTimeStep == state.dataGlobal->NumOfTimeStepInHour)
    5009     2093327 :                         state.dataHeatBal->SurfSunlitFracHR(iHour, SurfNum) = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
    5010             :                 } else {
    5011      278208 :                     state.dataHeatBal->SurfSunlitFracHR(iHour, SurfNum) = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
    5012             :                 }
    5013    11044677 :                 state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
    5014    11044677 :                 if (state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) < 1.e-5)
    5015     8560454 :                     state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = 0.0;
    5016             :             }
    5017             :             // Added check
    5018    11044677 :             if (state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) > 1.0) {
    5019           0 :                 state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = 1.0;
    5020             :             }
    5021             :         }
    5022             :     }
    5023             :     //   Note -- if not the below, values are set in SkyDifSolarShading routine (constant for simulation)
    5024      173403 :     if (state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
    5025           0 :         state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) {
    5026           0 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5027           0 :             state.dataSolarShading->SurfWithShdgIsoSky(SurfNum) = 0.;
    5028           0 :             state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) = 0.;
    5029           0 :             state.dataSolarShading->SurfWithShdgHoriz(SurfNum) = 0.;
    5030           0 :             state.dataSolarShading->SurfWoShdgHoriz(SurfNum) = 0.;
    5031             :         }
    5032             : 
    5033           0 :         for (int IPhi = 0; IPhi < NPhi; ++IPhi) { // Loop over patch altitude values
    5034           0 :             state.dataSolarShading->SUNCOS(3) = state.dataSolarShading->sin_Phi[IPhi];
    5035             : 
    5036           0 :             for (int ITheta = 0; ITheta < NTheta; ++ITheta) { // Loop over patch azimuth values
    5037           0 :                 state.dataSolarShading->SUNCOS(1) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->cos_Theta[ITheta];
    5038           0 :                 state.dataSolarShading->SUNCOS(2) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->sin_Theta[ITheta];
    5039             : 
    5040           0 :                 for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
    5041           0 :                     state.dataSolarShading->SurfSunCosTheta(SurfNum) =
    5042           0 :                         state.dataSolarShading->SUNCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
    5043           0 :                         state.dataSolarShading->SUNCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
    5044           0 :                         state.dataSolarShading->SUNCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
    5045             :                 }
    5046             : 
    5047           0 :                 SHADOW(state, iHour, iTimeStep); // Determine sunlit areas and solar multipliers for all surfaces.
    5048             : 
    5049           0 :                 for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
    5050             : 
    5051           0 :                     if (state.dataSolarShading->SurfSunCosTheta(SurfNum) < 0.0) continue;
    5052             : 
    5053           0 :                     Fac1WoShdg = state.dataSolarShading->cos_Phi[IPhi] * DThetaDPhi * state.dataSolarShading->SurfSunCosTheta(SurfNum);
    5054           0 :                     SurfArea = state.dataSurface->Surface(SurfNum).NetAreaShadowCalc;
    5055           0 :                     if (SurfArea > Eps) {
    5056           0 :                         FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
    5057             :                     } else {
    5058           0 :                         FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / (SurfArea + Eps);
    5059             :                     }
    5060           0 :                     Fac1WithShdg = Fac1WoShdg * FracIlluminated;
    5061           0 :                     state.dataSolarShading->SurfWithShdgIsoSky(SurfNum) += Fac1WithShdg;
    5062           0 :                     state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) += Fac1WoShdg;
    5063             : 
    5064             :                     // Horizon region
    5065           0 :                     if (IPhi == 0) {
    5066           0 :                         state.dataSolarShading->SurfWithShdgHoriz(SurfNum) += Fac1WithShdg;
    5067           0 :                         state.dataSolarShading->SurfWoShdgHoriz(SurfNum) += Fac1WoShdg;
    5068             :                     }
    5069             :                 } // End of surface loop
    5070             :             }     // End of Theta loop
    5071             :         }         // End of Phi loop
    5072             : 
    5073           0 :         for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
    5074             :             // Original conditions:
    5075             :             // if (!state.dataSurface->Surface(SurfNum).IsShadowing &&
    5076             :             //    (!state.dataSurface->Surface(SurfNum).HeatTransSurf || !state.dataSurface->Surface(SurfNum).ExtSolar))
    5077             :             //    continue;
    5078             : 
    5079           0 :             if (std::abs(state.dataSolarShading->SurfWoShdgIsoSky(SurfNum)) > Eps) {
    5080           0 :                 state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(iTimeStep, iHour, SurfNum) =
    5081           0 :                     (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum));
    5082             :             } else {
    5083           0 :                 state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(iTimeStep, iHour, SurfNum) =
    5084           0 :                     (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) + Eps);
    5085             :             }
    5086           0 :             if (std::abs(state.dataSolarShading->SurfWoShdgHoriz(SurfNum)) > Eps) {
    5087           0 :                 state.dataSolarShading->SurfDifShdgRatioHorizHRTS(iTimeStep, iHour, SurfNum) =
    5088           0 :                     (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum));
    5089             :             } else {
    5090           0 :                 state.dataSolarShading->SurfDifShdgRatioHorizHRTS(iTimeStep, iHour, SurfNum) =
    5091           0 :                     (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum) + Eps);
    5092             :             }
    5093             :         }
    5094             : 
    5095             :         //  ! Get IR view factors. An exterior surface can receive IR radiation from
    5096             :         //  ! sky, ground or shadowing surfaces. Assume shadowing surfaces have same
    5097             :         //  ! temperature as outside air (and therefore same temperature as ground),
    5098             :         //  ! so that the view factor to these shadowing surfaces can be included in
    5099             :         //  ! the ground view factor. Sky IR is assumed to be isotropic and shadowing
    5100             :         //  ! surfaces are assumed to be opaque to IR so they totally "shade" IR from
    5101             :         //  ! sky or ground.
    5102             : 
    5103             :         //  DO SurfNum = 1,TotSurfaces
    5104             :         //    Surface(SurfNum)%ViewFactorSkyIR = Surface(SurfNum)%ViewFactorSkyIR * DifShdgRatioIsoSky(SurfNum,IHOUR,TS)
    5105             :         //    Surface(SurfNum)%ViewFactorGroundIR = 1.0 - Surface(SurfNum)%ViewFactorSkyIR
    5106             :         //  END DO
    5107             : 
    5108             :     } // test for shading surfaces
    5109             : 
    5110      249106 :     for (int SurfNum : state.dataSurface->AllExtSolWinWithFrameSurfaceList) {
    5111             :         // For exterior windows with frame/divider that are partially or fully sunlit,
    5112             :         // correct SunlitFrac due to shadowing of frame and divider projections onto window glass.
    5113             :         // Note: if SunlitFrac = 0.0 the window is either completely shaded or the sun is in back
    5114             :         // of the window; in either case, frame/divider shadowing doesn't have to be done.
    5115             : 
    5116       75703 :         if (state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) > 0.0) {
    5117       68875 :             CalcFrameDividerShadow(state, SurfNum, state.dataSurface->Surface(SurfNum).FrameDivider, iHour);
    5118             :         }
    5119             :     }
    5120             : }
    5121             : 
    5122         771 : void DetermineShadowingCombinations(EnergyPlusData &state)
    5123             : {
    5124             : 
    5125             :     // SUBROUTINE INFORMATION:
    5126             :     //       AUTHOR         From Legacy Code
    5127             :     //       DATE WRITTEN
    5128             :     //       MODIFIED       LKL; March 2002 -- another missing translation from BLAST's routine
    5129             :     //                      FCW; Jan 2003 -- removed line that prevented beam solar through interior windows
    5130             :     //       RE-ENGINEERED  Rick Strand; 1998
    5131             :     //                      Linda Lawrie; Oct 2000
    5132             : 
    5133             :     // PURPOSE OF THIS SUBROUTINE:
    5134             :     // This routine prepares a list of heat transfer surfaces and
    5135             :     // their possible shadowers which is used to direct the hourly
    5136             :     // calculation of shadows and sunlit areas.
    5137             : 
    5138             :     // METHODOLOGY EMPLOYED:
    5139             :     // As appropriate surfaces are identified, they are placed into the
    5140             :     // ShadowComb data structure (module level) with the accompanying lists
    5141             :     // of other surface numbers.
    5142             : 
    5143             :     // REFERENCES:
    5144             :     // BLAST/IBLAST code, original author George Walton
    5145             : 
    5146             :     // Using/Aliasing
    5147             :     using namespace DataErrorTracking;
    5148             : 
    5149        1542 :     Array1D_int GSS;             // List of shadowing surfaces numbers for a receiving surface
    5150        1542 :     Array1D_int BKS;             // List of back surface numbers for a receiving surface
    5151        1542 :     Array1D_int SBS;             // List of subsurfaces for a receiving surface
    5152             :     bool CannotShade;            // TRUE if subsurface cannot shade receiving surface
    5153             :     bool HasWindow;              // TRUE if a window is present on receiving surface
    5154             :     Real64 ZMIN;                 // Lowest point on the receiving surface
    5155             :     int BackSurfaceNumber;       // Back surface number
    5156             :     int HTS;                     // Heat transfer surface number for a receiving surface
    5157             :     int GRSNR;                   // Receiving surface number
    5158             :     int GSSNR;                   // Shadowing surface number
    5159             :     int SBSNR;                   // Subsurface number
    5160             :     int NBKS;                    // Number of back surfaces for a receiving surface
    5161             :     int NGSS;                    // Number of shadowing surfaces for a receiving surface
    5162             :     int NSBS;                    // Number of subsurfaces for a receiving surface
    5163             :     bool ShadowingSurf;          // True if a receiving surface is a shadowing surface
    5164        1542 :     Array1D_bool CastingSurface; // tracking during setup of ShadowComb
    5165             : 
    5166             : #ifdef EP_Count_Calls
    5167             :     ++state.dataTimingsData->NumDetShadowCombs_Calls;
    5168             : #endif
    5169             : 
    5170        2313 :     state.dataShadowComb->ShadowComb.dimension(state.dataSurface->TotSurfaces,
    5171        2313 :                                                ShadowingCombinations{}); // Set all elements to default constructed state
    5172             : 
    5173         771 :     CastingSurface.dimension(state.dataSurface->TotSurfaces, false);
    5174             : 
    5175         771 :     state.dataSolarShading->HCA.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
    5176         771 :     state.dataSolarShading->HCB.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
    5177         771 :     state.dataSolarShading->HCC.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
    5178         771 :     state.dataSolarShading->HCX.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
    5179         771 :     state.dataSolarShading->HCY.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
    5180         771 :     state.dataSolarShading->HCAREA.dimension(2 * state.dataSolarShading->MaxHCS, 0.0);
    5181         771 :     state.dataSolarShading->HCNS.dimension(2 * state.dataSolarShading->MaxHCS, 0);
    5182         771 :     state.dataSolarShading->HCNV.dimension(2 * state.dataSolarShading->MaxHCS, 0);
    5183         771 :     state.dataSolarShading->HCT.dimension(2 * state.dataSolarShading->MaxHCS, 0.0);
    5184             : 
    5185         771 :     GSS.dimension(state.dataSolarShading->MaxGSS, 0);
    5186         771 :     BKS.dimension(state.dataSolarShading->MaxGSS, 0);
    5187         771 :     SBS.dimension(state.dataSolarShading->MaxGSS, 0);
    5188             : 
    5189         771 :     state.dataSolarShading->penumbraIDs.clear();
    5190             : 
    5191         771 :     HTS = 0;
    5192             : 
    5193             :     // Check every surface as a possible shadow receiving surface ("RS" = receiving surface).
    5194         771 :     if (state.dataEnvrn->IgnoreSolarRadiation) {
    5195           0 :         return;
    5196             :     }
    5197             : 
    5198       44533 :     for (GRSNR = 1; GRSNR <= state.dataSurface->TotSurfaces; ++GRSNR) { // Loop through all surfaces (looking for potential receiving surfaces)...
    5199             : 
    5200       43762 :         ShadowingSurf = state.dataSurface->Surface(GRSNR).IsShadowing;
    5201       43762 :         NGSS = 0;
    5202       43762 :         NSBS = 0;
    5203       43762 :         NBKS = 0;
    5204             : 
    5205       43762 :         if (!ShadowingSurf && !state.dataSurface->Surface(GRSNR).HeatTransSurf) continue;
    5206       43748 :         HTS = GRSNR;
    5207             : 
    5208             : #ifndef EP_NO_OPENGL
    5209       43748 :         if (state.dataSolarShading->penumbra) {
    5210         113 :             bool skipSurface = state.dataSurface->Surface(GRSNR).MirroredSurf;
    5211             :             // Penumbra doesn't need mirrored surfaces TODO: Don't bother creating them in the first place?
    5212             : 
    5213             :             // Skip interior surfaces if the other side has already been added to penumbra
    5214         113 :             if (state.dataSurface->Surface(GRSNR).ExtBoundCond > 0) {
    5215          20 :                 if (state.dataSurface->SurfPenumbraID(state.dataSurface->Surface(GRSNR).ExtBoundCond) >= 0) {
    5216          10 :                     state.dataSurface->SurfPenumbraID(GRSNR) = state.dataSurface->SurfPenumbraID(state.dataSurface->Surface(GRSNR).ExtBoundCond);
    5217          10 :                     skipSurface = true;
    5218             :                 }
    5219             :             }
    5220             : 
    5221         113 :             if (!skipSurface) {
    5222             :                 // Add surfaces to penumbra...
    5223         184 :                 Pumbra::Polygon poly;
    5224             : 
    5225          92 :                 if (state.dataSurface->Surface(GRSNR).Reveal > 0.0) {
    5226          21 :                     Real64 R = state.dataSurface->Surface(GRSNR).Reveal;
    5227          21 :                     auto &norm = state.dataSurface->Surface(GRSNR).NewellSurfaceNormalVector;
    5228          21 :                     auto &v = state.dataSurface->Surface(GRSNR).Vertex;
    5229         105 :                     for (unsigned i = 0; i < v.size(); ++i) {
    5230          84 :                         poly.push_back(v[i].x);
    5231          84 :                         poly.push_back(v[i].y);
    5232          84 :                         poly.push_back(v[i].z);
    5233             : 
    5234         168 :                         Vector vPrev;
    5235          84 :                         if (i == 0) {
    5236          21 :                             vPrev = v[v.size() - 1];
    5237             :                         } else {
    5238          63 :                             vPrev = v[i - 1];
    5239             :                         }
    5240             : 
    5241         168 :                         Pumbra::Polygon rPoly; // Reveal surface
    5242          84 :                         rPoly.push_back(v[i].x);
    5243          84 :                         rPoly.push_back(v[i].y);
    5244          84 :                         rPoly.push_back(v[i].z);
    5245             : 
    5246          84 :                         rPoly.push_back(v[i].x + norm.x * R);
    5247          84 :                         rPoly.push_back(v[i].y + norm.y * R);
    5248          84 :                         rPoly.push_back(v[i].z + norm.z * R);
    5249             : 
    5250          84 :                         rPoly.push_back(vPrev.x + norm.x * R);
    5251          84 :                         rPoly.push_back(vPrev.y + norm.y * R);
    5252          84 :                         rPoly.push_back(vPrev.z + norm.z * R);
    5253             : 
    5254          84 :                         rPoly.push_back(vPrev.x);
    5255          84 :                         rPoly.push_back(vPrev.y);
    5256          84 :                         rPoly.push_back(vPrev.z);
    5257             : 
    5258         168 :                         Pumbra::Surface rSurf(rPoly);
    5259          84 :                         state.dataSolarShading->penumbra->addSurface(rSurf);
    5260             :                     }
    5261             :                 } else {
    5262         353 :                     for (auto v : state.dataSurface->Surface(GRSNR).Vertex) {
    5263         282 :                         poly.push_back(v.x);
    5264         282 :                         poly.push_back(v.y);
    5265         282 :                         poly.push_back(v.z);
    5266             :                     }
    5267             :                 }
    5268         184 :                 Pumbra::Surface pSurf(poly);
    5269             : 
    5270             :                 // Punch holes for subsurfaces
    5271          92 :                 if (state.dataSurface->Surface(GRSNR).BaseSurf == GRSNR) { // Only look for subsurfaces on base surfaces
    5272        6840 :                     for (int subSurface = 1; subSurface <= state.dataSurface->TotSurfaces; ++subSurface) {
    5273       13539 :                         if (state.dataSurface->Surface(subSurface).BaseSurf != GRSNR) continue; // Ignore subsurfaces of other surfaces
    5274          81 :                         if (!state.dataSurface->Surface(subSurface).HeatTransSurf) continue;    // Skip non heat transfer subsurfaces
    5275          81 :                         if (subSurface == GRSNR) continue;                                      // Surface itself cannot be its own subsurface
    5276             : 
    5277          42 :                         Pumbra::Polygon subPoly;
    5278          21 :                         if (state.dataSurface->Surface(subSurface).Reveal > 0.0) {
    5279          21 :                             Real64 R = state.dataSurface->Surface(subSurface).Reveal;
    5280          21 :                             auto &norm = state.dataSurface->Surface(subSurface).NewellSurfaceNormalVector;
    5281         105 :                             for (auto v : state.dataSurface->Surface(subSurface).Vertex) {
    5282          84 :                                 subPoly.push_back(v.x + norm.x * R);
    5283          84 :                                 subPoly.push_back(v.y + norm.y * R);
    5284          84 :                                 subPoly.push_back(v.z + norm.z * R);
    5285             :                             }
    5286             :                         } else {
    5287           0 :                             for (auto v : state.dataSurface->Surface(subSurface).Vertex) {
    5288           0 :                                 subPoly.push_back(v.x);
    5289           0 :                                 subPoly.push_back(v.y);
    5290           0 :                                 subPoly.push_back(v.z);
    5291             :                             }
    5292             :                         }
    5293             : 
    5294          21 :                         pSurf.addHole(subPoly);
    5295             :                     }
    5296             :                 }
    5297          92 :                 state.dataSurface->SurfPenumbraID(GRSNR) = state.dataSolarShading->penumbra->addSurface(pSurf);
    5298          92 :                 state.dataSolarShading->penumbraIDs.push_back(state.dataSurface->SurfPenumbraID(GRSNR));
    5299             :             }
    5300             :         }
    5301             : #endif
    5302             : 
    5303       43748 :         if (!ShadowingSurf && !state.dataSurface->Surface(GRSNR).ExtSolar) continue; // Skip surfaces with no external solar
    5304             : 
    5305       18505 :         if (!ShadowingSurf && state.dataSurface->Surface(GRSNR).BaseSurf != GRSNR) { // Skip subsurfaces (SBS)
    5306        6337 :             continue;
    5307             :         }
    5308             : 
    5309             :         // Get the lowest point of receiving surface
    5310       12168 :         ZMIN = minval(state.dataSurface->Surface(GRSNR).Vertex, &Vector::z);
    5311             : 
    5312             :         // Check every surface as a possible shadow casting surface ("SS" = shadow sending)
    5313       12168 :         NGSS = 0;
    5314       12168 :         if (state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) { // Except when doing simplified exterior shadowing.
    5315             : 
    5316     1553482 :             for (GSSNR = 1; GSSNR <= state.dataSurface->TotSurfaces; ++GSSNR) { // Loop through all surfaces, looking for ones that could shade GRSNR
    5317             : 
    5318     1542814 :                 if (GSSNR == GRSNR) continue; // Receiving surface cannot shade itself
    5319     1532146 :                 if ((state.dataSurface->Surface(GSSNR).HeatTransSurf) && (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR))
    5320        5416 :                     continue; // A heat transfer subsurface of a receiving surface
    5321             :                 // cannot shade the receiving surface
    5322     1526730 :                 if (ShadowingSurf) {
    5323             :                     // If receiving surf is a shadowing surface exclude matching shadow surface as sending surface
    5324             :                     // IF((GSSNR == GRSNR+1 .AND. Surface(GSSNR)%Name(1:3) == 'Mir').OR. &
    5325             :                     //   (GSSNR == GRSNR-1 .AND. Surface(GRSNR)%Name(1:3) == 'Mir')) CYCLE
    5326      251538 :                     if (((GSSNR == GRSNR + 1) && state.dataSurface->Surface(GSSNR).MirroredSurf) ||
    5327      125901 :                         ((GSSNR == GRSNR - 1) && state.dataSurface->Surface(GRSNR).MirroredSurf))
    5328        1540 :                         continue;
    5329             :                 }
    5330             : 
    5331     1525190 :                 if (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR) { // Shadowing subsurface of receiving surface
    5332             : 
    5333           0 :                     ++NGSS;
    5334           0 :                     if (NGSS > state.dataSolarShading->MaxGSS) {
    5335           0 :                         GSS.redimension(state.dataSolarShading->MaxGSS *= 2, 0);
    5336             :                     }
    5337           0 :                     GSS(NGSS) = GSSNR;
    5338             : 
    5339     3367075 :                 } else if ((state.dataSurface->Surface(GSSNR).BaseSurf == 0) ||
    5340     2691573 :                            ((state.dataSurface->Surface(GSSNR).BaseSurf == GSSNR) &&
    5341     2123579 :                             ((state.dataSurface->Surface(GSSNR).ExtBoundCond == ExternalEnvironment) ||
    5342      903698 :                              state.dataSurface->Surface(GSSNR).ExtBoundCond ==
    5343             :                                  OtherSideCondModeledExt))) { // Detached shadowing surface or | any other base surface
    5344             :                     // exposed to outside environment
    5345             : 
    5346      370193 :                     CHKGSS(state, GRSNR, GSSNR, ZMIN, CannotShade); // Check to see if this can shade the receiving surface
    5347      370193 :                     if (!CannotShade) {                             // Update the shadowing surface data if shading is possible
    5348       24993 :                         ++NGSS;
    5349       24993 :                         if (NGSS > state.dataSolarShading->MaxGSS) {
    5350           0 :                             GSS.redimension(state.dataSolarShading->MaxGSS *= 2, 0);
    5351             :                         }
    5352       24993 :                         GSS(NGSS) = GSSNR;
    5353             :                     }
    5354             :                 }
    5355             : 
    5356             :             }    // ...end of surfaces DO loop (GSSNR)
    5357             :         } else { // Simplified Distribution -- still check for Shading Subsurfaces
    5358             : 
    5359      469239 :             for (GSSNR = 1; GSSNR <= state.dataSurface->TotSurfaces;
    5360             :                  ++GSSNR) { // Loop through all surfaces (looking for surfaces which could shade GRSNR) ...
    5361             : 
    5362      467739 :                 if (GSSNR == GRSNR) continue; // Receiving surface cannot shade itself
    5363      466239 :                 if ((state.dataSurface->Surface(GSSNR).HeatTransSurf) && (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR))
    5364         921 :                     continue;                                              // Skip heat transfer subsurfaces of receiving surface
    5365      465318 :                 if (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR) { // Shadowing subsurface of receiving surface
    5366           0 :                     ++NGSS;
    5367           0 :                     if (NGSS > state.dataSolarShading->MaxGSS) {
    5368           0 :                         GSS.redimension(state.dataSolarShading->MaxGSS *= 2, 0);
    5369             :                     }
    5370           0 :                     GSS(NGSS) = GSSNR;
    5371             :                 }
    5372             :             }
    5373             : 
    5374             :         } // ...end of check for simplified solar distribution
    5375             : 
    5376             :         // Check every surface as a receiving subsurface of the receiving surface
    5377       12168 :         NSBS = 0;
    5378       12168 :         HasWindow = false;
    5379             :         // legacy: IF (OSENV(HTS) > 10) WINDOW=.TRUE. -->Note: WINDOW was set true for roof ponds, solar walls, or other zones
    5380     2022721 :         for (SBSNR = 1; SBSNR <= state.dataSurface->TotSurfaces;
    5381             :              ++SBSNR) { // Loop through the surfaces yet again (looking for subsurfaces of GRSNR)...
    5382             : 
    5383     2010553 :             if (!state.dataSurface->Surface(SBSNR).HeatTransSurf) continue;    // Skip non heat transfer subsurfaces
    5384     1953571 :             if (SBSNR == GRSNR) continue;                                      // Surface itself cannot be its own subsurface
    5385     1942944 :             if (state.dataSurface->Surface(SBSNR).BaseSurf != GRSNR) continue; // Ignore subsurfaces of other surfaces and other surfaces
    5386             : 
    5387        6337 :             if (state.dataConstruction->Construct(state.dataSurface->Surface(SBSNR).Construction).TransDiff > 0.0)
    5388        5955 :                 HasWindow = true;             // Check for window
    5389        6337 :             CHKSBS(state, HTS, GRSNR, SBSNR); // Check that the receiving surface completely encloses the subsurface;
    5390             :             // severe error if not
    5391        6337 :             ++NSBS;
    5392        6337 :             if (NSBS > state.dataSolarShading->MaxSBS) {
    5393           3 :                 SBS.redimension(state.dataSolarShading->MaxSBS *= 2, 0);
    5394             :             }
    5395        6337 :             SBS(NSBS) = SBSNR;
    5396             : 
    5397             :         } // ...end of surfaces DO loop (SBSNR)
    5398             : 
    5399             :         // Check every surface as a back surface
    5400       12168 :         NBKS = 0;
    5401             :         //                                        Except for simplified
    5402             :         //                                        interior solar distribution,
    5403       12168 :         if ((state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) &&
    5404             :             (HasWindow)) { // For full interior solar distribution | and a window present on base surface (GRSNR)
    5405             : 
    5406      711526 :             for (BackSurfaceNumber = 1; BackSurfaceNumber <= state.dataSurface->TotSurfaces;
    5407             :                  ++BackSurfaceNumber) { // Loop through surfaces yet again, looking for back surfaces to GRSNR
    5408             : 
    5409      709246 :                 if (!state.dataSurface->Surface(BackSurfaceNumber).HeatTransSurf) continue;    // Skip non-heat transfer surfaces
    5410      704452 :                 if (state.dataSurface->Surface(BackSurfaceNumber).BaseSurf == GRSNR) continue; // Skip subsurfaces of this GRSNR
    5411      698497 :                 if (BackSurfaceNumber == GRSNR) continue;                                      // A back surface cannot be GRSNR itself
    5412      698497 :                 if (state.dataSurface->Surface(BackSurfaceNumber).SolarEnclIndex != state.dataSurface->Surface(GRSNR).SolarEnclIndex)
    5413      679141 :                     continue; // Skip if back surface not in same solar enclosure
    5414             : 
    5415       19356 :                 if (state.dataSurface->Surface(BackSurfaceNumber).Class == SurfaceClass::IntMass) continue;
    5416             : 
    5417             :                 // Following line removed 1/27/03 by FCW. Was in original code that didn't do beam solar transmitted through
    5418             :                 // interior windows. Was removed to allow such beam solar but then somehow was put back in.
    5419             :                 // IF (Surface(BackSurfaceNumber)%BaseSurf /= BackSurfaceNumber) CYCLE ! Not for subsurfaces of Back Surface
    5420             : 
    5421       17679 :                 if (!state.dataSolarShading->penumbra) {
    5422       17490 :                     CHKBKS(state, BackSurfaceNumber, GRSNR); // CHECK FOR CONVEX ZONE; severe error if not
    5423             :                 }
    5424       17679 :                 ++NBKS;
    5425       17679 :                 if (NBKS > state.dataSolarShading->MaxBKS) {
    5426           0 :                     BKS.redimension(state.dataSolarShading->MaxBKS *= 2, 0);
    5427             :                 }
    5428       17679 :                 BKS(NBKS) = BackSurfaceNumber;
    5429             : 
    5430             :             } // ...end of surfaces DO loop (BackSurfaceNumber)
    5431             :         }
    5432             : 
    5433             :         // Put this into the ShadowComb data structure
    5434       12168 :         state.dataShadowComb->ShadowComb(GRSNR).UseThisSurf = true;
    5435       12168 :         state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf = NGSS;
    5436       12168 :         state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf = NBKS;
    5437       12168 :         state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf = NSBS;
    5438       12168 :         state.dataSolarShading->MaxDim = max(state.dataSolarShading->MaxDim, NGSS, NBKS, NSBS);
    5439             : 
    5440       12168 :         state.dataShadowComb->ShadowComb(GRSNR).GenSurf.allocate({0, state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf});
    5441       12168 :         state.dataShadowComb->ShadowComb(GRSNR).GenSurf(0) = 0;
    5442       12168 :         if (state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf > 0) {
    5443        3703 :             state.dataShadowComb->ShadowComb(GRSNR).GenSurf({1, state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf}) = GSS({1, NGSS});
    5444             :         }
    5445             : 
    5446       12168 :         state.dataShadowComb->ShadowComb(GRSNR).BackSurf.allocate({0, state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf});
    5447       12168 :         state.dataShadowComb->ShadowComb(GRSNR).BackSurf(0) = 0;
    5448       12168 :         if (state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf > 0) {
    5449        2280 :             state.dataShadowComb->ShadowComb(GRSNR).BackSurf({1, state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf}) = BKS({1, NBKS});
    5450             :         }
    5451             : 
    5452       12168 :         state.dataShadowComb->ShadowComb(GRSNR).SubSurf.allocate({0, state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf});
    5453       12168 :         state.dataShadowComb->ShadowComb(GRSNR).SubSurf(0) = 0;
    5454       12168 :         if (state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf > 0) {
    5455        4031 :             state.dataShadowComb->ShadowComb(GRSNR).SubSurf({1, state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf}) = SBS({1, NSBS});
    5456             :         }
    5457             : 
    5458             :     } // ...end of surfaces (GRSNR) DO loop
    5459             : 
    5460         771 :     GSS.deallocate();
    5461         771 :     SBS.deallocate();
    5462         771 :     BKS.deallocate();
    5463             : 
    5464         771 :     if (!state.dataSolarShading->penumbra) {
    5465         770 :         if (state.dataSolarShading->shd_stream) {
    5466         770 :             *state.dataSolarShading->shd_stream << "Shadowing Combinations\n";
    5467         770 :             if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
    5468         102 :                 *state.dataSolarShading->shd_stream
    5469         102 :                     << "..Solar Distribution=Minimal Shadowing, Detached Shading will not be used in shadowing calculations\n";
    5470         668 :             } else if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullExterior) {
    5471         229 :                 if (state.dataSurface->CalcSolRefl) {
    5472           3 :                     *state.dataSolarShading->shd_stream << "..Solar Distribution=FullExteriorWithReflectionsFromExteriorSurfaces\n";
    5473             :                 } else {
    5474         226 :                     *state.dataSolarShading->shd_stream << "..Solar Distribution=FullExterior\n";
    5475             :                 }
    5476         439 :             } else if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) {
    5477         439 :                 if (state.dataSurface->CalcSolRefl) {
    5478           6 :                     *state.dataSolarShading->shd_stream << "..Solar Distribution=FullInteriorAndExteriorWithReflectionsFromExteriorSurfaces\n";
    5479             :                 } else {
    5480         433 :                     *state.dataSolarShading->shd_stream << "..Solar Distribution=FullInteriorAndExterior\n";
    5481             :                 }
    5482             :             } else {
    5483             :             }
    5484             : 
    5485         770 :             *state.dataSolarShading->shd_stream << "..In the following, only the first 10 reference surfaces will be shown.\n";
    5486         770 :             *state.dataSolarShading->shd_stream << "..But all surfaces are used in the calculations.\n";
    5487             : 
    5488       44419 :             for (int HTSnum : state.dataSurface->AllSurfaceListReportOrder) {
    5489       43649 :                 *state.dataSolarShading->shd_stream << "==================================\n";
    5490       43649 :                 if (state.dataShadowComb->ShadowComb(HTSnum).UseThisSurf) {
    5491       12100 :                     if (state.dataSurface->Surface(HTSnum).IsConvex) {
    5492       24138 :                         *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(HTSnum).Name
    5493       24138 :                                                             << " is used as Receiving Surface in calculations and is convex.\n";
    5494             :                     } else {
    5495          62 :                         *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(HTSnum).Name
    5496          62 :                                                             << " is used as Receiving Surface in calculations and is non-convex.\n";
    5497          31 :                         if (state.dataShadowComb->ShadowComb(HTSnum).NumGenSurf > 0) {
    5498           0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    5499           0 :                                 ShowWarningError(state,
    5500           0 :                                                  "DetermineShadowingCombinations: Surface=\"" + state.dataSurface->Surface(HTSnum).Name +
    5501             :                                                      "\" is a receiving surface and is non-convex.");
    5502           0 :                                 ShowContinueError(state,
    5503             :                                                   "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
    5504             :                             } else {
    5505           0 :                                 ++state.dataErrTracking->TotalReceivingNonConvexSurfaces;
    5506             :                             }
    5507             :                         }
    5508             :                     }
    5509             :                 } else {
    5510       63098 :                     *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(HTSnum).Name
    5511       63098 :                                                         << " is not used as Receiving Surface in calculations.\n";
    5512             :                 }
    5513       43649 :                 *state.dataSolarShading->shd_stream << "Number of general casting surfaces=" << state.dataShadowComb->ShadowComb(HTSnum).NumGenSurf
    5514       43649 :                                                     << '\n';
    5515       68009 :                 for (NGSS = 1; NGSS <= state.dataShadowComb->ShadowComb(HTSnum).NumGenSurf; ++NGSS) {
    5516       24360 :                     if (NGSS <= 10)
    5517       14735 :                         *state.dataSolarShading->shd_stream
    5518       14735 :                             << "..Surface=" << state.dataSurface->Surface(state.dataShadowComb->ShadowComb(HTSnum).GenSurf(NGSS)).Name << '\n';
    5519       24360 :                     CastingSurface(state.dataShadowComb->ShadowComb(HTSnum).GenSurf(NGSS)) = true;
    5520             :                 }
    5521       43649 :                 *state.dataSolarShading->shd_stream << "Number of back surfaces=" << state.dataShadowComb->ShadowComb(HTSnum).NumBackSurf << '\n';
    5522       57968 :                 for (NGSS = 1; NGSS <= min(10, state.dataShadowComb->ShadowComb(HTSnum).NumBackSurf); ++NGSS) {
    5523       14319 :                     *state.dataSolarShading->shd_stream
    5524       14319 :                         << "...Surface=" << state.dataSurface->Surface(state.dataShadowComb->ShadowComb(HTSnum).BackSurf(NGSS)).Name << '\n';
    5525             :                 }
    5526       43649 :                 *state.dataSolarShading->shd_stream << "Number of receiving sub surfaces=" << state.dataShadowComb->ShadowComb(HTSnum).NumSubSurf
    5527       43649 :                                                     << '\n';
    5528       49700 :                 for (NGSS = 1; NGSS <= min(10, state.dataShadowComb->ShadowComb(HTSnum).NumSubSurf); ++NGSS) {
    5529        6051 :                     *state.dataSolarShading->shd_stream
    5530        6051 :                         << "....Surface=" << state.dataSurface->Surface(state.dataShadowComb->ShadowComb(HTSnum).SubSurf(NGSS)).Name << '\n';
    5531             :                 }
    5532             :             }
    5533             :         }
    5534             : 
    5535       44419 :         for (HTS = 1; HTS <= state.dataSurface->TotSurfaces; ++HTS) {
    5536       43649 :             if (CastingSurface(HTS) && !state.dataSurface->Surface(HTS).IsConvex) {
    5537           0 :                 if (state.dataGlobal->DisplayExtraWarnings) {
    5538           0 :                     ShowSevereError(state,
    5539           0 :                                     "DetermineShadowingCombinations: Surface=\"" + state.dataSurface->Surface(HTS).Name +
    5540             :                                         "\" is a casting surface and is non-convex.");
    5541           0 :                     ShowContinueError(state, "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
    5542             :                 } else {
    5543           0 :                     ++state.dataErrTracking->TotalCastingNonConvexSurfaces;
    5544             :                 }
    5545             :             }
    5546             :         }
    5547             : 
    5548         770 :         if (state.dataErrTracking->TotalReceivingNonConvexSurfaces > 0) {
    5549           0 :             ShowWarningMessage(state,
    5550           0 :                                format("DetermineShadowingCombinations: There are {} surfaces which are receiving surfaces and are non-convex.",
    5551           0 :                                       state.dataErrTracking->TotalReceivingNonConvexSurfaces));
    5552           0 :             ShowContinueError(state, "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
    5553           0 :             ShowContinueError(state, "...Add Output:Diagnostics,DisplayExtraWarnings; to see individual warnings for each surface.");
    5554           0 :             state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalReceivingNonConvexSurfaces;
    5555             :         }
    5556             : 
    5557         770 :         if (state.dataErrTracking->TotalCastingNonConvexSurfaces > 0) {
    5558           0 :             ShowSevereMessage(state,
    5559           0 :                               format("DetermineShadowingCombinations: There are {} surfaces which are casting surfaces and are non-convex.",
    5560           0 :                                      state.dataErrTracking->TotalCastingNonConvexSurfaces));
    5561           0 :             ShowContinueError(state, "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
    5562           0 :             ShowContinueError(state, "...Add Output:Diagnostics,DisplayExtraWarnings; to see individual severes for each surface.");
    5563           0 :             state.dataErrTracking->TotalSevereErrors += state.dataErrTracking->TotalCastingNonConvexSurfaces;
    5564             :         }
    5565             :     }
    5566             : 
    5567         771 :     CastingSurface.deallocate();
    5568             : 
    5569             : #ifndef EP_NO_OPENGL
    5570         771 :     if (state.dataSolarShading->penumbra && state.dataSolarShading->penumbra->getNumSurfaces() > 0) {
    5571           1 :         state.dataSolarShading->penumbra->setModel();
    5572             :     }
    5573             : #endif
    5574             : }
    5575             : 
    5576      284427 : void SHADOW(EnergyPlusData &state,
    5577             :             int const iHour, // Hour index
    5578             :             int const TS     // Time Step
    5579             : )
    5580             : {
    5581             : 
    5582             :     // SUBROUTINE INFORMATION:
    5583             :     //       AUTHOR         Legacy Code
    5584             :     //       DATE WRITTEN
    5585             :     //       MODIFIED       Nov 2003, FCW: modify to do shadowing on shadowing surfaces
    5586             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    5587             : 
    5588             :     // PURPOSE OF THIS SUBROUTINE:
    5589             :     // This subroutine is a driving routine for calculations of shadows
    5590             :     // and sunlit areas used in computing the solar beam flux multipliers.
    5591             : 
    5592             :     // REFERENCES:
    5593             :     // BLAST/IBLAST code, original author George Walton
    5594             : 
    5595             :     Real64 XS; // Intermediate result
    5596             :     Real64 YS; // Intermediate result
    5597             :     Real64 ZS; // Intermediate result
    5598             :     int N;     // Vertex number
    5599             :     int NGRS;  // Coordinate transformation index
    5600             :     int NVT;
    5601             :     int HTS;         // Heat transfer surface number of the general receiving surface
    5602             :     int GRSNR;       // Surface number of general receiving surface
    5603             :     int NBKS;        // Number of back surfaces
    5604             :     int NGSS;        // Number of general shadowing surfaces
    5605             :     int NSBS;        // Number of subsurfaces (windows and doors)
    5606             :     Real64 SurfArea; // Surface area. For walls, includes all window frame areas.
    5607             :     // For windows, includes divider area
    5608             : 
    5609      284427 :     if (state.dataSolarShading->ShadowOneTimeFlag) {
    5610         771 :         state.dataSolarShading->XVrt.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    5611         771 :         state.dataSolarShading->YVrt.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    5612         771 :         state.dataSolarShading->ZVrt.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    5613         771 :         state.dataSolarShading->XVrt = 0.0;
    5614         771 :         state.dataSolarShading->YVrt = 0.0;
    5615         771 :         state.dataSolarShading->ZVrt = 0.0;
    5616         771 :         state.dataSolarShading->ShadowOneTimeFlag = false;
    5617             :     }
    5618             : 
    5619             : #ifdef EP_Count_Calls
    5620             :     if (iHour == 0) {
    5621             :         ++state.dataTimingsData->NumShadow_Calls;
    5622             :     } else {
    5623             :         ++state.dataTimingsData->NumShadowAtTS_Calls;
    5624             :     }
    5625             : #endif
    5626             : 
    5627      284427 :     state.dataSolarShading->SurfSunlitArea = 0.0;
    5628             : 
    5629             : #ifndef EP_NO_OPENGL
    5630      284427 :     if (state.dataSolarShading->penumbra) {
    5631         239 :         Real64 ElevSun = DataGlobalConstants::PiOvr2 - std::acos(state.dataSolarShading->SUNCOS(3));
    5632         239 :         Real64 AzimSun = std::atan2(state.dataSolarShading->SUNCOS(1), state.dataSolarShading->SUNCOS(2));
    5633         239 :         state.dataSolarShading->penumbra->setSunPosition(AzimSun, ElevSun);
    5634         239 :         state.dataSolarShading->penumbra->submitPSSA();
    5635             :     }
    5636             : #endif
    5637             : 
    5638    17630832 :     for (GRSNR = 1; GRSNR <= state.dataSurface->TotSurfaces; ++GRSNR) {
    5639             : 
    5640    17346405 :         if (!state.dataShadowComb->ShadowComb(GRSNR).UseThisSurf) continue;
    5641             : 
    5642     4531243 :         state.dataSolarShading->SurfSunlitArea(GRSNR) = 0.0;
    5643             : 
    5644     4531243 :         NGSS = state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf;
    5645     4531243 :         state.dataSolarShading->NGSSHC = 0;
    5646     4531243 :         NBKS = state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf;
    5647     4531243 :         state.dataSolarShading->NBKSHC = 0;
    5648     4531243 :         NSBS = state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf;
    5649     4531243 :         state.dataSolarShading->NRVLHC = 0;
    5650     4531243 :         state.dataSolarShading->NSBSHC = 0;
    5651     4531243 :         state.dataSolarShading->LOCHCA = 1;
    5652             :         // Temporarily determine the old heat transfer surface number (HTS)
    5653     4531243 :         HTS = GRSNR;
    5654             : 
    5655     4531243 :         if (state.dataSolarShading->SurfSunCosTheta(GRSNR) < DataEnvironment::SunIsUpValue) { //.001) THEN ! Receiving surface is not in the sun
    5656             : 
    5657     1907122 :             state.dataSolarShading->SurfSunlitArea(HTS) = 0.0;
    5658     1907122 :             SHDSBS(state, iHour, GRSNR, NBKS, NSBS, HTS, TS);
    5659             : 
    5660     2624121 :         } else if ((NGSS <= 0) && (NSBS <= 0)) { // Simple surface--no shaders or subsurfaces
    5661             : 
    5662     1310781 :             state.dataSolarShading->SurfSunlitArea(HTS) = state.dataSurface->Surface(GRSNR).NetAreaShadowCalc;
    5663             :         } else { // Surface in sun and either shading surfaces or subsurfaces present (or both)
    5664             : 
    5665             : #ifndef EP_NO_OPENGL
    5666     1313340 :             auto id = state.dataSurface->SurfPenumbraID(HTS);
    5667     1313340 :             if (state.dataSolarShading->penumbra && id >= 0) {
    5668             :                 // SurfSunlitArea(HTS) = buildingPSSF.at(id) / SurfSunCosTheta(HTS);
    5669        5410 :                 state.dataSolarShading->SurfSunlitArea(HTS) =
    5670        5410 :                     state.dataSolarShading->penumbra->fetchPSSA(id) / state.dataSolarShading->SurfSunCosTheta(HTS);
    5671             :                 // SurfSunlitArea(HTS) = penumbra->fetchPSSA(Surface(HTS).PenumbraID)/SurfSunCosTheta(HTS);
    5672        7987 :                 for (int SS = 1; SS <= NSBS; ++SS) {
    5673        2577 :                     auto HTSS = state.dataShadowComb->ShadowComb(HTS).SubSurf(SS);
    5674        2577 :                     id = state.dataSurface->SurfPenumbraID(HTSS);
    5675        2577 :                     if (id >= 0) {
    5676             :                         // SurfSunlitArea(HTSS) = buildingPSSF.at(id) / SurfSunCosTheta(HTSS);
    5677        2577 :                         state.dataSolarShading->SurfSunlitArea(HTSS) =
    5678        2577 :                             state.dataSolarShading->penumbra->fetchPSSA(id) / state.dataSolarShading->SurfSunCosTheta(HTSS);
    5679             :                         // SurfSunlitArea(HTSS) = penumbra->fetchPSSA(Surface(HTSS).PenumbraID)/SurfSunCosTheta(HTSS);
    5680        2577 :                         if (state.dataSolarShading->SurfSunlitArea(HTSS) > 0.0) {
    5681        2329 :                             if (iHour > 0 && TS > 0)
    5682        1059 :                                 state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) =
    5683        1059 :                                     state.dataSolarShading->SurfSunlitArea(HTSS) / state.dataSurface->Surface(HTSS).Area;
    5684             :                         }
    5685             :                     }
    5686             :                 }
    5687     1307930 :             } else if (!state.dataSolarShading->penumbra) {
    5688             : #else
    5689             :             {
    5690             : #endif
    5691     1305779 :                 NGRS = state.dataSurface->Surface(GRSNR).BaseSurf;
    5692     1305779 :                 if (state.dataSurface->Surface(GRSNR).IsShadowing) NGRS = GRSNR;
    5693             : 
    5694             :                 // Compute the X and Y displacements of a shadow.
    5695     3917337 :                 XS = state.dataSurface->Surface(NGRS).lcsx.x * state.dataSolarShading->SUNCOS(1) +
    5696     1305779 :                      state.dataSurface->Surface(NGRS).lcsx.y * state.dataSolarShading->SUNCOS(2) +
    5697     1305779 :                      state.dataSurface->Surface(NGRS).lcsx.z * state.dataSolarShading->SUNCOS(3);
    5698     3917337 :                 YS = state.dataSurface->Surface(NGRS).lcsy.x * state.dataSolarShading->SUNCOS(1) +
    5699     1305779 :                      state.dataSurface->Surface(NGRS).lcsy.y * state.dataSolarShading->SUNCOS(2) +
    5700     1305779 :                      state.dataSurface->Surface(NGRS).lcsy.z * state.dataSolarShading->SUNCOS(3);
    5701     3917337 :                 ZS = state.dataSurface->Surface(NGRS).lcsz.x * state.dataSolarShading->SUNCOS(1) +
    5702     1305779 :                      state.dataSurface->Surface(NGRS).lcsz.y * state.dataSolarShading->SUNCOS(2) +
    5703     1305779 :                      state.dataSurface->Surface(NGRS).lcsz.z * state.dataSolarShading->SUNCOS(3);
    5704             : 
    5705     1305779 :                 if (std::abs(ZS) > 1.e-4) {
    5706     1305776 :                     state.dataSolarShading->XShadowProjection = XS / ZS;
    5707     1305776 :                     state.dataSolarShading->YShadowProjection = YS / ZS;
    5708     1305776 :                     if (std::abs(state.dataSolarShading->XShadowProjection) < 1.e-8) state.dataSolarShading->XShadowProjection = 0.0;
    5709     1305776 :                     if (std::abs(state.dataSolarShading->YShadowProjection) < 1.e-8) state.dataSolarShading->YShadowProjection = 0.0;
    5710             :                 } else {
    5711           3 :                     state.dataSolarShading->XShadowProjection = 0.0;
    5712           3 :                     state.dataSolarShading->YShadowProjection = 0.0;
    5713             :                 }
    5714             : 
    5715     3917337 :                 CTRANS(state,
    5716             :                        GRSNR,
    5717             :                        NGRS,
    5718             :                        NVT,
    5719     1305779 :                        state.dataSolarShading->XVrt,
    5720     1305779 :                        state.dataSolarShading->YVrt,
    5721     1305779 :                        state.dataSolarShading->ZVrt); // Transform coordinates of the receiving surface to 2-D form
    5722             : 
    5723             :                 // Re-order its vertices to clockwise sequential.
    5724     6520609 :                 for (N = 1; N <= NVT; ++N) {
    5725     5214830 :                     state.dataSolarShading->XVS(N) = state.dataSolarShading->XVrt(NVT + 1 - N);
    5726     5214830 :                     state.dataSolarShading->YVS(N) = state.dataSolarShading->YVrt(NVT + 1 - N);
    5727             :                 }
    5728             : 
    5729     1305779 :                 HTRANS1(state, 1, NVT); // Transform to homogeneous coordinates.
    5730             : 
    5731     1305779 :                 state.dataSolarShading->HCAREA(1) = -state.dataSolarShading->HCAREA(1); // Compute (+) gross surface area.
    5732     1305779 :                 state.dataSolarShading->HCT(1) = 1.0;
    5733             : 
    5734     1305779 :                 SHDGSS(state, NGRS, iHour, TS, GRSNR, NGSS, HTS); // Determine shadowing on surface.
    5735             : 
    5736     1305779 :                 if (!state.dataSolarShading->CalcSkyDifShading) {
    5737      833552 :                     SHDBKS(state, state.dataSurface->Surface(GRSNR).BaseSurf, GRSNR, NBKS, HTS); // Determine possible back surfaces.
    5738             :                 }
    5739             :             }
    5740             : 
    5741     1313340 :             SHDSBS(state, iHour, GRSNR, NBKS, NSBS, HTS, TS); // Subtract subsurf areas from total
    5742             : 
    5743             :             // Error checking:  require that 0 <= SurfSunlitArea <= AREA.  + or - .01*AREA added for round-off errors
    5744     1313340 :             SurfArea = state.dataSurface->Surface(GRSNR).NetAreaShadowCalc;
    5745     1313340 :             state.dataSolarShading->SurfSunlitArea(HTS) = max(0.0, state.dataSolarShading->SurfSunlitArea(HTS));
    5746             : 
    5747     1313340 :             state.dataSolarShading->SurfSunlitArea(HTS) = min(state.dataSolarShading->SurfSunlitArea(HTS), SurfArea);
    5748             :         } // ...end of surface in sun/surface with shaders and/or subsurfaces IF-THEN block
    5749             : 
    5750             :         // NOTE:
    5751             :         // There used to be a call to legacy subroutine SHDCVR here when the
    5752             :         // zone type was not a standard zone.
    5753             :     }
    5754      284427 : }
    5755             : 
    5756      833552 : void SHDBKS(EnergyPlusData &state,
    5757             :             int const NGRS, // Number of the general receiving surface
    5758             :             int const CurSurf,
    5759             :             int const NBKS, // Number of back surfaces
    5760             :             int const HTS   // Heat transfer surface number of the general receiving surf
    5761             : )
    5762             : {
    5763             : 
    5764             :     // SUBROUTINE INFORMATION:
    5765             :     //       AUTHOR         Legacy Code
    5766             :     //       DATE WRITTEN
    5767             :     //       MODIFIED       na
    5768             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    5769             : 
    5770             :     // PURPOSE OF THIS SUBROUTINE:
    5771             :     // This is the driving subroutine for computing
    5772             :     // the sunlit areas for back surfaces.
    5773             : 
    5774             :     // REFERENCES:
    5775             :     // BLAST/IBLAST code, original author George Walton
    5776             : 
    5777             :     typedef Array2D<Int64>::size_type size_type;
    5778             :     int I;
    5779             :     int M;
    5780             :     int N;
    5781             :     int NVR;
    5782             :     int NVT; // Number of vertices of back surface
    5783             :     int BackSurfaceNumber;
    5784             :     int NS1; // Number of the figure being overlapped
    5785             :     int NS2; // Number of the figure doing overlapping
    5786             :     int NS3; // Location to place results of overlap
    5787             : 
    5788             :     // Tuned Linear indexing
    5789             : 
    5790      833552 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    5791      833552 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
    5792             : 
    5793      833552 :     if (state.dataSolarShading->SHDBKSOneTimeFlag) {
    5794         681 :         state.dataSolarShading->XVrtx.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    5795         681 :         state.dataSolarShading->YVrtx.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    5796         681 :         state.dataSolarShading->ZVrtx.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
    5797         681 :         state.dataSolarShading->XVrtx = 0.0;
    5798         681 :         state.dataSolarShading->YVrtx = 0.0;
    5799         681 :         state.dataSolarShading->ZVrtx = 0.0;
    5800         681 :         state.dataSolarShading->SHDBKSOneTimeFlag = false;
    5801             :     }
    5802             : 
    5803     1188084 :     if ((NBKS <= 0) || (state.dataSolarShading->SurfSunlitArea(HTS) <= 0.0) || (state.dataSolarShading->OverlapStatus == TooManyVertices) ||
    5804      354532 :         (state.dataSolarShading->OverlapStatus == TooManyFigures))
    5805      479020 :         return;
    5806             : 
    5807      354532 :     state.dataSolarShading->FBKSHC = state.dataSolarShading->LOCHCA + 1;
    5808             : 
    5809     2805491 :     for (I = 1; I <= NBKS; ++I) { // Loop through all back surfaces associated with the receiving surface
    5810             : 
    5811     2450959 :         BackSurfaceNumber = state.dataShadowComb->ShadowComb(CurSurf).BackSurf(I);
    5812             : 
    5813     2450959 :         if (state.dataSolarShading->SurfSunCosTheta(BackSurfaceNumber) > -DataEnvironment::SunIsUpValue)
    5814      996296 :             continue; //-0.001) CYCLE ! go to next back surface since inside of this surface
    5815             :         // cannot be in sun if the outside can be
    5816             : 
    5817             :         // Transform coordinates of back surface from general system to the
    5818             :         // plane of the receiving surface
    5819             : 
    5820     1454663 :         CTRANS(state, BackSurfaceNumber, NGRS, NVT, state.dataSolarShading->XVrtx, state.dataSolarShading->YVrtx, state.dataSolarShading->ZVrtx);
    5821             : 
    5822             :         // Project "shadow" from back surface along sun's rays to receiving surface.  Back surface vertices
    5823             :         // become clockwise sequential.
    5824             : 
    5825     7301355 :         for (N = 1; N <= NVT; ++N) {
    5826     5846692 :             state.dataSolarShading->XVS(N) =
    5827     5846692 :                 state.dataSolarShading->XVrtx(N) - state.dataSolarShading->XShadowProjection * state.dataSolarShading->ZVrtx(N);
    5828     5846692 :             state.dataSolarShading->YVS(N) =
    5829     5846692 :                 state.dataSolarShading->YVrtx(N) - state.dataSolarShading->YShadowProjection * state.dataSolarShading->ZVrtx(N);
    5830             :         }
    5831             : 
    5832             :         // Transform to the homogeneous coordinate system.
    5833             : 
    5834     1454663 :         NS3 = state.dataSolarShading->LOCHCA + 1;
    5835     1454663 :         state.dataSolarShading->HCT(NS3) = 0.0;
    5836     1454663 :         HTRANS1(state, NS3, NVT);
    5837             : 
    5838             :         // Adjust near-duplicate points.
    5839             : 
    5840     1454663 :         NVR = state.dataSolarShading->HCNV(1);
    5841     1454663 :         auto l3(state.dataSolarShading->HCX.index(NS3, 1));
    5842     7301355 :         for (N = 1; N <= NVT; ++N, ++l3) {
    5843     5846692 :             auto const x3(state.dataSolarShading->HCX[l3]); // [ l3 ] == ( NS3, N )
    5844     5846692 :             auto const y3(state.dataSolarShading->HCY[l3]);
    5845     5846692 :             size_type l1(0);
    5846    25457248 :             for (M = 1; M <= NVR; ++M, ++l1) {
    5847    21127914 :                 if (std::abs(state.dataSolarShading->HCX[l1] - x3) > 6) continue; // [ l1 ] == ( 1, M )
    5848     2475414 :                 if (std::abs(state.dataSolarShading->HCY[l1] - y3) > 6) continue;
    5849     1517358 :                 state.dataSolarShading->HCX[l3] = state.dataSolarShading->HCX[l1];
    5850     1517358 :                 state.dataSolarShading->HCY[l3] = state.dataSolarShading->HCY[l1];
    5851     1517358 :                 break;
    5852             :             }
    5853             :         }
    5854             : 
    5855     1454663 :         HTRANS0(state, NS3, NVT);
    5856             : 
    5857             :         // Determine area of overlap of projected back surface and receiving surface.
    5858             : 
    5859     1454663 :         NS1 = 1;
    5860     1454663 :         NS2 = NS3;
    5861     1454663 :         state.dataSolarShading->HCT(NS3) = 1.0;
    5862     1454663 :         DeterminePolygonOverlap(state, NS1, NS2, NS3);
    5863             : 
    5864     1454663 :         if (state.dataSolarShading->OverlapStatus == NoOverlap) continue; // to next back surface
    5865      947937 :         if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
    5866           0 :             break; // back surfaces DO loop
    5867             : 
    5868             :         // Increment back surface count.
    5869             : 
    5870      947937 :         state.dataSolarShading->LOCHCA = NS3;
    5871      947937 :         state.dataSolarShading->HCNS(state.dataSolarShading->LOCHCA) = BackSurfaceNumber;
    5872      947937 :         state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA) = -state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
    5873      947937 :         state.dataSolarShading->NBKSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FBKSHC + 1;
    5874             :     }
    5875             : }
    5876             : 
    5877     1305779 : void SHDGSS(EnergyPlusData &state,
    5878             :             int const NGRS,
    5879             :             int const iHour,   // Hour Counter
    5880             :             int const TS,      // TimeStep
    5881             :             int const CurSurf, // Current Surface
    5882             :             int const NGSS,    // Number of general shadowing surfaces
    5883             :             int const HTS      // Heat transfer surface number of the general receiving surf
    5884             : )
    5885             : {
    5886             : 
    5887             :     // SUBROUTINE INFORMATION:
    5888             :     //       AUTHOR         Legacy Code
    5889             :     //       DATE WRITTEN
    5890             :     //       MODIFIED       na
    5891             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    5892             : 
    5893             :     // PURPOSE OF THIS SUBROUTINE:
    5894             :     // This subroutine determines the shadows on a general receiving surface.
    5895             : 
    5896             :     // REFERENCES:
    5897             :     // BLAST/IBLAST code, original author George Walton
    5898             : 
    5899             :     // Using/Aliasing
    5900             :     using ScheduleManager::GetCurrentScheduleValue;
    5901             :     using ScheduleManager::GetScheduleMinValue;
    5902             :     using ScheduleManager::GetScheduleName;
    5903             :     using ScheduleManager::LookUpScheduleValue;
    5904             : 
    5905             :     typedef Array2D<Int64>::size_type size_type;
    5906             :     int GSSNR;             // General shadowing surface number
    5907             :     int MainOverlapStatus; // Overlap status of the main overlap calculation not the check for
    5908             :     // multiple overlaps (unless there was an error)
    5909             :     int NS1;         // Number of the figure being overlapped
    5910             :     int NS2;         // Number of the figure doing overlapping
    5911             :     int NS3;         // Location to place results of overlap
    5912             :     Real64 SchValue; // Value for Schedule of shading transmittence
    5913             : 
    5914     1305779 :     if (state.dataSolarShading->SHDGSSOneTimeFlag) {
    5915         682 :         state.dataSolarShading->XVert.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
    5916         682 :         state.dataSolarShading->YVert.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
    5917         682 :         state.dataSolarShading->ZVert.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
    5918         682 :         state.dataSolarShading->SHDGSSOneTimeFlag = false;
    5919             :     }
    5920             : 
    5921     1305779 :     state.dataSolarShading->FGSSHC = state.dataSolarShading->LOCHCA + 1;
    5922     1305779 :     MainOverlapStatus = NoOverlap; // Set to ensure that the value from the last surface is not saved
    5923     1305779 :     state.dataSolarShading->OverlapStatus = NoOverlap;
    5924             : 
    5925     1305779 :     if (NGSS <= 0) { // IF NO S.S., receiving surface FULLY SUNLIT.
    5926             : 
    5927      613451 :         state.dataSolarShading->SurfSunlitArea(HTS) = state.dataSolarShading->HCAREA(1); // Surface fully sunlit
    5928             : 
    5929             :     } else {
    5930             : 
    5931      692328 :         int ExitLoopStatus(-1);
    5932      692328 :         auto const &GenSurf(state.dataShadowComb->ShadowComb(CurSurf).GenSurf);
    5933      692328 :         auto const sunIsUp(DataEnvironment::SunIsUpValue);
    5934     5652249 :         for (int I = 1; I <= NGSS; ++I) { // Loop through all shadowing surfaces...
    5935             : 
    5936     4975846 :             GSSNR = GenSurf(I);
    5937             : 
    5938     6761574 :             if (state.dataSolarShading->SurfSunCosTheta(GSSNR) > sunIsUp) continue; //.001) CYCLE ! NO SHADOW IF GSS IN SUNLIGHT.
    5939             : 
    5940     3228506 :             auto const &surface(state.dataSurface->Surface(GSSNR));
    5941     3228506 :             bool const notHeatTransSurf(!surface.HeatTransSurf);
    5942             : 
    5943             :             //     This used to check to see if the shadowing surface was not opaque (within the scheduled dates of
    5944             :             //            transmittance value.  Perhaps it ignored it if it were outside the range.  (if so, was an error)
    5945             :             //     The proper action seems to be delete this statement all together, but there would also be no shading if
    5946             :             //            the shading surface were transparent...
    5947             :             //---former stmt      IF ((.NOT.Surface(GSSNR)%HeatTransSurf) .AND. &
    5948             :             //---former stmt            GetCurrentScheduleValue(state, Surface(GSSNR)%SchedShadowSurfIndex,IHOUR) == 0.0) CYCLE
    5949             : 
    5950     3228506 :             if (notHeatTransSurf) {
    5951     1288260 :                 if (surface.IsTransparent) continue; // No shadow if shading surface is transparent
    5952     1288260 :                 if (surface.SchedShadowSurfIndex > 0) {
    5953     1000951 :                     if (LookUpScheduleValue(state, surface.SchedShadowSurfIndex, iHour) == 1.0) continue;
    5954     1000951 :                     if (!state.dataSolarShading->CalcSkyDifShading) {
    5955      531787 :                         if (LookUpScheduleValue(state, surface.SchedShadowSurfIndex, iHour, TS) == 1.0) continue;
    5956             :                     }
    5957             :                 }
    5958             :             }
    5959             :             // Elimate shawdowing surfaces that is supposed to be disabled.
    5960     3228506 :             if (state.dataSysVars->DisableAllSelfShading) {
    5961       61671 :                 if (surface.Zone != 0) {
    5962       32098 :                     continue; // Disable all shadowing surfaces in all zones. Attached shading surfaces are not part of a zone, zone value is 0.
    5963             :                 }
    5964     3166835 :             } else if (state.dataSysVars->DisableGroupSelfShading) {
    5965      113920 :                 std::vector<int> DisabledZones = state.dataSurface->SurfShadowDisabledZoneList(CurSurf);
    5966       60105 :                 bool isDisabledShadowSurf = false;
    5967      165705 :                 for (int i : DisabledZones) {
    5968      111890 :                     if (surface.Zone == i) {
    5969        6290 :                         isDisabledShadowSurf = true;
    5970        6290 :                         break;
    5971             :                     }
    5972             :                 }
    5973       60105 :                 if (isDisabledShadowSurf) continue; // Disable all shadowing surfaces in all disabled zones.
    5974             :             }
    5975             : 
    5976             :             //      IF ((.NOT.Surface(GSSNR)%HeatTransSurf) .AND. &
    5977             :             //            GetCurrentScheduleValue(state, Surface(GSSNR)%SchedShadowSurfIndex) == 1.0) CYCLE
    5978             : 
    5979             :             // Transform shadow casting surface from cartesian to homogeneous coordinates according to surface type.
    5980             : 
    5981     3190118 :             if ((notHeatTransSurf) && (surface.BaseSurf != 0)) {
    5982             : 
    5983             :                 // For shadowing subsurface coordinates of shadow casting surface are relative to the receiving surface
    5984             :                 // project shadow to the receiving surface
    5985             : 
    5986           0 :                 state.dataSolarShading->NVS = surface.Sides;
    5987           0 :                 auto const &XV(state.dataSurface->ShadeV(GSSNR).XV);
    5988           0 :                 auto const &YV(state.dataSurface->ShadeV(GSSNR).YV);
    5989           0 :                 auto const &ZV(state.dataSurface->ShadeV(GSSNR).ZV);
    5990           0 :                 for (int N = 1; N <= state.dataSolarShading->NVS; ++N) {
    5991           0 :                     state.dataSolarShading->XVS(N) = XV(N) - state.dataSolarShading->XShadowProjection * ZV(N);
    5992           0 :                     state.dataSolarShading->YVS(N) = YV(N) - state.dataSolarShading->YShadowProjection * ZV(N);
    5993           0 :                 }
    5994             : 
    5995             :             } else {
    5996             :                 // Transform coordinates of shadow casting surface from general system to the system relative to the receiving surface
    5997             :                 int NVT;
    5998     3190118 :                 CTRANS(state, GSSNR, NGRS, NVT, state.dataSolarShading->XVert, state.dataSolarShading->YVert, state.dataSolarShading->ZVert);
    5999     9570354 :                 CLIP(state,
    6000             :                      NVT,
    6001     3190118 :                      state.dataSolarShading->XVert,
    6002     3190118 :                      state.dataSolarShading->YVert,
    6003     3190118 :                      state.dataSolarShading->ZVert); // Clip portions of the shadow casting surface which are behind the receiving surface
    6004             : 
    6005     3190118 :                 if (state.dataSolarShading->NumVertInShadowOrClippedSurface <= 2) continue;
    6006             : 
    6007             :                 // Project shadow from shadow casting surface along sun's rays to receiving surface Shadow vertices
    6008             :                 // become clockwise sequential
    6009             : 
    6010    15862432 :                 for (int N = 1; N <= state.dataSolarShading->NumVertInShadowOrClippedSurface; ++N) {
    6011    12672314 :                     state.dataSolarShading->XVS(N) =
    6012    12672314 :                         state.dataSolarShading->XVC(N) - state.dataSolarShading->XShadowProjection * state.dataSolarShading->ZVC(N);
    6013    12672314 :                     state.dataSolarShading->YVS(N) =
    6014    12672314 :                         state.dataSolarShading->YVC(N) - state.dataSolarShading->YShadowProjection * state.dataSolarShading->ZVC(N);
    6015             :                 }
    6016             :             }
    6017             : 
    6018             :             // Transform to the homogeneous coordinate system.
    6019             : 
    6020     3190118 :             NS3 = state.dataSolarShading->LOCHCA + 1;
    6021     3190118 :             HTRANS1(state, NS3, state.dataSolarShading->NVS);
    6022             : 
    6023             :             // Adjust near-duplicate points.
    6024             : 
    6025     3190118 :             assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    6026     3190118 :             assert(state.dataSolarShading->HCX.index(1, 1) == 0u);
    6027     3190118 :             size_type j(state.dataSolarShading->HCX.index(NS3, 1));
    6028     3190118 :             size_type NVR(state.dataSolarShading->HCNV(1));
    6029    15862432 :             for (int N = 1; N <= state.dataSolarShading->NumVertInShadowOrClippedSurface;
    6030             :                  ++N, ++j) {                                      // Tuned Logic change: break after 1st "close" point found
    6031    12672314 :                 auto const HCX_N(state.dataSolarShading->HCX[j]); // [ j ] == ( NS3, N )
    6032    12672314 :                 auto const HCY_N(state.dataSolarShading->HCY[j]);
    6033    62460841 :                 for (size_type l = 0; l < NVR; ++l) { // [ l ] == ( 1, l+1 )
    6034    50077796 :                     auto const delX(std::abs(state.dataSolarShading->HCX[l] - HCX_N));
    6035    50077796 :                     if (delX > 6) continue;
    6036      937672 :                     auto const delY(std::abs(state.dataSolarShading->HCY[l] - HCY_N));
    6037      937672 :                     if (delY > 6) continue;
    6038      289269 :                     if (delX > 0) state.dataSolarShading->HCX[j] = state.dataSolarShading->HCX[l]; // [ j ] == ( NS3, N )
    6039      289269 :                     if (delY > 0) state.dataSolarShading->HCY[j] = state.dataSolarShading->HCY[l];
    6040      289269 :                     break;
    6041             :                 }
    6042             :             }
    6043     3190118 :             HTRANS0(state, NS3, state.dataSolarShading->NumVertInShadowOrClippedSurface);
    6044     3190118 :             if (!state.dataSolarShading->CalcSkyDifShading) {
    6045     1873434 :                 if (iHour != 0) {
    6046     1873434 :                     SchValue = LookUpScheduleValue(state, surface.SchedShadowSurfIndex, iHour, TS);
    6047             :                 } else {
    6048           0 :                     SchValue = surface.SchedMinValue;
    6049             :                 }
    6050             :             } else {
    6051     1316684 :                 SchValue = surface.SchedMinValue;
    6052             :             }
    6053             : 
    6054     3190118 :             state.dataSolarShading->HCT(NS3) = SchValue;
    6055             : 
    6056             :             // Determine overlap of shadow with receiving surface
    6057             : 
    6058     3190118 :             state.dataSolarShading->CurrentShadowingSurface = I;
    6059     3190118 :             state.dataSolarShading->CurrentSurfaceBeingShadowed = GSSNR;
    6060     3190118 :             NS1 = 1;
    6061     3190118 :             NS2 = NS3;
    6062     3190118 :             DeterminePolygonOverlap(state, NS1, NS2, NS3);
    6063             :             //  Next statement is special to deal with transmitting shading devices
    6064     3190118 :             if (state.dataSolarShading->OverlapStatus == FirstSurfWithinSecond && SchValue > 0.0)
    6065         328 :                 state.dataSolarShading->OverlapStatus = PartialOverlap;
    6066     3190118 :             MainOverlapStatus = state.dataSolarShading->OverlapStatus;
    6067     3190118 :             ExitLoopStatus = MainOverlapStatus;
    6068             : 
    6069     3190118 :             if (MainOverlapStatus == NoOverlap) { // No overlap of general surface shadow and receiving surface
    6070             :                                                   // Continue
    6071      582941 :             } else if ((MainOverlapStatus == FirstSurfWithinSecond) || (MainOverlapStatus == TooManyVertices) ||
    6072             :                        (MainOverlapStatus == TooManyFigures)) {
    6073             :                 goto ShadowingSurfaces_exit;
    6074      567016 :             } else if ((MainOverlapStatus == SecondSurfWithinFirst) || (MainOverlapStatus == PartialOverlap)) {
    6075             :                 // Determine overlaps with previous shadows.
    6076      567016 :                 state.dataSolarShading->LOCHCA = NS3;
    6077      567016 :                 state.dataSolarShading->NGSSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FGSSHC + 1;
    6078      567016 :                 if (state.dataSolarShading->NGSSHC > 1)
    6079      680130 :                     MULTOL(state,
    6080      226710 :                            state.dataSolarShading->LOCHCA,
    6081      226710 :                            state.dataSolarShading->FGSSHC - 1,
    6082      226710 :                            state.dataSolarShading->NGSSHC - 1); // HOYT - Remove this call
    6083             :             } else {
    6084             :                 goto ShadowingSurfaces_exit;
    6085             :             }
    6086             : 
    6087     3174193 :             ExitLoopStatus = -1;
    6088             :         }
    6089      676403 :     ShadowingSurfaces_exit:;
    6090             : 
    6091             :         // Compute sunlit area of surface (excluding effects of subsurfs).
    6092             : 
    6093      692328 :         if (ExitLoopStatus == FirstSurfWithinSecond) { // Surface fully shaded
    6094       15925 :             state.dataSolarShading->SurfSunlitArea(HTS) = 0.0;
    6095       15925 :             state.dataSolarShading->LOCHCA = state.dataSolarShading->FGSSHC;
    6096             : 
    6097      676403 :         } else if ((ExitLoopStatus == TooManyVertices) || (ExitLoopStatus == TooManyFigures)) { // Array limits exceeded, estimate
    6098           0 :             state.dataSolarShading->SurfSunlitArea(HTS) = 0.25 * state.dataSolarShading->HCAREA(1);
    6099             : 
    6100             :         } else {
    6101             : 
    6102             :             // Compute the sunlit area here.
    6103             :             // Call UnionShadow(FGSSHC,LOCHCA)
    6104             : 
    6105      676403 :             state.dataSolarShading->NGSSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FGSSHC + 1;
    6106      676403 :             if (state.dataSolarShading->NGSSHC <= 0) {
    6107      337199 :                 state.dataSolarShading->SurfSunlitArea(HTS) = state.dataSolarShading->HCAREA(1); // Surface fully sunlit
    6108             :             } else {
    6109      339204 :                 Real64 A(state.dataSolarShading->HCAREA(1)); // Area
    6110      985368 :                 for (int i = state.dataSolarShading->FGSSHC, e = state.dataSolarShading->FGSSHC + state.dataSolarShading->NGSSHC - 1; i <= e; ++i) {
    6111      646164 :                     A += state.dataSolarShading->HCAREA(i) * (1.0 - state.dataSolarShading->HCT(i));
    6112             :                 }
    6113      339204 :                 state.dataSolarShading->SurfSunlitArea(HTS) = A;
    6114      339204 :                 if (state.dataSolarShading->SurfSunlitArea(HTS) <= 0.0) { // Surface fully shaded
    6115        8175 :                     state.dataSolarShading->SurfSunlitArea(HTS) = 0.0;
    6116        8175 :                     state.dataSolarShading->LOCHCA = state.dataSolarShading->FGSSHC;
    6117             :                 }
    6118             :             }
    6119             :         }
    6120             :     }
    6121     1305779 :     state.dataSolarShading->NGSSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FGSSHC + 1;
    6122     1305779 : }
    6123             : 
    6124     1534620 : void CalcInteriorSolarOverlaps(EnergyPlusData &state,
    6125             :                                int const iHour, // Hour Index
    6126             :                                int const NBKS,  // Number of back surfaces associated with this GRSNR (in general, only
    6127             :                                int const HTSS,  // Surface number of the subsurface (exterior window)
    6128             :                                int const GRSNR, // General receiving surface number (base surface of the exterior window)
    6129             :                                int const TS     // Time step Index
    6130             : )
    6131             : {
    6132             : 
    6133             :     // SUBROUTINE INFORMATION:
    6134             :     //       AUTHOR         Fred Winkelmann
    6135             :     //       DATE WRITTEN   January 1999
    6136             :     //       MODIFIED       Nov 2001, FW: include beam radiation overlaps with
    6137             :     //                       back windows and doors; previously these subsurfaces ignored.
    6138             :     //                      May 2002, FW: fix problem where reveal was not being considered
    6139             :     //                       in calculating overlap areas if window is shaded only by reveal.
    6140             :     //                      June 2002, FW: fix problem that gave incorrect calculation when
    6141             :     //                       window is not shaded only by reveal
    6142             :     //                      June 2002, FW: remove incorrect multiplication of overlap areas
    6143             :     //                       by sunlit fraction when window is shaded only by reveal
    6144             : 
    6145             :     // PURPOSE OF THIS SUBROUTINE:
    6146             :     // For an exterior window with surface number HTSS, determines (1) the surface numbers of back
    6147             :     // surfaces receiving beam radiation from the window and (2) for each such back surface, the area
    6148             :     // of the portion of the window sending beam radiation to the back surface; this is called the
    6149             :     // "overlap area."
    6150             : 
    6151             :     // REFERENCES:
    6152             :     // BLAST/IBLAST code, original author George Walton
    6153             : 
    6154             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    6155             :     //  some of these will receive beam radiation from HTSS this hour)
    6156             : 
    6157             :     // SUBROUTINE PARAMETER DEFINITIONS:
    6158     1534620 :     int constexpr WindowShadedOnlyByReveal(2); // for use with RevealStatus
    6159             : 
    6160             :     typedef Array2D<Int64>::size_type size_type;
    6161             :     int JBKS;        // Counter of back surfaces with non-zero overlap with HTSS
    6162             :     int BackSurfNum; // Back surface number
    6163             : 
    6164             :     bool UseSimpleDistribution; // TRUE means simple interior solar distribution
    6165             :     // (all incoming beam assumed to strike floor),
    6166             :     // FALSE means exact interior solar distribution
    6167             :     // (track which back surfaces beam illuminates)
    6168             : 
    6169             :     // Tuned Linear indexing
    6170             : 
    6171     1534620 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
    6172     1534620 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
    6173     1534620 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
    6174     1534620 :     assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
    6175             : 
    6176     1534620 :     if (state.dataSolarShading->SurfSunlitArea(HTSS) > 0.0) {
    6177             : 
    6178      825857 :         UseSimpleDistribution = false;
    6179             : 
    6180      825857 :         if ((NBKS <= 0) || (state.dataSurface->Surface(GRSNR).ExtBoundCond > 0)) {
    6181             : 
    6182      248631 :             UseSimpleDistribution = true;
    6183             : 
    6184             :         } else {
    6185             :             // Using 'exact' distribution, replace subsurface HC entries with reveal HC entries
    6186             :             // so that the reveal HC is used in calculating interior solar overlap areas
    6187             : 
    6188             :             // Adding the following line fixes a problem where, if the window was shaded only
    6189             :             // by reveal, then the reveal was not considered in calculating interior solar
    6190             :             // overlap areas (FCW 5/3/02).
    6191             :             // IF(Surface(HTSS)%Reveal > 0.0) NRVLHC = 1
    6192             :             // Changing the line to the following avoids incorrect calculation when window is not shaded
    6193             :             // only by reveal (FCW 6/28/02).
    6194      577226 :             if (state.dataSolarShading->SurfWinRevealStatus(iHour, TS, HTSS) == WindowShadedOnlyByReveal) state.dataSolarShading->NRVLHC = 1;
    6195      577226 :             if (state.dataSolarShading->NRVLHC > 0) {
    6196       23630 :                 for (int I = 1; I <= state.dataSolarShading->NRVLHC; ++I) {
    6197       15530 :                     int const iS(state.dataSolarShading->FSBSHC - 1 + I);
    6198       15530 :                     int const iR(state.dataSolarShading->FRVLHC - 1 + I);
    6199       15530 :                     state.dataSolarShading->HCT(iS) = state.dataSolarShading->HCT(iR);
    6200       15530 :                     state.dataSolarShading->HCNV(iS) = state.dataSolarShading->HCNV(iR);
    6201       15530 :                     state.dataSolarShading->HCAREA(iS) = state.dataSolarShading->HCAREA(iR);
    6202       15530 :                     size_type lS(state.dataSolarShading->HCX.index(iS, 1));
    6203       15530 :                     size_type lR(state.dataSolarShading->HCX.index(iR, 1));
    6204      248480 :                     for (int J = 1; J <= state.dataSolarShading->MaxHCV; ++J, ++lS, ++lR) { // [ lS ] == ( iS, J ), [ lR ] == ( iR, J )
    6205      232950 :                         state.dataSolarShading->HCX[lS] = state.dataSolarShading->HCX[lR];
    6206      232950 :                         state.dataSolarShading->HCY[lS] = state.dataSolarShading->HCY[lR];
    6207      232950 :                         state.dataSolarShading->HCA[lS] = state.dataSolarShading->HCA[lR];
    6208      232950 :                         state.dataSolarShading->HCB[lS] = state.dataSolarShading->HCB[lR];
    6209      232950 :                         state.dataSolarShading->HCC[lS] = state.dataSolarShading->HCC[lR];
    6210             :                     }
    6211             :                 }
    6212        8100 :                 state.dataSolarShading->NSBSHC = state.dataSolarShading->NRVLHC;
    6213             :             }
    6214             :         }
    6215             : 
    6216             :         // Check for array space.
    6217      825857 :         if (state.dataSolarShading->FSBSHC + state.dataSolarShading->NBKSHC > state.dataSolarShading->MaxHCS) UseSimpleDistribution = true;
    6218             : 
    6219      825857 :         if (!UseSimpleDistribution) { // Compute overlaps
    6220             : 
    6221     1154452 :             std::map<unsigned, float> pssas;
    6222             : 
    6223             : #ifndef EP_NO_OPENGL
    6224      577226 :             if (state.dataSolarShading->penumbra) {
    6225             :                 // Add back surfaces to array
    6226        2118 :                 std::vector<unsigned> pbBackSurfaces;
    6227       11599 :                 for (auto bkSurfNum : state.dataShadowComb->ShadowComb(GRSNR).BackSurf) {
    6228       10540 :                     if (bkSurfNum == 0) continue;
    6229        9481 :                     if (state.dataSolarShading->SurfSunCosTheta(bkSurfNum) < DataEnvironment::SunIsUpValue) {
    6230        5405 :                         pbBackSurfaces.push_back(state.dataSurface->SurfPenumbraID(bkSurfNum));
    6231             :                     }
    6232             :                 }
    6233        1059 :                 pssas = state.dataSolarShading->penumbra->calculateInteriorPSSAs({(unsigned)state.dataSurface->SurfPenumbraID(HTSS)}, pbBackSurfaces);
    6234             :                 // penumbra->renderInteriorScene({(unsigned)Surface(HTSS).PenumbraID}, pbBackSurfaces);
    6235             : 
    6236        1059 :                 JBKS = 0;
    6237       11599 :                 for (auto bkSurfNum : state.dataShadowComb->ShadowComb(GRSNR).BackSurf) {
    6238       10540 :                     if (bkSurfNum == 0) continue;
    6239        9481 :                     if (pssas[state.dataSurface->SurfPenumbraID(bkSurfNum)] > 0) {
    6240        1655 :                         ++JBKS;
    6241        1655 :                         state.dataHeatBal->SurfWinBackSurfaces(iHour, TS, JBKS, HTSS) = bkSurfNum;
    6242        1655 :                         Real64 OverlapArea = pssas[state.dataSurface->SurfPenumbraID(bkSurfNum)] / state.dataSolarShading->SurfSunCosTheta(HTSS);
    6243        1655 :                         state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, JBKS, HTSS) = OverlapArea * state.dataSurface->SurfWinGlazedFrac(HTSS);
    6244             :                     }
    6245             :                 }
    6246             :             }
    6247             : #endif
    6248             : 
    6249      577226 :             if (!state.dataSolarShading->penumbra) {
    6250             : 
    6251      576167 :                 state.dataSolarShading->FINSHC = state.dataSolarShading->FSBSHC + state.dataSolarShading->NSBSHC;
    6252             : 
    6253      576167 :                 JBKS = 0;
    6254             : 
    6255     2252777 :                 for (int IBKS = 1; IBKS <= state.dataSolarShading->NBKSHC;
    6256             :                      ++IBKS) { // Loop over back surfaces to GRSNR this hour. NBKSHC is the number of
    6257             :                     // back surfaces that would receive beam radiation from the base surface, GRSNR,
    6258             :                     // if the base surface was transparent. In general, some (at least one) or all of these
    6259             :                     // will receive beam radiation from the exterior window subsurface, HTSS, of GRSNR,
    6260             :                     // depending on the size of HTSS and its location on GRSNR
    6261             : 
    6262     1676610 :                     BackSurfNum = state.dataSolarShading->HCNS(state.dataSolarShading->FBKSHC - 1 + IBKS);
    6263             : 
    6264             :                     // Determine if this back surface number can receive beam radiation from the
    6265             :                     // exterior window, HTSS, this hour, i.e., overlap area is positive
    6266             : 
    6267     1676610 :                     state.dataSolarShading->LOCHCA = state.dataSolarShading->FINSHC - 1;
    6268             : 
    6269     1676610 :                     MULTOL(state, state.dataSolarShading->FBKSHC - 1 + IBKS, state.dataSolarShading->FSBSHC - 1, state.dataSolarShading->NSBSHC);
    6270             : 
    6271             :                     // Compute overlap area for this back surface
    6272             : 
    6273     1676610 :                     state.dataSolarShading->NINSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FINSHC + 1;
    6274     1676610 :                     if (state.dataSolarShading->NINSHC <= 0) continue;
    6275     1073029 :                     Real64 OverlapArea = state.dataSolarShading->HCAREA(state.dataSolarShading->FINSHC);
    6276     1147420 :                     for (int J = 2; J <= state.dataSolarShading->NINSHC; ++J) {
    6277      148782 :                         OverlapArea += state.dataSolarShading->HCAREA(state.dataSolarShading->FINSHC - 1 + J) *
    6278       74391 :                                        (1.0 - state.dataSolarShading->HCT(state.dataSolarShading->FINSHC - 1 + J));
    6279             :                     }
    6280             : 
    6281     1073029 :                     if (OverlapArea > 0.001) {
    6282     1065281 :                         ++JBKS;
    6283     1065281 :                         if (JBKS <= state.dataBSDFWindow->MaxBkSurf) {
    6284     1065281 :                             state.dataHeatBal->SurfWinBackSurfaces(iHour, TS, JBKS, HTSS) = BackSurfNum;
    6285     1065281 :                             int baseSurfaceNum = state.dataSurface->Surface(BackSurfNum).BaseSurf;
    6286     1065281 :                             state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, JBKS, HTSS) = OverlapArea * state.dataSurface->SurfWinGlazedFrac(HTSS);
    6287             :                             // If this is a subsurface, subtract its overlap area from its base surface
    6288     1065281 :                             if (baseSurfaceNum != BackSurfNum) {
    6289       76066 :                                 for (int iBaseBKS = 1; iBaseBKS <= JBKS; ++iBaseBKS) {
    6290       76064 :                                     if (baseSurfaceNum == state.dataHeatBal->SurfWinBackSurfaces(iHour, TS, iBaseBKS, HTSS)) {
    6291       58041 :                                         state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, iBaseBKS, HTSS) =
    6292       58041 :                                             max(0.0,
    6293       58041 :                                                 state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, iBaseBKS, HTSS) -
    6294       58041 :                                                     state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, JBKS, HTSS));
    6295       58041 :                                         break;
    6296             :                                     }
    6297             :                                 }
    6298             :                             }
    6299             :                         }
    6300             :                     }
    6301             :                 } // End of loop over back surfaces
    6302             :             }
    6303             :         }
    6304             :     } // End of check that sunlit area > 0.
    6305     1534620 : }
    6306      821277 : void CalcInteriorSolarDistribution(EnergyPlusData &state)
    6307             : {
    6308             : 
    6309             :     // SUBROUTINE INFORMATION:
    6310             :     //       AUTHOR         Fred Winkelmann
    6311             :     //       DATE WRITTEN   January 1999
    6312             :     //       MODIFIED       Nov 1999, FW, for Window5 calculation method
    6313             :     //                      Oct 2000, FW: add transmitted solar variables for reporting
    6314             :     //                      Mar 2001, FW: add new calc of solar absorbed by window shades
    6315             :     //                      May 2001, FW: add calc of solar transmitted and absorbed by window blinds
    6316             :     //                      Oct 2001, LL: remove interpolation, solar now at time step
    6317             :     //                      Oct 2001, FW: add solar transmitted through interior windows
    6318             :     //                      Mar 24, 2001, FW: remove incorrect multiplication of Boverlap by sunlit fraction
    6319             :     //                                        since effect of shadowing is already included in Aoverlap
    6320             :     //                      Apr 2001, FW: add effects of beam solar reflection from outside and inside reveals
    6321             :     //                      Jan 2003, FW: add between-glass shades and blinds
    6322             :     //                      Dec 2003, FW: report beam incident on inside of surface
    6323             :     //                      Jan 2004, FW: for blinds with horizontal slats, allow different diffuse/diffuse
    6324             :     //                                    transmittance for ground and sky solar
    6325             :     //                      Apr 2004, FW: allow diffusing glazing
    6326             :     //                      May 2006, RR: allow external window screen
    6327             :     //                      Jan 2010, TH: add calculating and reporting of WinBmBmSolar, WinBmDifSolar,
    6328             :     //                                    WinBmBmSolarEnergy, and WinBmDifSolarEnergy
    6329             :     //                      Jun 2013, SV: scheduled surface gains for walls and windows
    6330             : 
    6331             :     // PURPOSE OF THIS SUBROUTINE:
    6332             :     // For a time step, calculates solar radiation absorbed by exterior
    6333             :     // surfaces and interior solar radiation distribution
    6334             : 
    6335             :     using DaylightingDevices::TransTDD;
    6336             :     using General::POLYF;
    6337             :     using ScheduleManager::GetCurrentScheduleValue;
    6338             :     using namespace DataWindowEquivalentLayer;
    6339             : 
    6340     1642554 :     Array1D<Real64> CFBoverlap;    // Sum of boverlap for each back surface
    6341     1642554 :     Array2D<Real64> CFDirBoverlap; // Directional boverlap (Direction, IBack)
    6342             : 
    6343             : #ifdef EP_Count_Calls
    6344             :     ++state.dataTimingsData->NumIntSolarDist_Calls;
    6345             : #endif
    6346     6668675 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6347    11699752 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6348     5852354 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    6349     5852354 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    6350     5852354 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    6351    12977287 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    6352    56999464 :                 for (int lay = 1; lay <= CFSMAXNL + 1; ++lay) {
    6353    49874531 :                     state.dataSurface->SurfWinA(SurfNum, lay) = 0.0;
    6354             :                 }
    6355     7124933 :                 state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfNum) = 0.0;
    6356     7124933 :                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = 0.0;
    6357             :             }
    6358     5852354 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
    6359     5852354 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
    6360    49240560 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
    6361    43388206 :                 state.dataSurface->SurfOpaqAI(SurfNum) = 0.0;
    6362    43388206 :                 state.dataSurface->SurfOpaqAO(SurfNum) = 0.0;
    6363             :             }
    6364             :         }
    6365             :     }
    6366      821277 :     if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
    6367        1848 :         for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
    6368        1232 :             int SurfDome = e.Dome;
    6369        9856 :             for (int lay = 1; lay <= CFSMAXNL + 1; ++lay) {
    6370        8624 :                 state.dataSurface->SurfWinA(SurfDome, lay) = 0.0;
    6371             :             }
    6372        1232 :             state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfDome) = 0.0;
    6373        1232 :             state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfDome) = 0.0;
    6374             :         }
    6375             :     }
    6376             : 
    6377     6664958 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    6378             :         // Solar entering a zone as beam or diffuse radiation, originating as beam solar incident on exterior windows)/(Beam normal solar) [W/(W/m2)]
    6379     5843681 :         Real64 BTOTZone = 0.0;
    6380             :         // Beam radiation from exterior windows absorbed in a zone or transmitted through
    6381     5843681 :         Real64 BABSZone = 0.0;
    6382     5843681 :         state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
    6383     5843681 :         state.dataHeatBal->EnclSolDBSSG(enclosureNum) = 0.0;
    6384     5843681 :         state.dataHeatBal->EnclSolDBIntWin(enclosureNum) = 0.0;
    6385             :         // Loop over exterior surfaces in this zone
    6386     5843681 :         auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
    6387             :         // delete values from previous timestep
    6388     5843681 :         if (state.dataHeatBal->AnyBSDF) state.dataSurface->SurfWinACFOverlap = 0.0;
    6389             : 
    6390             :         //-------------------------------------------------------------------------
    6391             :         // EXTERIOR BEAM SOLAR RADIATION ABSORBED ON THE OUTSIDE OF OPAQUE SURFACES
    6392             :         //-------------------------------------------------------------------------
    6393             :         // TODO: use opaq and window loop after airboundary is sorted
    6394             :         // TODO: It may be useful to sort SurfacePtr to group windows and domes together to reduce if conditions
    6395    56358052 :         for (int const SurfNum : thisEnclosure.SurfacePtr) {
    6396    93903809 :             if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Window &&
    6397    43389438 :                 state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome) {
    6398    43388206 :                 if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue;
    6399    43388206 :                 if (!state.dataSurface->Surface(SurfNum).ExtSolar) continue;
    6400    12356802 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    6401    12356802 :                 Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    6402    12356802 :                 Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    6403    12356802 :                 state.dataSurface->SurfOpaqAO(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar * CosInc * SunLitFract;
    6404             :             }
    6405             :         }
    6406             : 
    6407             :         //--------------------------------------------------------------------------------------------------------
    6408             :         // EXTERIOR WINDOWS OR TDD DOMES
    6409             :         //--------------------------------------------------------------------------------------------------------
    6410    56358052 :         for (int const SurfNum : thisEnclosure.SurfacePtr) {
    6411    93903809 :             if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Window &&
    6412    43389438 :                 state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome)
    6413    43388206 :                 continue;
    6414     7126165 :             if (!state.dataSurface->Surface(SurfNum).ExtSolar && state.dataSurface->SurfWinOriginalClass(SurfNum) != SurfaceClass::TDD_Diffuser)
    6415        8510 :                 continue;
    6416     7117655 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    6417     7117655 :             int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    6418     7117655 :             int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
    6419     7117655 :             int ScNum = state.dataSurface->SurfWinScreenNumber(SurfNum);
    6420     7117655 :             WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); // Set in subr. WindowShadingManager
    6421             : 
    6422     7117655 :             Real64 ProfAng = 0.0; // Window solar profile angle (radians)
    6423             : 
    6424     7117655 :             Real64 SlatAng = state.dataSurface->SurfWinSlatAngThisTS(SurfNum);
    6425     7117655 :             Real64 VarSlats = state.dataSurface->SurfWinMovableSlats(SurfNum);
    6426     7117655 :             int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    6427     7117655 :             int SurfNum2 = SurfNum;
    6428     7117655 :             if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    6429        1232 :                 SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
    6430             :             }
    6431     7117655 :             Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    6432     7117655 :             Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    6433             : 
    6434             :             //-----------------------------------------
    6435             :             // BLOCK 1
    6436             :             // EXTERIOR BEAM AND DIFFUSE SOLAR RADIATION ABSORBED IN THE GLASS LAYERS OF (SurfWinA)
    6437             :             // EXTERIOR BEAM ABSORBED BY SHADING DEVICE (SurfWinExtBeamAbsByShadFac)
    6438             :             //-----------------------------------------
    6439             :             // Somewhat of a kludge
    6440    14234078 :             if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::TDD_Dome ||
    6441     7116423 :                 state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser)
    6442        2464 :                 state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) =
    6443             :                     SunLitFract; // Frames/dividers not allow
    6444     7117655 :             int FenSolAbsPtr = 0;
    6445     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    6446       12243 :                 FenSolAbsPtr = WindowScheduledSolarAbs(state, SurfNum, ConstrNum);
    6447             :             }
    6448             :             bool SunlitFracWithoutReveal =
    6449     7117655 :                 state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) > 0;
    6450             : 
    6451             :             // Calculate interpolated blind properties
    6452             :             Real64 FrontDiffDiffTrans; // Bare-blind front diffuse-diffuse solar transmittance
    6453             :             Real64 FrontDiffDiffRefl;
    6454             :             Real64 FrontDiffAbs;      // Bare-blind front diffuse solar reflectance
    6455             :             Real64 BackDiffDiffTrans; // Bare-blind back diffuse-diffuse solar transmittance
    6456             :             Real64 BackDiffDiffRefl;
    6457             :             Real64 BackDiffAbs; // Bare-blind back diffuse solar reflectance
    6458             : 
    6459             :             Real64 FrontBeamDiffTrans; // Blind ProfileAnglesolar front beam-diffuse transmittance
    6460             :             Real64 BackBeamDiffTrans;  // Blind solar back beam-diffuse transmittance
    6461             :             Real64 FrontBeamDiffRefl;  // Blind solar front beam-diffuse reflectance
    6462             :             Real64 BackBeamDiffRefl;   // Blind solar back beam-diffuse reflectance
    6463             :             Real64 FrontBeamAbs;       // Blind solar front beam absorptance
    6464             :             Real64 BackBeamAbs;        // Blind solar back beam absorptance
    6465             : 
    6466     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL && ANY_BLIND(ShadeFlag)) {
    6467       18094 :                 int SlatsAngIndexLower = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    6468       18094 :                 int ProfAngIndexLower = state.dataSurface->SurfWinProfAngIndex(SurfNum);
    6469       18094 :                 int SlatsAngIndexUpper = std::min(MaxProfAngs, SlatsAngIndexLower + 1);
    6470       18094 :                 int ProfAngIndexUpper = std::min(MaxProfAngs, ProfAngIndexLower + 1);
    6471       18094 :                 Real64 SlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    6472       18094 :                 Real64 ProfAngInterpFac = state.dataSurface->SurfWinProfAngInterpFac(SurfNum);
    6473       18094 :                 if (VarSlats) {
    6474             :                     // Used in time step variable reporting
    6475        1722 :                     FrontDiffDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexLower),
    6476        1722 :                                                                 state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexUpper),
    6477             :                                                                 SlatsAngInterpFac);
    6478             :                 } else {
    6479       16372 :                     FrontDiffDiffTrans = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(1);
    6480             :                 }
    6481             : 
    6482       18094 :                 if (SunLitFract > 0.0 || SunlitFracWithoutReveal) {
    6483       12003 :                     if (VarSlats) {
    6484        1092 :                         FrontBeamDiffTrans =
    6485        3276 :                             General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexLower),
    6486        1092 :                                                     state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexLower),
    6487        1092 :                                                     state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexUpper),
    6488        1092 :                                                     state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexUpper),
    6489             :                                                     SlatsAngInterpFac,
    6490             :                                                     ProfAngInterpFac);
    6491        3276 :                         FrontBeamAbs = General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLower, ProfAngIndexLower),
    6492        1092 :                                                                state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpper, ProfAngIndexLower),
    6493        1092 :                                                                state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLower, ProfAngIndexUpper),
    6494        1092 :                                                                state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpper, ProfAngIndexUpper),
    6495             :                                                                SlatsAngInterpFac,
    6496             :                                                                ProfAngInterpFac);
    6497        1092 :                         if (ShadeFlag != WinShadingType::ExtBlind) { // FRONT: interior or bg blinds
    6498         728 :                             FrontDiffDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(SlatsAngIndexLower),
    6499         728 :                                                                        state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(SlatsAngIndexUpper),
    6500             :                                                                        SlatsAngInterpFac);
    6501         728 :                             FrontDiffAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(SlatsAngIndexLower),
    6502         728 :                                                                   state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(SlatsAngIndexUpper),
    6503             :                                                                   SlatsAngInterpFac);
    6504         728 :                             FrontBeamDiffRefl =
    6505        2184 :                                 General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexLower),
    6506         728 :                                                         state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexLower),
    6507         728 :                                                         state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexUpper),
    6508         728 :                                                         state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexUpper),
    6509             :                                                         SlatsAngInterpFac,
    6510             :                                                         ProfAngInterpFac);
    6511             :                         }
    6512        1092 :                         if (ShadeFlag != WinShadingType::IntBlind) { // BACK: exterior or bg blinds
    6513         364 :                             BackDiffDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(SlatsAngIndexLower),
    6514         364 :                                                                        state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(SlatsAngIndexUpper),
    6515             :                                                                        SlatsAngInterpFac);
    6516         364 :                             BackDiffDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(SlatsAngIndexLower),
    6517         364 :                                                                       state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(SlatsAngIndexUpper),
    6518             :                                                                       SlatsAngInterpFac);
    6519         364 :                             BackDiffAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(SlatsAngIndexLower),
    6520         364 :                                                                  state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(SlatsAngIndexUpper),
    6521             :                                                                  SlatsAngInterpFac);
    6522         364 :                             BackBeamDiffTrans =
    6523        1092 :                                 General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexLower),
    6524         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexLower),
    6525         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexUpper),
    6526         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexUpper),
    6527             :                                                         SlatsAngInterpFac,
    6528             :                                                         ProfAngInterpFac);
    6529         364 :                             BackBeamDiffRefl =
    6530        1092 :                                 General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexLower),
    6531         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexLower),
    6532         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexUpper),
    6533         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexUpper),
    6534             :                                                         SlatsAngInterpFac,
    6535             :                                                         ProfAngInterpFac);
    6536         364 :                             BackBeamAbs =
    6537        1092 :                                 General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLower, ProfAngIndexLower),
    6538         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpper, ProfAngIndexLower),
    6539         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLower, ProfAngIndexUpper),
    6540         364 :                                                         state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpper, ProfAngIndexUpper),
    6541             :                                                         SlatsAngInterpFac,
    6542             :                                                         ProfAngInterpFac);
    6543             :                         }
    6544             :                     } else {
    6545       10911 :                         FrontBeamAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexLower),
    6546       10911 :                                                               state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexUpper),
    6547             :                                                               ProfAngInterpFac);
    6548       10911 :                         FrontBeamDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexLower),
    6549       10911 :                                                                     state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexUpper),
    6550             :                                                                     ProfAngInterpFac);
    6551       10911 :                         if (ShadeFlag != WinShadingType::ExtBlind) { // FRONT: interior or bg blinds
    6552       10547 :                             FrontDiffDiffRefl = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(1);
    6553       10547 :                             FrontDiffAbs = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(1);
    6554       10547 :                             FrontBeamDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexLower),
    6555       10547 :                                                                        state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexUpper),
    6556             :                                                                        ProfAngInterpFac);
    6557             :                         }
    6558       10911 :                         if (ShadeFlag != WinShadingType::IntBlind) { // BACK: exterior or bg blinds{
    6559        2310 :                             BackDiffDiffTrans = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(1);
    6560        2310 :                             BackDiffDiffRefl = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(1);
    6561        2310 :                             BackDiffAbs = state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(1);
    6562        2310 :                             BackBeamDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexLower),
    6563        2310 :                                                                        state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexUpper),
    6564             :                                                                        ProfAngInterpFac);
    6565        2310 :                             BackBeamDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLower),
    6566        2310 :                                                                       state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpper),
    6567             :                                                                       ProfAngInterpFac);
    6568        2310 :                             BackBeamAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLower),
    6569        2310 :                                                                  state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpper),
    6570             :                                                                  ProfAngInterpFac);
    6571             :                         }
    6572             :                     }
    6573             :                 }
    6574             :             }
    6575             : 
    6576     7117655 :             if (SunlitFracWithoutReveal) {
    6577             : 
    6578     3670733 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {
    6579             : 
    6580             :                     // For bare glazing or switchable glazing, the following includes the effects of
    6581             :                     // (1) diffuse solar produced by beam solar incident on the outside and inside reveal
    6582             :                     // surfaces, and (2) absorption of beam solar by outside and inside reveal surfaces.
    6583             :                     // If there is an exterior shade/blind both of these effects are ignored. If there
    6584             :                     // is an interior or between-glass shade/blind the effects of beam incident on
    6585             :                     // inside reveal surfaces is ignored.
    6586     3662886 :                     int NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    6587     7325772 :                     Array1D<Real64> AbWin(NGlass); // Factor for front beam radiation absorbed in window glass layer
    6588     8414893 :                     for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6589     9504014 :                         AbWin(Lay) = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(Lay)) * CosInc * SunLitFract *
    6590     4752007 :                                      state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay);
    6591             :                     }
    6592     3662886 :                     if (!IS_SHADED_NO_GLARE_CTRL(ShadeFlag)) {
    6593             :                         // (ShadeFlag <= 0 || ShadeFlag >= 10) - Bare window (ShadeFlag = -1 or 0 or shading device of off)
    6594     8165348 :                         for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6595             :                             // Add contribution of beam reflected from outside and inside reveal
    6596    13770384 :                             state.dataSurface->SurfWinA(SurfNum, Lay) = AbWin(Lay) +
    6597     9180256 :                                                                         state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
    6598     9180256 :                                                                             state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay) +
    6599     9180256 :                                                                         state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) *
    6600     4590128 :                                                                             state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay);
    6601             :                         }
    6602             :                     } else {
    6603             :                         // Shade, screen, blind or switchable glazing on (ShadeFlag > 0)
    6604      175332 :                         Real64 FracSunLit = SunLitFract * state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(
    6605      175332 :                                                               state.dataGlobal->HourOfDay); // Effective fraction of window that is sunlit;
    6606       87666 :                         Real64 InOutProjSLFracMult = state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    6607      175332 :                         Array1D<Real64> AbWinSh(NGlass);    // Like AbWin, but for shaded window
    6608      175332 :                         Array1D<Real64> ADiffWinSh(NGlass); // Diffuse solar absorptance of glass layer, window with shading device
    6609       87666 :                         if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) FracSunLit = SunLitFract;
    6610             : 
    6611       87666 :                         if (ANY_SHADE(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
    6612             :                             // Shade or switchable glazing on
    6613      218805 :                             for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6614      144766 :                                 AbWinSh(Lay) = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).AbsBeamCoef(Lay)) * CosInc * FracSunLit;
    6615      144766 :                                 ADiffWinSh(Lay) = state.dataConstruction->Construct(ConstrNumSh).AbsDiff(Lay);
    6616             :                             }
    6617       74039 :                             if (ShadeFlag == WinShadingType::IntShade) { // Exterior beam absorbed by INTERIOR SHADE
    6618             :                                 // Note that AbsBeamShadeCoef includes effect of shade/glazing inter-reflection
    6619       10905 :                                 Real64 AbsShade = POLYF(CosInc,
    6620       10905 :                                                         state.dataConstruction->Construct(ConstrNumSh)
    6621       10905 :                                                             .AbsBeamShadeCoef); // Interior shade or blind beam solar absorptance
    6622       10905 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
    6623       21810 :                                     (AbsShade * CosInc * SunLitFract * InOutProjSLFracMult +
    6624       21810 :                                      state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
    6625       21810 :                                          state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade) *
    6626       10905 :                                     state.dataSurface->SurfWinGlazedFrac(SurfNum);
    6627             :                                 // In the above, GlazedFrac corrects for shadowing of divider onto interior shade
    6628       63134 :                             } else if (ShadeFlag == WinShadingType::ExtShade) { // Exterior beam absorbed by EXTERIOR SHADE
    6629        4094 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
    6630        4094 :                                     state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade * CosInc * SunLitFract;
    6631       59040 :                             } else if (ShadeFlag == WinShadingType::BGShade) { // Exterior beam absorbed by BETWEEN-GLASS SHADE
    6632        1456 :                                 Real64 AbsShade = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).AbsBeamShadeCoef);
    6633        1456 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
    6634        2912 :                                     AbsShade * CosInc * SunLitFract + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
    6635        1456 :                                                                           state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade;
    6636             :                             }
    6637             : 
    6638             :                         } else {
    6639             :                             // Blind or screen on
    6640       13627 :                             ProfAng = state.dataSurface->SurfWinProfileAng(SurfNum);
    6641       13627 :                             if (ShadeFlag == WinShadingType::IntBlind) {
    6642             :                                 // Interior blind on
    6643        9329 :                                 Real64 TBmBm = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
    6644             :                                 Real64 RGlDiffBack =
    6645        9329 :                                     state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; // Glazing system back diffuse solar reflectance
    6646        9329 :                                 Real64 RhoBlFront = FrontBeamDiffRefl;                               // Blind solar front beam reflectance
    6647        9329 :                                 Real64 RhoBlDiffFront = FrontDiffDiffRefl;                           // Blind solar front diffuse reflectance
    6648       18658 :                                 for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6649        9329 :                                     Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(
    6650        9329 :                                         Lay); // Diffuse solar absorptance of glass layer, bare window
    6651             :                                     Real64 AGlDiffBack =
    6652        9329 :                                         state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay); // Glass layer back diffuse solar absorptance
    6653        9329 :                                     AbWinSh(Lay) =
    6654        9329 :                                         AbWin(Lay) + (TBmBm * AGlDiffBack * RhoBlFront / (1.0 - RhoBlFront * RGlDiffBack)) * CosInc * FracSunLit;
    6655       18658 :                                     ADiffWinSh(Lay) = ADiffWin + state.dataConstruction->Construct(ConstrNum).TransDiff * AGlDiffBack *
    6656        9329 :                                                                      RhoBlDiffFront / (1.0 - RhoBlDiffFront * RGlDiffBack);
    6657             :                                 }
    6658             :                                 // Exterior beam absorbed by INTERIOR BLIND
    6659             : 
    6660        9329 :                                 Real64 AbsBlFront = FrontBeamAbs;     // Blind solar front beam absorptance
    6661        9329 :                                 Real64 AbsBlDiffFront = FrontDiffAbs; // Blind solar front diffuse absorptance
    6662        9329 :                                 Real64 AbsShade =
    6663        9329 :                                     TBmBm * (AbsBlFront + RhoBlFront * RGlDiffBack * AbsBlDiffFront / (1.0 - RhoBlDiffFront * RGlDiffBack));
    6664             :                                 Real64 AbsShadeDiff =
    6665        9329 :                                     state.dataConstruction->Construct(ConstrNum).TransDiff *
    6666       18658 :                                     (AbsBlDiffFront + RhoBlDiffFront * RGlDiffBack * AbsBlDiffFront /
    6667       18658 :                                                           (1.0 - RhoBlDiffFront * RGlDiffBack)); // Interior shade or blind diffuse solar absorptance
    6668             : 
    6669        9329 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
    6670       18658 :                                     (AbsShade * CosInc * SunLitFract * InOutProjSLFracMult +
    6671       18658 :                                      state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * AbsShadeDiff) *
    6672        9329 :                                     state.dataSurface->SurfWinGlazedFrac(SurfNum);
    6673             :                                 // In the above, GlazedFrac corrects for shadowing of divider onto interior blind
    6674        4298 :                             } else if (ShadeFlag == WinShadingType::ExtBlind) {
    6675             :                                 // Exterior blind on
    6676         728 :                                 Real64 TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum); // Blind solar front beam-beam transmittance
    6677         728 :                                 Real64 TBlDifDif = FrontDiffDiffTrans;                              // Diffuse-diffuse solar transmittance of blind
    6678         728 :                                 Real64 TBlBmDiff = FrontBeamDiffTrans;                              // Blind solar front beam-diffuse transmittance
    6679         728 :                                 Real64 RhoBlBack = BackBeamDiffRefl;                                // Blind solar back beam-diffuse reflectance
    6680         728 :                                 Real64 RhoBlDiffBack = BackDiffDiffRefl;                            // Blind solar back diffuse reflectance
    6681         728 :                                 Real64 RGlFront = POLYF(CosInc,
    6682         728 :                                                         state.dataConstruction->Construct(ConstrNum)
    6683         728 :                                                             .ReflSolBeamFrontCoef); // Glazing system solar front beam-beam reflectance
    6684         728 :                                 Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNum)
    6685         728 :                                                           .ReflectSolDiffFront; // Glazing system front diffuse solar reflectance
    6686        1456 :                                 for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6687         728 :                                     Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(
    6688         728 :                                         Lay); // Diffuse solar absorptance of glass layer, bare window
    6689             :                                     Real64 AGlDiffFront =
    6690         728 :                                         state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay); // Glass layer front diffuse solar absorptance
    6691        2184 :                                     AbWinSh(Lay) = TBlBmBm * AbWin(Lay) + ((TBlBmBm * RGlFront * RhoBlBack + TBlBmDiff) * AGlDiffFront /
    6692        1456 :                                                                            (1 - RGlDiffFront * RhoBlDiffBack)) *
    6693         728 :                                                                               CosInc * FracSunLit;
    6694             :                                     // ADiffWinSh = 0.0  ! Assumes no contribution from reveal reflection when exterior blind in place
    6695             :                                     // Replaced above line with (FCW, 2/10/03):
    6696         728 :                                     ADiffWinSh(Lay) = ADiffWin * TBlDifDif / (1.0 - RGlDiffFront * RhoBlDiffBack);
    6697             :                                 }
    6698             :                                 // Exterior beam absorbed by EXTERIOR BLIND
    6699         728 :                                 Real64 AbsBlFront = FrontBeamAbs;
    6700         728 :                                 Real64 AbsBlBack = BackBeamAbs;     // Blind solar back beam absorptance
    6701         728 :                                 Real64 AbsBlDiffBack = BackDiffAbs; // Blind solar back diffuse absorptance
    6702        1456 :                                 Real64 AbsShade = AbsBlFront + AbsBlBack * RGlFront * TBlBmBm +
    6703        1456 :                                                   (AbsBlDiffBack * RGlDiffFront / (1.0 - RhoBlDiffBack * RGlDiffFront)) *
    6704         728 :                                                       (RGlFront * TBlBmBm * RhoBlBack + TBlBmDiff);
    6705         728 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = AbsShade * CosInc * SunLitFract * InOutProjSLFracMult;
    6706         728 :                                 if (state.dataEnvrn->Month == 7 && state.dataEnvrn->DayOfMonth == 21 && state.dataGlobal->HourOfDay == 8) {
    6707          42 :                                     double tst = state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum);
    6708          42 :                                     tst = 0;
    6709             :                                 }
    6710        3570 :                             } else if (ShadeFlag == WinShadingType::ExtScreen) {
    6711             :                                 // Exterior screen on
    6712        1624 :                                 Real64 TScBmBm = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTrans; // Screen solar front beam-beam transmittance
    6713             :                                 Real64 TScBmDiff =
    6714        1624 :                                     state.dataHeatBal->SurfaceScreens(ScNum).BmDifTrans; // Screen solar front beam-diffuse transmittance
    6715             :                                 Real64 RScBack =
    6716        1624 :                                     state.dataHeatBal->SurfaceScreens(ScNum).ReflectSolBeamFront; // Screen solar back beam-diffuse reflectance
    6717             :                                 Real64 RScDifBack =
    6718        1624 :                                     state.dataHeatBal->SurfaceScreens(ScNum).DifReflect; // Screen solar back diffuse-diffuse reflectance
    6719        1624 :                                 Real64 RGlFront = POLYF(CosInc,
    6720        1624 :                                                         state.dataConstruction->Construct(ConstrNum)
    6721        1624 :                                                             .ReflSolBeamFrontCoef); // Glazing system solar front beam-beam reflectance
    6722        1624 :                                 Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNum)
    6723        1624 :                                                           .ReflectSolDiffFront; // Glazing system front diffuse solar reflectance
    6724             :                                 Real64 TScDifDif =
    6725        1624 :                                     state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans; // Diffuse-diffuse solar transmittance of screen
    6726             :                                 Real64 RGlDifFr =
    6727        1624 :                                     state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront; // Diffuse front reflectance of glass
    6728             :                                 // Reduce the bare window absorbed beam by the screen beam transmittance and then account for
    6729             :                                 // interreflections
    6730        4060 :                                 for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6731        2436 :                                     Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(
    6732        2436 :                                         Lay); // Diffuse solar absorptance of glass layer, bare window
    6733        7308 :                                     AbWinSh(Lay) = TScBmBm * AbWin(Lay) + (TScBmBm * RGlFront * RScBack + TScBmDiff) *
    6734        4872 :                                                                               state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay) /
    6735        4872 :                                                                               (1.0 - RGlDiffFront * RScDifBack) * CosInc * FracSunLit;
    6736        2436 :                                     ADiffWinSh(Lay) = ADiffWin * TScDifDif / (1.0 - RGlDifFr * RScDifBack);
    6737             :                                 }
    6738             :                                 // Exterior beam absorbed by EXTERIOR SCREEN
    6739        1624 :                                 Real64 AbsScBeam = state.dataHeatBal->SurfaceScreens(ScNum).AbsorpSolarBeamFront; // Screen solar beam absorptance
    6740             :                                 Real64 AbsScDiffBack =
    6741        1624 :                                     state.dataHeatBal->SurfaceScreens(ScNum).DifScreenAbsorp; // Screen solar back diffuse absorptance
    6742        3248 :                                 Real64 AbsScreen = AbsScBeam * (1.0 + TScBmBm * RGlFront) +
    6743        3248 :                                                    (AbsScDiffBack * TScBmBm * RGlFront * RGlDiffFront * RScBack /
    6744        1624 :                                                     (1.0 - RScDifBack * RGlDiffFront)); // Exterior screen beam solar absorptance
    6745        1624 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = AbsScreen * CosInc * SunLitFract * InOutProjSLFracMult;
    6746        1946 :                             } else if (ShadeFlag == WinShadingType::BGBlind) {
    6747             :                                 // Between-glass blind o
    6748             :                                 // Isolated glass and blind properties at current incidence angle, profile angle and slat angle
    6749             :                                 Real64 t1 = POLYF(CosInc,
    6750        1946 :                                                   state.dataConstruction->Construct(ConstrNum).tBareSolCoef(
    6751        1946 :                                                       1)); // Bare-glass beam solar transmittance for glass layers 1,2 and 3
    6752        1946 :                                 Real64 t2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(2));
    6753             :                                 Real64 af1 = POLYF(CosInc,
    6754        1946 :                                                    state.dataConstruction->Construct(ConstrNum).afBareSolCoef(
    6755        1946 :                                                        1)); // Bare-glass beam solar front absorptance for glass layers 1,2 and 3
    6756        1946 :                                 Real64 af2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).afBareSolCoef(2));
    6757             :                                 Real64 ab1 = POLYF(CosInc,
    6758        1946 :                                                    state.dataConstruction->Construct(ConstrNum).abBareSolCoef(
    6759        1946 :                                                        1)); // Bare-glass beam solar back absorptance for glass layers 1,2 and 3
    6760        1946 :                                 Real64 ab2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).abBareSolCoef(2));
    6761        1946 :                                 Real64 rf2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(2));
    6762        1946 :                                 Real64 td1 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(
    6763        1946 :                                     1); // Bare-glass diffuse solar transmittance for glass layers 1,2 and 3
    6764        1946 :                                 Real64 td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
    6765        1946 :                                 Real64 afd1 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(
    6766        1946 :                                     1); // Bare-glass diffuse solar front absorptance for glass layers 1,2 and 3
    6767        1946 :                                 Real64 afd2 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(2);
    6768        1946 :                                 Real64 abd1 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(
    6769        1946 :                                     1); // Bare-glass diffuse solar back absorptance for glass layers 1,2 and 3
    6770        1946 :                                 Real64 abd2 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(2);
    6771        1946 :                                 Real64 rfd2 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(2);
    6772        1946 :                                 Real64 rbd1 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(
    6773        1946 :                                     1); // Bare-glass diffuse solar back reflectance for glass layers 1,2 and 3
    6774        1946 :                                 Real64 rbd2 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(2);
    6775             :                                 Real64 tfshBB =
    6776        1946 :                                     state.dataSurface->SurfWinBlindBmBmTrans(SurfNum); // Bare-blind front and back beam-beam solar transmittance
    6777        5838 :                                 Real64 tbshBB = General::BlindBeamBeamTrans(ProfAng,
    6778             :                                                                             DataGlobalConstants::Pi - SlatAng,
    6779        1946 :                                                                             state.dataHeatBal->Blind(BlNum).SlatWidth,
    6780        1946 :                                                                             state.dataHeatBal->Blind(BlNum).SlatSeparation,
    6781        3892 :                                                                             state.dataHeatBal->Blind(BlNum).SlatThickness);
    6782        1946 :                                 Real64 tfshBd = FrontBeamDiffTrans; // Bare-blind front and back beam-diffuse solar transmittance
    6783        1946 :                                 Real64 tbshBd = BackBeamDiffTrans;
    6784        1946 :                                 Real64 rfshB = FrontBeamDiffRefl; // Bare-blind front and back beam solar reflectance
    6785        1946 :                                 Real64 rbshB = BackBeamDiffRefl;
    6786        1946 :                                 Real64 afshB = FrontBeamAbs;
    6787        1946 :                                 Real64 abshB = BackBeamAbs;
    6788             : 
    6789        1946 :                                 Real64 tfshd = FrontDiffDiffTrans; // Bare-blind front and back diffuse-diffuse solar transmittance
    6790        1946 :                                 Real64 tbshd = BackDiffDiffTrans;
    6791        1946 :                                 Real64 rfshd = FrontDiffDiffRefl; // Bare-blind front and back diffuse solar reflectance
    6792        1946 :                                 Real64 rbshd = BackDiffDiffRefl;
    6793        1946 :                                 Real64 afshd = FrontDiffAbs;
    6794        1946 :                                 Real64 abshd = BackDiffAbs;
    6795             : 
    6796        1946 :                                 Real64 AbsShade = 0.0;
    6797        1946 :                                 Real64 AbsShadeDiff = 0.0;
    6798        1946 :                                 if (NGlass == 2) {
    6799        2436 :                                     AbWinSh(1) = CosInc * FracSunLit *
    6800        2436 :                                                  (af1 + t1 * tfshBB * rf2 * tbshBB * ab1 +
    6801        1218 :                                                   t1 * (rfshB + rfshB * rbd1 * rfshd + tfshBB * rf2 * tbshBd + tfshBd * rfd2 * tbshd) * abd1);
    6802        1218 :                                     ADiffWinSh(1) = afd1 + td1 * (rfshd + rfshd * rbd1 * rfshd + tfshd * rfd2 * tbshd) * abd1;
    6803        1218 :                                     AbWinSh(2) =
    6804        2436 :                                         CosInc * FracSunLit *
    6805        1218 :                                         (t1 * rfshB * af2 + t1 * (rfshB * rf2 * rbshd + tfshBd * (1 + rfd2 * rbshd) + rfshB * rbd1 * tfshd) * afd2);
    6806        1218 :                                     ADiffWinSh(2) = td1 * (tfshd * (1 + rfd2 * rbshd) + rfshd * rbd1 * tfshd) * afd2;
    6807        1218 :                                     AbsShade = t1 * (afshB + tfshBB * rf2 * abshB + tfshBd * rfd2 * abshd + rfshB * rbd1 * afshd);
    6808        1218 :                                     AbsShadeDiff = td1 * (afshd * (1 + rfshd * rbd1) + tfshd * rfd2 * abshd);
    6809         728 :                                 } else if (NGlass == 3) {
    6810         728 :                                     Real64 t1t2 = t1 * t2; // t1*t2
    6811         728 :                                     Real64 td1td2 = td1 * td2;
    6812         728 :                                     Real64 af3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).afBareSolCoef(3));
    6813         728 :                                     Real64 rf3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(3));
    6814         728 :                                     Real64 afd3 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(3);
    6815         728 :                                     Real64 rfd3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
    6816         728 :                                     Real64 td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
    6817        1456 :                                     AbWinSh(1) = CosInc * FracSunLit *
    6818        1456 :                                                  (af1 + t1 * rf2 * ab1 + t1t2 * tfshBB * rf3 * tbshBB * t2 * ab1 +
    6819         728 :                                                   t1t2 * (rfshB * td2 + rfshB * rbd2 * rfshd * td2 + tfshBd * rfd3 * tbshd * td2) * abd1);
    6820        1456 :                                     ADiffWinSh(1) = afd1 + td1 * rbd2 * abd1 +
    6821         728 :                                                     td1td2 *
    6822        1456 :                                                         (rfshd * (1 + rbd2 * rfshd + td2 * rbd1 * td2 * rfshd) +
    6823        1456 :                                                          tfshd * (rfd3 * tbshd + rfd3 * rbshd * rfd3 * tbshd)) *
    6824         728 :                                                         td2 * abd1;
    6825        1456 :                                     AbWinSh(2) = CosInc * FracSunLit *
    6826        1456 :                                                  (t1 * af2 + t1t2 * (tfshBB * rf3 * tbshBB * ab2 + rfshB * td2 * rbd1 * afd2) +
    6827         728 :                                                   t1t2 * (rfshB * (1 + rbd2 * rfshd) + tfshBB * rf3 * tbshBd + tfshBd * rfd3 * tbshd) * abd2);
    6828        1456 :                                     ADiffWinSh(2) = td1 * afd2 + td1td2 * rfshd * td2 * rbd1 * afd2 +
    6829         728 :                                                     td1td2 * (rfshd * (1 + rbd2 * rfshd) + tfshd * rfd3 * tbshd) * abd2;
    6830        1456 :                                     AbWinSh(3) = CosInc * FracSunLit *
    6831        2184 :                                                  (t1t2 * tfshBB * af3 + t1t2 *
    6832        1456 :                                                                             (tfshBB * rf3 * rbshB + tfshBd * (1 + rfd3 * rbshd) +
    6833        1456 :                                                                              rfshB * (rbd2 * tfshd + td2 * rbd1 * td2 * tfshd)) *
    6834             :                                                                             afd3);
    6835         728 :                                     ADiffWinSh(3) = td1td2 * (tfshd * (1 + rfd3 * rbshd) + rfshd * (rbd2 * tfshd + td2 * rbd1 * td2 * tfshd)) * afd3;
    6836         728 :                                     AbsShade = t1t2 * (afshB * (1 + tfshBB * rf3) + afshd * (tfshBd * rfd3 + rfshB * (rbd2 + td2 * rbd1 * td2)));
    6837         728 :                                     AbsShadeDiff = td1td2 * (afshd + tfshd * rfd3 * abshd + rfshd * (rfd2 + td2 * rbd2 * td2) * afshd);
    6838             :                                 } // End of check if NGlass
    6839        1946 :                                 state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
    6840        3892 :                                     AbsShade * CosInc * SunLitFract * InOutProjSLFracMult +
    6841        1946 :                                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * AbsShadeDiff;
    6842             :                             } // End of check if blind is interior, exterior or between-glass
    6843             :                         }     // End of check if a blind is on
    6844             : 
    6845       87666 :                         if (ShadeFlag != WinShadingType::SwitchableGlazing) {
    6846             :                             // Interior or between glass shade or blind on
    6847       76793 :                             for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6848       46711 :                                 state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinSh(Lay);
    6849             :                                 // Add contribution of diffuse from beam on outside reveal
    6850       46711 :                                 if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) || ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag))
    6851       37831 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) +=
    6852       37831 :                                         ADiffWinSh(Lay) * state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum);
    6853             :                             }
    6854             :                         } else {
    6855             :                             // Switchable glazing
    6856      172752 :                             for (int Lay = 1; Lay <= NGlass; ++Lay) {
    6857      115168 :                                 Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    6858      115168 :                                 Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay);
    6859      115168 :                                 state.dataSurface->SurfWinA(SurfNum, Lay) = General::InterpSw(SwitchFac, AbWin(Lay), AbWinSh(Lay));
    6860             :                                 // Add contribution of diffuse from beam on outside and inside reveal
    6861      115168 :                                 state.dataSurface->SurfWinA(SurfNum, Lay) +=
    6862      230336 :                                     General::InterpSw(SwitchFac, ADiffWin, ADiffWinSh(Lay)) *
    6863      230336 :                                         state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) +
    6864      230336 :                                     General::InterpSw(SwitchFac,
    6865      115168 :                                                       state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay),
    6866      230336 :                                                       state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(Lay)) *
    6867      115168 :                                         state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum);
    6868             :                             }
    6869             :                         }
    6870             :                     }
    6871             : 
    6872        7847 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    6873             :                     // Do not read from schedule file here since this will be called only if direct beam is hitting the window and schedule
    6874             :                     // will not be loaded in that case even if diffuse part of solar radiation is entering through the window
    6875        6461 :                     if (FenSolAbsPtr == 0) {
    6876             :                         // Put in the equivalent layer absorptions
    6877             :                         // Simon: This should not be multiplied with CosInc since Abs coefficient already includes angular
    6878             :                         // factor
    6879       48090 :                         for (int Lay = 1; Lay <= state.dataSurface->SurfaceWindow(SurfNum)
    6880       24045 :                                                      .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6881       24045 :                                                      .NLayers;
    6882             :                              ++Lay) {
    6883       17640 :                             auto absBeamWin = state.dataSurface->SurfaceWindow(SurfNum)
    6884       17640 :                                                   .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6885       17640 :                                                   .WinBmFtAbs(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, Lay);
    6886       17640 :                             Real64 AbWin = absBeamWin * CosInc * SunLitFract *
    6887       17640 :                                            state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay);
    6888             : 
    6889             :                             // Add contribution of beam reflected from outside and inside reveal
    6890       17640 :                             state.dataSurface->SurfWinA(SurfNum, Lay) =
    6891       17640 :                                 AbWin +
    6892       35280 :                                 state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
    6893       17640 :                                     state.dataSurface->SurfaceWindow(SurfNum)
    6894       17640 :                                         .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6895       35280 :                                         .WinFtHemAbs(Lay) +
    6896       35280 :                                 state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) *
    6897       17640 :                                     state.dataSurface->SurfaceWindow(SurfNum)
    6898       17640 :                                         .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6899       17640 :                                         .WinBkHemAbs(Lay);
    6900             :                         }
    6901             :                     }
    6902             : 
    6903        1386 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
    6904             :                     // call the ASHWAT fenestration model for optical properties
    6905             :                     // determine the beam radiation absorptance and tranmittance of the
    6906             :                     // the equivalent layer window model
    6907        1386 :                     WindowEquivalentLayer::CalcEQLOpticalProperty(state, SurfNum, SolarArrays::BEAM, state.dataSolarShading->SurfWinAbsSolBeamEQL);
    6908        1386 :                     auto &CFS = state.dataWindowEquivLayer->CFS;
    6909             :                     // recalcuate the diffuse absorptance and transmittance of the
    6910             :                     // the equivalent layer window model if there is shade control
    6911        1386 :                     int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction)
    6912        1386 :                                      .EQLConsPtr; // equivalent layer fenestration index
    6913        1386 :                     if (CFS(EQLNum).ISControlled) {
    6914           0 :                         WindowEquivalentLayer::CalcEQLOpticalProperty(
    6915           0 :                             state, SurfNum, SolarArrays::DIFF, state.dataSolarShading->SurfWinAbsSolDiffEQL);
    6916             :                     } else {
    6917        1386 :                         state.dataSolarShading->SurfWinAbsSolDiffEQL(_, {1, CFS(EQLNum).NL + 1}) =
    6918        2772 :                             state.dataWindowEquivalentLayer->CFSDiffAbsTrans(_, {1, CFS(EQLNum).NL + 1}, EQLNum);
    6919             :                     }
    6920        1386 :                     state.dataConstruction->Construct(ConstrNum).TransDiff = state.dataSolarShading->SurfWinAbsSolDiffEQL(1, CFS(EQLNum).NL + 1);
    6921             : 
    6922        7658 :                     for (int Lay = 1; Lay <= CFS(EQLNum).NL + 1; ++Lay) {
    6923             :                         // Factor for front beam radiation absorbed for equivalent layer window model
    6924        6272 :                         Real64 AbWinEQL = state.dataSolarShading->SurfWinAbsSolBeamEQL(1, Lay) * CosInc * SunLitFract *
    6925        6272 :                                           state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    6926             :                         ;
    6927        6272 :                         if (CFS(EQLNum).L(1).LTYPE != LayerType::GLAZE) {
    6928             :                             // if the first layer is not glazing (or it is a shade) do not
    6929        2842 :                             state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinEQL;
    6930             :                         } else {
    6931             :                             // the first layer is a glazing, include the outside reveal reflection
    6932             :                             // and the inside reveal reflection until indoor shade layer is encountered.
    6933        3430 :                             if (CFS(EQLNum).L(Lay).LTYPE == LayerType::GLAZE) {
    6934        3920 :                                 state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinEQL +
    6935        3920 :                                                                             state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
    6936        3920 :                                                                                 state.dataSolarShading->SurfWinAbsSolBeamEQL(1, Lay) +
    6937        3920 :                                                                             state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) *
    6938        1960 :                                                                                 state.dataSolarShading->SurfWinAbsSolDiffEQL(2, Lay);
    6939             :                             } else {
    6940        2940 :                                 state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinEQL + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
    6941        1470 :                                                                                            state.dataSolarShading->SurfWinAbsSolBeamEQL(1, Lay);
    6942             :                             }
    6943             :                         }
    6944             :                     }
    6945             :                 }
    6946             :             } // End of SunlitFrac check
    6947             : 
    6948             :             //-----------------------------------------------------------------
    6949             :             // BLOCK 2
    6950             :             // SKY AND GROUND DIFFUSE SOLAR GAIN INTO ZONE FROM EXTERIOR WINDOW
    6951             :             //-----------------------------------------------------------------
    6952             : 
    6953     7117655 :             Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(
    6954     7117655 :                 SurfNum);           // Incident solar radiation on a window: sky diffuse plus beam reflected from obstruction (W/m2)
    6955     7117655 :             Real64 DiffTrans = 0.0; // Glazing diffuse solar transmittance (including shade/blind/switching, if present)
    6956             :             Real64 DiffTransGnd;    // Ground diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
    6957             :             Real64 DiffTransBmGnd;  // Complex fen: diffuse solar transmittance for ground-reflected beam radiation
    6958             :             Real64 DiffTransSky;    // Sky diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
    6959     7117655 :             Real64 NomDiffTrans = 0.0;
    6960             : 
    6961     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { // complex fenestration
    6962       12243 :                 if (FenSolAbsPtr == 0) {
    6963             :                     // Sky diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
    6964       24290 :                     DiffTransSky = state.dataSurface->SurfaceWindow(SurfNum)
    6965       12145 :                                        .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6966             :                                        .WinSkyTrans;
    6967             :                     // Ground diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
    6968       24290 :                     DiffTransGnd = state.dataSurface->SurfaceWindow(SurfNum)
    6969       12145 :                                        .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6970             :                                        .WinSkyGndTrans;
    6971             :                     // Complex fen: diffuse solar transmittance for ground-reflected beam radiation
    6972       24290 :                     DiffTransBmGnd = state.dataSurface->SurfaceWindow(SurfNum)
    6973       12145 :                                          .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6974       12145 :                                          .WinBmGndTrans(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
    6975             :                     // Define the effective transmittance for total sky and ground radiation
    6976       12145 :                     if ((SkySolarInc + state.dataSurface->SurfWinBmGndSolarInc(SurfNum) + state.dataSurface->SurfWinSkyGndSolarInc(SurfNum)) != 0.0) {
    6977       12145 :                         DiffTrans =
    6978       24290 :                             (SkySolarInc * DiffTransSky + state.dataSurface->SurfWinBmGndSolarInc(SurfNum) * DiffTransBmGnd +
    6979       12145 :                              state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) * DiffTransGnd) /
    6980       12145 :                             (SkySolarInc + state.dataSurface->SurfWinBmGndSolarInc(SurfNum) + state.dataSurface->SurfWinSkyGndSolarInc(SurfNum));
    6981             :                     }
    6982             :                     // Also update the nominal diffuse transmittance
    6983       24290 :                     NomDiffTrans = state.dataSurface->SurfaceWindow(SurfNum)
    6984       12145 :                                        .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    6985             :                                        .WinDiffTrans;
    6986             :                     // Do not store in TransDiff because it is not used by BSDF and rest of the code uses it as flag for opaque
    6987             :                     // surface incorrectly assuming wall heat transfer routines for windows.
    6988             :                     // Construct( Surface( SurfNum ).Construction ).TransDiff = NomDiffTrans;
    6989             :                 }
    6990     7105412 :             } else if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    6991        1232 :                 DiffTrans = TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarAniso);
    6992             :             } else {
    6993     7104180 :                 DiffTrans = state.dataConstruction->Construct(ConstrNum).TransDiff;
    6994             :             }
    6995             : 
    6996     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {
    6997     7102934 :                 if (IS_SHADED_NO_GLARE_CTRL(state.dataSurface->SurfWinShadingFlag(SurfNum))) {
    6998      123072 :                     if (ShadeFlag != WinShadingType::SwitchableGlazing) {
    6999             :                         // Shade or blind
    7000       51818 :                         if (ANY_SHADE_SCREEN(ShadeFlag)) {
    7001             :                             // Shade or screen
    7002       33724 :                             DiffTrans = state.dataConstruction->Construct(ConstrNumSh).TransDiff;
    7003             :                         } else {
    7004             :                             // Blind
    7005       18094 :                             int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    7006       18094 :                             Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    7007       18094 :                             if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    7008        3444 :                                 DiffTrans = General::InterpGeneral(
    7009        1722 :                                     state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(SurfWinSlatsAngIndex),
    7010        3444 :                                     state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    7011             :                                     SurfWinSlatsAngInterpFac);
    7012             :                             } else {
    7013       16372 :                                 DiffTrans = state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(1);
    7014             :                             }
    7015             :                             // For blinds with horizontal slats, allow different diffuse/diffuse transmittance for
    7016             :                             // ground and sky solar
    7017       18094 :                             if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
    7018             :                                 DataWindowEquivalentLayer::Orientation::Horizontal) {
    7019       18094 :                                 if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    7020        1722 :                                     DiffTransGnd =
    7021        1722 :                                         General::InterpGeneral(state.dataConstruction->Construct(ConstrNumSh).BlTransDiffGnd(SurfWinSlatsAngIndex),
    7022        1722 :                                                                state.dataConstruction->Construct(ConstrNumSh)
    7023        3444 :                                                                    .BlTransDiffGnd(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    7024             :                                                                SurfWinSlatsAngInterpFac);
    7025        1722 :                                     DiffTransSky =
    7026        1722 :                                         General::InterpGeneral(state.dataConstruction->Construct(ConstrNumSh).BlTransDiffSky(SurfWinSlatsAngIndex),
    7027        1722 :                                                                state.dataConstruction->Construct(ConstrNumSh)
    7028        3444 :                                                                    .BlTransDiffSky(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    7029             :                                                                SurfWinSlatsAngInterpFac);
    7030             :                                 } else {
    7031       16372 :                                     DiffTransGnd = state.dataConstruction->Construct(ConstrNumSh).BlTransDiffGnd(1);
    7032       16372 :                                     DiffTransSky = state.dataConstruction->Construct(ConstrNumSh).BlTransDiffSky(1);
    7033             :                                 }
    7034             :                             }
    7035             :                         }
    7036             : 
    7037             :                     } else {
    7038             :                         // Switchable glazing
    7039       71254 :                         Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for a window
    7040      142508 :                         DiffTrans = General::InterpSw(SwitchFac,
    7041       71254 :                                                       state.dataConstruction->Construct(ConstrNum).TransDiff,
    7042       71254 :                                                       state.dataConstruction->Construct(ConstrNumSh).TransDiff);
    7043             :                     }
    7044             :                 }
    7045             :             }
    7046             : 
    7047             :             // Reporting variables
    7048     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) {
    7049     7115177 :                 state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = DiffTrans;
    7050     7115177 :                 state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = DiffTrans;
    7051     7115177 :                 if (ANY_BLIND(ShadeFlag) || ShadeFlag == WinShadingType::ExtScreen) {
    7052       21342 :                     state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = DiffTrans;
    7053       21342 :                     state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = DiffTrans;
    7054       21342 :                     if (ShadeFlag == WinShadingType::ExtScreen) {
    7055        3248 :                         state.dataSurface->SurfWinScTsolDifDif(SurfNum) = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans;
    7056             :                     } else {
    7057       18094 :                         state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = FrontDiffDiffTrans;
    7058             :                     }
    7059             :                 }
    7060             :             }
    7061             : 
    7062             :             //-----------------------------------------------------------------
    7063             :             // BEAM SOLAR ON EXTERIOR WINDOW TRANSMITTED AS BEAM AND/OR DIFFUSE
    7064             :             //-----------------------------------------------------------------
    7065     7117655 :             Real64 TBmBm = 0.0;        // Beam-beam solar transmittance for bare window or window with switchable glazing
    7066     7117655 :             Real64 TBmDif = 0.0;       // Beam-diffuse solar transmittance for bare window with diffusing glass
    7067     7117655 :             Real64 TBmAllShBlSc = 0.0; // Beam-beam + beam-diffuse transmittance for window with shade, blind, screen, or switchable glazing
    7068     7117655 :             Real64 TBmBmShBlSc = 0.0;  // Beam-beam transmittance for window with shade, blind, screen, or switchable glazing
    7069     7117655 :             Real64 TBmDifShBlSc = 0.0; // Beam-diffuse transmittance for window with shade, blind, screen, or switchable glazing
    7070             :             Real64 TBmBmBl;            // Beam-beam transmittance for window with blind
    7071             :             Real64 TBmBmSc;            // Beam-beam transmittance for window with screen
    7072             :             Real64 TDifBare;           // Bare diffuse transmittance of exterior window
    7073             :             // Beam-beam transmittance for bare exterior window
    7074     7117655 :             if (SunLitFract > 0.0) {
    7075     3661727 :                 if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    7076        1148 :                     TBmDif = TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarBeam);
    7077        1148 :                     state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolBeam = TBmDif;                  // Report variable
    7078     3660579 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {      // Regular window
    7079     3652732 :                     if (!state.dataSurface->SurfWinSolarDiffusing(SurfNum)) {                                  // Clear glazing
    7080     3652732 :                         TBmBm = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);  //[-]
    7081             :                     } else {                                                                                   // Diffusing glazing
    7082           0 :                         TBmDif = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); //[-]
    7083             :                     }
    7084        7847 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    7085             :                     // Need to check what effect, if any, defining these here has
    7086       12922 :                     TBmBm = state.dataSurface->SurfaceWindow(SurfNum)
    7087        6461 :                                 .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    7088        6461 :                                 .WinDirSpecTrans(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
    7089       12922 :                     TBmDif = state.dataSurface->SurfaceWindow(SurfNum)
    7090        6461 :                                  .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    7091        6461 :                                  .WinDirHemiTrans(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep) -
    7092             :                              TBmBm;
    7093        1386 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
    7094             :                     // get ASHWAT fenestration model beam-beam and beam-diffuse properties
    7095        1386 :                     int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction)
    7096        1386 :                                      .EQLConsPtr; // equivalent layer fenestration index
    7097        1386 :                     Real64 TBmBmEQL = state.dataSolarShading->SurfWinAbsSolBeamEQL(1, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1);
    7098             :                     // Beam-diffuse transmittance
    7099        1386 :                     Real64 TBmDiffEQL = max(0.0, state.dataSolarShading->SurfWinAbsSolBeamEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1));
    7100             :                     // Beam-beam transmittance: difference between beam-total and beam-diffuse transmittance
    7101        1386 :                     TBmBmEQL = max(0.0, (TBmBmEQL - TBmDiffEQL));
    7102        1386 :                     TBmBm = TBmBmEQL;
    7103        1386 :                     TBmDif = TBmDiffEQL;
    7104             :                 }
    7105             :             }
    7106             :             // Diffuse-diffuse transmittance for bare exterior window
    7107     7117655 :             if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    7108        1232 :                 TDifBare = TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarAniso);
    7109             :             } else {
    7110     7116423 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    7111             :                     // Complex Fenestration: use hemispherical ave of directional-hemispherical transmittance
    7112             :                     // Note: this is not quite the same as the effective transmittance for total of sky and ground radiation
    7113       24486 :                     TDifBare = state.dataSurface->SurfaceWindow(SurfNum)
    7114       12243 :                                    .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
    7115             :                                    .WinDiffTrans;
    7116             :                 } else { // Regular window
    7117     7104180 :                     TDifBare = state.dataConstruction->Construct(ConstrNum).TransDiff;
    7118             :                 }
    7119             :             }
    7120             : 
    7121             :             //-----------------------------------------------------------------
    7122             :             // BLOCK 3 - SCREEN, BLINDS AND GLAZING SYSTEM BEAM SOLAR TRANSMITTANCE
    7123             :             //-----------------------------------------------------------------
    7124     7117655 :             if (ConstrNumSh != 0 && SunLitFract > 0.0) {
    7125      114957 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) {
    7126      114957 :                     if (IS_SHADED_NO_GLARE_CTRL(ShadeFlag)) {
    7127             :                         // Shade or screen or blind on, or switchable glazing
    7128             :                         // (note in the following that diffusing glass is not allowed in a window with shade, blind or switchable glazing)
    7129       87666 :                         if (ANY_SHADE(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
    7130             :                             // Shade on or switchable glazing
    7131       74039 :                             TBmAllShBlSc = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef);
    7132             :                         } else {
    7133             :                             // Blind or Screen on
    7134             :                             Real64 TScBmDif;  // Beam-diffuse solar transmittance of screen
    7135             :                             Real64 TBlBmDif;  // Beam-diffuse solar transmittance of blind
    7136             :                             Real64 TBlDifDif; // Diffuse-diffuse solar transmittance of blind
    7137             :                             Real64 TScBmBm;
    7138             :                             Real64 TBlBmBm;
    7139       13627 :                             if (ShadeFlag == WinShadingType::ExtScreen) { // Exterior screen
    7140        1624 :                                 Real64 RScBack = state.dataHeatBal->SurfaceScreens(ScNum).ReflectSolBeamFront;
    7141        1624 :                                 Real64 RScDifDifBk = state.dataHeatBal->SurfaceScreens(ScNum).DifReflect; // Diffuse-diffuse back refectance of screen
    7142        1624 :                                 Real64 RGlBmFr = POLYF(
    7143        3248 :                                     CosInc, state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef); // Beam front reflectance of glass
    7144             :                                 Real64 RGlDifFr =
    7145        1624 :                                     state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront; // Diffuse front reflectance of glass
    7146             :                                 // beam transmittance (written in subroutine CalcScreenTransmittance each time step)
    7147        1624 :                                 TScBmBm = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTrans;
    7148        1624 :                                 TBmBmSc = TBmBm * TScBmBm;
    7149        1624 :                                 TScBmDif = state.dataHeatBal->SurfaceScreens(ScNum).BmDifTrans;
    7150             :                                 // beam-beam and diffuse transmittance of exterior beam
    7151        3248 :                                 TBmAllShBlSc = TScBmBm * (TBmBm + RGlBmFr * RScBack * TDifBare / (1 - RGlDifFr * RScDifDifBk)) +
    7152        1624 :                                                TScBmDif * TDifBare / (1 - RGlDifFr * RScDifDifBk);
    7153        1624 :                                 TBmBmShBlSc = TBmBmSc;
    7154        1624 :                                 TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
    7155             :                                 // Report variable for Beam-to-Diffuse transmittance (scattered transmittance)
    7156        1624 :                                 state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = TBmBmSc;
    7157        1624 :                                 state.dataSurface->SurfWinScTsolBmBm(SurfNum) = TScBmBm;
    7158        1624 :                                 state.dataSurface->SurfWinScTsolBmDif(SurfNum) = TScBmDif;
    7159             :                             } else {
    7160       12003 :                                 TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum);
    7161       12003 :                                 TBlBmDif = FrontBeamDiffTrans;
    7162       12003 :                                 if (ShadeFlag == WinShadingType::IntBlind) {
    7163        9329 :                                     Real64 RhoBlBmDifFr = FrontBeamDiffRefl; // Beam-diffuse front reflectance of blind
    7164             :                                     Real64 RGlDifBk =
    7165        9329 :                                         state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; // Diffuse front reflectance of glass
    7166        9329 :                                     Real64 RhoBlDifDifFr = FrontDiffDiffRefl;                            // Diffuse-diffuse front refectance of blind
    7167             :                                     // beam-beam and diffuse transmittance of exterior beam
    7168        9329 :                                     TBmBmBl = TBmBm * TBlBmBm;
    7169        9329 :                                     TBlDifDif = FrontDiffDiffTrans;
    7170        9329 :                                     TBmAllShBlSc =
    7171        9329 :                                         TBmBm * (TBlBmBm + TBlBmDif + TBlDifDif * RhoBlBmDifFr * RGlDifBk / (1 - RhoBlDifDifFr * RGlDifBk));
    7172        9329 :                                     TBmBmShBlSc = TBmBmBl; // TBmBm * TBlBmBm
    7173        9329 :                                     TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
    7174        9329 :                                     if (TBmDifShBlSc < 0.0) TBmDifShBlSc = 0.0;
    7175        2674 :                                 } else if (ShadeFlag == WinShadingType::ExtBlind) {
    7176         728 :                                     Real64 RhoBlBmDifBk = BackBeamDiffRefl;  // Beam-diffuse back reflectance of blind
    7177         728 :                                     Real64 RhoBlDifDifBk = BackDiffDiffRefl; // Diffuse-diffuse back refectance of blind
    7178         728 :                                     Real64 RGlBmFr = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef);
    7179         728 :                                     Real64 RGlDifFr = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront;
    7180             :                                     // beam-beam and diffuse transmittance of exterior beam
    7181         728 :                                     TBmBmBl = TBmBm * TBlBmBm;
    7182        1456 :                                     TBmAllShBlSc = TBlBmBm * (TBmBm + TDifBare * RGlBmFr * RhoBlBmDifBk / (1 - RGlDifFr * RhoBlDifDifBk)) +
    7183         728 :                                                    TBlBmDif * TDifBare / (1 - RGlDifFr * RhoBlDifDifBk);
    7184         728 :                                     TBmBmShBlSc = TBmBmBl; // TBmBm * TBlBmBm
    7185         728 :                                     TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
    7186             :                                 } else {
    7187             :                                     // Between-glass blind on
    7188        1946 :                                     int NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    7189        1946 :                                     Real64 td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
    7190        1946 :                                     Real64 rbd1 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(1);
    7191        1946 :                                     Real64 rbshB = BackBeamDiffRefl;
    7192        1946 :                                     Real64 rfshd = FrontDiffDiffRefl;
    7193        1946 :                                     Real64 rbshd = BackDiffDiffRefl;
    7194        1946 :                                     Real64 tfshBd = FrontBeamDiffTrans;
    7195        1946 :                                     Real64 t1 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(1));
    7196        1946 :                                     Real64 t2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(2));
    7197        1946 :                                     Real64 tfshBB = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum);
    7198        1946 :                                     if (NGlass == 2) {
    7199        1218 :                                         Real64 rf2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(2));
    7200        1218 :                                         Real64 rfshB = FrontBeamDiffRefl;
    7201        1218 :                                         Real64 rfd2 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(2);
    7202        1218 :                                         TBmBmBl = t1 * tfshBB * t2;
    7203        2436 :                                         TBmAllShBlSc = t1 * tfshBB * t2 +
    7204        1218 :                                                        t1 * (tfshBB * rf2 * rbshB + tfshBd * (1.0 + rfd2 * rbshd) + rfshB * rbd1 * rfshd) * td2;
    7205             :                                     } else { // NGlass = 3
    7206         728 :                                         Real64 t1t2 = t1 * t2;
    7207         728 :                                         Real64 t3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(3));
    7208         728 :                                         Real64 td3 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(3);
    7209         728 :                                         Real64 rf3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(3));
    7210         728 :                                         Real64 rbd2 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(2);
    7211         728 :                                         Real64 rfd3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
    7212         728 :                                         Real64 tfshd = FrontDiffDiffTrans;
    7213         728 :                                         TBmBmBl = t1 * t2 * tfshBB * t3;
    7214        2184 :                                         TBmAllShBlSc = t1t2 * tfshBB * t3 + t1t2 *
    7215        1456 :                                                                                 (tfshBB * rf3 * rbshB + tfshBd * (1.0 + rfd3 * rbshd) +
    7216        1456 :                                                                                  rbshB * (rbd2 * tfshd + td2 * rbd1 * td2 * tfshd)) *
    7217             :                                                                                 td3;
    7218             :                                     }
    7219             :                                     // added TH 12/9/2009
    7220        1946 :                                     TBmBmShBlSc = TBmBmBl;
    7221        1946 :                                     TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
    7222             :                                 }
    7223       12003 :                                 state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = TBlBmBm;
    7224       12003 :                                 state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = TBlBmDif;
    7225       12003 :                                 state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = TBmBmBl;
    7226             :                             }
    7227             :                         }
    7228             :                     } // End of check if ShadeFlag > 0 and ShadeFlag < 10
    7229             :                 }     // end of checking if not eql window model
    7230             :             }         // end of checking if sunlitfract > 0
    7231             : 
    7232     7117655 :             if (ShadeFlag == WinShadingType::SwitchableGlazing) {
    7233             :                 // Switchable glazing
    7234       71254 :                 Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    7235       71254 :                 if (!state.dataSurface->SurfWinSolarDiffusing(SurfNum)) {
    7236       71254 :                     TBmBm = General::InterpSw(SwitchFac, TBmBm, TBmAllShBlSc);
    7237             :                 } else {
    7238           0 :                     TBmDif = General::InterpSw(SwitchFac, TBmDif, TBmAllShBlSc);
    7239             :                 }
    7240             :             }
    7241             :             // Report variables
    7242     7117655 :             state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = TBmBm;
    7243     7117655 :             state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = TBmDif;
    7244     7117655 :             state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = TDifBare;
    7245             : 
    7246             :             //-----------------------------------------------------------------
    7247             :             // BLOCK 4 - REPORT WINDOW TRANSMITTANCE
    7248             :             //-----------------------------------------------------------------
    7249             : 
    7250             :             // The following SurfWinTransBmSolar and SurfWinTransDifSolar will be combined later to give
    7251             :             // WinTransSolar for reporting
    7252     7117655 :             state.dataSolarShading->SurfWinTransBmSolar(SurfNum) = 0.0;
    7253     7117655 :             state.dataSolarShading->SurfWinTransDifSolar(SurfNum) = 0.0;
    7254     7117655 :             state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum) = 0.0;
    7255     7117655 :             state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) = 0.0;
    7256     7117655 :             state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
    7257             :                 0.0; // Factor for exterior beam to beam solar transmitted through window, or window plus shade, into zone at current time (m2)
    7258     7117655 :             state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
    7259             :                 0.0; // Factor for exterior beam to diffuse solar transmitted through window, or window plus shade, into zone at current time (m2)
    7260             : 
    7261     7117655 :             Real64 InOutProjSLFracMult = state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    7262     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) {
    7263     7115177 :                 state.dataSolarShading->SurfWinTransDifSolar(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7264     7115177 :                 if (ANY_BLIND(ShadeFlag)) {
    7265       18094 :                     if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
    7266             :                         DataWindowEquivalentLayer::Orientation::Horizontal) {
    7267       18094 :                         state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum) = DiffTransGnd * state.dataSurface->Surface(SurfNum).Area;
    7268       18094 :                         state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) = DiffTransSky * state.dataSurface->Surface(SurfNum).Area;
    7269             :                     }
    7270             :                 }
    7271             :             } else {
    7272             :                 // In equivalent layer window model system diffuse transmittance is based on unit
    7273             :                 // diffuse radiation flux, and hence doesn't distinguish between sky and
    7274             :                 // ground reflected diffuse radiations
    7275        2478 :                 state.dataSolarShading->SurfWinTransDifSolar(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7276        2478 :                 state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7277        2478 :                 state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7278             :             }
    7279             : 
    7280     7117655 :             if (!IS_SHADED_NO_GLARE_CTRL(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
    7281             :                 // Unshaded or switchable glazing
    7282             :                 // Note: with previous defs of TBmBm & TBmDif, these come out right for Complex Fenestration
    7283             :                 // SurfWinTransBmSolar uses the directional-hemispherical transmittance
    7284     7057787 :                 state.dataSolarShading->SurfWinTransBmSolar(SurfNum) =
    7285     7057787 :                     (TBmBm + TBmDif) * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
    7286     7057787 :                 state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
    7287     7057787 :                     TBmBm * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
    7288     7057787 :                 state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
    7289     7057787 :                     TBmDif * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
    7290             : 
    7291             :             } else {
    7292       59868 :                 state.dataSolarShading->SurfWinTransBmSolar(SurfNum) =
    7293       59868 :                     TBmAllShBlSc * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
    7294       59868 :                 state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
    7295       59868 :                     TBmBmShBlSc * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
    7296       59868 :                 state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
    7297       59868 :                     TBmDifShBlSc * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
    7298             :             }
    7299             : 
    7300             :             // Add diffuse transmitted by window from beam reflected from outside reveal
    7301     7117655 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { // Complex Fenestration
    7302       12243 :                 if (FenSolAbsPtr == 0) {
    7303       12145 :                     state.dataSolarShading->SurfWinTransBmSolar(SurfNum) =
    7304       12145 :                         (TBmBm + TBmDif) * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
    7305       12145 :                     state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
    7306       12145 :                         TBmBm * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
    7307       12145 :                     state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
    7308       12145 :                         TBmDif * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
    7309       12145 :                     state.dataSolarShading->SurfWinTransBmSolar(SurfNum) +=
    7310       12145 :                         state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * NomDiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7311       12145 :                     state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) +=
    7312       12145 :                         state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * NomDiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7313             :                 } else {
    7314          98 :                     state.dataSolarShading->SurfWinTransBmSolar(SurfNum) = 0.0;
    7315          98 :                     state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) = 0.0;
    7316             :                 }
    7317             :             } else { // Regular window
    7318             :                 // this is also valid for equivalent layer window
    7319     7105412 :                 state.dataSolarShading->SurfWinTransBmSolar(SurfNum) +=
    7320     7105412 :                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7321     7105412 :                 state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) +=
    7322     7105412 :                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7323             :             }
    7324             : 
    7325             :             //-----------------------------------------------------------------
    7326             :             // BLOCK 5 - UPDATE SOLAR ENTERING A ZONE AS BEAM OR DIFFUSE RADIATION
    7327             :             //-----------------------------------------------------------------
    7328             :             // Increment factor for total exterior beam solar entering zone through window as beam or diffuse
    7329     7117655 :             if (SunLitFract > 0.0 && state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome) {
    7330             :                 // Window is schedule surface gained. Do not make addition to what enters into zone since that information is not available
    7331     3660579 :                 if (FenSolAbsPtr == 0) {
    7332             :                     Real64 TBmAll; // Window beam-to-(beam+diffuse) transmittance
    7333     7344723 :                     if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::BSDF &&
    7334     7296233 :                         (ANY_BLIND(ShadeFlag) || ANY_SHADE_SCREEN(ShadeFlag))) {
    7335       30082 :                         TBmAll = TBmAllShBlSc;
    7336             :                     } else {
    7337     3630441 :                         TBmAll = TBmBm + TBmDif;
    7338             :                     }
    7339     3660523 :                     BTOTZone += TBmAll * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // [m2]
    7340             :                 }
    7341             :             }
    7342             : 
    7343             :             // Correct for effect of (1) beam absorbed by inside reveal, (2) diffuse entering zone from beam
    7344             :             // reflected by inside reveal and (3) diffuse transmitted by window from beam reflected from outside reveal.
    7345     7117655 :             if (CosInc > 0.0) {
    7346             :                 // The BTOTZone is the solar into zone assuming no inside or outside reveals
    7347             :                 // The inside reveals receive solar (reflected part + absorbed part) from the window, this amount should be deducted from the
    7348             :                 // BTOTZone, then adds the InsRevealDiffIntoZone
    7349     3852729 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { // Complex Fenestration
    7350             :                     // Do not add total into zone from scheduled surface gains.  That will be added later
    7351        6461 :                     if (SurfaceScheduledSolarInc(state, SurfNum, ConstrNum) == 0) {
    7352        6461 :                         BTOTZone =
    7353       12922 :                             BTOTZone - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) -
    7354       12922 :                             state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) +
    7355        6461 :                             state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * NomDiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7356             :                     }
    7357             :                 } else { // Regular window
    7358    11538804 :                     BTOTZone = BTOTZone - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) -
    7359     7692536 :                                state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) +
    7360     3846268 :                                state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * DiffTrans * state.dataSurface->Surface(SurfNum).Area;
    7361             :                 }
    7362             :                 // Add beam solar absorbed by outside reveal to outside of window's base surface. Add beam solar absorbed by inside reveal to inside
    7363             :                 // of window's base surface. This ignores 2-D heat transfer effects.
    7364     3852729 :                 int BaseSurfNum = state.dataSurface->Surface(SurfNum).BaseSurf;
    7365     3852729 :                 state.dataSurface->SurfOpaqAI(BaseSurfNum) +=
    7366     3852729 :                     state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) / state.dataSurface->Surface(BaseSurfNum).Area;
    7367     3852729 :                 state.dataSurface->SurfOpaqAO(BaseSurfNum) +=
    7368     3852729 :                     state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) / state.dataSurface->Surface(BaseSurfNum).Area;
    7369             :             }
    7370             : 
    7371             :             //-----------------------------------------------------------------
    7372             :             // BLOCK 6 - INTERIOR BEAM FROM EXTERIOR WINDOW THAT IS ABSORBED/TRANSMITTED BY BACK SURFACES
    7373             :             //-----------------------------------------------------------------
    7374             : 
    7375             :             // If shade is in place or there is a diffusing glass layer there is no interior beam
    7376             :             // from this exterior window since the beam-beam transmittance of shades and diffusing glass
    7377             :             // is assumed to be zero. The beam-beam transmittance of tubular daylighting devices is also
    7378             :             // assumed to be zero.
    7379             : 
    7380     7117655 :             if (SunLitFract > 0.0) {
    7381     3661727 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::BSDF)
    7382    14588154 :                     if (ANY_SHADE(ShadeFlag) || state.dataSurface->SurfWinSolarDiffusing(SurfNum) ||
    7383    10931740 :                         state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser ||
    7384     3637663 :                         state.dataSurface->Surface(SurfNum).Class == SurfaceClass::TDD_Dome)
    7385       18751 :                         continue;
    7386             : 
    7387             :                 // Find interior beam radiation that is:
    7388             :                 // (1) absorbed by opaque back surfaces;
    7389             :                 // (2) absorbed by glass layers of back surfaces that are interior or exterior windows;
    7390             :                 // (3) absorbed by interior, exterior or between-glass shades or blinds of back surfaces
    7391             :                 //       that are exterior windows; and
    7392             :                 // (4) transmitted through back surfaces that are interior or exterior windows.
    7393             :                 // Beam-beam transmittance of exterior window
    7394             :                 Real64 TBm;      // Window beam-beam transmittance
    7395             :                 Real64 TBmDenom; // TBmDenominator
    7396     3642976 :                 Real64 TBmBmSc = state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum);
    7397     3642976 :                 Real64 TBmBmBl = state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum);
    7398     3642976 :                 Real64 TBmBm = state.dataSurface->SurfWinGlTsolBmBm(SurfNum);
    7399             : 
    7400     3642976 :                 Real64 InOutProjSLFracMult = state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    7401     3642976 :                 int InShelfSurf = 0; // Inside daylighting shelf surface number
    7402     3642976 :                 int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum);
    7403     3642976 :                 if (ShelfNum > 0) { // Daylighting shelf
    7404         364 :                     InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf;
    7405             :                 }
    7406     3642976 :                 if (ANY_BLIND(ShadeFlag)) {
    7407       12003 :                     TBm = TBmBmBl; // Interior, exterior or between-glass blind on
    7408     3630973 :                 } else if (ShadeFlag == WinShadingType::ExtScreen) {
    7409        1624 :                     TBm = TBmBmSc; // Exterior screen on
    7410             :                 } else {
    7411     3629349 :                     TBm = TBmBm; // Bare glass or switchable glazing
    7412             :                     // Correction for beam absorbed by inside reveal
    7413     3629349 :                     TBmDenom = (SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult);
    7414     3629349 :                     if (TBmDenom != 0.0) { // when =0.0, no correction
    7415     3629349 :                         TBm -= state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) / TBmDenom;
    7416             :                     }
    7417     3629349 :                     TBm = max(0.0, TBm);
    7418             :                 }
    7419             : 
    7420     3642976 :                 if (TBm == 0.0) continue;
    7421     3627602 :                 if (InShelfSurf > 0) { // Inside daylighting shelf
    7422             :                     // Inside daylighting shelves assume that no beam will pass the end of the shelf.
    7423             :                     // Since all beam is absorbed on the shelf, this might cause them to get unrealistically hot at times.
    7424             :                     // BTOTWinZone - Transmitted beam solar factor for a window [m2]
    7425         364 :                     Real64 BTOTWinZone = TBm * SunLitFract * state.dataSurface->Surface(SurfNum).Area * CosInc * InOutProjSLFracMult;
    7426             :                     // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
    7427         364 :                     state.dataSurface->SurfOpaqAI(InShelfSurf) += BTOTWinZone / (0.5 * state.dataSurface->Surface(InShelfSurf).Area); //[-]
    7428         364 :                     BABSZone += BTOTWinZone;                                                                                          //[m2]
    7429         364 :                     continue;
    7430             :                 }
    7431             : 
    7432     3627238 :                 if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) { // Full interior solar distribution
    7433     2434124 :                     if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {
    7434             :                         // Loop over back surfaces irradiated by beam from this exterior window
    7435     6907178 :                         for (int IBack = 1; IBack <= state.dataBSDFWindow->MaxBkSurf; ++IBack) {
    7436             :                             int BackSurfNum =
    7437     6907178 :                                 state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
    7438     6907178 :                             if (BackSurfNum == 0) break; // No more irradiated back surfaces for this exterior window
    7439     4478451 :                             int ConstrNumBack = state.dataSurface->SurfActiveConstruction(BackSurfNum);
    7440     4478451 :                             int NBackGlass = state.dataConstruction->Construct(ConstrNumBack).TotGlassLayers;
    7441             :                             // Irradiated (overlap) area for this back surface, projected onto window plane
    7442             :                             // (includes effect of shadowing on exterior window)
    7443             :                             Real64 AOverlap =
    7444     4478451 :                                 state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
    7445             :                             // Back surface area irradiated by beam solar from an exterior window, projected onto window plane
    7446     4478451 :                             Real64 BOverlap = TBm * AOverlap * CosInc; //[m2]
    7447             :                             // AOverlap multiplied by exterior window beam transmittance and cosine of incidence angle
    7448     4478451 :                             if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
    7449             : 
    7450             :                                 // Back surface is opaque interior or exterior wall
    7451             :                                 // Interior solar absorptance of opaque surface
    7452     4193441 :                                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(BackSurfNum);
    7453     4193441 :                                 state.dataSurface->SurfOpaqAI(BackSurfNum) +=
    7454     4193441 :                                     BOverlap * AbsIntSurf / state.dataSurface->Surface(BackSurfNum).Area; //[-]
    7455     4193441 :                                 BABSZone += BOverlap * AbsIntSurf;                                        //[m2]
    7456             : 
    7457             :                             } else {
    7458             : 
    7459             :                                 // Back surface is an interior or exterior window
    7460             :                                 // Note that exterior back windows can have a shading device but interior back windows
    7461             :                                 // are assumed to be bare, i.e., they have no shading device and are non-switchable.
    7462             :                                 // The layer order for interior windows is "outside" to "inside," where "outside" refers to
    7463             :                                 // the adjacent zone and "inside" refers to the current zone.
    7464      285010 :                                 WinShadingType ShadeFlagBack = state.dataSurface->SurfWinShadingFlag(BackSurfNum);
    7465      285010 :                                 Real64 SlatAngBack = state.dataSurface->SurfWinSlatAngThisTS(BackSurfNum);
    7466             :                                 Real64 CosIncBack =
    7467      285010 :                                     std::abs(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, BackSurfNum));
    7468      285010 :                                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    7469             :                                     // Transmitting window is complex fen, change the incident angle to one for ray joining
    7470             :                                     // transmitting and back window centers
    7471           0 :                                     CosIncBack = std::abs(state.dataBSDFWindow->ComplexWind(SurfNum).sdotN(IBack));
    7472             :                                 }
    7473      285010 :                                 int ConstrNumBackShRaw = state.dataSurface->SurfWinActiveShadedConstruction(BackSurfNum);
    7474      285010 :                                 int const ConstrNumBackSh = ConstrNumBackShRaw == 0 ? ConstrNumBack : ConstrNumBackShRaw;
    7475      285010 :                                 state.dataSolarShading->SurfWinAbsBeam.dimension(state.dataHeatBal->MaxSolidWinLayers, 0.0);
    7476      285010 :                                 Real64 TransBeamWin = 0.0;  // Beam solar transmittance of a window
    7477      285010 :                                 Real64 AbsBeamTotWin = 0.0; // Sum of window glass layer beam solar absorptances
    7478             : 
    7479             :                                 // Interior beam absorptance of glass layers and beam transmittance of back exterior  &
    7480             :                                 // or interior window WITHOUT SHADING this timestep
    7481      285010 :                                 if (NOT_SHADED(ShadeFlagBack)) {
    7482      710908 :                                     for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
    7483      425898 :                                         state.dataSolarShading->SurfWinAbsBeam(Lay) =
    7484      425898 :                                             POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).AbsBeamBackCoef(Lay));
    7485             :                                     }
    7486      285010 :                                     TransBeamWin = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef);
    7487             :                                 }
    7488             : 
    7489             :                                 // Interior beam absorptance of glass layers and beam transmittance
    7490             :                                 // of back exterior window with SHADE
    7491      285010 :                                 if (ANY_SHADE(ShadeFlagBack)) {
    7492           0 :                                     for (int Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNumBackSh).TotGlassLayers; ++Lay) {
    7493           0 :                                         state.dataSolarShading->SurfWinAbsBeam(Lay) =
    7494           0 :                                             POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).AbsBeamBackCoef(Lay));
    7495             :                                     }
    7496           0 :                                     TransBeamWin = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).TransSolBeamCoef);
    7497             :                                 }
    7498             : 
    7499             :                                 // Interior beam absorbed by INTERIOR SHADE of back exterior window
    7500             : 
    7501      285010 :                                 if (ShadeFlagBack == WinShadingType::IntShade) {
    7502           0 :                                     state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7503           0 :                                         BOverlap * state.dataConstruction->Construct(ConstrNumBackSh).AbsDiffBackShade /
    7504           0 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    7505           0 :                                     BABSZone += BOverlap * state.dataConstruction->Construct(ConstrNumBackSh).AbsDiffBackShade;
    7506      285010 :                                 } else if (ShadeFlagBack ==
    7507             :                                            WinShadingType::ExtShade) { // Interior beam absorbed by EXTERIOR SHADE of back exterior window
    7508           0 :                                     Real64 RGlFront = state.dataConstruction->Construct(ConstrNumBack).ReflectSolDiffFront;
    7509             :                                     Real64 AbsSh =
    7510           0 :                                         state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(1)).AbsorpSolar;
    7511             :                                     Real64 RhoSh =
    7512           0 :                                         1.0 - AbsSh -
    7513           0 :                                         state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(1)).Trans;
    7514           0 :                                     Real64 AShBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef) * AbsSh /
    7515           0 :                                                      (1.0 - RGlFront * RhoSh);
    7516           0 :                                     BABSZone += BOverlap * AShBack;
    7517           0 :                                     state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7518           0 :                                         BOverlap * AShBack /
    7519           0 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    7520      285010 :                                 } else if (ShadeFlagBack ==
    7521             :                                            WinShadingType::BGShade) { // Interior beam absorbed by BETWEEN-GLASS SHADE of back exterior window
    7522           0 :                                     Real64 rbd1k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(1);
    7523           0 :                                     Real64 rfd2k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(2);
    7524             :                                     Real64 AShBack; // System shade absorptance for interior beam solar
    7525           0 :                                     if (NBackGlass == 2) {
    7526           0 :                                         Real64 t2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(2));
    7527           0 :                                         Real64 TrSh = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(3))
    7528           0 :                                                           .Trans; // Shade material solar transmittance
    7529           0 :                                         Real64 RhoSh = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(3))
    7530           0 :                                                            .ReflectShade;                    // Shade material solar absorptance
    7531           0 :                                         Real64 AbsSh = min(1.0, max(0.0, 1 - TrSh - RhoSh)); // Shade material solar absorptance
    7532           0 :                                         AShBack = t2k * (1 + RhoSh * rfd2k + TrSh * rbd1k) * AbsSh;
    7533             :                                     } else { // NBackGlass = 3
    7534           0 :                                         Real64 t3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(3));
    7535           0 :                                         Real64 td2k = state.dataConstruction->Construct(ConstrNumBack).tBareSolDiff(2);
    7536           0 :                                         Real64 rbd2k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(2);
    7537           0 :                                         Real64 rfd3k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(3);
    7538             :                                         Real64 TrSh =
    7539           0 :                                             state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(5)).Trans;
    7540           0 :                                         Real64 RhoSh = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(5))
    7541           0 :                                                            .ReflectShade;
    7542           0 :                                         Real64 AbsSh = min(1.0, max(0.0, 1 - TrSh - RhoSh));
    7543           0 :                                         AShBack = t3k * (1 + RhoSh * rfd3k + TrSh * (rbd2k + td2k * rbd1k * td2k)) * AbsSh;
    7544             :                                     }
    7545           0 :                                     state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7546           0 :                                         BOverlap * AShBack / state.dataSurface->Surface(BackSurfNum).Area;
    7547           0 :                                     BABSZone += BOverlap * AShBack;
    7548             :                                 }
    7549             : 
    7550             :                                 // Interior beam absorptance of glass layers and beam absorbed in blind
    7551             :                                 // of back exterior window with BLIND
    7552      285010 :                                 if (ANY_BLIND(ShadeFlagBack)) {
    7553           0 :                                     int BlNumBack = state.dataSurface->SurfWinBlindNumber(BackSurfNum); // Back surface blind number
    7554             :                                     Real64 ProfAngBack =
    7555           0 :                                         state.dataSurface->SurfWinProfileAng(BackSurfNum); // Back window solar profile angle (radians)
    7556             : 
    7557           0 :                                     int SlatsAngIndexLowerBack = state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum);
    7558           0 :                                     int ProfAngIndexLowerBack = state.dataSurface->SurfWinProfAngIndex(BackSurfNum);
    7559           0 :                                     int SlatsAngIndexUpperBack = std::min(MaxProfAngs, SlatsAngIndexLowerBack + 1);
    7560           0 :                                     int ProfAngIndexUpperBack = std::min(MaxProfAngs, ProfAngIndexLowerBack + 1);
    7561           0 :                                     Real64 SlatsAngInterpFacBack = state.dataSurface->SurfWinSlatsAngInterpFac(BackSurfNum);
    7562           0 :                                     Real64 ProfAngInterpFacBack = state.dataSurface->SurfWinProfAngInterpFac(BackSurfNum);
    7563             : 
    7564           0 :                                     Real64 TGlBmBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef);
    7565           0 :                                     Real64 TBlBmBmBack = General::BlindBeamBeamTrans(
    7566             :                                         ProfAngBack,
    7567             :                                         DataGlobalConstants::Pi - SlatAngBack,
    7568           0 :                                         state.dataHeatBal->Blind(BlNumBack).SlatWidth,
    7569           0 :                                         state.dataHeatBal->Blind(BlNumBack).SlatSeparation,
    7570           0 :                                         state.dataHeatBal->Blind(BlNumBack).SlatThickness); // Blind solar back beam-beam transmittance
    7571             :                                     Real64 TBlBmDiffBack;                                   // Blind solar back beam-diffuse transmittance
    7572           0 :                                     if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
    7573           0 :                                         TBlBmDiffBack = General::InterpProfSlat(
    7574           0 :                                             state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7575           0 :                                             state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7576           0 :                                             state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7577           0 :                                             state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7578             :                                             SlatsAngInterpFacBack,
    7579             :                                             ProfAngInterpFacBack);
    7580             :                                     } else {
    7581           0 :                                         TBlBmDiffBack =
    7582           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexLowerBack),
    7583           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexUpperBack),
    7584             :                                                                    ProfAngInterpFacBack);
    7585             :                                     }
    7586             : 
    7587           0 :                                     if (ShadeFlagBack == WinShadingType::IntBlind) {
    7588             :                                         // Interior beam absorptance of GLASS LAYERS of exterior back window with INTERIOR BLIND
    7589             :                                         Real64 RhoBlFront; // Blind solar front diffuse reflectance
    7590             :                                         Real64 AbsBlFront; // Blind solar front beam absorptance
    7591             :                                         Real64 AbsBlBack;  // Blind solar back beam absorptance
    7592           0 :                                         if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
    7593           0 :                                             FrontDiffDiffRefl =
    7594           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(
    7595           0 :                                                                            state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum)),
    7596           0 :                                                                        state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(std::min(
    7597           0 :                                                                            MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum) + 1)),
    7598           0 :                                                                        state.dataSurface->SurfWinSlatsAngInterpFac(BackSurfNum));
    7599           0 :                                             FrontDiffAbs =
    7600           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(
    7601           0 :                                                                            state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum)),
    7602           0 :                                                                        state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(std::min(
    7603           0 :                                                                            MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum) + 1)),
    7604           0 :                                                                        state.dataSurface->SurfWinSlatsAngInterpFac(BackSurfNum));
    7605           0 :                                             RhoBlFront = General::InterpProfSlat(
    7606           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7607           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7608           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7609           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7610             :                                                 SlatsAngInterpFacBack,
    7611             :                                                 ProfAngInterpFacBack);
    7612           0 :                                             AbsBlFront = General::InterpProfSlat(
    7613           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7614           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7615           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7616           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7617             :                                                 SlatsAngInterpFacBack,
    7618             :                                                 ProfAngInterpFacBack);
    7619           0 :                                             AbsBlBack = General::InterpProfSlat(
    7620           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7621           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7622           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7623           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7624             :                                                 SlatsAngInterpFacBack,
    7625             :                                                 ProfAngInterpFacBack);
    7626             :                                         } else {
    7627           0 :                                             FrontDiffDiffRefl =
    7628           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(1); // Blind solar front beam reflectance
    7629           0 :                                             FrontDiffAbs = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(1);
    7630           0 :                                             RhoBlFront =
    7631           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexLowerBack),
    7632           0 :                                                                        state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexUpperBack),
    7633             :                                                                        ProfAngInterpFacBack);
    7634           0 :                                             AbsBlFront =
    7635           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexLowerBack),
    7636           0 :                                                                        state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexUpperBack),
    7637             :                                                                        ProfAngInterpFacBack);
    7638           0 :                                             AbsBlBack =
    7639           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLowerBack),
    7640           0 :                                                                        state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpperBack),
    7641             :                                                                        ProfAngInterpFacBack);
    7642             :                                         }
    7643             : 
    7644           0 :                                         Real64 RhoBlDiffFront = FrontDiffDiffRefl; // Glazing system solar back beam-beam reflectance
    7645           0 :                                         Real64 RGlBack = POLYF(CosIncBack,
    7646           0 :                                                                state.dataConstruction->Construct(ConstrNumBack)
    7647           0 :                                                                    .ReflSolBeamBackCoef); // Glazing system back diffuse solar reflectance
    7648           0 :                                         Real64 RGlDiffBack = state.dataConstruction->Construct(ConstrNumBack).ReflectSolDiffBack;
    7649           0 :                                         for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
    7650             :                                             Real64 AbWinBack =
    7651             :                                                 POLYF(CosIncBack,
    7652           0 :                                                       state.dataConstruction->Construct(ConstrNumBack)
    7653           0 :                                                           .AbsBeamBackCoef(Lay)); // Factor for back beam radiation absorbed in window glass layer
    7654           0 :                                             Real64 AGlDiffBack = state.dataConstruction->Construct(ConstrNumBack)
    7655           0 :                                                                      .AbsDiffBack(Lay); // Glass layer back diffuse solar absorptance
    7656           0 :                                             state.dataSolarShading->SurfWinAbsBeam(Lay) =
    7657           0 :                                                 TBlBmBmBack * AbWinBack + ((TBlBmBmBack * RGlBack * RhoBlFront + TBlBmDiffBack) * AGlDiffBack /
    7658           0 :                                                                            (1.0 - RGlDiffBack * RhoBlDiffFront));
    7659             :                                         }
    7660             : 
    7661             :                                         // Interior beam transmitted by exterior back window with INTERIOR BLIND
    7662             :                                         Real64 TGlDif =
    7663           0 :                                             state.dataConstruction->Construct(ConstrNumBack).TransDiff; // Bare diffuse transmittance of back window
    7664           0 :                                         TransBeamWin =
    7665           0 :                                             TBlBmBmBack * (TGlBmBack + TGlDif * RGlBack * RhoBlFront / (1.0 - RGlDiffBack * RhoBlDiffFront)) +
    7666           0 :                                             TBlBmDiffBack * TGlDif / (1.0 - RGlDiffBack * RhoBlDiffFront);
    7667             : 
    7668             :                                         // Interior beam absorbed by BLIND on exterior back window with INTERIOR BLIND
    7669             : 
    7670           0 :                                         Real64 AbsBlDiffFront = FrontDiffAbs; // Blind solar front diffuse absorptance
    7671           0 :                                         Real64 ABlBack = AbsBlBack + TBlBmBmBack * RGlBack * AbsBlFront +
    7672           0 :                                                          (AbsBlDiffFront * RGlDiffBack / (1 - RhoBlDiffFront * RGlDiffBack)) *
    7673           0 :                                                              (RGlBack * TBlBmBmBack * RhoBlFront +
    7674             :                                                               TBlBmDiffBack); // Blind solar back absorptance for interior solar
    7675           0 :                                         state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7676           0 :                                             BOverlap * ABlBack /
    7677           0 :                                             (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    7678           0 :                                         BABSZone += BOverlap * ABlBack;
    7679             : 
    7680           0 :                                     } else if (ShadeFlagBack == WinShadingType::ExtBlind) {
    7681             : 
    7682             :                                         // Interior beam absorptance of GLASS LAYERS of exterior back window with EXTERIOR BLIND
    7683             : 
    7684           0 :                                         Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNumBack)
    7685           0 :                                                                   .ReflectSolDiffFront; // Glazing system front diffuse solar reflectance
    7686             :                                         Real64 RhoBlBack;                               // Blind solar back beam-diffuse reflectance
    7687             :                                         Real64 RhoBlBmDifBk;
    7688             :                                         Real64 AbsBlBack;
    7689           0 :                                         if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
    7690           0 :                                             RhoBlBack = General::InterpProfSlat(
    7691           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7692           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7693           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7694           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7695             :                                                 SlatsAngInterpFacBack,
    7696             :                                                 ProfAngInterpFacBack);
    7697           0 :                                             RhoBlBmDifBk = General::InterpProfSlat(
    7698           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7699           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7700           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7701           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7702             :                                                 SlatsAngInterpFacBack,
    7703             :                                                 ProfAngInterpFacBack);
    7704           0 :                                             AbsBlBack = General::InterpProfSlat(
    7705           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7706           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7707           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7708           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7709             :                                                 SlatsAngInterpFacBack,
    7710             :                                                 ProfAngInterpFacBack);
    7711             :                                         } else {
    7712           0 :                                             RhoBlBack =
    7713           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLowerBack),
    7714           0 :                                                                        state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpperBack),
    7715             :                                                                        ProfAngInterpFacBack);
    7716           0 :                                             RhoBlBmDifBk =
    7717           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLowerBack),
    7718           0 :                                                                        state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpperBack),
    7719             :                                                                        ProfAngInterpFacBack);
    7720           0 :                                             AbsBlBack =
    7721           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLowerBack),
    7722           0 :                                                                        state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpperBack),
    7723             :                                                                        ProfAngInterpFacBack);
    7724             :                                         }
    7725             : 
    7726           0 :                                         for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
    7727             :                                             Real64 AbWinBack =
    7728           0 :                                                 POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).AbsBeamBackCoef(Lay));
    7729           0 :                                             Real64 AGlDiffFront = state.dataConstruction->Construct(ConstrNumBack).AbsDiff(Lay);
    7730           0 :                                             state.dataSolarShading->SurfWinAbsBeam(Lay) =
    7731           0 :                                                 AbWinBack + (TGlBmBack * AGlDiffFront * RhoBlBack / (1.0 - RhoBlBack * RGlDiffFront));
    7732             :                                         }
    7733             : 
    7734             :                                         // Interior beam transmitted by exterior back window with EXTERIOR BLIND
    7735           0 :                                         Real64 TBlDifDif = BackDiffDiffTrans;
    7736           0 :                                         Real64 RhoBlDifDifBk = BackDiffDiffRefl;
    7737           0 :                                         Real64 AbsBlDiffBack = BackDiffAbs;
    7738           0 :                                         Real64 ABlBack =
    7739           0 :                                             TGlBmBack * (AbsBlBack + RhoBlBack * RGlDiffFront * AbsBlDiffBack / (1 - RhoBlDifDifBk * RGlDiffFront));
    7740           0 :                                         Real64 RGlDifFr = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront;
    7741           0 :                                         TransBeamWin = TGlBmBack * (TBlBmBmBack + TBlBmDiffBack +
    7742           0 :                                                                     TBlDifDif * RhoBlBmDifBk * RGlDifFr / (1.0 - RhoBlDifDifBk * RGlDifFr));
    7743             :                                         // Interior beam absorbed by EXTERIOR BLIND on exterior back window
    7744           0 :                                         BABSZone += BOverlap * ABlBack;
    7745           0 :                                         state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7746           0 :                                             BOverlap * ABlBack /
    7747           0 :                                             (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    7748             : 
    7749             :                                     } else {
    7750             :                                         // ShadeFlagBack == BGBlindOn
    7751           0 :                                         Real64 t1k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(1));
    7752           0 :                                         Real64 t2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(2));
    7753           0 :                                         Real64 af2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).afBareSolCoef(2));
    7754           0 :                                         Real64 ab1k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).abBareSolCoef(1));
    7755           0 :                                         Real64 ab2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).abBareSolCoef(2));
    7756           0 :                                         Real64 rb1k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).rbBareSolCoef(1));
    7757           0 :                                         Real64 rb2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).rbBareSolCoef(2));
    7758           0 :                                         Real64 td1k = state.dataConstruction->Construct(ConstrNumBack).tBareSolDiff(1);
    7759           0 :                                         Real64 td2k = state.dataConstruction->Construct(ConstrNumBack).tBareSolDiff(2);
    7760           0 :                                         Real64 afd2k = state.dataConstruction->Construct(ConstrNumBack).afBareSolDiff(2);
    7761           0 :                                         Real64 abd1k = state.dataConstruction->Construct(ConstrNumBack).abBareSolDiff(1);
    7762           0 :                                         Real64 abd2k = state.dataConstruction->Construct(ConstrNumBack).abBareSolDiff(2);
    7763           0 :                                         Real64 rfd2k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(2);
    7764           0 :                                         Real64 rbd1k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(1);
    7765           0 :                                         Real64 rbd2k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(2);
    7766           0 :                                         Real64 tfshBBk = General::BlindBeamBeamTrans(ProfAngBack,
    7767             :                                                                                      SlatAngBack,
    7768           0 :                                                                                      state.dataHeatBal->Blind(BlNumBack).SlatWidth,
    7769           0 :                                                                                      state.dataHeatBal->Blind(BlNumBack).SlatSeparation,
    7770           0 :                                                                                      state.dataHeatBal->Blind(BlNumBack).SlatThickness);
    7771           0 :                                         Real64 tbshBBk = General::BlindBeamBeamTrans(ProfAngBack,
    7772             :                                                                                      DataGlobalConstants::Pi - SlatAngBack,
    7773           0 :                                                                                      state.dataHeatBal->Blind(BlNumBack).SlatWidth,
    7774           0 :                                                                                      state.dataHeatBal->Blind(BlNumBack).SlatSeparation,
    7775           0 :                                                                                      state.dataHeatBal->Blind(BlNumBack).SlatThickness);
    7776             : 
    7777             :                                         Real64 tfshBdk =
    7778           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexLowerBack),
    7779           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexUpperBack),
    7780           0 :                                                                    ProfAngInterpFacBack);
    7781             :                                         Real64 tbshBdk =
    7782           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexLowerBack),
    7783           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexUpperBack),
    7784           0 :                                                                    ProfAngInterpFacBack);
    7785             :                                         Real64 rfshBk =
    7786           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexLowerBack),
    7787           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexUpperBack),
    7788           0 :                                                                    ProfAngInterpFacBack);
    7789             :                                         Real64 rbshBk =
    7790           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLowerBack),
    7791           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpperBack),
    7792           0 :                                                                    ProfAngInterpFacBack);
    7793             :                                         Real64 afshBk =
    7794           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexLowerBack),
    7795           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexUpperBack),
    7796           0 :                                                                    ProfAngInterpFacBack);
    7797             :                                         Real64 abshBk =
    7798           0 :                                             General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLowerBack),
    7799           0 :                                                                    state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpperBack),
    7800           0 :                                                                    ProfAngInterpFacBack);
    7801           0 :                                         Real64 tfshdk = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffTrans(1);
    7802           0 :                                         Real64 rfshdk = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(1);
    7803           0 :                                         Real64 afshdk = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(1);
    7804           0 :                                         Real64 tbshdk = state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffTrans(1);
    7805           0 :                                         Real64 rbshdk = state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffRefl(1);
    7806           0 :                                         Real64 abshdk = state.dataHeatBal->Blind(BlNumBack).SolBackDiffAbs(1);
    7807           0 :                                         if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
    7808           0 :                                             tfshdk = General::InterpGeneral(
    7809           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffTrans(SlatsAngIndexLowerBack),
    7810           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffTrans(SlatsAngIndexUpperBack),
    7811             :                                                 SlatsAngInterpFacBack);
    7812           0 :                                             rfshdk = General::InterpGeneral(
    7813           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(SlatsAngIndexLowerBack),
    7814           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(SlatsAngIndexUpperBack),
    7815             :                                                 SlatsAngInterpFacBack);
    7816           0 :                                             afshdk =
    7817           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(SlatsAngIndexLowerBack),
    7818           0 :                                                                        state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(SlatsAngIndexUpperBack),
    7819             :                                                                        SlatsAngInterpFacBack);
    7820           0 :                                             tbshdk = General::InterpGeneral(
    7821           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffTrans(SlatsAngIndexLowerBack),
    7822           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffTrans(SlatsAngIndexUpperBack),
    7823             :                                                 SlatsAngInterpFacBack);
    7824           0 :                                             rbshdk = General::InterpGeneral(
    7825           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffRefl(SlatsAngIndexLowerBack),
    7826           0 :                                                 state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffRefl(SlatsAngIndexUpperBack),
    7827             :                                                 SlatsAngInterpFacBack);
    7828           0 :                                             abshdk =
    7829           0 :                                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolBackDiffAbs(SlatsAngIndexLowerBack),
    7830           0 :                                                                        state.dataHeatBal->Blind(BlNumBack).SolBackDiffAbs(SlatsAngIndexUpperBack),
    7831             :                                                                        SlatsAngInterpFacBack);
    7832           0 :                                             tfshBdk = General::InterpProfSlat(
    7833           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7834           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7835           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7836           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7837             :                                                 SlatsAngInterpFacBack,
    7838             :                                                 ProfAngInterpFacBack);
    7839           0 :                                             tbshBdk = General::InterpProfSlat(
    7840           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7841           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7842           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7843           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7844             :                                                 SlatsAngInterpFacBack,
    7845             :                                                 ProfAngInterpFacBack);
    7846           0 :                                             rfshBk = General::InterpProfSlat(
    7847           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7848           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7849           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7850           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7851             :                                                 SlatsAngInterpFacBack,
    7852             :                                                 ProfAngInterpFacBack);
    7853           0 :                                             rbshBk = General::InterpProfSlat(
    7854           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7855           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7856           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7857           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7858             :                                                 SlatsAngInterpFacBack,
    7859             :                                                 ProfAngInterpFacBack);
    7860           0 :                                             afshBk = General::InterpProfSlat(
    7861           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7862           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7863           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7864           0 :                                                 state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7865             :                                                 SlatsAngInterpFacBack,
    7866             :                                                 ProfAngInterpFacBack);
    7867           0 :                                             abshBk = General::InterpProfSlat(
    7868           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
    7869           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
    7870           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
    7871           0 :                                                 state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
    7872             :                                                 SlatsAngInterpFacBack,
    7873             :                                                 ProfAngInterpFacBack);
    7874             :                                         }
    7875             : 
    7876             :                                         Real64 ABlBack;
    7877           0 :                                         if (NBackGlass == 2) {
    7878             :                                             // Interior beam absorptance of GLASS LAYERS of exterior back window with BETWEEN-GLASS BLIND
    7879           0 :                                             state.dataSolarShading->SurfWinAbsBeam(2) =
    7880           0 :                                                 ab2k + t2k * tbshBBk * rb1k * tfshBBk * af2k +
    7881           0 :                                                 t2k * (tbshBBk * rb1k * tfshBdk + tbshBdk * rbd1k * tfshdk + rbshBk * (1.0 + rfd2k * rbshdk)) * afd2k;
    7882           0 :                                             state.dataSolarShading->SurfWinAbsBeam(1) =
    7883           0 :                                                 t2k * tbshBBk * ab1k + t2k * (rbshBk * rfd2k * tbshdk + tbshBdk * (1.0 + rbd1k * rfshdk)) * abd1k;
    7884             :                                             // Interior beam transmitted by exterior back window with BETWEEN-GLASS BLIND
    7885           0 :                                             TransBeamWin =
    7886           0 :                                                 t2k * tbshBBk * t1k +
    7887           0 :                                                 t2k * (tbshBBk * rb1k * rfshBk + rbshBk * rfd2k * tbshdk + tbshBdk * (1.0 + rbd1k * rfshdk)) * td1k;
    7888             :                                             // Interior beam absorbed by BLIND on exterior back window with BETWEEN-GLASS BLIND
    7889           0 :                                             ABlBack = t2k * (abshBk + tbshBBk * rb1k * afshBk + rbshBk * rfd2k * abshdk + tbshBdk * rbd1k * afshdk);
    7890             :                                         } else { // NBackGlass = 3
    7891           0 :                                             Real64 t3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(3));
    7892           0 :                                             Real64 af3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).afBareSolCoef(3));
    7893           0 :                                             Real64 ab3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).abBareSolCoef(3));
    7894           0 :                                             Real64 afd3k = state.dataConstruction->Construct(ConstrNumBack).afBareSolDiff(3);
    7895           0 :                                             Real64 rfd3k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(3);
    7896           0 :                                             state.dataSolarShading->SurfWinAbsBeam(3) =
    7897           0 :                                                 ab3k + t3k * tbshBBk * (rb2k + t2k * rb1k * t2k) * tfshBBk * af3k +
    7898           0 :                                                 t3k *
    7899           0 :                                                     (tbshBdk * rbd2k * tfshdk + tbshBdk * td2k * rbd1k * td2k * tfshdk +
    7900           0 :                                                      rbshBk * (1.0 + rfd3k * rbshdk)) *
    7901             :                                                     afd3k;
    7902           0 :                                             state.dataSolarShading->SurfWinAbsBeam(2) =
    7903           0 :                                                 t3k * tbshBBk * (ab2k + t2k * rb1k * (af2k + t2k * rfshBk * abd2k)) +
    7904           0 :                                                 t3k * (tbshBdk + tbshBdk * (rbd2k + td2k * rbd1k * td2k) * rfshdk + rbshBk * rfd3k * tbshdk) * abd2k +
    7905           0 :                                                 t3k * tbshBdk * td2k * rbd1k * afd2k;
    7906           0 :                                             state.dataSolarShading->SurfWinAbsBeam(1) =
    7907           0 :                                                 t3k * tbshBBk * (t2k * ab1k + (rb2k + t2k * rb1k * t2k) * rfshBk * td2k * abd1k) +
    7908           0 :                                                 t3k * (rbshBk * rfd3k * tbshdk + tbshBdk * (1.0 + rbd2k * rfshdk + td2k * rbd2k * td2k * rfshdk)) *
    7909           0 :                                                     td2k * abd1k;
    7910           0 :                                             TransBeamWin = t3k * tbshBBk * t2k * t1k +
    7911           0 :                                                            t3k *
    7912           0 :                                                                (tbshBBk * (rb2k * rfshBk + t2k * rb1k * t2k * rfshBk) + rbshBk * rfd3k * tbshdk +
    7913           0 :                                                                 tbshBdk * (1.0 + rbd2k * rfshdk + td2k * rbd1k * td2k * rfshdk)) *
    7914           0 :                                                                td2k * td1k;
    7915           0 :                                             ABlBack = t3k * abshBk + t3k * tbshBBk * (rb2k + t2k * rb1k * t2k) * afshBk +
    7916           0 :                                                       t3k * rbshBk * rfd3k * abshdk + t3k * tbshBdk * (rbd2k + td2k * rbd1k * td2k) * afshdk;
    7917             :                                         }
    7918             : 
    7919           0 :                                         BABSZone += BOverlap * ABlBack;
    7920           0 :                                         state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7921           0 :                                             BOverlap * ABlBack / state.dataSurface->Surface(BackSurfNum).Area;
    7922             : 
    7923             :                                     } // End of check if between-glass blind is on back window
    7924      285010 :                                 } else if (ShadeFlagBack == WinShadingType::ExtScreen) {
    7925             : 
    7926             :                                     // Interior beam absorptance of GLASS LAYERS of exterior back window with EXTERIOR SCREEN
    7927           0 :                                     int ScNumBack = state.dataSurface->SurfWinScreenNumber(BackSurfNum); // Back surface screen number
    7928           0 :                                     Real64 TGlBmBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef);
    7929           0 :                                     Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNumBack).ReflectSolDiffFront;
    7930             :                                     Real64 TScBmBmBack =
    7931           0 :                                         state.dataHeatBal->SurfaceScreens(ScNumBack).BmBmTransBack; // Screen solar back beam-beam transmittance
    7932             :                                     Real64 TScBmDiffBack =
    7933           0 :                                         state.dataHeatBal->SurfaceScreens(ScNumBack).BmDifTransBack; // Screen solar back beam-diffuse transmittance
    7934           0 :                                     Real64 RScBack = state.dataHeatBal->SurfaceScreens(ScNumBack).ReflectSolBeamFront;
    7935           0 :                                     Real64 RScDifBack = state.dataHeatBal->SurfaceScreens(ScNumBack).DifReflect;
    7936           0 :                                     for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
    7937           0 :                                         Real64 AbWinBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).AbsBeamBackCoef(Lay));
    7938           0 :                                         Real64 AGlDiffFront = state.dataConstruction->Construct(ConstrNumBack).AbsDiff(Lay);
    7939           0 :                                         state.dataSolarShading->SurfWinAbsBeam(Lay) =
    7940           0 :                                             AbWinBack + (TGlBmBack * AGlDiffFront * RScBack / (1.0 - RScDifBack * RGlDiffFront));
    7941             :                                     }
    7942             : 
    7943             :                                     // Interior beam transmitted by exterior back window with EXTERIOR SCREEN
    7944           0 :                                     Real64 TScDifDif = state.dataHeatBal->SurfaceScreens(ScNumBack).DifDifTrans;
    7945             :                                     Real64 RScBmDifBk =
    7946           0 :                                         state.dataHeatBal->SurfaceScreens(ScNumBack).ReflectSolBeamBack; // Beam-diffuse back reflectance of blind
    7947           0 :                                     Real64 RGlDifFr = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront;
    7948           0 :                                     Real64 RScDifDifBk = state.dataHeatBal->SurfaceScreens(ScNumBack).DifReflect;
    7949           0 :                                     TransBeamWin = TGlBmBack *
    7950           0 :                                                    (TScBmBmBack + TScBmDiffBack + TScDifDif * RScBmDifBk * RGlDifFr / (1.0 - RScDifDifBk * RGlDifFr));
    7951             : 
    7952             :                                     // Interior beam absorbed by EXTERIOR SCREEN on exterior back window
    7953             :                                     Real64 AbsScBack =
    7954           0 :                                         state.dataHeatBal->SurfaceScreens(ScNumBack).AbsorpSolarBeamBack; // Screen solar back beam absorptance
    7955             :                                     Real64 AbsScDiffBack =
    7956           0 :                                         state.dataHeatBal->SurfaceScreens(ScNumBack).DifScreenAbsorp; // Screen solar back diffuse absorptance
    7957             :                                     Real64 RScDiffBack =
    7958           0 :                                         state.dataHeatBal->SurfaceScreens(ScNumBack).ReflectSolBeamFront; // Screen solar back diffuse reflectance
    7959           0 :                                     Real64 AScBack =
    7960             :                                         TGlBmBack *
    7961           0 :                                         (AbsScBack + RScBack * RGlDiffFront * AbsScDiffBack /
    7962           0 :                                                          (1.0 - RScDiffBack * RGlDiffFront)); // Screen solar back absorptance for interior solar
    7963           0 :                                     BABSZone += BOverlap * AScBack;
    7964           0 :                                     state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    7965           0 :                                         BOverlap * AScBack /
    7966           0 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    7967             : 
    7968             :                                 } // End of check if exterior screen on back window
    7969             : 
    7970             :                                 // Interior beam absorptance of glass layers of back exterior window with SWITCHABLE GLAZING
    7971      285010 :                                 if (ShadeFlagBack == WinShadingType::SwitchableGlazing && state.dataSurface->Surface(BackSurfNum).ExtBoundCond == 0) {
    7972           0 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for a window
    7973             :                                     Real64 AbsBeamWinSh; // Glass layer beam solar absorptance of a shaded window
    7974           0 :                                     for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
    7975           0 :                                         AbsBeamWinSh = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).AbsBeamBackCoef(Lay));
    7976           0 :                                         state.dataSolarShading->SurfWinAbsBeam(Lay) =
    7977           0 :                                             General::InterpSw(SwitchFac, state.dataSolarShading->SurfWinAbsBeam(Lay), AbsBeamWinSh);
    7978             :                                     }
    7979             :                                     // Beam solar transmittance of a shaded window
    7980           0 :                                     Real64 TransBeamWinSh = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).TransSolBeamCoef);
    7981           0 :                                     TransBeamWin = General::InterpSw(SwitchFac, TransBeamWin, TransBeamWinSh);
    7982             :                                 }
    7983             : 
    7984             :                                 // Sum of interior beam absorbed by all glass layers of back window
    7985      285010 :                                 AbsBeamTotWin = 0.0;
    7986      710908 :                                 for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
    7987      425898 :                                     AbsBeamTotWin += state.dataSolarShading->SurfWinAbsBeam(Lay);
    7988      425898 :                                     state.dataSurface->SurfWinA(BackSurfNum, Lay) +=
    7989      851796 :                                         BOverlap * state.dataSolarShading->SurfWinAbsBeam(Lay) /
    7990      425898 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum)); //[-]
    7991             :                                 }
    7992             : 
    7993             :                                 // To BABSZon, add interior beam glass absorption and overall beam transmission for this back window
    7994      285010 :                                 BABSZone += BOverlap * (AbsBeamTotWin + TransBeamWin);
    7995             :                                 // Interior beam transmitted to adjacent zone through an interior back window (assumed unshaded);
    7996             :                                 // this beam radiation is categorized as diffuse radiation in the adjacent zone.
    7997      285010 :                                 int AdjSurfNum = state.dataSurface->Surface(BackSurfNum).ExtBoundCond;
    7998      285010 :                                 if (AdjSurfNum > 0) {
    7999         399 :                                     int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
    8000         399 :                                     state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) += BOverlap * TransBeamWin; //[m2]
    8001         399 :                                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) +=
    8002         399 :                                         BOverlap * TransBeamWin * state.dataEnvrn->BeamSolarRad; //[W]
    8003         399 :                                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(BackSurfNum) =
    8004         399 :                                         state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
    8005             :                                 }
    8006             :                             } // End of check if back surface is opaque or window
    8007     4478451 :                             state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) += BOverlap;
    8008     4478451 :                             state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(BackSurfNum) =
    8009     4478451 :                                 state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
    8010             :                         } // End of loop over back surfaces
    8011        5397 :                     } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    8012             :                         // For complex window calculation goes over outgoing basis directions for current state
    8013             :                         int CurCplxFenState =
    8014        5397 :                             state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState; // Current state for complex fenestration
    8015             :                         // Get construction number which keeps transmittance properties
    8016             :                         int IConst =
    8017        5397 :                             state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurCplxFenState).Konst; // Current surface construction number
    8018             :                                                                                                                // (it depends of state too)
    8019             :                         // Solar radiation from this window will be calculated only in case when this window is not scheduled surface gained
    8020        5397 :                         if (WindowScheduledSolarAbs(state, SurfNum, IConst) == 0) {
    8021             :                             // Current incoming direction number (Sun direction)
    8022        5341 :                             int IBm = state.dataBSDFWindow->ComplexWind(SurfNum)
    8023        5341 :                                           .Geom(CurCplxFenState)
    8024        5341 :                                           .SolBmIndex(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
    8025             :                             // Report variables for complex fenestration here
    8026        5341 :                             state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = IBm;
    8027        5341 :                             state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) =
    8028        5341 :                                 state.dataBSDFWindow->ComplexWind(SurfNum)
    8029        5341 :                                     .Geom(CurCplxFenState)
    8030        5341 :                                     .ThetaBm(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
    8031       10682 :                             state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = state.dataBSDFWindow->ComplexWind(SurfNum)
    8032        5341 :                                                                                     .Geom(CurCplxFenState)
    8033        5341 :                                                                                     .PhiBm(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
    8034             : 
    8035        5341 :                             int BaseSurf = state.dataSurface->Surface(SurfNum).BaseSurf; // Base surface number for current complex window
    8036             :                             // Get total number of back surfaces for current window (surface)
    8037             :                             // Note that it is organized by base surface
    8038        5341 :                             int NBkSurf = state.dataShadowComb->ShadowComb(BaseSurf).NumBackSurf;
    8039        5341 :                             if (!allocated(CFBoverlap)) {
    8040        5341 :                                 CFBoverlap.allocate(NBkSurf);
    8041             :                             }
    8042        5341 :                             if (!allocated(CFDirBoverlap)) {
    8043        5341 :                                 CFDirBoverlap.allocate(NBkSurf, state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).Trn.NBasis);
    8044             :                             }
    8045             : 
    8046        5341 :                             CFBoverlap = 0.0;
    8047             :                             // Calculate effects on all back surfaces for each of basis directions.  Each of basis directions from the back of the
    8048             :                             // window has to be considered as beam and therefore calcualte CFBoverlap for each of them
    8049      491498 :                             for (int CurTrnDir = 1; CurTrnDir <= state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).Trn.NBasis;
    8050             :                                  ++CurTrnDir) {
    8051      486157 :                                 Real64 CurLambda = state.dataBSDFWindow->ComplexWind(SurfNum)
    8052      486157 :                                                        .Geom(CurCplxFenState)
    8053      486157 :                                                        .Trn.Lamda(CurTrnDir); // Current lambda value in BSDF outgoing directions
    8054      486157 :                                 Real64 DirTrans = state.dataConstruction->Construct(IConst).BSDFInput.SolFrtTrans(
    8055      486157 :                                     IBm, CurTrnDir); // Current BSDF directional transmittance
    8056             :                                 // Now calculate effect of this direction on all back surfaces
    8057     3545346 :                                 for (int IBack = 1; IBack <= NBkSurf; ++IBack) {
    8058     3059189 :                                     CFDirBoverlap(IBack, CurTrnDir) =
    8059     3059189 :                                         state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).AOverlap(IBack, CurTrnDir) * DirTrans *
    8060     3059189 :                                         CurLambda * CosInc;
    8061     3059189 :                                     CFBoverlap(IBack) += CFDirBoverlap(IBack, CurTrnDir);
    8062             :                                 } // DO IBack = 1,MaxBkSurf
    8063             :                             }
    8064             : 
    8065             :                             // Summarizing results
    8066       38850 :                             for (int IBack = 1; IBack <= NBkSurf; ++IBack) {
    8067       33509 :                                 int BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(IBack);
    8068       33509 :                                 int ConstrNumBack = state.dataSurface->Surface(BackSurfaceNumber).Construction;
    8069             :                                 // Do not perform any calculation if surface is scheduled for incoming solar radiation
    8070       33509 :                                 int SurfSolIncPtr = SurfaceScheduledSolarInc(state, BackSurfaceNumber, ConstrNumBack);
    8071             : 
    8072       33509 :                                 if (SurfSolIncPtr == 0) {
    8073             :                                     // Surface hit is another complex fenestration
    8074       33509 :                                     if (state.dataSurface->SurfWinWindowModelType(BackSurfaceNumber) == WindowModel::BSDF) {
    8075             :                                         int CurBackState =
    8076        6804 :                                             state.dataSurface->SurfaceWindow(BackSurfaceNumber)
    8077        6804 :                                                 .ComplexFen.CurrentState; // Current state for back surface if that surface is complex fenestration
    8078             :                                         // Do not take into account this window if it is scheduled for surface gains
    8079        6804 :                                         if (WindowScheduledSolarAbs(state, BackSurfaceNumber, ConstrNumBack) == 0) {
    8080             :                                             // Calculate energy loss per each outgoing orientation
    8081      635208 :                                             for (int CurTrnDir = 1;
    8082      635208 :                                                  CurTrnDir <= state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).Trn.NBasis;
    8083             :                                                  ++CurTrnDir) {
    8084             :                                                 Real64 bestDot; // complex fenestration hits other complex fenestration, it is important to find
    8085             :                                                 // matching beam directions.  Beam leving one window will have certaing number for it's basis
    8086             :                                                 // while same beam reaching back surface will have different beam number.  This value is used
    8087             :                                                 // to keep best matching dot product for those directions
    8088             :                                                 Real64 curDot;   // temporary variable for current dot product
    8089             :                                                 int bestBackTrn; // Direction corresponding best dot product for back surface window
    8090    77061768 :                                                 for (int CurBackDir = 1;
    8091    77061768 :                                                      CurBackDir <= state.dataBSDFWindow->ComplexWind(BackSurfaceNumber).Geom(CurBackState).Trn.NBasis;
    8092             :                                                      ++CurBackDir) {
    8093             :                                                     // Purpose of this part is to find best match for outgoing beam number of window back surface
    8094             :                                                     // and incoming beam number of complex fenestration which this beam will hit on (back surface
    8095             :                                                     // again)
    8096    76433364 :                                                     curDot =
    8097    76433364 :                                                         dot(state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).sTrn(CurTrnDir),
    8098    76433364 :                                                             state.dataBSDFWindow->ComplexWind(BackSurfaceNumber).Geom(CurBackState).sTrn(CurBackDir));
    8099    76433364 :                                                     if (CurBackDir == 1) {
    8100      628404 :                                                         bestDot = curDot;
    8101      628404 :                                                         bestBackTrn = CurBackDir;
    8102             :                                                     } else {
    8103    75804960 :                                                         if (curDot < bestDot) {
    8104     8032227 :                                                             bestDot = curDot;
    8105     8032227 :                                                             bestBackTrn = CurBackDir;
    8106             :                                                         }
    8107             :                                                     }
    8108             :                                                 }
    8109             :                                                 // CurLambda = ComplexWind(BackSurfaceNumber)%Geom(CurBackState)%Trn%Lamda(CurTrnDir)
    8110             :                                                 // Add influence of this exact direction to what stays in the zone.  It is important to note that
    8111             :                                                 // this needs to be done for each outgoing direction
    8112     1256808 :                                                 BABSZone += CFDirBoverlap(IBack, CurTrnDir) * (1 - state.dataSurface->SurfaceWindow(BackSurfaceNumber)
    8113      628404 :                                                                                                        .ComplexFen.State(CurBackState)
    8114      628404 :                                                                                                        .IntegratedBkRefl(bestBackTrn));
    8115             : 
    8116             :                                                 // Absorptance from current back direction
    8117      628404 :                                                 int TotSolidLay = state.dataConstruction->Construct(ConstrNumBack).TotSolidLayers;
    8118     2625266 :                                                 for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    8119             :                                                     // IF (ALLOCATED(Construct(ConstrNumBack)%BSDFInput)) THEN
    8120             :                                                     // CFDirBoverlap is energy transmitted for current basis beam.  It is important to note that
    8121             :                                                     // AWinOverlap array needs to contain flux and not absorbed energy because later in the code
    8122             :                                                     // this will be multiplied with window area
    8123     1996862 :                                                     state.dataSurface->SurfWinACFOverlap(BackSurfaceNumber, Lay) +=
    8124     3993724 :                                                         state.dataConstruction->Construct(ConstrNumBack).BSDFInput.Layer(Lay).BkAbs(bestBackTrn, 1) *
    8125     3993724 :                                                         CFDirBoverlap(IBack, CurTrnDir) / state.dataSurface->Surface(BackSurfaceNumber).Area;
    8126             :                                                     // END IF
    8127             :                                                 }
    8128             : 
    8129             :                                                 // Interior beam transmitted to adjacent zone through an interior back window;
    8130             :                                                 // This beam radiation is categorized as diffuse radiation in the adjacent zone.
    8131             :                                                 // Note that this is done for each outgoing direction of exterior window
    8132      628404 :                                                 int AdjSurfNum = state.dataSurface->Surface(BackSurfaceNumber).ExtBoundCond;
    8133      628404 :                                                 if (AdjSurfNum > 0) {
    8134           0 :                                                     int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
    8135           0 :                                                     state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) +=
    8136           0 :                                                         CFDirBoverlap(IBack, CurTrnDir) * state.dataSurface->SurfaceWindow(BackSurfaceNumber)
    8137           0 :                                                                                               .ComplexFen.State(CurBackState)
    8138           0 :                                                                                               .IntegratedBkTrans(bestBackTrn);
    8139           0 :                                                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfaceNumber) +=
    8140           0 :                                                         CFDirBoverlap(IBack, CurTrnDir) *
    8141           0 :                                                         state.dataSurface->SurfaceWindow(BackSurfaceNumber)
    8142           0 :                                                             .ComplexFen.State(CurBackState)
    8143           0 :                                                             .IntegratedBkTrans(bestBackTrn) *
    8144           0 :                                                         state.dataEnvrn->BeamSolarRad; //[W]
    8145           0 :                                                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(BackSurfaceNumber) =
    8146           0 :                                                         state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfaceNumber) *
    8147           0 :                                                         state.dataGlobal->TimeStepZoneSec;
    8148             :                                                 }
    8149             :                                             }
    8150             :                                         }
    8151             :                                     } else {
    8152       26705 :                                         if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
    8153             :                                             // Do not take into account this window if it is scheduled for surface gains
    8154       26705 :                                             Real64 AbsIntSurf = state.dataConstruction->Construct(ConstrNumBack).InsideAbsorpSolar;
    8155       26705 :                                             state.dataSurface->SurfOpaqAI(BackSurfaceNumber) +=
    8156       26705 :                                                 CFBoverlap(IBack) * AbsIntSurf / state.dataSurface->Surface(BackSurfaceNumber).Area;
    8157       26705 :                                             BABSZone += CFBoverlap(IBack) * AbsIntSurf;
    8158             :                                         } else {
    8159             :                                             // Code for mixed windows goes here.  It is same as above code for "ordinary" windows.
    8160             :                                             // Try to do something which will not produce duplicate code.
    8161             :                                         }
    8162             :                                     }
    8163             :                                 }
    8164             :                             }
    8165             : 
    8166        5341 :                             if (allocated(CFBoverlap)) CFBoverlap.deallocate();
    8167        5341 :                             if (allocated(CFDirBoverlap)) CFDirBoverlap.deallocate();
    8168             :                         }
    8169             : 
    8170           0 :                     } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
    8171             : 
    8172           0 :                         for (int IBack = 1; IBack <= state.dataBSDFWindow->MaxBkSurf; ++IBack) {
    8173             :                             int BackSurfNum =
    8174           0 :                                 state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
    8175           0 :                             if (BackSurfNum == 0) break; // No more irradiated back surfaces for this exterior window
    8176           0 :                             if (state.dataSurface->SurfWinWindowModelType(IBack) != WindowModel::EQL) continue; // only EQL back window is allowed
    8177             : 
    8178           0 :                             int ConstrNumBack = state.dataSurface->Surface(BackSurfNum).Construction;
    8179           0 :                             int NBackGlass = state.dataConstruction->Construct(ConstrNumBack).TotGlassLayers;
    8180             :                             // Irradiated (overlap) area for this back surface, projected onto window plane
    8181             :                             // (includes effect of shadowing on exterior window)
    8182             : 
    8183             :                             Real64 AOverlap =
    8184           0 :                                 state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
    8185           0 :                             Real64 BOverlap = TBm * AOverlap * CosInc; //[m2]
    8186             : 
    8187           0 :                             if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
    8188             : 
    8189             :                                 // Back surface is opaque interior or exterior wall
    8190           0 :                                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(BackSurfNum);
    8191           0 :                                 state.dataSurface->SurfOpaqAI(BackSurfNum) +=
    8192           0 :                                     BOverlap * AbsIntSurf / state.dataSurface->Surface(BackSurfNum).Area; //[-]
    8193           0 :                                 BABSZone += BOverlap * AbsIntSurf;                                        //[m2]
    8194             : 
    8195             :                             } else {
    8196             : 
    8197             :                                 // Back surface is an interior or exterior window
    8198             :                                 // Note that exterior back windows with and without shades are treated as defined.
    8199             :                                 // Equivalent Layer window model has no distinction when treating windows with and
    8200             :                                 // without shades (interior, inbetween and exterior shades)
    8201             :                                 //  Note in equivalent layer window model if storm window exists it is defined as part of
    8202             :                                 //  window construction, hence it does not require a separate treatment
    8203           0 :                                 state.dataSolarShading->SurfWinAbsBeamEQL = 0.0;
    8204           0 :                                 Real64 TransBeamWin = 0.0; // Beam solar transmittance of a window
    8205             : 
    8206             :                                 // Interior beam absorptance of glass layers and beam transmittance of back exterior  &
    8207             :                                 // or interior window (treates windows with/without shades as defined) for this timestep
    8208             : 
    8209             :                                 // call the ASHWAT fenestration model for beam radiation here
    8210           0 :                                 WindowEquivalentLayer::CalcEQLOpticalProperty(
    8211           0 :                                     state, BackSurfNum, SolarArrays::BEAM, state.dataSolarShading->SurfWinAbsSolBeamBackEQL);
    8212           0 :                                 auto &CFS = state.dataWindowEquivLayer->CFS;
    8213           0 :                                 int EQLNum = state.dataConstruction->Construct(ConstrNumBack).EQLConsPtr;
    8214           0 :                                 state.dataSolarShading->SurfWinAbsBeamEQL({1, CFS(EQLNum).NL}) =
    8215           0 :                                     state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, {1, CFS(EQLNum).NL});
    8216             :                                 // get the interior beam transmitted through back exterior or interior EQL window
    8217           0 :                                 TransBeamWin = state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, CFS(EQLNum).NL + 1);
    8218             :                                 //   Absorbed by the interior shade layer of back exterior window
    8219           0 :                                 if (CFS(EQLNum).L(CFS(EQLNum).NL).LTYPE != LayerType::GLAZE) {
    8220           0 :                                     state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    8221           0 :                                         BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, CFS(EQLNum).NL) /
    8222           0 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    8223           0 :                                     BABSZone += BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, CFS(EQLNum).NL);
    8224             :                                 }
    8225             :                                 //   Absorbed by the exterior shade layer of back exterior window
    8226           0 :                                 if (CFS(EQLNum).L(1).LTYPE != LayerType::GLAZE) {
    8227           0 :                                     state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
    8228           0 :                                         BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, 1) /
    8229           0 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
    8230           0 :                                     BABSZone += BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, 1);
    8231             :                                 }
    8232             : 
    8233             :                                 // determine the number of glass layers
    8234           0 :                                 NBackGlass = 0;
    8235           0 :                                 for (int Lay = 1; Lay <= CFS(EQLNum).NL; ++Lay) {
    8236           0 :                                     if (CFS(EQLNum).L(Lay).LTYPE != LayerType::GLAZE) continue;
    8237           0 :                                     ++NBackGlass;
    8238             :                                 }
    8239           0 :                                 if (NBackGlass >= 2) {
    8240             :                                     // If the number of glass is greater than 2, in between glass shade can be present
    8241           0 :                                     for (int Lay = 2; Lay <= CFS(EQLNum).NL - 1; ++Lay) {
    8242           0 :                                         if (CFS(EQLNum).L(CFS(EQLNum).NL).LTYPE != LayerType::GLAZE) {
    8243             :                                             // if there is in between shade glass determine the shade absorptance
    8244           0 :                                             state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) +=
    8245           0 :                                                 BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, Lay) /
    8246           0 :                                                 state.dataSurface->Surface(BackSurfNum).Area;
    8247           0 :                                             BABSZone += BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, Lay);
    8248             :                                         }
    8249             :                                     }
    8250             :                                 }
    8251             :                                 // Sum of interior beam absorbed by all glass layers of back window
    8252           0 :                                 Real64 AbsBeamTotWin = 0.0; // Glass layer beam solar absorptance of a shaded window
    8253           0 :                                 for (int Lay = 1; Lay <= CFS(EQLNum).NL; ++Lay) {
    8254           0 :                                     AbsBeamTotWin += state.dataSolarShading->SurfWinAbsBeamEQL(Lay);
    8255           0 :                                     state.dataSurface->SurfWinA(BackSurfNum, Lay) +=
    8256           0 :                                         BOverlap * state.dataSolarShading->SurfWinAbsBeamEQL(Lay) /
    8257           0 :                                         (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum)); //[-]
    8258             :                                 }
    8259             : 
    8260             :                                 // To BABSZon, add interior beam glass absorption and overall beam transmission for this back window
    8261             : 
    8262           0 :                                 BABSZone += BOverlap * (AbsBeamTotWin + TransBeamWin);
    8263             : 
    8264             :                                 // Interior beam transmitted to adjacent zone through an interior back window (assumed unshaded);
    8265             :                                 // this beam radiation is categorized as diffuse radiation in the adjacent zone.
    8266             : 
    8267           0 :                                 int AdjSurfNum = state.dataSurface->Surface(BackSurfNum).ExtBoundCond;
    8268           0 :                                 if (AdjSurfNum > 0) {
    8269           0 :                                     int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
    8270           0 :                                     state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) += BOverlap * TransBeamWin; //[m2]
    8271           0 :                                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) +=
    8272           0 :                                         BOverlap * TransBeamWin * state.dataEnvrn->BeamSolarRad; //[W]
    8273           0 :                                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(BackSurfNum) =
    8274           0 :                                         state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
    8275             :                                 }
    8276             :                             } // End of check if back surface is opaque or window
    8277           0 :                             state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) += BOverlap;
    8278           0 :                             state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(BackSurfNum) =
    8279           0 :                                 state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
    8280             :                         } // End of loop over back surfaces
    8281             : 
    8282             :                         //  *****************************
    8283             : 
    8284             :                     }    // IF (SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: BSDF) THEN
    8285             :                 } else { // Simple interior solar distribution. All beam from exterior windows falls on floor;
    8286             :                     // some of this is absorbed/transmitted, rest is reflected to other surfaces.
    8287             : 
    8288    17702651 :                     for (int const FloorNum : thisEnclosure.SurfacePtr) {
    8289             :                         // In following, ISABSF is zero except for nominal floor surfaces
    8290    16509537 :                         if (state.dataSolarShading->SurfIntAbsFac(FloorNum) <= 0.0 || FloorNum == SurfNum) continue; // Keep only floor surfaces
    8291     1375112 :                         int const FlConstrNum = state.dataSurface->SurfActiveConstruction(FloorNum);
    8292             : 
    8293     1375112 :                         Real64 BTOTWinZone = TBm * SunLitFract * state.dataSurface->Surface(SurfNum).Area * CosInc * InOutProjSLFracMult; //[m2]
    8294     1375112 :                         Real64 AbsBeamTotWin = 0.0;
    8295             : 
    8296     1375112 :                         if (state.dataConstruction->Construct(FlConstrNum).TransDiff <= 0.0) {
    8297             :                             // Opaque surface
    8298     1375112 :                             state.dataSurface->SurfOpaqAI(FloorNum) +=
    8299     1375112 :                                 BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) / state.dataSurface->Surface(FloorNum).Area; //[-]
    8300             :                         } else {
    8301             :                             // Window
    8302             : 
    8303             :                             // Note that diffuse solar absorptance is used here for floor windows even though we're
    8304             :                             // dealing with incident beam radiation. This is because, for this simple interior distribution,
    8305             :                             // the beam radiation from exterior windows is assumed to be uniformly distributed over the
    8306             :                             // floor and so it makes no sense to use directional absorptances. Note also that floor windows
    8307             :                             // are assumed to not have blinds or shades in this calculation.
    8308             :                             // For the case of the floor window a complex fenestration (strange situation) the correct back
    8309             :                             // diffuse layer absorptions have already been put into the construction
    8310             : 
    8311           0 :                             for (int Lay = 1; Lay <= state.dataConstruction->Construct(FlConstrNum).TotGlassLayers; ++Lay) {
    8312           0 :                                 AbsBeamTotWin += state.dataConstruction->Construct(FlConstrNum).AbsDiffBack(Lay);
    8313             :                             }
    8314             :                             // In the following we have to multiply by the AbsDiffBack(Lay)/AbsBeamTotWin ratio to get the
    8315             :                             // layer by layer absorbed beam since ISABSF(FloorNum) is proportional to AbsBeamTotWin
    8316             :                             // (see ComputeIntSolarAbsorpFactors).
    8317             : 
    8318           0 :                             for (int Lay = 1; Lay <= state.dataConstruction->Construct(FlConstrNum).TotGlassLayers; ++Lay) {
    8319           0 :                                 state.dataSurface->SurfWinA(FloorNum, Lay) +=
    8320           0 :                                     state.dataConstruction->Construct(FlConstrNum).AbsDiffBack(Lay) / AbsBeamTotWin * BTOTWinZone *
    8321           0 :                                     state.dataSolarShading->SurfIntAbsFac(FloorNum) / state.dataSurface->Surface(FloorNum).Area; //[-]
    8322             :                             }
    8323             :                         }
    8324             : 
    8325     1375112 :                         BABSZone += BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum); //[m2]
    8326             : 
    8327     1375112 :                         int AdjSurfNum = state.dataSurface->Surface(FloorNum).ExtBoundCond;
    8328     1375112 :                         if (state.dataConstruction->Construct(FlConstrNum).TransDiff > 0.0 && AdjSurfNum > 0) {
    8329             : 
    8330             :                             // Window in an interior floor
    8331             : 
    8332           0 :                             int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
    8333             : 
    8334             :                             // Contribution (assumed diffuse) to adjacent zone of beam radiation passing
    8335             :                             // through this window
    8336           0 :                             state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) += BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) *
    8337           0 :                                                                                    state.dataConstruction->Construct(FlConstrNum).TransDiff /
    8338             :                                                                                    AbsBeamTotWin;
    8339             : 
    8340           0 :                             BABSZone += BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) *
    8341           0 :                                         state.dataConstruction->Construct(FlConstrNum).TransDiff / AbsBeamTotWin;
    8342             :                         }
    8343             : 
    8344             :                     } // End of loop over floor sections
    8345             :                 }     // End of check on complex vs. simple interior solar distribution
    8346             : 
    8347             :             } // End of sunlit fraction > 0 test
    8348             :         }     // End of first loop over surfaces in zone
    8349             : 
    8350     5843681 :         Real64 BABSZoneSSG = 0.0; // Beam radiation from exterior windows absorbed in a zone (only for scheduled surface gains)
    8351     5843681 :         Real64 BTOTZoneSSG = 0.0; // Solar entering a zone in case of scheduled surface gains
    8352     5844269 :         for (int iSSG = 1; iSSG <= state.dataSurface->TotSurfIncSolSSG; ++iSSG) {
    8353         588 :             int SurfNum = state.dataSurface->SurfIncSolSSG(iSSG).SurfPtr;
    8354             :             // do calculation only if construction number match.
    8355         588 :             if (state.dataSurface->SurfIncSolSSG(iSSG).ConstrPtr == state.dataSurface->Surface(SurfNum).Construction) {
    8356         588 :                 if (state.dataSurface->Surface(SurfNum).SolarEnclIndex == enclosureNum) {
    8357         588 :                     Real64 AbsIntSurf = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).InsideAbsorpSolar;
    8358             :                     // SolarIntoZone = GetCurrentScheduleValue(SurfIncSolSSG(iSSG)%SchedPtr) * Surface(SurfNum)%Area
    8359         588 :                     Real64 SolarIntoZone = GetCurrentScheduleValue(
    8360        1176 :                         state, state.dataSurface->SurfIncSolSSG(iSSG).SchedPtr); // Solar radiation into zone to current surface
    8361         588 :                     state.dataSurface->SurfOpaqAI(SurfNum) = SolarIntoZone * AbsIntSurf;
    8362         588 :                     BABSZoneSSG += state.dataSurface->SurfOpaqAI(SurfNum) * state.dataSurface->Surface(SurfNum).Area;
    8363         588 :                     BTOTZoneSSG += SolarIntoZone * state.dataSurface->Surface(SurfNum).Area;
    8364             :                 }
    8365             :             }
    8366             :         }
    8367     5843681 :         state.dataHeatBal->EnclSolDBSSG(enclosureNum) = BTOTZoneSSG - BABSZoneSSG;
    8368     5843681 :         state.dataHeatBal->EnclSolDB(enclosureNum) = BTOTZone - BABSZone;
    8369             : 
    8370     5843681 :         if (state.dataHeatBal->EnclSolDB(enclosureNum) < 0.0) {
    8371       13846 :             state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
    8372             :         }
    8373             : 
    8374             :         // Variables for reporting
    8375    56358052 :         for (int const SurfNum : thisEnclosure.SurfacePtr) {
    8376    50514371 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    8377    50514371 :             Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    8378    50514371 :             Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    8379    50514371 :             Real64 currGndSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    8380    50514371 :             if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) {
    8381    33277199 :                 state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) *= currBeamSolarRad;
    8382    33277199 :                 state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfNum) =
    8383    33277199 :                     state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8384    33277199 :                 state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) =
    8385    66554398 :                     state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) /
    8386    33277199 :                     (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum));
    8387             :             } else { // Simple interior solar distribution. All beam falls on floor.
    8388    17237172 :                 if (state.dataSolarShading->SurfIntAbsFac(SurfNum) > 0.0 && state.dataSurface->Surface(SurfNum).HeatTransSurf) {
    8389     3085832 :                     if (thisEnclosure.FloorArea > 0.0) {
    8390             :                         // spread onto all floor surfaces, these may or may not be called "floor"
    8391     3085832 :                         state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = currBeamSolarRad * BTOTZone / thisEnclosure.FloorArea;
    8392           0 :                     } else if (thisEnclosure.TotalSurfArea > 0.0) {
    8393             :                         // spread onto all interior surfaces
    8394           0 :                         state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = currBeamSolarRad * BTOTZone / thisEnclosure.TotalSurfArea;
    8395             :                     } else { // divide be zero otherwise
    8396           0 :                         state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
    8397             :                     }
    8398             :                 }
    8399    17237172 :                 state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) =
    8400    17237172 :                     state.dataSurface->Surface(SurfNum).Area * state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum);
    8401    17237172 :                 state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfNum) =
    8402    17237172 :                     state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8403             :             }
    8404    93903809 :             if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window ||
    8405    43389438 :                 state.dataSurface->Surface(SurfNum).Class == SurfaceClass::TDD_Dome) {
    8406             : 
    8407     7126165 :                 state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfNum);
    8408     7126165 :                 state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum);
    8409             : 
    8410     7134675 :                 if ((state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) ||
    8411        8510 :                     (state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCondModeledExt)) {
    8412             : 
    8413     7117655 :                     WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    8414     7117655 :                     int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum);
    8415     7117655 :                     int OutShelfSurf = 0;
    8416     7117655 :                     if (ShelfNum > 0) { // Outside daylighting shelf
    8417         616 :                         OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf;
    8418             :                     }
    8419             : 
    8420             :                     // This lookup may be avoid if this 2nd surf loop can be combined with the 1st
    8421     7117655 :                     if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    8422        1232 :                         int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8423        1232 :                         int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
    8424        1232 :                         Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    8425             :                         // Exterior diffuse solar incident on window (W/m2)
    8426        1232 :                         Real64 DifSolarInc = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) +
    8427        1232 :                                              currGndSolarRad * state.dataSurface->Surface(SurfNum2).ViewFactorGround;
    8428             :                         // Exterior diffuse sky solar transmitted by TDD (W/m2)
    8429        1232 :                         Real64 SkySolarTrans = currDifSolarRad * TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarAniso) *
    8430        1232 :                                                state.dataSolarShading->SurfAnisoSkyMult(SurfNum2);
    8431             :                         // Exterior diffuse ground solar transmitted by TDD (W/m2)
    8432        1232 :                         Real64 GndSolarTrans = currGndSolarRad * state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso *
    8433        1232 :                                                state.dataSurface->Surface(SurfNum2).ViewFactorGround;
    8434             : 
    8435        1232 :                         state.dataSurface->SurfWinBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmSolar(SurfNum);
    8436        1232 :                         state.dataSurface->SurfWinDifSolar(SurfNum) =
    8437        1232 :                             SkySolarTrans * state.dataSurface->Surface(SurfNum).Area + GndSolarTrans * state.dataSurface->Surface(SurfNum).Area;
    8438        1232 :                         state.dataSurface->SurfWinBmSolarEnergy(SurfNum) =
    8439        1232 :                             state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8440        1232 :                         state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
    8441        1232 :                             state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8442             : 
    8443        1232 :                         state.dataSurface->SurfWinTransSolar(SurfNum) =
    8444        1232 :                             state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum); //[W]
    8445        1232 :                         state.dataSurface->SurfWinTransSolarEnergy(SurfNum) =
    8446        1232 :                             state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8447             : 
    8448        1232 :                         state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransmittedSolar = state.dataSurface->SurfWinTransSolar(SurfNum);
    8449             :                         // TDDPipe(PipeNum)%TransSolBeam = TBmBm ! Reported above
    8450        1232 :                         if (DifSolarInc > 0) {
    8451        1232 :                             state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolDiff = (SkySolarTrans + GndSolarTrans) / DifSolarInc;
    8452             :                         } else {
    8453           0 :                             state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolDiff = 0.0;
    8454             :                         }
    8455             : 
    8456     7116423 :                     } else if (OutShelfSurf > 0) { // Outside daylighting shelf
    8457             :                         Real64 ShelfSolarRad =
    8458         616 :                             (currBeamSolarRad *
    8459        1232 :                                  state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
    8460        1232 :                                  state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
    8461         616 :                              currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
    8462         616 :                             state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
    8463             : 
    8464        1232 :                         Real64 DifSolarInc = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum) +
    8465         616 :                                              currGndSolarRad * state.dataSurface->Surface(SurfNum).ViewFactorGround +
    8466         616 :                                              ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
    8467             : 
    8468         616 :                         state.dataSurface->SurfWinBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmSolar(SurfNum);
    8469         616 :                         state.dataSurface->SurfWinDifSolar(SurfNum) = DifSolarInc * state.dataSolarShading->SurfWinTransDifSolar(SurfNum);
    8470         616 :                         state.dataSurface->SurfWinBmSolarEnergy(SurfNum) =
    8471         616 :                             state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8472         616 :                         state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
    8473         616 :                             state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8474             : 
    8475         616 :                         state.dataSurface->SurfWinTransSolar(SurfNum) =
    8476         616 :                             state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum); //[W]
    8477         616 :                         state.dataSurface->SurfWinTransSolarEnergy(SurfNum) =
    8478         616 :                             state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8479             : 
    8480             :                     } else { // Regular window
    8481     7115807 :                         Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum);
    8482     7115807 :                         Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum);
    8483     7115807 :                         Real64 DifSolarInc = SkySolarInc + GndSolarInc;
    8484     7115807 :                         state.dataSurface->SurfWinBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmSolar(SurfNum);
    8485             :                         // Note: for complex fenestration, SurfWinTransDifSolar has previously been defined using the effective
    8486             :                         // transmittance for sky and ground diffuse radiation (including beam radiation reflected from the ground)
    8487             :                         // so these calculations should be correct
    8488     7115807 :                         state.dataSurface->SurfWinDifSolar(SurfNum) = DifSolarInc * state.dataSolarShading->SurfWinTransDifSolar(SurfNum);
    8489     7115807 :                         state.dataSurface->SurfWinBmSolarEnergy(SurfNum) =
    8490     7115807 :                             state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8491     7115807 :                         state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
    8492     7115807 :                             state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8493     7115807 :                         if (ANY_BLIND(ShadeFlag)) {
    8494       18094 :                             if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
    8495             :                                 DataWindowEquivalentLayer::Orientation::Horizontal) {
    8496       36188 :                                 state.dataSurface->SurfWinDifSolar(SurfNum) = SkySolarInc * state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) +
    8497       18094 :                                                                               GndSolarInc * state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum);
    8498       18094 :                                 state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
    8499       18094 :                                     state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8500             :                             }
    8501             :                         }
    8502             : 
    8503     7115807 :                         state.dataSurface->SurfWinTransSolar(SurfNum) =
    8504     7115807 :                             state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum); //[W]
    8505     7115807 :                         state.dataSurface->SurfWinTransSolarEnergy(SurfNum) =
    8506     7115807 :                             state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8507             :                     }
    8508             : 
    8509             :                     // added TH 12/9/2009, CR 7907 & 7809
    8510     7117655 :                     state.dataSurface->SurfWinBmBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum);
    8511             : 
    8512     7117655 :                     state.dataSurface->SurfWinBmDifSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum);
    8513     7117655 :                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) =
    8514     7117655 :                         state.dataSurface->SurfWinBmBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8515     7117655 :                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) =
    8516     7117655 :                         state.dataSurface->SurfWinBmDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8517             : 
    8518             :                     // Solar not added by TDD:DOME; added to zone via TDD:DIFFUSER
    8519     7117655 :                     if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome) {
    8520     7116423 :                         state.dataHeatBal->ZoneTransSolar(enclosureNum) += state.dataSurface->SurfWinTransSolar(SurfNum); //[W]
    8521     7116423 :                         state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum) =
    8522     7116423 :                             state.dataHeatBal->ZoneTransSolar(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8523     7116423 :                         state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinBmSolar(SurfNum);
    8524     7116423 :                         state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinDifSolar(SurfNum);
    8525     7116423 :                         state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum) =
    8526     7116423 :                             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8527     7116423 :                         state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum) =
    8528     7116423 :                             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8529             :                     }
    8530             :                 }
    8531             :             }
    8532             :         } // End of second loop over surfaces in zone
    8533             : 
    8534             :     } // End of first zone loop
    8535             : 
    8536             :     // Add interior window contribution to EnclSolDB
    8537             : 
    8538     6664958 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    8539     5843681 :         state.dataHeatBal->EnclSolDB(enclosureNum) += state.dataHeatBal->EnclSolDBIntWin(enclosureNum);
    8540     5843681 :         state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) = state.dataHeatBal->EnclSolDBIntWin(enclosureNum) * state.dataEnvrn->BeamSolarRad;
    8541     5843681 :         state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclosureNum) =
    8542     5843681 :             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8543             :     }
    8544             : 
    8545             :     // RJH - Calculate initial distribution of diffuse solar transmitted by exterior windows into each zone
    8546             :     //       to all interior surfaces in the zone
    8547             :     //       Includes subsequent transmittance of diffuse solar to adjacent zones through interior windows
    8548      821277 :     CalcWinTransDifSolInitialDistribution(state);
    8549      821277 : }
    8550         826 : void CalcAbsorbedOnExteriorOpaqueSurfaces(EnergyPlusData &state)
    8551             : {
    8552             :     // SUBROUTINE INFORMATION:
    8553             :     //       AUTHOR         Simon Vidanovic
    8554             :     //       DATE WRITTEN   May 2017
    8555             :     //       MODIFIED       na
    8556             :     //       RE-ENGINEERED  na
    8557             : 
    8558             :     // PURPOSE OF THIS SUBROUTINE:
    8559             :     // Calculates solar energy absorbed on exterior opaque surfaces
    8560             : 
    8561        1652 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    8562        1652 :         for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
    8563         826 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    8564        6608 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    8565             :                 // TH added 3/24/2010 while debugging CR 7872
    8566        5782 :                 if (!state.dataSurface->Surface(SurfNum).ExtSolar && state.dataSurface->SurfWinOriginalClass(SurfNum) != SurfaceClass::TDD_Diffuser)
    8567        4130 :                     continue;
    8568        1652 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    8569        1652 :                 int SurfNum2 = SurfNum;
    8570        1652 :                 if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    8571           0 :                     int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8572           0 :                     SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
    8573             :                 }
    8574        1652 :                 Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    8575        1652 :                 Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    8576             : 
    8577             :                 //-------------------------------------------------------------------------
    8578             :                 // EXTERIOR BEAM SOLAR RADIATION ABSORBED ON THE OUTSIDE OF OPAQUE SURFACES
    8579             :                 //-------------------------------------------------------------------------
    8580             : 
    8581        1652 :                 if (SunLitFract > 0.0 && state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) {
    8582         490 :                     state.dataSurface->SurfOpaqAO(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar * CosInc * SunLitFract;
    8583             : 
    8584             :                     // Note: movable insulation, if present, is accounted for in subr. InitIntSolarDistribution,
    8585             :                     // where SurfQRadSWOutMvIns is calculated from SurfOpaqQRadSWOutAbs and insulation solar absorptance
    8586             :                 }
    8587             :             }
    8588             :         }
    8589             :     }
    8590         826 : }
    8591             : 
    8592         826 : void CalcInteriorSolarDistributionWCESimple(EnergyPlusData &state)
    8593             : {
    8594             : 
    8595             :     // SUBROUTINE INFORMATION:
    8596             :     //       AUTHOR         Simon Vidanovic
    8597             :     //       DATE WRITTEN   May 2017
    8598             : 
    8599             :     // PURPOSE OF THIS SUBROUTINE:
    8600             :     // For a time step, calculates solar radiation absorbed by window layers, sky and diffuse solar
    8601             :     // gain into zone from exterior window, beam solar on exterior window transmitted as beam and/or diffuse
    8602             :     // and interior beam from exterior window that is absorbed/transmitted by back surfaces
    8603             : 
    8604             :     using ScheduleManager::GetCurrentScheduleValue;
    8605             :     using namespace MultiLayerOptics;
    8606             : 
    8607        1652 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    8608        1652 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8609         826 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    8610         826 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    8611         826 :             int const lastSurf = thisSpace.HTSurfaceLast;
    8612        6608 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8613        5782 :                 state.dataSurface->SurfOpaqAI(surfNum) = 0.0;
    8614        5782 :                 state.dataSurface->SurfOpaqAO(surfNum) = 0.0;
    8615             :             }
    8616             :         }
    8617             :     }
    8618             : 
    8619        1652 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    8620             : 
    8621         826 :         Real64 BABSZone = 0;
    8622         826 :         Real64 BTOTZone = 0;
    8623         826 :         state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
    8624         826 :         state.dataHeatBal->EnclSolDBIntWin(enclosureNum) = 0.0;
    8625         826 :         state.dataHeatBal->ZoneTransSolar(enclosureNum) = 0;
    8626         826 :         state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum) = 0;
    8627         826 :         state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) = 0;
    8628         826 :         state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) = 0;
    8629         826 :         state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum) = 0;
    8630         826 :         state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum) = 0;
    8631         826 :         auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
    8632             : 
    8633        6608 :         for (int const SurfNum : thisEnclosure.SurfacePtr) {
    8634        5782 :             if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Window) continue;
    8635         826 :             int SurfNum2 = 0;
    8636         826 :             if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
    8637           0 :                 int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8638           0 :                 SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
    8639             :             } else {
    8640         826 :                 SurfNum2 = SurfNum;
    8641             :             }
    8642         826 :             auto &window = state.dataSurface->SurfaceWindow(SurfNum2);
    8643         826 :             Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2); // Note: surfnum 2
    8644         826 :             Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    8645             : 
    8646         826 :             std::pair<Real64, Real64> incomingAngle = getSunWCEAngles(state, SurfNum2, BSDFDirection::Incoming);
    8647         826 :             Real64 Theta = incomingAngle.first;
    8648         826 :             Real64 Phi = incomingAngle.second;
    8649             : 
    8650         826 :             int ConstrNum = state.dataSurface->Surface(SurfNum2).Construction;
    8651         826 :             if (state.dataSurface->Surface(SurfNum2).activeShadedConstruction > 0)
    8652         826 :                 ConstrNum = state.dataSurface->Surface(SurfNum2).activeShadedConstruction;
    8653        1652 :             auto aLayer = CWindowConstructionsSimplified::instance().getEquivalentLayer(state, WavelengthRange::Solar, ConstrNum);
    8654             : 
    8655             :             ///////////////////////////////////////////////
    8656             :             // Solar absorbed in window layers
    8657             :             ///////////////////////////////////////////////
    8658         826 :             if (state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2) > 0.0) {
    8659         490 :                 auto numOfLayers = aLayer->getNumOfLayers();
    8660         490 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    8661           0 :                     auto CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
    8662           0 :                     auto &cplxState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState);
    8663           0 :                     for (size_t Lay = 1; Lay <= numOfLayers; ++Lay) {
    8664             :                         // Simon: Imporant note about this equation is to use BeamSolarRad and not SurfQRadSWOutIncident
    8665             :                         // is becuase BeamSolarRad is direct normal radiation (looking at the Sun) while SurfRadSWOutIncident
    8666             :                         // is normal to window incidence. Since BSDF coefficients are taking into account angle of incidence,
    8667             :                         // BeamSolarRad should be used in this case
    8668           0 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    8669           0 :                             cplxState.WinSkyFtAbs(Lay) * state.dataSurface->SurfSkySolarInc(SurfNum2) +
    8670           0 :                             cplxState.WinSkyGndAbs(Lay) * state.dataSurface->SurfGndSolarInc(SurfNum2) +
    8671           0 :                             state.dataSurface->SurfWinA(SurfNum, Lay) * state.dataEnvrn->BeamSolarRad +
    8672           0 :                             state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * state.dataEnvrn->BeamSolarRad;
    8673           0 :                         state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    8674           0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * state.dataSurface->Surface(SurfNum).Area;
    8675           0 :                         state.dataSurface->SurfWinADiffFront(SurfNum, Lay) = cplxState.WinSkyGndAbs(Lay);
    8676             :                     }
    8677             :                 } else {
    8678        1470 :                     for (size_t Lay = 1; Lay <= numOfLayers; ++Lay) {
    8679         980 :                         auto AbWinBeam = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Direct, Theta, Phi) *
    8680         980 :                                          window.OutProjSLFracMult(state.dataGlobal->HourOfDay);
    8681         980 :                         auto AbWinDiffFront = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Diffuse, Theta, Phi);
    8682             :                         //                        auto AbWinDiffBack = aLayer->getAbsorptanceLayer(Lay, Side::Back, ScatteringSimple::Diffuse,
    8683             :                         //                        Theta, Phi);
    8684             : 
    8685             :                         // Simon: This should not be multiplied with cosine of incident angle. This however gives same
    8686             :                         // results as BSDF and Winkelmann models.
    8687         980 :                         state.dataSurface->SurfWinA(SurfNum, Lay) =
    8688        1960 :                             AbWinBeam * CosInc * SunLitFract *
    8689         980 :                             state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay);
    8690         980 :                         state.dataSurface->SurfWinADiffFront(SurfNum, Lay) = AbWinDiffFront;
    8691             : 
    8692             :                         // Simon: Same not as for BSDF. Normal solar radiation should be taken here because angle of
    8693             :                         // incidence is already taken into account
    8694         980 :                         auto absBeam = state.dataSurface->SurfWinA(SurfNum, Lay) * state.dataEnvrn->BeamSolarRad;
    8695         980 :                         auto absDiff = state.dataSurface->SurfWinADiffFront(SurfNum, Lay) *
    8696         980 :                                        (state.dataSurface->SurfSkySolarInc(SurfNum2) + state.dataSurface->SurfGndSolarInc(SurfNum2));
    8697         980 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = (absBeam + absDiff);
    8698         980 :                         state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    8699         980 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * state.dataSurface->Surface(SurfNum).Area;
    8700             :                     }
    8701             :                 }
    8702             :             }
    8703             : 
    8704             :             ////////////////////////////////////////////////////////////////////
    8705             :             // SKY AND GROUND DIFFUSE SOLAR GAIN INTO ZONE FROM EXTERIOR WINDOW
    8706             :             ////////////////////////////////////////////////////////////////////
    8707         826 :             const auto minLambda{0.3};
    8708         826 :             const auto maxLambda{2.5};
    8709             :             const Real64 Tdiff =
    8710         826 :                 aLayer->getPropertySimple(minLambda, maxLambda, PropertySimple::T, Side::Front, Scattering::DiffuseDiffuse, Theta, Phi);
    8711         826 :             state.dataConstruction->Construct(ConstrNum).TransDiff = Tdiff;
    8712         826 :             Real64 EnclSolDSWin = state.dataSurface->SurfSkySolarInc(SurfNum2) * Tdiff * state.dataSurface->Surface(SurfNum2).Area;
    8713         826 :             if ((state.dataEnvrn->DifSolarRad != 0)) {
    8714         826 :                 EnclSolDSWin /= state.dataEnvrn->DifSolarRad;
    8715             :             } else {
    8716           0 :                 EnclSolDSWin /= 1e-8;
    8717             :             }
    8718             : 
    8719         826 :             Real64 EnclSolDGWin = state.dataSurface->SurfGndSolarInc(SurfNum2) * Tdiff * state.dataSurface->Surface(SurfNum2).Area;
    8720         826 :             (state.dataEnvrn->GndSolarRad != 0) ? EnclSolDGWin /= state.dataEnvrn->GndSolarRad : EnclSolDGWin /= 1e-8;
    8721             : 
    8722             :             ////////////////////////////////////////////////////////////////////
    8723             :             // BEAM SOLAR ON EXTERIOR WINDOW TRANSMITTED AS BEAM AND/OR DIFFUSE
    8724             :             ////////////////////////////////////////////////////////////////////
    8725         826 :             Real64 TBmBm = aLayer->getPropertySimple(minLambda, maxLambda, PropertySimple::T, Side::Front, Scattering::DirectDirect, Theta, Phi);
    8726         826 :             Real64 TBmDif = aLayer->getPropertySimple(minLambda, maxLambda, PropertySimple::T, Side::Front, Scattering::DirectDiffuse, Theta, Phi);
    8727             :             Real64 SurfWinTransBmBmSolar =
    8728         826 :                 TBmBm * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * window.InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    8729             :             Real64 SurfWinTransBmDifSolar =
    8730         826 :                 TBmDif * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * window.InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    8731         826 :             BTOTZone += SurfWinTransBmBmSolar + SurfWinTransBmDifSolar;
    8732             : 
    8733         826 :             Real64 DifSolarRadiation = state.dataSurface->SurfSkySolarInc(SurfNum2) + state.dataSurface->SurfGndSolarInc(SurfNum2);
    8734         826 :             state.dataSurface->SurfWinBmSolar(SurfNum) =
    8735         826 :                 state.dataEnvrn->BeamSolarRad * (TBmBm + TBmDif) * state.dataSurface->Surface(SurfNum).Area * CosInc;
    8736         826 :             state.dataSurface->SurfWinDifSolar(SurfNum) = DifSolarRadiation * Tdiff * state.dataSurface->Surface(SurfNum).Area;
    8737         826 :             state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8738         826 :             state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8739         826 :             state.dataSurface->SurfWinTransSolar(SurfNum) = state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum);
    8740         826 :             state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    8741             : 
    8742             :             // Add beam solar absorbed by outside reveal to outside of window's base surface.
    8743             :             // Add beam solar absorbed by inside reveal to inside of window's base surface.
    8744             :             // This ignores 2-D heat transfer effects.
    8745         826 :             int BaseSurfNum = state.dataSurface->Surface(SurfNum).BaseSurf;
    8746         826 :             state.dataSurface->SurfOpaqAI(BaseSurfNum) =
    8747         826 :                 state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum2) / state.dataSurface->Surface(BaseSurfNum).Area;
    8748         826 :             state.dataSurface->SurfOpaqAO(BaseSurfNum) =
    8749         826 :                 state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum2) / state.dataSurface->Surface(BaseSurfNum).Area;
    8750             : 
    8751             :             ////////////////////////////////////////////////////////////////////
    8752             :             // BEAM SOLAR ON EXTERIOR WINDOW TRANSMITTED AS BEAM AND/OR DIFFUSE
    8753             :             ////////////////////////////////////////////////////////////////////
    8754         826 :             Real64 TBm = TBmBm;
    8755             :             // Correction for beam absorbed by inside reveal
    8756             :             Real64 TBmDenom =
    8757         826 :                 SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * window.InOutProjSLFracMult(state.dataGlobal->HourOfDay);
    8758         826 :             if (TBmDenom != 0.0) { // when =0.0, no correction
    8759         490 :                 TBm -= state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) / TBmDenom;
    8760             :             }
    8761             : 
    8762         826 :             TBm = max(0.0, TBm);
    8763             : 
    8764         826 :             int NumOfBackSurf = state.dataShadowComb->ShadowComb(BaseSurfNum).NumBackSurf;
    8765             : 
    8766         826 :             if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) {
    8767        1792 :                 for (int IBack = 1; IBack <= NumOfBackSurf; ++IBack) {
    8768             : 
    8769             :                     int const BackSurfNum =
    8770        1792 :                         state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
    8771             : 
    8772        1792 :                     if (BackSurfNum == 0) break; // No more irradiated back surfaces for this exterior window
    8773         966 :                     int ConstrNumBack = state.dataSurface->Surface(BackSurfNum).Construction;
    8774             :                     // NBackGlass = Construct( ConstrNumBack ).TotGlassLayers;
    8775             :                     // Irradiated (overlap) area for this back surface, projected onto window plane
    8776             :                     // (includes effect of shadowing on exterior window)
    8777         966 :                     Real64 AOverlap = state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
    8778         966 :                     Real64 BOverlap = TBm * AOverlap * CosInc; //[m2]
    8779             : 
    8780         966 :                     if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
    8781             :                         // Back surface is opaque interior or exterior wall
    8782             : 
    8783         966 :                         Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(BackSurfNum);
    8784         966 :                         state.dataSurface->SurfOpaqAI(BackSurfNum) += BOverlap * AbsIntSurf / state.dataSurface->Surface(BackSurfNum).Area; //[-]
    8785         966 :                         BABSZone += BOverlap * AbsIntSurf;                                                                                  //[m2]
    8786             :                     }
    8787             :                 }
    8788             :             } else {
    8789           0 :                 for (int const FloorNum : thisEnclosure.SurfacePtr) {
    8790             :                     // In following, ISABSF is zero except for nominal floor surfaces
    8791           0 :                     if (!state.dataSurface->Surface(FloorNum).HeatTransSurf) continue;
    8792           0 :                     if (state.dataSolarShading->SurfIntAbsFac(FloorNum) <= 0.0 || FloorNum == SurfNum) continue; // Keep only floor surfaces
    8793             : 
    8794           0 :                     Real64 BTOTWinZone = TBm * SunLitFract * state.dataSurface->Surface(SurfNum).Area * CosInc *
    8795           0 :                                          window.InOutProjSLFracMult(state.dataGlobal->HourOfDay); //[m2]
    8796             : 
    8797           0 :                     if (state.dataConstruction->Construct(state.dataSurface->Surface(FloorNum).Construction).TransDiff <= 0.0) {
    8798             :                         // Opaque surface
    8799           0 :                         state.dataSurface->SurfOpaqAI(FloorNum) +=
    8800           0 :                             BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) / state.dataSurface->Surface(FloorNum).Area; //[-]
    8801             :                     }
    8802             :                 }
    8803             :             }
    8804         826 :             state.dataHeatBal->ZoneTransSolar(enclosureNum) += state.dataSurface->SurfWinTransSolar(SurfNum); //[W]
    8805         826 :             state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum) =
    8806         826 :                 state.dataHeatBal->ZoneTransSolar(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8807         826 :             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinBmSolar(SurfNum);
    8808         826 :             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinDifSolar(SurfNum);
    8809         826 :             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum) =
    8810         826 :                 state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8811         826 :             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum) =
    8812         826 :                 state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
    8813             :         }
    8814         826 :         state.dataHeatBal->EnclSolDB(enclosureNum) = BTOTZone - BABSZone;
    8815             :     }
    8816         826 : }
    8817             : 
    8818       36688 : int WindowScheduledSolarAbs(EnergyPlusData &state,
    8819             :                             int const SurfNum, // Surface number
    8820             :                             int const ConstNum // Construction number
    8821             : )
    8822             : {
    8823             :     // SUBROUTINE INFORMATION:
    8824             :     //       AUTHOR         Simon Vidanovic
    8825             :     //       DATE WRITTEN   June 2013
    8826             : 
    8827             :     // PURPOSE OF THIS SUBROUTINE:
    8828             :     // Returns scheduled surface gain object for given surface-construction combination
    8829             : 
    8830             :     // Return value
    8831             :     int WindowScheduledSolarAbs;
    8832             : 
    8833       36688 :     WindowScheduledSolarAbs = 0;
    8834             : 
    8835       36688 :     for (int i = 1; i <= state.dataSurface->TotFenLayAbsSSG; ++i) {
    8836         253 :         if ((state.dataSurface->FenLayAbsSSG(i).SurfPtr == SurfNum) && (state.dataSurface->FenLayAbsSSG(i).ConstrPtr == ConstNum)) {
    8837         253 :             WindowScheduledSolarAbs = i;
    8838         253 :             return WindowScheduledSolarAbs;
    8839             :         }
    8840             :     }
    8841             : 
    8842       36435 :     return WindowScheduledSolarAbs;
    8843             : }
    8844             : 
    8845    43433138 : int SurfaceScheduledSolarInc(EnergyPlusData &state,
    8846             :                              int const SurfNum, // Surface number
    8847             :                              int const ConstNum // Construction number
    8848             : )
    8849             : {
    8850             :     // SUBROUTINE INFORMATION:
    8851             :     //       AUTHOR         Simon Vidanovic
    8852             :     //       DATE WRITTEN   June 2013
    8853             : 
    8854             :     // PURPOSE OF THIS SUBROUTINE:
    8855             :     // Returns scheduled surface gain pointer for given surface-construction combination
    8856             : 
    8857             :     // Return value
    8858             :     int SurfaceScheduledSolarInc;
    8859             : 
    8860    43433138 :     SurfaceScheduledSolarInc = 0;
    8861             : 
    8862    43434959 :     for (int i = 1; i <= state.dataSurface->TotSurfIncSolSSG; ++i) {
    8863        2415 :         if ((state.dataSurface->SurfIncSolSSG(i).SurfPtr == SurfNum) && (state.dataSurface->SurfIncSolSSG(i).ConstrPtr == ConstNum)) {
    8864         594 :             SurfaceScheduledSolarInc = i;
    8865         594 :             return SurfaceScheduledSolarInc;
    8866             :         }
    8867             :     }
    8868             : 
    8869    43432544 :     return SurfaceScheduledSolarInc;
    8870             : }
    8871             : 
    8872       31444 : void PerformSolarCalculations(EnergyPlusData &state)
    8873             : {
    8874             : 
    8875             :     // SUBROUTINE INFORMATION:
    8876             :     //       AUTHOR         Linda K. Lawrie
    8877             :     //       DATE WRITTEN   July 1999
    8878             :     //       MODIFIED       Sept 2003, FCW: add calls to CalcBeamSolDiffuseReflFactors and
    8879             :     //                       CalcBeamSolSpecularReflFactors
    8880             :     //                      Jan 2004, FCW: call CalcDayltgCoefficients if storm window status on
    8881             :     //                       any window has changed
    8882             :     //       RE-ENGINEERED  na
    8883             : 
    8884             :     // PURPOSE OF THIS SUBROUTINE:
    8885             :     // This subroutine determines if new solar/shading calculations need
    8886             :     // to be performed and calls the proper routines to do the job.
    8887             : 
    8888             :     // METHODOLOGY EMPLOYED:
    8889             :     // Users are allowed to enter a value for number of days in each period that
    8890             :     // will be used for calculating solar.  (Later, this could be more complicated as
    8891             :     // in allowing a number of days in a month or something).  Using this value or the
    8892             :     // default (20 days) if nothing is entered by the user, the routine will use the
    8893             :     // number of days left to determine if a new set of calculations should be done.
    8894             :     // The calculations use the average of "equation of time" and "solar declination"
    8895             :     // to perform the calculations.
    8896             : 
    8897             :     // REFERENCES:
    8898             :     // na
    8899             : 
    8900             :     // Using/Aliasing
    8901             :     using DaylightingManager::CalcDayltgCoefficients;
    8902             :     // Locals
    8903             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    8904             :     // na
    8905             : 
    8906             :     // SUBROUTINE PARAMETER DEFINITIONS:
    8907             :     // na
    8908             : 
    8909             :     // INTERFACE BLOCK SPECIFICATIONS
    8910             :     // na
    8911             : 
    8912             :     // DERIVED TYPE DEFINITIONS
    8913             :     // na
    8914             : 
    8915             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8916             :     Real64 SumDec;
    8917             :     Real64 SumET;
    8918             :     Real64 AvgEqOfTime;
    8919             :     Real64 AvgSinSolarDeclin;
    8920             :     Real64 AvgCosSolarDeclin;
    8921             :     int PerDayOfYear;
    8922             :     int Count;
    8923             :     Real64 SinDec;
    8924             :     Real64 EqTime;
    8925             :     // not used INTEGER SurfNum
    8926             : 
    8927             :     // Calculate sky diffuse shading
    8928             : 
    8929       31444 :     if (state.dataGlobal->BeginSimFlag) {
    8930         771 :         state.dataSolarShading->CalcSkyDifShading = true;
    8931         771 :         SkyDifSolarShading(state); // Calculate factors for shading of sky diffuse solar
    8932         771 :         state.dataSolarShading->CalcSkyDifShading = false;
    8933             :     }
    8934             : 
    8935       31444 :     if (state.dataGlobal->BeginEnvrnFlag) {
    8936        6218 :         state.dataSolarShading->ShadowingDaysLeft = 0;
    8937             :     }
    8938             : 
    8939       31444 :     if (state.dataSolarShading->ShadowingDaysLeft <= 0 || state.dataSysVars->DetailedSolarTimestepIntegration) {
    8940             : 
    8941       14330 :         if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
    8942             :             //  Perform calculations.
    8943        6236 :             state.dataSolarShading->ShadowingDaysLeft = state.dataSolarShading->ShadowingCalcFrequency;
    8944        6236 :             if (state.dataGlobal->DayOfSim + state.dataSolarShading->ShadowingDaysLeft > state.dataGlobal->NumOfDayInEnvrn) {
    8945        5757 :                 state.dataSolarShading->ShadowingDaysLeft = state.dataGlobal->NumOfDayInEnvrn - state.dataGlobal->DayOfSim + 1;
    8946             :             }
    8947             : 
    8948             :             //  Calculate average Equation of Time, Declination Angle for this period
    8949             : 
    8950        6236 :             if (!state.dataGlobal->WarmupFlag) {
    8951          36 :                 if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
    8952          36 :                     DisplayString(state, "Updating Shadowing Calculations, Start Date=" + state.dataEnvrn->CurMnDyYr);
    8953             :                 } else {
    8954           0 :                     DisplayString(state, "Updating Shadowing Calculations, Start Date=" + state.dataEnvrn->CurMnDy);
    8955             :                 }
    8956          36 :                 state.dataReportFlag->DisplayPerfSimulationFlag = true;
    8957             :             }
    8958             : 
    8959        6236 :             PerDayOfYear = state.dataEnvrn->DayOfYear;
    8960        6236 :             SumDec = 0.0;
    8961        6236 :             SumET = 0.0;
    8962       22563 :             for (Count = 1; Count <= state.dataSolarShading->ShadowingDaysLeft; ++Count) {
    8963       16327 :                 SUN3(PerDayOfYear, SinDec, EqTime);
    8964       16327 :                 SumDec += SinDec;
    8965       16327 :                 SumET += EqTime;
    8966       16327 :                 ++PerDayOfYear;
    8967             :             }
    8968             : 
    8969             :             //  Compute Period Values
    8970        6236 :             AvgSinSolarDeclin = SumDec / double(state.dataSolarShading->ShadowingDaysLeft);
    8971        6236 :             AvgCosSolarDeclin = std::sqrt(1.0 - pow_2(AvgSinSolarDeclin));
    8972        6236 :             AvgEqOfTime = SumET / double(state.dataSolarShading->ShadowingDaysLeft);
    8973             :         } else {
    8974        8094 :             SUN3(state.dataEnvrn->DayOfYear, AvgSinSolarDeclin, AvgEqOfTime);
    8975        8094 :             AvgCosSolarDeclin = std::sqrt(1.0 - pow_2(AvgSinSolarDeclin));
    8976             :             // trigger display of progress in the simulation every two weeks
    8977        8094 :             if (!state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag && (state.dataGlobal->DayOfSim % 14 == 0)) {
    8978           0 :                 state.dataReportFlag->DisplayPerfSimulationFlag = true;
    8979             :             }
    8980             :         }
    8981             : 
    8982       14330 :         CalcPerSolarBeam(state, AvgEqOfTime, AvgSinSolarDeclin, AvgCosSolarDeclin);
    8983             : 
    8984             :         // Calculate factors for solar reflection
    8985       14330 :         if (state.dataSurface->CalcSolRefl) {
    8986          54 :             CalcBeamSolDiffuseReflFactors(state);
    8987          54 :             CalcBeamSolSpecularReflFactors(state);
    8988          54 :             if (state.dataGlobal->BeginSimFlag) CalcSkySolDiffuseReflFactors(state);
    8989             :         }
    8990             :         //  Calculate daylighting coefficients
    8991       14330 :         CalcDayltgCoefficients(state);
    8992             :     }
    8993             : 
    8994       31444 :     if (!state.dataGlobal->WarmupFlag) {
    8995        4468 :         --state.dataSolarShading->ShadowingDaysLeft;
    8996             :     }
    8997             : 
    8998             :     // Recalculate daylighting coefficients if storm window has been added
    8999             :     // or removed from one or more windows at beginning of day
    9000       66275 :     if (state.dataDaylightingManager->TotWindowsWithDayl > 0 && !state.dataGlobal->BeginSimFlag && !state.dataGlobal->BeginEnvrnFlag &&
    9001       33084 :         !state.dataGlobal->WarmupFlag && state.dataSurface->TotStormWin > 0 && state.dataHeatBal->StormWinChangeThisDay) {
    9002           0 :         CalcDayltgCoefficients(state);
    9003             :     }
    9004       31444 : }
    9005             : 
    9006     1284477 : void SHDRVL(EnergyPlusData &state,
    9007             :             int const HTSS,  // Heat transfer surface number of the subsurface
    9008             :             int const SBSNR, // Subsurface number
    9009             :             int const Hour,
    9010             :             int const TS)
    9011             : {
    9012             : 
    9013             :     // SUBROUTINE INFORMATION:
    9014             :     //       AUTHOR         Legacy Code
    9015             :     //       DATE WRITTEN
    9016             :     //       MODIFIED       May 2002 (FCW): allow triangular windows to have reveal.
    9017             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    9018             : 
    9019             :     // PURPOSE OF THIS SUBROUTINE:
    9020             :     // This subroutine computes the shadowing from a reveal onto a subsurface.
    9021             : 
    9022             :     // REFERENCES:
    9023             :     // BLAST/IBLAST code, original author George Walton
    9024             : 
    9025             :     int NVS; // Number of verticies
    9026             : 
    9027     1284477 :     int constexpr None(0);                       // for use with RevealStatus
    9028     1284477 :     int constexpr EntireWindowShadedByReveal(1); // for use with RevealStatus
    9029     1284477 :     int constexpr WindowShadedOnlyByReveal(2);   // for use with RevealStatus
    9030             : 
    9031             :     Real64 A; // Area
    9032             :     Real64 R; // Depth of the reveal (m)
    9033             :     int I;    // Loop control
    9034             :     int N;    // Vertex number
    9035             :     int NS1;  // Locations in homogeneous coordinate array
    9036             :     int NS2;
    9037             :     // note, below dimensions not changed because subsurface still max 4
    9038     2568954 :     Array1D<Real64> XVT(5); // Projected X coordinates of vertices
    9039     2568954 :     Array1D<Real64> YVT(5); // Projected Y coordinates of vertices
    9040             :     bool RevealStatusSet;   // Used to control flow through this subroutine.
    9041             :     // Certain operations performed only if reveal status not yet set.
    9042             :     int RevealStatus; // Status of the reveal, takes the parameter values above
    9043             : 
    9044     1284477 :     RevealStatus = None;
    9045     1284477 :     RevealStatusSet = false;
    9046             : 
    9047     1284477 :     if (!state.dataSolarShading->CalcSkyDifShading) {
    9048      855794 :         state.dataSolarShading->SurfWinRevealStatus(Hour, TS, SBSNR) = None;
    9049             :     }
    9050             : 
    9051     1284477 :     R = state.dataSurface->Surface(SBSNR).Reveal;
    9052     1284477 :     if (R <= 0.0) {
    9053     1266602 :         RevealStatus = None;
    9054     1266602 :         RevealStatusSet = true;
    9055             :     }
    9056             : 
    9057     1284477 :     if (!RevealStatusSet) {
    9058             : 
    9059       17875 :         state.dataSolarShading->FRVLHC = state.dataSolarShading->LOCHCA + 1;
    9060       17875 :         ++state.dataSolarShading->LOCHCA;
    9061       17875 :         NVS = state.dataSurface->Surface(SBSNR).Sides;
    9062             : 
    9063             :         // Currently (06May02) windows are either rectangles (NVS=4) or triangles (NVS=3)
    9064             : 
    9065       17875 :         if (NVS == 4) { // Rectangular subsurface
    9066             : 
    9067             :             // Determine vertices of reveal.
    9068             :             // Project the subsurface up to the plane of the wall.
    9069             : 
    9070       17875 :             XVT(1) = state.dataSurface->ShadeV(SBSNR).XV(1) + R * max(state.dataSolarShading->XShadowProjection, 0.0);
    9071       17875 :             XVT(2) = state.dataSurface->ShadeV(SBSNR).XV(2) + R * max(state.dataSolarShading->XShadowProjection, 0.0);
    9072       17875 :             XVT(3) = state.dataSurface->ShadeV(SBSNR).XV(3) + R * min(state.dataSolarShading->XShadowProjection, 0.0);
    9073       17875 :             XVT(4) = state.dataSurface->ShadeV(SBSNR).XV(4) + R * min(state.dataSolarShading->XShadowProjection, 0.0);
    9074       17875 :             YVT(1) = state.dataSurface->ShadeV(SBSNR).YV(1) + R * min(state.dataSolarShading->YShadowProjection, 0.0);
    9075       17875 :             YVT(2) = state.dataSurface->ShadeV(SBSNR).YV(2) + R * max(state.dataSolarShading->YShadowProjection, 0.0);
    9076       17875 :             YVT(3) = state.dataSurface->ShadeV(SBSNR).YV(3) + R * max(state.dataSolarShading->YShadowProjection, 0.0);
    9077       17875 :             YVT(4) = state.dataSurface->ShadeV(SBSNR).YV(4) + R * min(state.dataSolarShading->YShadowProjection, 0.0);
    9078             : 
    9079             :             // Check for complete shadowing.
    9080             : 
    9081       17875 :             if ((XVT(2) >= XVT(3)) || (YVT(2) >= YVT(1))) {
    9082             : 
    9083         564 :                 RevealStatus = EntireWindowShadedByReveal;
    9084         564 :                 RevealStatusSet = true;
    9085             : 
    9086             :             } else {
    9087             :                 // Re-order vertices to clockwise.
    9088             : 
    9089       86555 :                 for (N = 1; N <= NVS; ++N) {
    9090       69244 :                     state.dataSolarShading->XVS(N) = XVT(NVS + 1 - N);
    9091       69244 :                     state.dataSolarShading->YVS(N) = YVT(NVS + 1 - N);
    9092             :                 }
    9093             : 
    9094             :                 // Transform to homogeneous coordinates
    9095             : 
    9096       17311 :                 HTRANS1(state, state.dataSolarShading->FRVLHC, NVS);
    9097       17311 :                 state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC) = -state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC);
    9098       17311 :                 state.dataSolarShading->HCT(state.dataSolarShading->FRVLHC) = 1.0;
    9099             : 
    9100       17311 :                 if (state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC) <= 0.0) {
    9101           0 :                     RevealStatus = EntireWindowShadedByReveal;
    9102           0 :                     RevealStatusSet = true;
    9103             :                 }
    9104             :             }
    9105             : 
    9106           0 :         } else if (NVS == 3) { // Triangular window
    9107             : 
    9108             :             // Project window to outside plane of parent surface
    9109             : 
    9110           0 :             for (N = 1; N <= 3; ++N) {
    9111           0 :                 XVT(N) = state.dataSurface->ShadeV(SBSNR).XV(N) + R * state.dataSolarShading->XShadowProjection;
    9112           0 :                 YVT(N) = state.dataSurface->ShadeV(SBSNR).YV(N) + R * state.dataSolarShading->YShadowProjection;
    9113             :             }
    9114             : 
    9115             :             // Find the overlap between the original window and the projected window
    9116             :             // Put XVT,YVT in clockwise order
    9117             : 
    9118           0 :             for (N = 1; N <= NVS; ++N) {
    9119           0 :                 state.dataSolarShading->XVS(N) = XVT(NVS + 1 - N);
    9120           0 :                 state.dataSolarShading->YVS(N) = YVT(NVS + 1 - N);
    9121             :             }
    9122             : 
    9123             :             // Transform to homogeneous coordinates
    9124             : 
    9125           0 :             NS1 = state.dataSolarShading->LOCHCA + 1;
    9126           0 :             state.dataSolarShading->LOCHCA = NS1;
    9127           0 :             HTRANS1(state, NS1, NVS);
    9128             : 
    9129             :             // Put XV,YV in clockwise order
    9130             : 
    9131           0 :             for (N = 1; N <= NVS; ++N) {
    9132           0 :                 state.dataSolarShading->XVS(N) = state.dataSurface->ShadeV(SBSNR).XV(NVS + 1 - N);
    9133           0 :                 state.dataSolarShading->YVS(N) = state.dataSurface->ShadeV(SBSNR).YV(NVS + 1 - N);
    9134             :             }
    9135             : 
    9136             :             // Transform to homogenous coordinates
    9137             : 
    9138           0 :             NS2 = state.dataSolarShading->LOCHCA + 1;
    9139           0 :             state.dataSolarShading->LOCHCA = NS2;
    9140           0 :             HTRANS1(state, NS2, NVS);
    9141           0 :             state.dataSolarShading->HCT(state.dataSolarShading->FRVLHC) = 1.0;
    9142             : 
    9143             :             // Find overlap
    9144             : 
    9145           0 :             DeterminePolygonOverlap(state, NS1, NS2, state.dataSolarShading->FRVLHC);
    9146           0 :             if (state.dataSolarShading->OverlapStatus == NoOverlap) {
    9147           0 :                 RevealStatus = EntireWindowShadedByReveal;
    9148           0 :                 RevealStatusSet = true;
    9149             :             }
    9150             :         }
    9151             :     }
    9152             : 
    9153     1284477 :     if (!RevealStatusSet) {
    9154             : 
    9155             :         // Check for no shadows on window.
    9156             : 
    9157       17311 :         if (state.dataSolarShading->NSBSHC <= 1) {
    9158        7797 :             RevealStatus = WindowShadedOnlyByReveal;
    9159        7797 :             RevealStatusSet = true;
    9160             :         } else {
    9161             :             // Reduce all previous shadows to size of reveal opening.
    9162        9514 :             state.dataSolarShading->LOCHCA = state.dataSolarShading->FRVLHC;
    9163        9514 :             MULTOL(state, state.dataSolarShading->LOCHCA, state.dataSolarShading->FSBSHC, state.dataSolarShading->NSBSHC - 1);
    9164        9514 :             if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures)) {
    9165           0 :                 RevealStatus = None;
    9166           0 :                 RevealStatusSet = true;
    9167             :             } else {
    9168        9514 :                 state.dataSolarShading->NRVLHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FRVLHC + 1;
    9169        9514 :                 if (state.dataSolarShading->NRVLHC <= 1) {
    9170          52 :                     RevealStatus = WindowShadedOnlyByReveal;
    9171          52 :                     RevealStatusSet = true;
    9172             :                 }
    9173             :             }
    9174             :         }
    9175             :     }
    9176             : 
    9177     1284477 :     if (!RevealStatusSet) {
    9178             :         // Compute sunlit area.
    9179        9462 :         A = state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC);
    9180       25271 :         for (I = 2; I <= state.dataSolarShading->NRVLHC; ++I) {
    9181       31618 :             A += state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC - 1 + I) *
    9182       15809 :                  (1.0 - state.dataSolarShading->HCT(state.dataSolarShading->FRVLHC - 1 + I));
    9183             :         }
    9184        9462 :         state.dataSolarShading->SurfSunlitArea(HTSS) = A;
    9185             :     }
    9186             : 
    9187     1284477 :     if ((RevealStatus == EntireWindowShadedByReveal) || (state.dataSolarShading->SurfSunlitArea(HTSS) < 0.0)) {
    9188         594 :         state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0; // Window entirely shaded by reveal.
    9189     1283883 :     } else if (RevealStatus == WindowShadedOnlyByReveal) {
    9190        7849 :         state.dataSolarShading->SurfSunlitArea(HTSS) =
    9191        7849 :             state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC); // Window shaded only by reveal.
    9192             :     }
    9193             : 
    9194     1284477 :     if (!state.dataSolarShading->CalcSkyDifShading) {
    9195      855794 :         state.dataSolarShading->SurfWinRevealStatus(Hour, TS, SBSNR) = RevealStatus;
    9196             :     }
    9197     1284477 : }
    9198             : 
    9199     3220462 : void SHDSBS(EnergyPlusData &state,
    9200             :             int const iHour, // Hour Index
    9201             :             int const CurSurf,
    9202             :             int const NBKS, // Number of back surfaces
    9203             :             int const NSBS, // Number of subsurfaces
    9204             :             int const HTS,  // Heat transfer surface number of the general receiving surf
    9205             :             int const TS    // Time step Index
    9206             : )
    9207             : {
    9208             : 
    9209             :     // SUBROUTINE INFORMATION:
    9210             :     //       AUTHOR         Legacy Code
    9211             :     //       DATE WRITTEN
    9212             :     //       MODIFIED       FCW, Oct 2002: Surface%Area --> Surface%Area + SurfaceWindow%DividerArea
    9213             :     //                       in calculation of SunlitFracWithoutReveal (i.e., use full window area, not
    9214             :     //                       just glass area.
    9215             :     //                      TH, May 2009: Bug fixed to address part of CR 7596 - inside reveals
    9216             :     //                       causing high cooling loads
    9217             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    9218             : 
    9219             :     // PURPOSE OF THIS SUBROUTINE:
    9220             :     // This subroutine determines the shadowing on subsurfaces and
    9221             :     // revises the base surface area accordingly.  It also computes
    9222             :     // the effect of transparent subsurfaces.
    9223             : 
    9224             :     // REFERENCES:
    9225             :     // BLAST/IBLAST code, original author George Walton
    9226             : 
    9227             :     Real64 A;        // Area
    9228             :     int I;           // Loop control
    9229             :     int J;           // Loop control
    9230             :     int K;           // Window construction number
    9231             :     int N;           // Vertex number
    9232             :     Real64 SurfArea; // Surface area. For walls, includes all window frame areas.
    9233             :     // For windows, includes divider area
    9234             :     //  REAL(r64) FrameAreaAdd    ! Additional frame area sunlit
    9235             :     //  REAL(r64) DividerAreaAdd  ! Additional frame area sunlit
    9236             :     int HTSS;  // Heat transfer surface number of the subsurface
    9237             :     int SBSNR; // Subsurface number
    9238             : 
    9239     3220462 :     if (NSBS > 0) { // Action taken only if subsurfaces present
    9240             : 
    9241     1610411 :         state.dataSolarShading->FSBSHC = state.dataSolarShading->LOCHCA + 1;
    9242             : 
    9243     4132113 :         for (I = 1; I <= NSBS; ++I) { // Do for all subsurfaces (sbs).
    9244             : 
    9245     2521702 :             SBSNR = state.dataShadowComb->ShadowComb(CurSurf).SubSurf(I);
    9246             : 
    9247     2521702 :             HTSS = SBSNR;
    9248             : 
    9249     2521702 :             K = state.dataSurface->Surface(SBSNR).Construction;
    9250             : 
    9251     2521702 :             if (!state.dataSolarShading->penumbra) {
    9252     5033366 :                 if ((state.dataSolarShading->OverlapStatus != TooManyVertices) && (state.dataSolarShading->OverlapStatus != TooManyFigures) &&
    9253     2516683 :                     (state.dataSolarShading->SurfSunlitArea(HTS) > 0.0)) {
    9254             : 
    9255             :                     // Re-order vertices to clockwise sequential; compute homogeneous coordinates.
    9256     1327134 :                     state.dataSolarShading->NVS = state.dataSurface->Surface(SBSNR).Sides;
    9257     6635320 :                     for (N = 1; N <= state.dataSolarShading->NVS; ++N) {
    9258     5308186 :                         state.dataSolarShading->XVS(N) = state.dataSurface->ShadeV(SBSNR).XV(state.dataSolarShading->NVS + 1 - N);
    9259     5308186 :                         state.dataSolarShading->YVS(N) = state.dataSurface->ShadeV(SBSNR).YV(state.dataSolarShading->NVS + 1 - N);
    9260             :                     }
    9261     1327134 :                     state.dataSolarShading->LOCHCA = state.dataSolarShading->FSBSHC;
    9262     1327134 :                     HTRANS1(state, state.dataSolarShading->LOCHCA, state.dataSolarShading->NVS);
    9263     1327134 :                     state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA) = -state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
    9264     1327134 :                     state.dataSolarShading->HCT(state.dataSolarShading->LOCHCA) = 1.0;
    9265     1327134 :                     state.dataSolarShading->NSBSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FSBSHC + 1;
    9266             : 
    9267             :                     // Determine sunlit area of subsurface due to shadows on general receiving surface.
    9268     1327134 :                     if (state.dataSolarShading->NGSSHC > 0) {
    9269      255778 :                         MULTOL(state, state.dataSolarShading->LOCHCA, state.dataSolarShading->FGSSHC - 1, state.dataSolarShading->NGSSHC);
    9270      255778 :                         if ((state.dataSolarShading->OverlapStatus != TooManyVertices) && (state.dataSolarShading->OverlapStatus != TooManyFigures))
    9271      255778 :                             state.dataSolarShading->NSBSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FSBSHC + 1;
    9272             :                     }
    9273             :                 }
    9274             : 
    9275     5033366 :                 if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures) ||
    9276     2516683 :                     (state.dataSolarShading->SurfSunlitArea(HTS) <= 0.0)) { // General receiving surface totally shaded.
    9277             : 
    9278     1189549 :                     state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
    9279             : 
    9280     1189549 :                     if (iHour > 0 && TS > 0) state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) = 0.0;
    9281             : 
    9282     1327134 :                 } else if ((state.dataSolarShading->NGSSHC <= 0) || (state.dataSolarShading->NSBSHC == 1)) { // No shadows.
    9283             : 
    9284     1133689 :                     state.dataSolarShading->SurfSunlitArea(HTSS) = state.dataSolarShading->HCAREA(state.dataSolarShading->FSBSHC);
    9285     1133689 :                     state.dataSolarShading->SurfSunlitArea(HTS) -=
    9286     1133689 :                         state.dataSolarShading->SurfSunlitArea(HTSS); // Revise sunlit area of general receiving surface.
    9287             : 
    9288             :                     // TH. This is a bug.  SunLitFracWithoutReveal should be a ratio of area
    9289             :                     // IF(IHour > 0 .AND. TS > 0) SunLitFracWithoutReveal(HTSS,IHour,TS) = &
    9290             :                     //      Surface(HTSS)%NetAreaShadowCalc
    9291             : 
    9292             :                     // new code fixed part of CR 7596. TH 5/29/2009
    9293     1133689 :                     if (iHour > 0 && TS > 0)
    9294      749358 :                         state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) =
    9295      749358 :                             state.dataSolarShading->SurfSunlitArea(HTSS) / state.dataSurface->Surface(HTSS).NetAreaShadowCalc;
    9296             : 
    9297     1133689 :                     SHDRVL(state, HTSS, SBSNR, iHour, TS); // Determine shadowing from reveal.
    9298             : 
    9299     1133689 :                     if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
    9300           0 :                         state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
    9301             : 
    9302             :                 } else { // Compute area.
    9303             : 
    9304      193445 :                     A = state.dataSolarShading->HCAREA(state.dataSolarShading->FSBSHC);
    9305      457523 :                     for (J = 2; J <= state.dataSolarShading->NSBSHC; ++J) {
    9306      528156 :                         A += state.dataSolarShading->HCAREA(state.dataSolarShading->FSBSHC - 1 + J) *
    9307      264078 :                              (1.0 - state.dataSolarShading->HCT(state.dataSolarShading->FSBSHC - 1 + J));
    9308             :                     }
    9309      193445 :                     state.dataSolarShading->SurfSunlitArea(HTSS) = A;
    9310      193445 :                     if (state.dataSolarShading->SurfSunlitArea(HTSS) > 0.0) {
    9311             : 
    9312      150788 :                         state.dataSolarShading->SurfSunlitArea(HTS) -=
    9313      150788 :                             state.dataSolarShading->SurfSunlitArea(HTSS); // Revise sunlit area of general receiving surface.
    9314             : 
    9315      150788 :                         if (iHour > 0 && TS > 0)
    9316      106436 :                             state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) =
    9317      106436 :                                 state.dataSolarShading->SurfSunlitArea(HTSS) / state.dataSurface->Surface(HTSS).Area;
    9318             : 
    9319      150788 :                         SHDRVL(state, HTSS, SBSNR, iHour, TS); // Determine shadowing from reveal.
    9320             : 
    9321      150788 :                         if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
    9322           0 :                             state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
    9323             : 
    9324             :                     } else { // General receiving surface totally shaded.
    9325             : 
    9326       42657 :                         state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
    9327             :                     }
    9328             :                 }
    9329             :             }
    9330             : 
    9331             :             // Determine transmittance and absorptances of sunlit window.
    9332     2521702 :             if (state.dataConstruction->Construct(K).TransDiff > 0.0) {
    9333             : 
    9334     2392140 :                 if (!state.dataSolarShading->CalcSkyDifShading) { // Overlaps calculation is only done for beam solar
    9335             :                     // shading, not for sky diffuse solar shading
    9336             : 
    9337     1534620 :                     CalcInteriorSolarOverlaps(state, iHour, NBKS, HTSS, CurSurf, TS);
    9338             :                 }
    9339             :             }
    9340             : 
    9341             :             // Error checking.
    9342     2521702 :             SurfArea = state.dataSurface->Surface(SBSNR).NetAreaShadowCalc;
    9343     2521702 :             state.dataSolarShading->SurfSunlitArea(HTSS) = max(0.0, state.dataSolarShading->SurfSunlitArea(HTSS));
    9344             : 
    9345     2521702 :             state.dataSolarShading->SurfSunlitArea(HTSS) = min(state.dataSolarShading->SurfSunlitArea(HTSS), SurfArea);
    9346             : 
    9347             :         } // End of subsurface loop
    9348             :     }
    9349     3220462 : }
    9350             : 
    9351       24421 : void SUN3(int const JulianDayOfYear,      // Julian Day Of Year
    9352             :           Real64 &SineOfSolarDeclination, // Sine of Solar Declination
    9353             :           Real64 &EquationOfTime          // Equation of Time (Degrees)
    9354             : )
    9355             : {
    9356             : 
    9357             :     // SUBROUTINE INFORMATION:
    9358             :     //       AUTHOR         Legacy Code
    9359             :     //       DATE WRITTEN
    9360             :     //       MODIFIED       na
    9361             :     //       RE-ENGINEERED  Linda K. Lawrie
    9362             : 
    9363             :     // PURPOSE OF THIS SUBROUTINE:
    9364             :     // This subroutine computes the coefficients for determining
    9365             :     // the solar position.
    9366             : 
    9367             :     // METHODOLOGY EMPLOYED:
    9368             :     // The expressions are based on least-squares fits of data on p.316 of 'Thermal
    9369             :     // Environmental Engineering' by Threlkeld and on p.387 of the ASHRAE Handbook
    9370             :     // of Fundamentals (need date of ASHRAE HOF).
    9371             : 
    9372             :     // REFERENCES:
    9373             :     // BLAST/IBLAST code, original author George Walton
    9374             : 
    9375             :     // Fitted coefficients of Fourier series | Sine of declination coefficients
    9376             :     static constexpr std::array<Real64, 9> SineSolDeclCoef = {
    9377             :         0.00561800, 0.0657911, -0.392779, 0.00064440, -0.00618495, -0.00010101, -0.00007951, -0.00011691, 0.00002096};
    9378             :     // Fitted coefficients of Fourier Series | Equation of Time coefficients
    9379             :     static constexpr std::array<Real64, 9> EqOfTimeCoef = {
    9380             :         0.00021971, -0.122649, 0.00762856, -0.156308, -0.0530028, -0.00388702, -0.00123978, -0.00270502, -0.00167992};
    9381             : 
    9382             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9383             :     Real64 X;     // Day of Year in Radians (Computed from Input JulianDayOfYear)
    9384             :     Real64 CosX;  // COS(X)
    9385             :     Real64 SineX; // SIN(X)
    9386             : 
    9387       24421 :     X = 0.017167 * JulianDayOfYear; // Convert julian date to angle X
    9388             : 
    9389             :     // Calculate sines and cosines of X
    9390       24421 :     SineX = std::sin(X);
    9391       24421 :     CosX = std::cos(X);
    9392             : 
    9393       73263 :     SineOfSolarDeclination = SineSolDeclCoef[0] + SineSolDeclCoef[1] * SineX + SineSolDeclCoef[2] * CosX + SineSolDeclCoef[3] * (SineX * CosX * 2.0) +
    9394       48842 :                              SineSolDeclCoef[4] * (pow_2(CosX) - pow_2(SineX)) +
    9395       48842 :                              SineSolDeclCoef[5] * (SineX * (pow_2(CosX) - pow_2(SineX)) + CosX * (SineX * CosX * 2.0)) +
    9396       48842 :                              SineSolDeclCoef[6] * (CosX * (pow_2(CosX) - pow_2(SineX)) - SineX * (SineX * CosX * 2.0)) +
    9397       48842 :                              SineSolDeclCoef[7] * (2.0 * (SineX * CosX * 2.0) * (pow_2(CosX) - pow_2(SineX))) +
    9398       24421 :                              SineSolDeclCoef[8] * (pow_2(pow_2(CosX) - pow_2(SineX)) - pow_2(SineX * CosX * 2.0));
    9399             : 
    9400       73263 :     EquationOfTime = EqOfTimeCoef[0] + EqOfTimeCoef[1] * SineX + EqOfTimeCoef[2] * CosX + EqOfTimeCoef[3] * (SineX * CosX * 2.0) +
    9401       48842 :                      EqOfTimeCoef[4] * (pow_2(CosX) - pow_2(SineX)) +
    9402       48842 :                      EqOfTimeCoef[5] * (SineX * (pow_2(CosX) - pow_2(SineX)) + CosX * (SineX * CosX * 2.0)) +
    9403       48842 :                      EqOfTimeCoef[6] * (CosX * (pow_2(CosX) - pow_2(SineX)) - SineX * (SineX * CosX * 2.0)) +
    9404       48842 :                      EqOfTimeCoef[7] * (2.0 * (SineX * CosX * 2.0) * (pow_2(CosX) - pow_2(SineX))) +
    9405       24421 :                      EqOfTimeCoef[8] * (pow_2(pow_2(CosX) - pow_2(SineX)) - pow_2(SineX * CosX * 2.0));
    9406       24421 : }
    9407             : 
    9408      344400 : void SUN4(EnergyPlusData &state,
    9409             :           Real64 const CurrentTime,    // Time to use in shadowing calculations
    9410             :           Real64 const EqOfTime,       // Equation of time for current day
    9411             :           Real64 const SinSolarDeclin, // Sine of the Solar declination (current day)
    9412             :           Real64 const CosSolarDeclin  // Cosine of the Solar declination (current day)
    9413             : )
    9414             : {
    9415             : 
    9416             :     // SUBROUTINE INFORMATION:
    9417             :     //       AUTHOR         Legacy Code
    9418             :     //       DATE WRITTEN
    9419             :     //       MODIFIED       na
    9420             :     //       RE-ENGINEERED  Lawrie, Oct 2000
    9421             : 
    9422             :     // PURPOSE OF THIS SUBROUTINE:
    9423             :     // This subroutine computes solar direction cosines for a given hour.  These
    9424             :     // cosines are used in the shadowing calculations.
    9425             :     // REFERENCES:
    9426             :     // BLAST/IBLAST code, original author George Walton
    9427             : 
    9428             :     Real64 H;       // Hour angle (before noon = +) (in radians)
    9429             :     Real64 HrAngle; // Basic hour angle
    9430             : 
    9431             :     // Compute the hour angle
    9432      344400 :     HrAngle = (15.0 * (12.0 - (CurrentTime + EqOfTime)) + (state.dataEnvrn->TimeZoneMeridian - state.dataEnvrn->Longitude));
    9433      344400 :     H = HrAngle * DataGlobalConstants::DegToRadians;
    9434             : 
    9435             :     // Compute the cosine of the solar zenith angle.
    9436      344400 :     state.dataSolarShading->SUNCOS(3) = SinSolarDeclin * state.dataEnvrn->SinLatitude + CosSolarDeclin * state.dataEnvrn->CosLatitude * std::cos(H);
    9437      344400 :     state.dataSolarShading->SUNCOS(2) = 0.0;
    9438      344400 :     state.dataSolarShading->SUNCOS(1) = 0.0;
    9439             : 
    9440      344400 :     if (state.dataSolarShading->SUNCOS(3) < DataEnvironment::SunIsUpValue) return; // Return if sun not above horizon.
    9441             : 
    9442             :     // Compute other direction cosines.
    9443      173403 :     state.dataSolarShading->SUNCOS(2) = SinSolarDeclin * state.dataEnvrn->CosLatitude - CosSolarDeclin * state.dataEnvrn->SinLatitude * std::cos(H);
    9444      173403 :     state.dataSolarShading->SUNCOS(1) = CosSolarDeclin * std::sin(H);
    9445             : }
    9446             : 
    9447     2568509 : void WindowShadingManager(EnergyPlusData &state)
    9448             : {
    9449             : 
    9450             :     // SUBROUTINE INFORMATION:
    9451             :     //       AUTHOR         Fred Winkelmann
    9452             :     //       DATE WRITTEN   December 1998
    9453             :     //       MODIFIED       November 1999 (FW)
    9454             :     //                      Aug 2001 (FW): change shading control names, change approach
    9455             :     //                       to scheduling and glare control, add movable
    9456             :     //                       insulation controls (mainly for heating reduction)
    9457             :     //                      Dec 2001 (FW): add slat angle control for blinds
    9458             :     //                      Aug 2002 (FW): add four new control types:
    9459             :     //                        OnIfHighOutsideAirTempAndHighSolarOnWindow
    9460             :     //                        OnIfHighOutsideAirTempAndHighHorizontalSolar
    9461             :     //                        OnIfHighZoneAirTempAndHighSolarOnWindow
    9462             :     //                        OnIfHighZoneAirTempAndHighHorizontalSolar
    9463             :     //                      Dec 2002 (FW): add between-glass shade/blind
    9464             :     //                      Mar 2003 (FW): allow GlareControlIsActive = .TRUE. only for daylit zones
    9465             :     //                      Apr 2003 (FW): use SNLoadCoolRate or SNLoadHeatRate only if not first time step
    9466             :     //                                     (fixes problem when used first time thru and not allocated)
    9467             :     //                      May 2006 (RR): add exterior window screen
    9468             :     //                      May 2009 (BG): add EMS actuator override for shade flag and slat angle
    9469             :     //       RE-ENGINEERED  na
    9470             : 
    9471             :     // PURPOSE OF THIS SUBROUTINE:
    9472             :     // For windows with shading, selects the shaded construction
    9473             :     // that is used in the heat balance calculation, and sets
    9474             :     // the window shading flag, which is:
    9475             :     //  -1: if window has no shading device
    9476             :     //   0: if shading device is off
    9477             :     //   1: if interior shade is on
    9478             :     //   2: if glazing is switched to darker state
    9479             :     //   3: if exterior shade is on
    9480             :     //   6: if interior blind is on
    9481             :     //   7: if exterior blind is on
    9482             :     //   8: if between-glass shade is on
    9483             :     //   9: if between-glass blind is on
    9484             :     //  10: window has interior shade that is off but may be triggered on later
    9485             :     //       to control daylight glare
    9486             :     //  20: window has switchable glazing that is unswitched but may be switched later
    9487             :     //       to control daylight glare or daylight illuminance
    9488             :     //  30: window has exterior shade that is off but may be triggered on later
    9489             :     //       to control daylight glare or daylight illuminance
    9490             :     //  60: window has interior blind that is off but may be triggered on later
    9491             :     //       to control daylight glare or daylight illuminance
    9492             :     //  70: window has exterior blind that is off but may be triggered on later
    9493             :     //       to control daylight glare or daylight illuminance
    9494             :     //  80: window has between-glass shade that is off but may be triggered on later
    9495             :     //       to control daylight glare or daylight illuminance
    9496             :     //  90: window has between-glass blind that is off but may be triggered on later
    9497             :     //       to control daylight glare or daylight illuminance
    9498             :     // A "shading device" may be an exterior, interior or between-glass shade or blind,
    9499             :     // or the lower-transmitting (dark) state of switchable glazing (e.g., electrochromic).
    9500             :     // In all cases, the unshaded condition is represented
    9501             :     // by the construction given by window's Surface()%Construction and
    9502             :     // the shaded condition is represented by the construction given by
    9503             :     // the window's Surface()%ShadedConstruction
    9504             :     // REFERENCES:
    9505             :     // na
    9506             : 
    9507             :     // Using/Aliasing
    9508             :     using General::POLYF;
    9509             :     using ScheduleManager::GetCurrentScheduleValue;
    9510             : 
    9511             :     static Real64 const DeltaAng(DataGlobalConstants::Pi / (double(MaxSlatAngs) - 1.0));
    9512             :     static Real64 const DeltaAng_inv(1.0 / DeltaAng);
    9513             :     static Real64 const DeltaProfAng(DataGlobalConstants::Pi / 36.0);
    9514             :     int IConst; // Construction
    9515             : 
    9516    21015074 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    9517    36909306 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    9518    18462741 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    9519    18462741 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    9520    18462741 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    9521    40474011 :             for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) {
    9522    22011270 :                 state.dataSurface->SurfWinExtIntShadePrevTS(ISurf) = state.dataSurface->SurfWinShadingFlag(ISurf);
    9523             : 
    9524    22011270 :                 state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::NoShade;
    9525    22011270 :                 state.dataSurface->SurfWinFracTimeShadingDeviceOn(ISurf) = 0.0;
    9526    22011270 :                 if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::EQL) {
    9527        8109 :                     int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction).EQLConsPtr;
    9528        8109 :                     if (state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr > 0) {
    9529           0 :                         if (state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).CNTRL ==
    9530           0 :                             state.dataWindowEquivalentLayer->lscNONE) {
    9531           0 :                             state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) =
    9532           0 :                                 state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).PHI_DEG;
    9533             :                         } else {
    9534           0 :                             state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0;
    9535             :                         }
    9536             :                     }
    9537             :                 }
    9538             : 
    9539             :                 // Initialization of complex fenestration shading device
    9540    22011270 :                 if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::BSDF) {
    9541       39540 :                     auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction));
    9542       39540 :                     auto &surface_window(state.dataSurface->SurfaceWindow(ISurf));
    9543       39540 :                     int TotLayers = construction.TotLayers;
    9544      219672 :                     for (auto Lay = 1; Lay <= TotLayers; ++Lay) {
    9545      180132 :                         const int LayPtr = construction.LayerPoint(Lay);
    9546      180132 :                         auto &material(state.dataMaterial->Material(LayPtr));
    9547      180132 :                         const bool isShading = material.Group == DataHeatBalance::MaterialGroup::ComplexWindowShade;
    9548      180132 :                         if (isShading && Lay == 1) {
    9549       10143 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShade;
    9550             :                         }
    9551      180132 :                         if (isShading && Lay == TotLayers) {
    9552       15894 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShade;
    9553             :                         }
    9554             :                     }
    9555       39540 :                     if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntShade) {
    9556       15894 :                         auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction));
    9557       15894 :                         const int TotLay = construction.TotLayers;
    9558       15894 :                         int ShadingLayerPtr = construction.LayerPoint(TotLay);
    9559       15894 :                         ShadingLayerPtr = state.dataMaterial->Material(ShadingLayerPtr).ComplexShadePtr;
    9560       15894 :                         auto &complexShade = state.dataHeatBal->ComplexShade(ShadingLayerPtr);
    9561       15894 :                         auto TauShadeIR = complexShade.IRTransmittance;
    9562       15894 :                         auto EpsShadeIR = complexShade.BackEmissivity;
    9563       15894 :                         auto RhoShadeIR = max(0.0, 1.0 - TauShadeIR - EpsShadeIR);
    9564             :                         // Get properties of glass next to inside shading layer
    9565       15894 :                         int GlassLayPtr = construction.LayerPoint(TotLay - 2);
    9566       15894 :                         auto EpsGlassIR = state.dataMaterial->Material(GlassLayPtr).AbsorpThermalBack;
    9567       15894 :                         auto RhoGlassIR = 1 - EpsGlassIR;
    9568             : 
    9569       15894 :                         auto EffShBlEmiss = EpsShadeIR * (1.0 + RhoGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR));
    9570       15894 :                         surface_window.EffShBlindEmiss[0] = EffShBlEmiss;
    9571       15894 :                         auto EffGlEmiss = EpsGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR);
    9572       15894 :                         surface_window.EffGlassEmiss[0] = EffGlEmiss;
    9573             :                     }
    9574             :                 }
    9575             : 
    9576    22011270 :                 if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue;
    9577    21984078 :                 if (!state.dataSurface->Surface(ISurf).HasShadeControl) {
    9578    21494751 :                     continue;
    9579             :                 } else {
    9580             :                     //
    9581             :                 }
    9582             : 
    9583             :                 // Initialize switching factor (applicable only to switchable glazing) to unswitched
    9584      489327 :                 state.dataSurface->SurfWinSwitchingFactor(ISurf) = 0.0;
    9585             : 
    9586      489327 :                 IConst = state.dataSurface->Surface(ISurf).Construction;
    9587             :                 // Vis trans at normal incidence of unswitched glass. Counting the GlazedFrac
    9588      489327 :                 if (IConst > 0)
    9589      489327 :                     state.dataSurface->SurfWinVisTransSelected(ISurf) =
    9590      489327 :                         POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf);
    9591             : 
    9592             :                 // Window has shading control
    9593             :                 // select the active window shading control and corresponding contructions
    9594      489327 :                 size_t indexWindowShadingControl = selectActiveWindowShadingControlIndex(state, ISurf);
    9595      978654 :                 if (!state.dataSurface->Surface(ISurf).windowShadingControlList.empty() &&
    9596      489327 :                     indexWindowShadingControl <= state.dataSurface->Surface(ISurf).windowShadingControlList.size() - 1) {
    9597      489327 :                     state.dataSurface->Surface(ISurf).activeWindowShadingControl =
    9598      489327 :                         state.dataSurface->Surface(ISurf).windowShadingControlList[indexWindowShadingControl];
    9599             :                 }
    9600      489327 :                 state.dataSurface->Surface(ISurf).activeShadedConstructionPrev = state.dataSurface->Surface(ISurf).activeShadedConstruction;
    9601      978654 :                 if (!state.dataSurface->Surface(ISurf).shadedConstructionList.empty() &&
    9602      489327 :                     indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedConstructionList.size() - 1) {
    9603      489327 :                     state.dataSurface->Surface(ISurf).activeShadedConstruction =
    9604      489327 :                         state.dataSurface->Surface(ISurf).shadedConstructionList[indexWindowShadingControl];
    9605             :                 }
    9606      489327 :                 state.dataSurface->SurfWinActiveShadedConstruction(ISurf) = state.dataSurface->Surface(ISurf).activeShadedConstruction;
    9607      489327 :                 if (!state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.empty() &&
    9608           0 :                     indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.size() - 1) {
    9609           0 :                     if (state.dataSurface->SurfWinStormWinFlag(ISurf) == 1) {
    9610           0 :                         state.dataSurface->SurfWinActiveShadedConstruction(ISurf) =
    9611           0 :                             state.dataSurface->Surface(ISurf).shadedStormWinConstructionList[indexWindowShadingControl];
    9612             :                     }
    9613             :                 }
    9614             : 
    9615      489327 :                 int IShadingCtrl = state.dataSurface->Surface(ISurf).activeWindowShadingControl;
    9616      489327 :                 int IZone = state.dataSurface->Surface(ISurf).Zone;
    9617             :                 // Setpoint for shading
    9618      489327 :                 Real64 SetPoint = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint;   // Control setpoint
    9619      489327 :                 Real64 SetPoint2 = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint2; // Second control setpoint
    9620             : 
    9621      489327 :                 bool SchedAllowsControl = true; // True if control schedule is not specified or is specified and schedule value = 1
    9622      489327 :                 int SchedulePtr = state.dataSurface->WindowShadingControl(IShadingCtrl).Schedule;
    9623      489327 :                 if (SchedulePtr != 0) {
    9624      261924 :                     if (state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingControlIsScheduled &&
    9625      130962 :                         GetCurrentScheduleValue(state, SchedulePtr) <= 0.0)
    9626      121860 :                         SchedAllowsControl = false;
    9627             :                 }
    9628             : 
    9629             :                 Real64 GlareControlIsActive =
    9630      579586 :                     (state.dataDaylightingData->ZoneDaylight(IZone).totRefPts > 0 && state.dataEnvrn->SunIsUp &&
    9631      579586 :                      state.dataSurface->WindowShadingControl(IShadingCtrl).GlareControlIsActive); // True if glare control is active
    9632             : 
    9633      489327 :                 Real64 SolarOnWindow = 0.0;     // Direct plus diffuse solar intensity on window (W/m2)
    9634      489327 :                 Real64 BeamSolarOnWindow = 0.0; // Direct solar intensity on window (W/m2)
    9635      489327 :                 Real64 HorizSolar = 0.0;        // Horizontal direct plus diffuse solar intensity
    9636      489327 :                 if (state.dataEnvrn->SunIsUp) {
    9637      248965 :                     Real64 SkySolarOnWindow = state.dataSolarShading->SurfAnisoSkyMult(ISurf) *
    9638      248965 :                                               state.dataEnvrn->DifSolarRad; // Sky diffuse solar intensity on window (W/m2)
    9639      746895 :                     BeamSolarOnWindow = state.dataEnvrn->BeamSolarRad *
    9640      248965 :                                         state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf) *
    9641      248965 :                                         state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf);
    9642      248965 :                     SolarOnWindow =
    9643      248965 :                         BeamSolarOnWindow + SkySolarOnWindow + state.dataEnvrn->GndSolarRad * state.dataSurface->Surface(ISurf).ViewFactorGround;
    9644      248965 :                     HorizSolar = state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad;
    9645             :                 }
    9646             : 
    9647             :                 // Determine whether to deploy shading depending on type of control
    9648      489327 :                 auto &thisIZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(IZone);
    9649             : 
    9650      489327 :                 bool shadingOn = false;
    9651      489327 :                 bool shadingOffButGlareControlOn = false;
    9652      489327 :                 switch (state.dataSurface->WindowShadingControl(IShadingCtrl).shadingControlType) {
    9653       20907 :                 case WindowShadingControlType::AlwaysOn: // 'ALWAYSON'
    9654       20907 :                     shadingOn = true;
    9655       20907 :                     break;
    9656           0 :                 case WindowShadingControlType::AlwaysOff: // 'ALWAYSOFF'
    9657           0 :                     break;
    9658      122880 :                 case WindowShadingControlType::OnIfScheduled: // 'ONIFSCHEDULEALLOWS'
    9659      122880 :                     if (SchedAllowsControl) shadingOn = true;
    9660      122880 :                     break;
    9661      173658 :                 case WindowShadingControlType::HiSolar: // 'ONIFHIGHSOLARONWINDOW'
    9662             :                     // ! Direct plus diffuse solar intensity on window
    9663      173658 :                     if (state.dataEnvrn->SunIsUp) {
    9664       85955 :                         if (SolarOnWindow > SetPoint && SchedAllowsControl) {
    9665       44140 :                             shadingOn = true;
    9666       41815 :                         } else if (GlareControlIsActive) {
    9667        3192 :                             shadingOffButGlareControlOn = true;
    9668             :                         }
    9669             :                     }
    9670      173658 :                     break;
    9671             : 
    9672           0 :                 case WindowShadingControlType::HiHorzSolar: // 'ONIFHIGHHORIZONTALSOLAR'  ! Direct plus diffuse exterior horizontal solar intensity
    9673           0 :                     if (state.dataEnvrn->SunIsUp) {
    9674           0 :                         if (HorizSolar > SetPoint && SchedAllowsControl) {
    9675           0 :                             shadingOn = true;
    9676           0 :                         } else if (GlareControlIsActive) {
    9677           0 :                             shadingOffButGlareControlOn = true;
    9678             :                         }
    9679             :                     }
    9680           0 :                     break;
    9681             : 
    9682           0 :                 case WindowShadingControlType::HiOutAirTemp: // 'OnIfHighOutdoorAirTemperature'
    9683           0 :                     if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SchedAllowsControl) {
    9684           0 :                         shadingOn = true;
    9685           0 :                     } else if (GlareControlIsActive) {
    9686           0 :                         shadingOffButGlareControlOn = true;
    9687             :                     }
    9688           0 :                     break;
    9689             : 
    9690           0 :                 case WindowShadingControlType::HiZoneAirTemp: // 'OnIfHighZoneAirTemperature'  ! Previous time step zone air temperature
    9691           0 :                     if (thisIZoneHB.MAT > SetPoint && SchedAllowsControl) {
    9692           0 :                         shadingOn = true;
    9693           0 :                     } else if (GlareControlIsActive) {
    9694           0 :                         shadingOffButGlareControlOn = true;
    9695             :                     }
    9696           0 :                     break;
    9697             : 
    9698           0 :                 case WindowShadingControlType::OnHiOutTemp_HiSolarWindow: // 'OnIfHighOutdoorAirTempAndHighSolarOnWindow'  ! Outside air temp and
    9699             :                                                                           // solar on window
    9700           0 :                     if (state.dataEnvrn->SunIsUp) {
    9701           0 :                         if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) {
    9702           0 :                             shadingOn = true;
    9703           0 :                         } else if (GlareControlIsActive) {
    9704           0 :                             shadingOffButGlareControlOn = true;
    9705             :                         }
    9706             :                     }
    9707           0 :                     break;
    9708             : 
    9709           0 :                 case WindowShadingControlType::OnHiOutTemp_HiHorzSolar: // 'OnIfHighOutdoorAirTempAndHighHorizontalSolar'  ! Outside air temp and
    9710             :                                                                         // horizontal solar
    9711           0 :                     if (state.dataEnvrn->SunIsUp) {
    9712           0 :                         if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) {
    9713           0 :                             shadingOn = true;
    9714           0 :                         } else if (GlareControlIsActive) {
    9715           0 :                             shadingOffButGlareControlOn = true;
    9716             :                         }
    9717             :                     }
    9718           0 :                     break;
    9719             : 
    9720           0 :                 case WindowShadingControlType::OnHiZoneTemp_HiSolarWindow: // 'ONIFHIGHZONEAIRTEMPANDHIGHSOLARONWINDOW'  ! Zone air temp and solar on
    9721             :                                                                            // window
    9722           0 :                     if (state.dataEnvrn->SunIsUp) {
    9723           0 :                         if (thisIZoneHB.MAT > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) {
    9724           0 :                             shadingOn = true;
    9725           0 :                         } else if (GlareControlIsActive) {
    9726           0 :                             shadingOffButGlareControlOn = true;
    9727             :                         }
    9728             :                     }
    9729           0 :                     break;
    9730             : 
    9731           0 :                 case WindowShadingControlType::OnHiZoneTemp_HiHorzSolar: // 'ONIFHIGHZONEAIRTEMPANDHIGHHORIZONTALSOLAR'  ! Zone air temp and
    9732             :                                                                          // horizontal solar
    9733           0 :                     if (state.dataEnvrn->SunIsUp) {
    9734           0 :                         if (thisIZoneHB.MAT > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) {
    9735           0 :                             shadingOn = true;
    9736           0 :                         } else if (GlareControlIsActive) {
    9737           0 :                             shadingOffButGlareControlOn = true;
    9738             :                         }
    9739             :                     }
    9740           0 :                     break;
    9741             : 
    9742           0 :                 case WindowShadingControlType::HiZoneCooling:
    9743             :                     // 'ONIFHIGHZONECOOLING'  ! Previous time step zone sensible cooling rate [W]
    9744             :                     // In the following, the check on BeginSimFlag is needed since SNLoadCoolRate (and SNLoadHeatRate,
    9745             :                     // used in other CASEs) are not allocated at this point for the first time step of the simulation.
    9746           0 :                     if (!state.dataGlobal->BeginSimFlag) {
    9747           0 :                         if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > SetPoint && SchedAllowsControl) {
    9748           0 :                             shadingOn = true;
    9749           0 :                         } else if (GlareControlIsActive) {
    9750           0 :                             shadingOffButGlareControlOn = true;
    9751             :                         }
    9752             :                     }
    9753           0 :                     break;
    9754             : 
    9755      166458 :                 case WindowShadingControlType::HiGlare:
    9756             :                     // 'ONIFHIGHGLARE'  ! Daylight glare index at first reference point in the zone.
    9757             :                     // This type of shading control is done in DayltgInteriorIllum. Glare control is not affected
    9758             :                     // by control schedule.
    9759      166458 :                     if (state.dataEnvrn->SunIsUp) {
    9760       83609 :                         shadingOffButGlareControlOn = true;
    9761             :                     }
    9762      166458 :                     break;
    9763             : 
    9764        2712 :                 case WindowShadingControlType::MeetDaylIlumSetp:
    9765             :                     // 'MEETDAYLIGHTILLUMINANCESETPOINT')  !  Daylight illuminance test is done in DayltgInteriorIllum
    9766             :                     // Only switchable glazing does daylight illuminance control
    9767        2712 :                     if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
    9768        1330 :                         shadingOffButGlareControlOn = true;
    9769             :                     }
    9770        2712 :                     break;
    9771             : 
    9772        2712 :                 case WindowShadingControlType::HiSolar_HiLumin_OffMidNight:
    9773             :                     // 'OnIfHighSolarOrHighLuminanceTillMidnight'
    9774             :                     // if shade is already on, then keep it on until midnight, otherwise check thresholds
    9775        2712 :                     if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) {
    9776         978 :                         shadingOn = true;
    9777        1734 :                     } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
    9778         630 :                         if (SolarOnWindow > SetPoint) {
    9779          14 :                             shadingOn = true;
    9780             :                         } else {
    9781             :                             // pass to DayltgInteriorIllum to check for luminance
    9782         616 :                             shadingOn = false;
    9783         616 :                             shadingOffButGlareControlOn = true;
    9784             :                         }
    9785             :                     }
    9786             :                     // if it is the beginning of the day, then shades off
    9787        2712 :                     if (state.dataGlobal->BeginDayFlag) {
    9788          36 :                         shadingOn = false;
    9789          36 :                         shadingOffButGlareControlOn = false;
    9790             :                     }
    9791        2712 :                     break;
    9792             : 
    9793           0 :                 case WindowShadingControlType::HiSolar_HiLumin_OffSunset:
    9794             :                     // 'OnIfHighSolarOrHighLuminanceTillSunset'
    9795             :                     // if shade is already on, then keep it on until sunset, otherwise check thresholds
    9796           0 :                     if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) {
    9797           0 :                         shadingOn = true;
    9798           0 :                     } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
    9799           0 :                         if (SolarOnWindow > SetPoint) {
    9800           0 :                             shadingOn = true;
    9801             :                         } else {
    9802             :                             // pass to DayltgInteriorIllum to check for luminance
    9803           0 :                             shadingOn = false;
    9804           0 :                             shadingOffButGlareControlOn = true;
    9805             :                         }
    9806             :                     }
    9807             :                     // if sunset, then shades off
    9808           0 :                     if (!state.dataEnvrn->SunIsUp) {
    9809           0 :                         shadingOn = false;
    9810           0 :                         shadingOffButGlareControlOn = false;
    9811             :                     }
    9812           0 :                     break;
    9813             : 
    9814           0 :                 case WindowShadingControlType::HiSolar_HiLumin_OffNextMorning:
    9815             :                     // 'OnIfHighSolarOrHighLuminanceTillNextMorning'
    9816             :                     // if shade is already on, then keep it on until next day when sun is up, otherwise check thresholds
    9817           0 :                     if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) {
    9818           0 :                         shadingOn = true;
    9819           0 :                     } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
    9820           0 :                         if (SolarOnWindow > SetPoint) {
    9821           0 :                             shadingOn = true;
    9822             :                         } else {
    9823             :                             // pass to DayltgInteriorIllum to check for luminance
    9824           0 :                             shadingOn = false;
    9825           0 :                             shadingOffButGlareControlOn = true;
    9826             :                         }
    9827             :                     }
    9828             :                     // if next morning (identified by sun is not up in previous time step and is up now), then shades off
    9829           0 :                     if (!state.dataEnvrn->SunIsUpPrevTS && state.dataEnvrn->SunIsUp) {
    9830           0 :                         shadingOn = false;
    9831           0 :                         shadingOffButGlareControlOn = false;
    9832             :                     }
    9833           0 :                     break;
    9834             : 
    9835           0 :                 case WindowShadingControlType::OnNightLoOutTemp_OffDay: // 'OnNightIfLowOutdoorTempAndOffDay'
    9836           0 :                     if (!state.dataEnvrn->SunIsUp && state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) {
    9837           0 :                         shadingOn = true;
    9838           0 :                     } else if (GlareControlIsActive) {
    9839           0 :                         shadingOffButGlareControlOn = true;
    9840             :                     }
    9841           0 :                     break;
    9842             : 
    9843           0 :                 case WindowShadingControlType::OnNightLoInTemp_OffDay: // 'OnNightIfLowInsideTempAndOffDay')
    9844           0 :                     if (!state.dataEnvrn->SunIsUp && thisIZoneHB.MAT < SetPoint && SchedAllowsControl) {
    9845           0 :                         shadingOn = true;
    9846           0 :                     } else if (GlareControlIsActive) {
    9847           0 :                         shadingOffButGlareControlOn = true;
    9848             :                     }
    9849           0 :                     break;
    9850             : 
    9851           0 :                 case WindowShadingControlType::OnNightIfHeating_OffDay: // 'OnNightIfHeatingAndOffDay'
    9852           0 :                     if (!state.dataGlobal->BeginSimFlag) {
    9853           0 :                         if (!state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadHeatRate > SetPoint &&
    9854             :                             SchedAllowsControl) {
    9855           0 :                             shadingOn = true;
    9856           0 :                         } else if (GlareControlIsActive) {
    9857           0 :                             shadingOffButGlareControlOn = true;
    9858             :                         }
    9859             :                     }
    9860           0 :                     break;
    9861             : 
    9862           0 :                 case WindowShadingControlType::OnNightLoOutTemp_OnDayCooling: // 'OnNightIfLowOutdoorTempAndOnDayIfCooling'
    9863           0 :                     if (!state.dataGlobal->BeginSimFlag) {
    9864           0 :                         if (!state.dataEnvrn->SunIsUp) { // Night
    9865           0 :                             if (state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) shadingOn = true;
    9866             :                         } else { // Day
    9867           0 :                             if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && SchedAllowsControl) {
    9868           0 :                                 shadingOn = true;
    9869           0 :                             } else if (GlareControlIsActive) {
    9870           0 :                                 shadingOffButGlareControlOn = true;
    9871             :                             }
    9872             :                         }
    9873             :                     }
    9874           0 :                     break;
    9875             : 
    9876           0 :                 case WindowShadingControlType::OnNightIfHeating_OnDayCooling: // 'OnNightIfHeatingAndOnDayIfCooling'
    9877           0 :                     if (!state.dataGlobal->BeginSimFlag) {
    9878           0 :                         if (!state.dataEnvrn->SunIsUp) { // Night
    9879           0 :                             if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadHeatRate > SetPoint && SchedAllowsControl)
    9880           0 :                                 shadingOn = true;
    9881             :                         } else { // Day
    9882           0 :                             if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && SchedAllowsControl) {
    9883           0 :                                 shadingOn = true;
    9884           0 :                             } else if (GlareControlIsActive) {
    9885           0 :                                 shadingOffButGlareControlOn = true;
    9886             :                             }
    9887             :                         }
    9888             :                     }
    9889           0 :                     break;
    9890             : 
    9891           0 :                 case WindowShadingControlType::OffNight_OnDay_HiSolarWindow: // 'OffNightAndOnDayIfCoolingAndHighSolarOnWindow'
    9892           0 :                     if (!state.dataGlobal->BeginSimFlag) {
    9893           0 :                         if (state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 &&
    9894             :                             SchedAllowsControl) {
    9895           0 :                             if (SolarOnWindow > SetPoint) shadingOn = true;
    9896           0 :                         } else if (GlareControlIsActive) {
    9897           0 :                             shadingOffButGlareControlOn = true;
    9898             :                         }
    9899             :                     }
    9900           0 :                     break;
    9901             : 
    9902           0 :                 case WindowShadingControlType::OnNight_OnDay_HiSolarWindow: // 'OnNightAndOnDayIfCoolingAndHighSolarOnWindow'
    9903           0 :                     if (!state.dataGlobal->BeginSimFlag) {
    9904           0 :                         if (state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 &&
    9905             :                             SchedAllowsControl) {
    9906           0 :                             if (SolarOnWindow > SetPoint) shadingOn = true;
    9907           0 :                         } else if (!state.dataEnvrn->SunIsUp && SchedAllowsControl) {
    9908           0 :                             shadingOn = true;
    9909           0 :                         } else if (GlareControlIsActive) {
    9910           0 :                             shadingOffButGlareControlOn = true;
    9911             :                         }
    9912             :                     }
    9913           0 :                     break;
    9914           0 :                 default:
    9915           0 :                     ShowWarningError(state, "Invalid Selection of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name);
    9916             :                 }
    9917             : 
    9918      489327 :                 WinShadingType ShType = state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingType;
    9919             : 
    9920      489327 :                 state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ShadeOff; // Initialize shading flag to off
    9921             : 
    9922      489327 :                 if (IS_SHADED(ShType)) {
    9923      489327 :                     if (shadingOn) {
    9924       71475 :                         state.dataSurface->SurfWinShadingFlag(ISurf) = ShType;
    9925      417852 :                     } else if (shadingOffButGlareControlOn) {
    9926       88747 :                         if (ShType == WinShadingType::SwitchableGlazing)
    9927       84939 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::GlassConditionallyLightened;
    9928        3808 :                         else if (ShType == WinShadingType::IntShade)
    9929         616 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShadeConditionallyOff;
    9930        3192 :                         else if (ShType == WinShadingType::ExtShade)
    9931        3192 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShadeConditionallyOff;
    9932           0 :                         else if (ShType == WinShadingType::IntBlind)
    9933           0 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntBlindConditionallyOff;
    9934           0 :                         else if (ShType == WinShadingType::ExtBlind)
    9935           0 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtBlindConditionallyOff;
    9936           0 :                         else if (ShType == WinShadingType::BGShade)
    9937           0 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGShadeConditionallyOff;
    9938           0 :                         else if (ShType == WinShadingType::BGBlind)
    9939           0 :                             state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGBlindConditionallyOff;
    9940             :                     }
    9941             :                 }
    9942             : 
    9943             :                 // Set switching factor to fully switched if ShadingFlag = 2
    9944      489327 :                 if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::SwitchableGlazing) {
    9945           0 :                     state.dataSurface->SurfWinSwitchingFactor(ISurf) = 1.0;
    9946             : 
    9947             :                     // Added TH 1/20/2010
    9948             :                     // Vis trans at normal incidence of fully switched glass
    9949           0 :                     IConst = state.dataSurface->Surface(ISurf).activeShadedConstruction;
    9950           0 :                     state.dataSurface->SurfWinVisTransSelected(ISurf) =
    9951           0 :                         POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf);
    9952             :                 }
    9953             : 
    9954             :                 // Slat angle control for blinds
    9955             : 
    9956      489327 :                 state.dataSurface->SurfWinSlatAngThisTS(ISurf) = 0.0;
    9957      489327 :                 state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0;
    9958      489327 :                 state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = false;
    9959     1439673 :                 if (ANY_BLIND(state.dataSurface->SurfWinShadingFlag(ISurf)) ||
    9960      922038 :                     state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntBlindConditionallyOff ||
    9961     1411365 :                     state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtBlindConditionallyOff ||
    9962      461019 :                     state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::BGBlindConditionallyOff) {
    9963             :                     // Blind in place or may be in place due to glare control
    9964       28308 :                     int BlNum = state.dataSurface->SurfWinBlindNumber(ISurf);
    9965       28308 :                     if (BlNum > 0) {
    9966       28308 :                         Real64 InputSlatAngle = state.dataHeatBal->Blind(BlNum).SlatAngle *
    9967       28308 :                                                 DataGlobalConstants::DegToRadians; // Slat angle of associated Material:WindowBlind (rad)
    9968             :                         Real64 ProfAng;                                            // Solar profile angle (rad)
    9969             :                         Real64 SlatAng;                                            // Slat angle this time step (rad)
    9970             :                         Real64 PermeabilityA;                                      // Intermediate variables in blind permeability calc
    9971             :                         Real64 PermeabilityB;
    9972             :                         Real64 ThetaBase;   // Intermediate slat angle variable (rad)
    9973             :                         Real64 ThetaBlock1; // Slat angles that just block beam solar (rad)
    9974             :                         Real64 ThetaBlock2;
    9975             : 
    9976       56616 :                         DaylightingManager::ProfileAngle(state,
    9977             :                                                          ISurf,
    9978       28308 :                                                          state.dataEnvrn->SOLCOS,
    9979       28308 :                                                          state.dataHeatBal->Blind(BlNum).SlatOrientation,
    9980       28308 :                                                          state.dataSurface->SurfWinProfileAng(ISurf));
    9981       28308 :                         ProfAng = state.dataSurface->SurfWinProfileAng(ISurf);
    9982       28308 :                         if (ProfAng > DataGlobalConstants::PiOvr2 || ProfAng < -DataGlobalConstants::PiOvr2) {
    9983           0 :                             ProfAng = min(max(ProfAng, -DataGlobalConstants::PiOvr2), DataGlobalConstants::PiOvr2);
    9984             :                         }
    9985       28308 :                         int ProfAngIndex = int((ProfAng + DataGlobalConstants::PiOvr2) / DeltaProfAng) + 1;
    9986       28308 :                         state.dataSurface->SurfWinProfAngIndex(ISurf) = ProfAngIndex;
    9987       28308 :                         state.dataSurface->SurfWinProfAngInterpFac(ISurf) =
    9988       28308 :                             (ProfAng + DataGlobalConstants::PiOvr2 - (ProfAngIndex - 1) * DeltaProfAng) / DeltaProfAng;
    9989             : 
    9990       28308 :                         if (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) {
    9991       13090 :                             ProfAng = state.dataSurface->SurfWinProfileAng(ISurf);
    9992       26180 :                             Real64 ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation /
    9993       26180 :                                                          state.dataHeatBal->Blind(BlNum).SlatWidth);
    9994             :                             // There are two solutions for the slat angle that just blocks beam radiation
    9995       13090 :                             ThetaBlock1 = ProfAng + ThetaBase;
    9996       13090 :                             ThetaBlock2 = ProfAng + DataGlobalConstants::Pi - ThetaBase;
    9997       13090 :                             state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2);
    9998       13090 :                             state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2);
    9999       13090 :                             state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians;
   10000       13090 :                             state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians;
   10001             :                         }
   10002             : 
   10003             :                         // TH 5/20/2010, CR 8064: Slat Width <= Slat Separation
   10004       28308 :                         if (state.dataHeatBal->Blind(BlNum).SlatWidth <= state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) {
   10005           0 :                             if (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl == SlatAngleControl::BlockBeamSolar) {
   10006           0 :                                 ProfAng = state.dataSurface->SurfWinProfileAng(ISurf);
   10007           0 :                                 if (std::abs(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation /
   10008           0 :                                              state.dataHeatBal->Blind(BlNum).SlatWidth) <= 1.0) {
   10009             :                                     // set to block 100% of beam solar, not necessarily to block maximum solar (beam + diffuse)
   10010           0 :                                     ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation /
   10011           0 :                                                           state.dataHeatBal->Blind(BlNum).SlatWidth);
   10012           0 :                                     state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10013             :                                 } else {
   10014             :                                     // cannot block 100% of beam solar, turn slats to be perpendicular to sun beam to block maximal beam solar
   10015           0 :                                     ThetaBase = 0.0;
   10016             :                                 }
   10017             : 
   10018             :                                 // There are two solutions for the slat angle that just blocks beam radiation
   10019           0 :                                 ThetaBlock1 = ProfAng + ThetaBase;
   10020           0 :                                 ThetaBlock2 = ProfAng - ThetaBase + DataGlobalConstants::Pi;
   10021             : 
   10022           0 :                                 state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2);
   10023           0 :                                 state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2);
   10024           0 :                                 state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians;
   10025           0 :                                 state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians;
   10026             :                             }
   10027             :                         }
   10028             : 
   10029       28308 :                         switch (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl) {
   10030       25177 :                         case SlatAngleControl::Fixed: { // 'FIXEDSLATANGLE'
   10031       25177 :                             state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle;
   10032       55834 :                             if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall ||
   10033       30494 :                                  state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) &&
   10034       75205 :                                 (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) &&
   10035             :                                 (BeamSolarOnWindow > 0.0))
   10036       11991 :                                 state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10037       25177 :                         } break;
   10038           0 :                         case SlatAngleControl::Scheduled: { // 'SCHEDULEDSLATANGLE'
   10039           0 :                             state.dataSurface->SurfWinSlatAngThisTS(ISurf) =
   10040           0 :                                 GetCurrentScheduleValue(state, state.dataSurface->WindowShadingControl(IShadingCtrl).SlatAngleSchedule);
   10041           0 :                             state.dataSurface->SurfWinSlatAngThisTS(ISurf) =
   10042           0 :                                 max(state.dataHeatBal->Blind(BlNum).MinSlatAngle,
   10043           0 :                                     min(state.dataSurface->SurfWinSlatAngThisTS(ISurf), state.dataHeatBal->Blind(BlNum).MaxSlatAngle)) *
   10044             :                                 DataGlobalConstants::DegToRadians;
   10045           0 :                             if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall ||
   10046           0 :                                  state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) &&
   10047           0 :                                 (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) &&
   10048             :                                 (BeamSolarOnWindow > 0.0))
   10049           0 :                                 state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10050           0 :                         } break;
   10051        3131 :                         case SlatAngleControl::BlockBeamSolar: { // 'BLOCKBEAMSOLAR'
   10052        3131 :                             if (BeamSolarOnWindow > 0.0) {
   10053        1092 :                                 if (state.dataHeatBal->Blind(BlNum).SlatSeparation >= state.dataHeatBal->Blind(BlNum).SlatWidth) {
   10054             :                                     // TH 5/20/2010. CR 8064.
   10055             :                                     // The following line of code assumes slats are always vertical/closed to minimize solar penetration
   10056             :                                     // The slat angle can however change if the only goal is to block maximum amount of direct beam solar
   10057             :                                     // SurfaceWindow(ISurf)%SlatAngThisTS = 0.0  ! Allows beam penetration but minimizes it
   10058             : 
   10059           0 :                                     if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin &&
   10060           0 :                                         state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) {
   10061           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall;
   10062           0 :                                     } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin &&
   10063           0 :                                                state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) {
   10064           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig;
   10065           0 :                                     } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin &&
   10066           0 :                                                state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) {
   10067           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
   10068           0 :                                     } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax &&
   10069           0 :                                                state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) {
   10070           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax;
   10071             :                                     } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition)
   10072           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
   10073             :                                     }
   10074             : 
   10075             :                                 } else { // Usual case -- slat width greater than slat separation
   10076        2184 :                                     if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin &&
   10077        1092 :                                         state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) {
   10078        1071 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall;
   10079        1071 :                                         state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10080          42 :                                     } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin &&
   10081          21 :                                                state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) {
   10082           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig;
   10083           0 :                                         state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10084          21 :                                     } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin &&
   10085           0 :                                                state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) {
   10086           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
   10087           0 :                                         state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10088          42 :                                     } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax &&
   10089          21 :                                                state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) {
   10090          21 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax;
   10091          21 :                                         state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
   10092             :                                     } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition)
   10093           0 :                                         state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
   10094             :                                     }
   10095             :                                 }
   10096             :                             } else {
   10097        2039 :                                 state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle;
   10098             :                             }
   10099        3131 :                         } break;
   10100           0 :                         default:
   10101           0 :                             break;
   10102             :                         }
   10103             : 
   10104       28308 :                         state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) =
   10105       28308 :                             state.dataSurface->SurfWinSlatAngThisTS(ISurf) / DataGlobalConstants::DegToRadians;
   10106       28308 :                         if (state.dataSurface->SurfWinSlatAngThisTSDegEMSon(ISurf)) {
   10107           0 :                             state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = state.dataSurface->SurfWinSlatAngThisTSDegEMSValue(ISurf);
   10108           0 :                             state.dataSurface->SurfWinSlatAngThisTS(ISurf) =
   10109           0 :                                 DataGlobalConstants::DegToRadians * state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf);
   10110             :                         }
   10111             :                         // Air flow permeability for calculation of convective air flow between blind and glass
   10112       28308 :                         SlatAng = state.dataSurface->SurfWinSlatAngThisTS(ISurf);
   10113       28308 :                         PermeabilityA =
   10114       28308 :                             std::sin(SlatAng) - state.dataHeatBal->Blind(BlNum).SlatThickness / state.dataHeatBal->Blind(BlNum).SlatSeparation;
   10115       84924 :                         PermeabilityB = 1.0 - (std::abs(state.dataHeatBal->Blind(BlNum).SlatWidth * std::cos(SlatAng)) +
   10116       56616 :                                                state.dataHeatBal->Blind(BlNum).SlatThickness * std::sin(SlatAng)) /
   10117       28308 :                                                   state.dataHeatBal->Blind(BlNum).SlatSeparation;
   10118       28308 :                         state.dataSurface->SurfWinBlindAirFlowPermeability(ISurf) = min(1.0, max(0.0, PermeabilityA, PermeabilityB));
   10119       84924 :                         state.dataSurface->SurfWinBlindBmBmTrans(ISurf) = General::BlindBeamBeamTrans(ProfAng,
   10120             :                                                                                                       SlatAng,
   10121       28308 :                                                                                                       state.dataHeatBal->Blind(BlNum).SlatWidth,
   10122       28308 :                                                                                                       state.dataHeatBal->Blind(BlNum).SlatSeparation,
   10123       28308 :                                                                                                       state.dataHeatBal->Blind(BlNum).SlatThickness);
   10124             :                         // Calculate blind interpolation factors and indices.
   10125       28308 :                         if (state.dataSurface->SurfWinMovableSlats(ISurf)) {
   10126        3131 :                             if (SlatAng > DataGlobalConstants::Pi || SlatAng < 0.0) {
   10127           0 :                                 SlatAng = min(max(SlatAng, 0.0), DataGlobalConstants::Pi);
   10128             :                             }
   10129        3131 :                             Real64 SlatsAngIndex = 1 + int(SlatAng * DeltaAng_inv);
   10130        3131 :                             state.dataSurface->SurfWinSlatsAngIndex(ISurf) = SlatsAngIndex;
   10131        3131 :                             state.dataSurface->SurfWinSlatsAngInterpFac(ISurf) = (SlatAng - DeltaAng * (SlatsAngIndex - 1)) * DeltaAng_inv;
   10132             :                         }
   10133             :                     }
   10134             :                 } // End of check if interior or exterior or between glass blind in place
   10135             : 
   10136             :                 //   CALL CalcScreenTransmittance to intialized all screens prior to HB calc's
   10137      489327 :                 if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtScreen && state.dataEnvrn->SunIsUp) {
   10138        3248 :                     CalcScreenTransmittance(state, ISurf);
   10139             :                 }
   10140             : 
   10141             :                 // EMS Actuator Point: override setting if ems flag on
   10142      489327 :                 if (state.dataSurface->SurfWinShadingFlagEMSOn(ISurf)) {
   10143       48400 :                     WinShadingType SurfWinShadingFlagEMS = findValueInEnumeration(state.dataSurface->SurfWinShadingFlagEMSValue(ISurf));
   10144       48400 :                     if (SurfWinShadingFlagEMS != WinShadingType::Invalid) {
   10145       48400 :                         state.dataSurface->SurfWinShadingFlag(ISurf) = SurfWinShadingFlagEMS;
   10146             :                     } else {
   10147           0 :                         ShowWarningError(state,
   10148           0 :                                          "Invalid EMS value of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name);
   10149             :                     }
   10150             :                 }
   10151             :             } // End of surface loop
   10152             :         }
   10153             :     }
   10154     2568509 : }
   10155             : 
   10156     2568509 : void CheckGlazingShadingStatusChange(EnergyPlusData &state)
   10157             : {
   10158     2568509 :     if (state.dataGlobal->BeginSimFlag) {
   10159         771 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
   10160           2 :             state.dataHeatBal->EnclRadAlwaysReCalc = true;
   10161             :         } else {
   10162        5581 :             for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
   10163        9628 :                 for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
   10164        4816 :                     auto &thisSpace = state.dataHeatBal->space(spaceNum);
   10165       46998 :                     for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
   10166       84367 :                         if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TCFlag == 1 ||
   10167       42183 :                             state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) {
   10168           2 :                             state.dataHeatBal->EnclRadAlwaysReCalc = true;
   10169           2 :                             break;
   10170             :                         }
   10171             :                     }
   10172             :                 }
   10173             :             }
   10174             :         }
   10175         771 :         if (state.dataHeatBal->EnclRadAlwaysReCalc) {
   10176          13 :             for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
   10177           9 :                 state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = true;
   10178             :             }
   10179          13 :             for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
   10180           9 :                 state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = true;
   10181             :             }
   10182             :         }
   10183             :     }
   10184     2568509 :     if (state.dataHeatBal->EnclRadAlwaysReCalc) return;
   10185             : 
   10186     2559053 :     if (state.dataGlobal->BeginEnvrnFlag || state.dataGlobal->AnyConstrOverridesInModel || state.dataGlobal->AnySurfPropOverridesInModel) {
   10187       94718 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
   10188       82476 :             state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = true;
   10189             :         }
   10190       94718 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
   10191       82476 :             state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = true;
   10192             :         }
   10193       12242 :         return;
   10194             :     }
   10195    20869059 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
   10196    18322248 :         state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = false;
   10197             :     }
   10198    20869059 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
   10199    18322248 :         state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = false;
   10200             :     }
   10201     2546811 :     if (!state.dataGlobal->AndShadingControlInModel) return;
   10202      818524 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
   10203     6719931 :         for (int const SurfNum : state.dataViewFactor->EnclRadInfo(enclosureNum).SurfacePtr) {
   10204             :             bool surfShadingStatusChange =
   10205    12145755 :                 state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) != state.dataSurface->SurfWinShadingFlag(SurfNum) ||
   10206    12145755 :                 state.dataSurface->Surface(SurfNum).activeShadedConstruction != state.dataSurface->Surface(SurfNum).activeShadedConstructionPrev ||
   10207    12145755 :                 state.dataSurface->SurfWinMovableSlats(SurfNum);
   10208     6093056 :             if (surfShadingStatusChange) {
   10209       46389 :                 state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = true;
   10210       46389 :                 state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = true;
   10211       46389 :                 break;
   10212             :             }
   10213             :         }
   10214             :     }
   10215             : }
   10216             : 
   10217       48400 : DataSurfaces::WinShadingType findValueInEnumeration(Real64 controlValue)
   10218             : {
   10219             :     // This is a workaround to translate EMS Shading control numerical values
   10220             :     // EMS control of window shading devices involves setting the control values for shading control actuators with
   10221             :     // one of these values.  The variable names can be used or replaced, it is the whole number values that trigger
   10222             :     // changes in the modeling.
   10223             :     // Shades and Blinds are either fully on or fully off, partial positions require multiple windows.
   10224             :     // the window shading control flag values follow
   10225             :     // -1: if window has no shading device
   10226             :     // 0: if shading device is off
   10227             :     // 1: if interior shade is on
   10228             :     // 2: if glazing is switched to darker state
   10229             :     // 3: if exterior shade is on
   10230             :     // 4: if exterior screen is on
   10231             :     // 6: if interior blind is on
   10232             :     // 7: if exterior blind is on
   10233             :     // 8: if between-glass shade is on
   10234             :     // 9: if between-glass blind is on
   10235             :     // 10: window has interior shade that is off but may be triggered on later to control daylight glare
   10236             :     // 20: window has switchable glazing that is unswitched but may be switched later to control daylight glare or
   10237             :     // daylight illuminance 30: window has exterior shade that is off but may be triggered on later to control
   10238             :     // daylight glare or daylight illuminance 60: window has interior blind that is off but may be triggered on later
   10239             :     // to control daylight glare or daylight illuminance 70: window has exterior blind that is off but may be
   10240             :     // triggered on later to control daylight glare or daylight illuminance 80: window has between-glass shade that is
   10241             :     // off but may be triggered on later to control daylight glare or daylight illuminance 90: window has
   10242             :     // between-glass blind that is off but may be triggered on later to control daylight glare or daylight illuminance
   10243       48400 :     if (controlValue == -1.0) return WinShadingType::NoShade;
   10244       48400 :     if (controlValue == 0.0) return WinShadingType::ShadeOff;
   10245       16204 :     if (controlValue == 1.0) return WinShadingType::IntShade;
   10246       16204 :     if (controlValue == 2.0) return WinShadingType::SwitchableGlazing;
   10247       16204 :     if (controlValue == 3.0) return WinShadingType::ExtShade;
   10248       16204 :     if (controlValue == 4.0) return WinShadingType::ExtScreen;
   10249       16204 :     if (controlValue == 6.0) return WinShadingType::IntBlind;
   10250           0 :     if (controlValue == 7.0) return WinShadingType::ExtBlind;
   10251           0 :     if (controlValue == 8.0) return WinShadingType::BGShade;
   10252           0 :     if (controlValue == 9.0) return WinShadingType::BGBlind;
   10253           0 :     if (controlValue == 10.0) return WinShadingType::IntShadeConditionallyOff;
   10254           0 :     if (controlValue == 20.0) return WinShadingType::GlassConditionallyLightened;
   10255           0 :     if (controlValue == 30.0) return WinShadingType::ExtShadeConditionallyOff;
   10256           0 :     if (controlValue == 60.0) return WinShadingType::IntBlindConditionallyOff;
   10257           0 :     if (controlValue == 70.0) return WinShadingType::ExtBlindConditionallyOff;
   10258           0 :     if (controlValue == 80.0) return WinShadingType::BGShadeConditionallyOff;
   10259           0 :     if (controlValue == 90.0) return WinShadingType::BGBlindConditionallyOff;
   10260           0 :     return WinShadingType::Invalid;
   10261             : }
   10262             : 
   10263      489327 : int selectActiveWindowShadingControlIndex(EnergyPlusData &state, int curSurface)
   10264             : {
   10265             :     // For a given surface, determine based on the schedules which index to the window shading control list vector
   10266             :     // should be active
   10267      489327 :     int selected = 0; // presume it is the first shading control - even if it is not active it needs to be some
   10268             :                       // shading control which is then turned off in the WindowShadingManager
   10269      489327 :     if (state.dataSurface->Surface(curSurface).windowShadingControlList.size() > 1) {
   10270       10476 :         for (std::size_t listIndex = 0; listIndex < state.dataSurface->Surface(curSurface).windowShadingControlList.size(); ++listIndex) {
   10271        6996 :             int wsc = state.dataSurface->Surface(curSurface).windowShadingControlList[listIndex];
   10272             :             // pick the first WindowShadingControl that has a non-zero schedule value
   10273        6996 :             if (ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->WindowShadingControl(wsc).Schedule) > 0.0) {
   10274          24 :                 selected = listIndex;
   10275          24 :                 break;
   10276             :             }
   10277             :         }
   10278             :     }
   10279      489327 :     return (selected);
   10280             : }
   10281             : 
   10282        4044 : void WindowGapAirflowControl(EnergyPlusData &state)
   10283             : {
   10284             : 
   10285             :     // SUBROUTINE INFORMATION:
   10286             :     //       AUTHOR         Fred Winkelmann
   10287             :     //       DATE WRITTEN   February 2003
   10288             :     //       MODIFIED       June 2003, FCW: add fatal error for illegal schedule value
   10289             :     //       RE-ENGINEERED  na
   10290             : 
   10291             :     // PURPOSE OF THIS SUBROUTINE:
   10292             :     // For airflow windows, determines the airflow in the gap of
   10293             :     // double glazing and in the inner gap of triple glazing.
   10294             : 
   10295             :     // REFERENCES:
   10296             :     // na
   10297             : 
   10298             :     // Using/Aliasing
   10299             :     using ScheduleManager::GetCurrentScheduleValue;
   10300             : 
   10301       16176 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
   10302       24264 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
   10303       12132 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
   10304       12132 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
   10305       12132 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
   10306       44484 :             for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) {
   10307             : 
   10308       32352 :                 state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0;
   10309       32352 :                 if (state.dataSurface->SurfWinMaxAirflow(ISurf) == 0.0) continue;
   10310       16176 :                 if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue;
   10311       16176 :                 switch (state.dataSurface->SurfWinAirflowControlType(ISurf)) {
   10312       16176 :                 case WindowAirFlowControlType::MaxFlow: {
   10313       16176 :                     state.dataSurface->SurfWinAirflowThisTS(ISurf) = state.dataSurface->SurfWinMaxAirflow(ISurf);
   10314       16176 :                 } break;
   10315           0 :                 case WindowAirFlowControlType::AlwaysOff: {
   10316           0 :                     state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0;
   10317           0 :                 } break;
   10318           0 :                 case WindowAirFlowControlType::Schedule: {
   10319           0 :                     if (state.dataSurface->SurfWinAirflowHasSchedule(ISurf)) {
   10320           0 :                         int SchedulePtr = state.dataSurface->SurfWinAirflowSchedulePtr(ISurf); // Schedule pointer
   10321           0 :                         Real64 ScheduleMult = GetCurrentScheduleValue(state, SchedulePtr);     // Multiplier value from schedule
   10322           0 :                         if (ScheduleMult < 0.0 || ScheduleMult > 1.0) {
   10323           0 :                             ShowFatalError(state,
   10324           0 :                                            "Airflow schedule has a value outside the range 0.0 to 1.0 for window=" +
   10325           0 :                                                state.dataSurface->Surface(ISurf).Name);
   10326             :                         }
   10327           0 :                         state.dataSurface->SurfWinAirflowThisTS(ISurf) = ScheduleMult * state.dataSurface->SurfWinMaxAirflow(ISurf);
   10328             :                     }
   10329           0 :                 } break;
   10330           0 :                 default:
   10331           0 :                     break;
   10332             :                 }
   10333             :             } // End of surface loop
   10334             :         }     // End of space loop
   10335             :     }         // End of zone loop
   10336        4044 : }
   10337             : 
   10338         771 : void SkyDifSolarShading(EnergyPlusData &state)
   10339             : {
   10340             : 
   10341             :     // SUBROUTINE INFORMATION:
   10342             :     //       AUTHOR         Fred Winkelmann
   10343             :     //       DATE WRITTEN   May 1999
   10344             :     //       MODIFIED       Sep 2000, FCW: add IR view factor calc
   10345             :     //                      Sep 2002, FCW: correct error in expression for ground IR view factor.
   10346             :     //                         Affects only non-vertical surfaces that are shadowed. For these surfaces
   10347             :     //                         error caused underestimate of IR from ground and shadowing surfaces.
   10348             :     //                      Dec 2002; LKL: Sky Radiance Distribution now only anisotropic
   10349             :     //                      Nov 2003: FCW: modify to do sky solar shading of shadowing surfaces
   10350             :     //       RE-ENGINEERED  na
   10351             : 
   10352             :     // PURPOSE OF THIS SUBROUTINE:
   10353             :     // Calculates factors that account for shading of sky diffuse
   10354             :     // solar radiation by shadowing surfaces such as overhangs and detached
   10355             :     // shades.
   10356             :     // Called by PerformSolarCalculations
   10357             :     // For each exterior heat transfer surface calculates the following
   10358             :     // ratio (called DifShdgRatioIsoSky in this subroutine):
   10359             :     //  R1 = (Diffuse solar from sky dome on surface, with shading)/
   10360             :     //       (Diffuse solar from sky dome on surface, without shading)
   10361             :     // To calculate the incident diffuse radiation on a surface the sky
   10362             :     // hemisphere is divided into source elements ("patches"). Each patch
   10363             :     // is assumed to have the same radiance, i.e. the sky radiance is isotropic.
   10364             :     // The irradiance from each patch on a surface is calculated. Then these
   10365             :     // irradiances are summed to get the net irradiance on a surface, which
   10366             :     // the denominator of R1.
   10367             :     // To get the numerator of R1 the same summation is done, but for each surface
   10368             :     // and each patch the Shadow subroutine is called to determine how much
   10369             :     // radiation from a patch is blocked by shading surfaces.
   10370             :     // Also calculated is the following ratio (called DifShdgRatioHoriz in this routine):
   10371             :     //  R2 = (Diffuse solar from sky horizon band on surface, with shading)/
   10372             :     //       (Diffuse solar from sky horizon band on surface, without shading)
   10373             :     // For this ratio only a band of sky just above the horizon is considered.
   10374             :     // R1 and R2 are used in SUBROUTINE AnisoSkyViewFactors, which determines the
   10375             :     // sky diffuse solar irradiance on each exterior heat transfer surface each
   10376             :     // time step. In that routine the sky radiance distribution is a superposition
   10377             :     // of an isotropic distribution,
   10378             :     // a horizon brightening distribution and a circumsolar brightening distribution,
   10379             :     // where the proportion of each distribution depends
   10380             :     // on cloud cover, sun position and other factors. R1 multiplies the irradiance
   10381             :     // due to the isotropic component and R2 multiplies the irradiance due to the
   10382             :     // horizon brightening component.
   10383             :     // Calculates sky and ground IR view factors assuming sky IR is isotropic and
   10384             :     // shadowing surfaces are opaque to IR.
   10385             : 
   10386             :     // Using/Aliasing
   10387             : 
   10388             :     Real64 Fac1WoShdg;      // Intermediate calculation factor, without shading
   10389             :     Real64 FracIlluminated; // Fraction of surface area illuminated by a sky patch
   10390             :     Real64 Fac1WithShdg;    // Intermediate calculation factor, with shading
   10391             :     Real64 SurfArea;        // Surface area (m2)
   10392             :     // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WithShdgIsoSky     ! Diffuse solar irradiance from isotropic
   10393             :     //                                                          ! sky on surface, with shading
   10394             :     // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgIsoSky       ! Diffuse solar from isotropic
   10395             :     //                                                           ! sky on surface, without shading
   10396             :     // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WithShdgHoriz      ! Diffuse solar irradiance from horizon portion
   10397             :     // of
   10398             :     //                                                           ! sky on surface, with shading
   10399             :     // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgHoriz        ! Diffuse solar irradiance from horizon portion
   10400             :     // of
   10401             :     //                                                           ! sky on surface, without shading
   10402             :     // INTEGER iHour,iTS
   10403             : 
   10404             :     // Initialize Surfaces Arrays
   10405         771 :     bool detailedShading = state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
   10406         771 :                            state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal;
   10407         771 :     state.dataSolarShading->SurfSunlitArea = 0.0;
   10408         771 :     state.dataSolarShading->SurfWithShdgIsoSky.dimension(state.dataSurface->TotSurfaces, 0.0);
   10409         771 :     state.dataSolarShading->SurfWoShdgIsoSky.dimension(state.dataSurface->TotSurfaces, 0.0);
   10410         771 :     state.dataSolarShading->SurfWithShdgHoriz.dimension(state.dataSurface->TotSurfaces, 0.0);
   10411         771 :     state.dataSolarShading->SurfWoShdgHoriz.dimension(state.dataSurface->TotSurfaces, 0.0);
   10412         771 :     state.dataSolarShading->SurfDifShdgRatioIsoSky.allocate(state.dataSurface->TotSurfaces);
   10413         771 :     state.dataSolarShading->SurfDifShdgRatioHoriz.allocate(state.dataSurface->TotSurfaces);
   10414             :     // initialized as no shading
   10415         771 :     state.dataSolarShading->SurfDifShdgRatioIsoSky = 1.0;
   10416         771 :     state.dataSolarShading->SurfDifShdgRatioHoriz = 1.0;
   10417         771 :     if (detailedShading) {
   10418           0 :         state.dataSolarShading->SurfCurDifShdgRatioIsoSky.dimension(state.dataSurface->TotSurfaces, 1.0);
   10419           0 :         state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, state.dataSurface->TotSurfaces);
   10420           0 :         state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS = 1.0;
   10421           0 :         state.dataSolarShading->SurfDifShdgRatioHorizHRTS.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, state.dataSurface->TotSurfaces);
   10422           0 :         state.dataSolarShading->SurfDifShdgRatioHorizHRTS = 1.0;
   10423             :     }
   10424             : 
   10425       19152 :     for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
   10426             : 
   10427             :         // CurrentModuleObject='Surfaces'
   10428       18381 :         if (detailedShading) {
   10429           0 :             SetupOutputVariable(state,
   10430             :                                 "Debug Surface Solar Shading Model DifShdgRatioIsoSky",
   10431             :                                 OutputProcessor::Unit::None,
   10432           0 :                                 state.dataSolarShading->SurfCurDifShdgRatioIsoSky(SurfNum),
   10433             :                                 OutputProcessor::SOVTimeStepType::Zone,
   10434             :                                 OutputProcessor::SOVStoreType::Average,
   10435           0 :                                 state.dataSurface->Surface(SurfNum).Name);
   10436             :         } else {
   10437       55143 :             SetupOutputVariable(state,
   10438             :                                 "Debug Surface Solar Shading Model DifShdgRatioIsoSky",
   10439             :                                 OutputProcessor::Unit::None,
   10440       18381 :                                 state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum),
   10441             :                                 OutputProcessor::SOVTimeStepType::Zone,
   10442             :                                 OutputProcessor::SOVStoreType::Average,
   10443       36762 :                                 state.dataSurface->Surface(SurfNum).Name);
   10444             :         }
   10445       55143 :         SetupOutputVariable(state,
   10446             :                             "Debug Surface Solar Shading Model DifShdgRatioHoriz",
   10447             :                             OutputProcessor::Unit::None,
   10448       18381 :                             state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum),
   10449             :                             OutputProcessor::SOVTimeStepType::Zone,
   10450             :                             OutputProcessor::SOVStoreType::Average,
   10451       36762 :                             state.dataSurface->Surface(SurfNum).Name);
   10452       55143 :         SetupOutputVariable(state,
   10453             :                             "Debug Surface Solar Shading Model WithShdgIsoSky",
   10454             :                             OutputProcessor::Unit::None,
   10455       18381 :                             state.dataSolarShading->SurfWithShdgIsoSky(SurfNum),
   10456             :                             OutputProcessor::SOVTimeStepType::Zone,
   10457             :                             OutputProcessor::SOVStoreType::Average,
   10458       36762 :                             state.dataSurface->Surface(SurfNum).Name);
   10459       55143 :         SetupOutputVariable(state,
   10460             :                             "Debug Surface Solar Shading Model WoShdgIsoSky",
   10461             :                             OutputProcessor::Unit::None,
   10462       18381 :                             state.dataSolarShading->SurfWoShdgIsoSky(SurfNum),
   10463             :                             OutputProcessor::SOVTimeStepType::Zone,
   10464             :                             OutputProcessor::SOVStoreType::Average,
   10465       36762 :                             state.dataSurface->Surface(SurfNum).Name);
   10466             :     }
   10467             : 
   10468        5397 :     for (int IPhi = 0; IPhi < NPhi; ++IPhi) { // Loop over patch altitude values
   10469        4626 :         state.dataSolarShading->SUNCOS(3) = state.dataSolarShading->sin_Phi[IPhi];
   10470             : 
   10471      115650 :         for (int ITheta = 0; ITheta < NTheta; ++ITheta) { // Loop over patch azimuth values
   10472      111024 :             state.dataSolarShading->SUNCOS(1) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->cos_Theta[ITheta];
   10473      111024 :             state.dataSolarShading->SUNCOS(2) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->sin_Theta[ITheta];
   10474             : 
   10475     2775744 :             for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
   10476             :                 // Cosine of angle of incidence on surface of solar radiation from patch
   10477     2664720 :                 state.dataSolarShading->SurfSunCosTheta(SurfNum) =
   10478     5329440 :                     state.dataSolarShading->SUNCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
   10479     5329440 :                     state.dataSolarShading->SUNCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
   10480     2664720 :                     state.dataSolarShading->SUNCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
   10481             :             }
   10482             : 
   10483      111024 :             SHADOW(state, 24, 0);
   10484             : 
   10485     2775744 :             for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
   10486             : 
   10487     2664720 :                 if (state.dataSolarShading->SurfSunCosTheta(SurfNum) < 0.0) continue;
   10488             : 
   10489     1530123 :                 Fac1WoShdg = state.dataSolarShading->cos_Phi[IPhi] * DThetaDPhi * state.dataSolarShading->SurfSunCosTheta(SurfNum);
   10490     1530123 :                 SurfArea = state.dataSurface->Surface(SurfNum).NetAreaShadowCalc;
   10491     1530123 :                 if (SurfArea > Eps) {
   10492     1530123 :                     FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
   10493             :                 } else {
   10494           0 :                     FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / (SurfArea + Eps);
   10495             :                 }
   10496     1530123 :                 Fac1WithShdg = Fac1WoShdg * FracIlluminated;
   10497     1530123 :                 state.dataSolarShading->SurfWithShdgIsoSky(SurfNum) += Fac1WithShdg;
   10498     1530123 :                 state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) += Fac1WoShdg;
   10499             : 
   10500             :                 // Horizon region
   10501     1530123 :                 if (IPhi == 0) {
   10502      253154 :                     state.dataSolarShading->SurfWithShdgHoriz(SurfNum) += Fac1WithShdg;
   10503      253154 :                     state.dataSolarShading->SurfWoShdgHoriz(SurfNum) += Fac1WoShdg;
   10504             :                 }
   10505             :             } // End of surface loop
   10506             :         }     // End of Theta loop
   10507             :     }         // End of Phi loop
   10508             : 
   10509       19276 :     for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
   10510             : 
   10511       18505 :         if (std::abs(state.dataSolarShading->SurfWoShdgIsoSky(SurfNum)) > Eps) {
   10512       17831 :             state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum) =
   10513       17831 :                 (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum));
   10514             :         } else {
   10515         674 :             state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum) =
   10516         674 :                 (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) + Eps);
   10517             :         }
   10518       18505 :         if (std::abs(state.dataSolarShading->SurfWoShdgHoriz(SurfNum)) > Eps) {
   10519       17831 :             state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum) =
   10520       17831 :                 (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum));
   10521             :         } else {
   10522         674 :             state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum) =
   10523         674 :                 (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum) + Eps);
   10524             :         }
   10525             :     }
   10526             : 
   10527             :     // Get IR view factors. An exterior surface can receive IR radiation from
   10528             :     // sky, ground or shadowing surfaces. Assume shadowing surfaces have same
   10529             :     // temperature as outside air (and therefore same temperature as ground),
   10530             :     // so that the view factor to these shadowing surfaces can be included in
   10531             :     // the ground view factor. Sky IR is assumed to be isotropic and shadowing
   10532             :     // surfaces are assumed to be opaque to IR so they totally "shade" IR from
   10533             :     // sky or ground.
   10534             : 
   10535       44533 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
   10536       43762 :         if (!state.dataSysVars->DetailedSkyDiffuseAlgorithm || !state.dataSurface->ShadingTransmittanceVaries ||
   10537           0 :             state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
   10538       43762 :             state.dataSurface->Surface(SurfNum).ViewFactorSkyIR *= state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum);
   10539             :         } else {
   10540           0 :             state.dataSurface->Surface(SurfNum).ViewFactorSkyIR *= state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(1, 1, SurfNum);
   10541             :         }
   10542       43762 :         state.dataSurface->Surface(SurfNum).ViewFactorGroundIR = 1.0 - state.dataSurface->Surface(SurfNum).ViewFactorSkyIR;
   10543             : 
   10544       43762 :         if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
   10545           6 :             Real64 SrdSurfsViewFactor = 0.0;
   10546           6 :             int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
   10547           6 :             auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
   10548          20 :             for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
   10549          14 :                 SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
   10550             :             }
   10551           6 :             state.dataSurface->Surface(SurfNum).ViewFactorGroundIR = 1.0 - state.dataSurface->Surface(SurfNum).ViewFactorSkyIR - SrdSurfsViewFactor;
   10552             :         }
   10553             :     }
   10554             : 
   10555             :     //  DEALLOCATE(WithShdgIsoSky)
   10556             :     //  DEALLOCATE(WoShdgIsoSky)
   10557             :     //  DEALLOCATE(WithShdgHoriz)
   10558             :     //  DEALLOCATE(WoShdgHoriz)
   10559             : 
   10560         771 :     if (state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
   10561           0 :         state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) {
   10562           0 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
   10563           0 :             state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}, SurfNum) =
   10564           0 :                 state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum);
   10565           0 :             state.dataSolarShading->SurfDifShdgRatioHorizHRTS({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}, SurfNum) =
   10566           0 :                 state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum);
   10567             :         }
   10568             :     }
   10569         771 : }
   10570             : 
   10571      822103 : void CalcWindowProfileAngles(EnergyPlusData &state)
   10572             : {
   10573             : 
   10574             :     // SUBROUTINE INFORMATION:
   10575             :     //       AUTHOR         Fred Winkelmann
   10576             :     //       DATE WRITTEN   April 2002
   10577             :     //       MODIFIED       na
   10578             :     //       RE-ENGINEERED  na
   10579             :     // PURPOSE OF THIS SUBROUTINE:
   10580             :     // Called by CalcPerSolarBeam for wholly or partially sunlit exterior windows
   10581             :     // Calculates horizontal and vertical beam solar profile angles
   10582             : 
   10583             :     Real64 ElevSun;       // Sun elevation; angle between sun and horizontal
   10584             :     Real64 ElevWin;       // Window elevation: angle between window outward normal and horizontal
   10585             :     Real64 AzimWin;       // Window azimuth (radians)
   10586             :     Real64 AzimSun;       // Sun azimuth (radians)
   10587             :     Real64 ProfileAngHor; // Solar profile angle (radians) for horizontally oriented window elements
   10588             :     // such as the top and bottom of a frame.
   10589             :     // This is the incidence angle in a plane that is normal to the window
   10590             :     // and parallel to the Y-axis of the window (the axis along
   10591             :     // which the height of the window is measured).
   10592             :     Real64 ProfileAngVert; // Solar profile angle (radians) for vertically oriented elements
   10593             :     // such as the sides of a frame.
   10594             :     // This is the incidence angle in a plane that is normal to the window
   10595             :     // and parallel to the X-axis of the window (the axis along
   10596             :     // which the width of the window is measured).
   10597     1644206 :     Vector3<Real64> WinNorm;                                  // Unit vector normal to window
   10598     1644206 :     Vector3<Real64> WinNormCrossBase;                         // Cross product of WinNorm and vector along window baseline
   10599     1644206 :     Vector3<Real64> SunPrime;                                 // Projection of sun vector onto plane (perpendicular to
   10600     1644206 :     Vector3<Real64> const SolCosVec(state.dataEnvrn->SOLCOS); // Local Vector3 copy for speed (until SOLCOS mig to Vector3)
   10601             :     //  window plane) determined by WinNorm and vector along
   10602             :     //  baseline of window
   10603             :     Real64 ThWin; // Azimuth angle of WinNorm (radians)
   10604             :     Real64 dot1;
   10605             :     Real64 dot2;
   10606             :     Real64 dot3;
   10607             : 
   10608      822103 :     ElevSun = DataGlobalConstants::PiOvr2 - std::acos(SolCosVec.z);
   10609      822103 :     AzimSun = std::atan2(SolCosVec.x, SolCosVec.y);
   10610             : 
   10611      822103 :     Real64 const cos_ElevSun = std::cos(ElevSun);
   10612      822103 :     Real64 const sin_ElevSun = std::sin(ElevSun);
   10613             : 
   10614     6670327 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
   10615    11701404 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
   10616     5853180 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
   10617     5853180 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
   10618     5853180 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
   10619    12978939 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
   10620             : 
   10621     7134269 :                 if (state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment &&
   10622        8510 :                     state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt)
   10623        8510 :                     continue;
   10624             : 
   10625     7117249 :                 state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
   10626     7117249 :                 state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
   10627     7117249 :                 if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue;
   10628             : 
   10629     3852155 :                 ElevWin = DataGlobalConstants::PiOvr2 - state.dataSurface->Surface(SurfNum).Tilt * DataGlobalConstants::DegToRadians;
   10630     3852155 :                 AzimWin = state.dataSurface->Surface(SurfNum).Azimuth * DataGlobalConstants::DegToRadians;
   10631             : 
   10632     3852155 :                 ProfileAngHor = std::atan(sin_ElevSun / std::abs(cos_ElevSun * std::cos(AzimWin - AzimSun))) - ElevWin;
   10633             : 
   10634             :                 // CR9280 - were having negative profile angles on west sides.  commenting out previous code
   10635             :                 // (original code) for vertical windows
   10636             :                 //  IF(ABS(ElevWin) < 0.1d0) THEN  ! Near-vertical window
   10637             :                 //    ProfileAngVert = ABS(AzimWin-AzimSun)
   10638             :                 //  ELSE
   10639     3852155 :                 WinNorm = state.dataSurface->Surface(SurfNum).OutNormVec;
   10640     3852155 :                 ThWin = AzimWin - DataGlobalConstants::PiOvr2;
   10641     3852155 :                 Real64 const sin_Elevwin(std::sin(ElevWin));
   10642     3852155 :                 WinNormCrossBase.x = -(sin_Elevwin * std::cos(ThWin));
   10643     3852155 :                 WinNormCrossBase.y = sin_Elevwin * std::sin(ThWin);
   10644     3852155 :                 WinNormCrossBase.z = std::cos(ElevWin);
   10645     3852155 :                 SunPrime = SolCosVec - WinNormCrossBase * dot(SolCosVec, WinNormCrossBase);
   10646     3852155 :                 dot1 = dot(WinNorm, SunPrime);
   10647     3852155 :                 dot2 = SunPrime.magnitude();
   10648     3852155 :                 dot3 = dot1 / dot2;
   10649     3852155 :                 if (dot3 > 1.0) {
   10650           0 :                     dot3 = 1.0;
   10651     3852155 :                 } else if (dot3 < -1.0) {
   10652           0 :                     dot3 = -1.0;
   10653             :                 }
   10654             :                 //    ProfileAngVert =
   10655             :                 //    ABS(ACOS(DOT_PRODUCT(WinNorm,SunPrime)/SQRT(DOT_PRODUCT(SunPrime,SunPrime))))
   10656     3852155 :                 ProfileAngVert = std::abs(std::acos(dot3));
   10657             :                 //  END IF
   10658             :                 // Constrain to 0 to pi
   10659     3852155 :                 if (ProfileAngVert > DataGlobalConstants::Pi) ProfileAngVert = DataGlobalConstants::TwoPi - ProfileAngVert;
   10660             : 
   10661     3852155 :                 state.dataSurface->SurfWinProfileAngHor(SurfNum) = ProfileAngHor / DataGlobalConstants::DegToRadians;
   10662     3852155 :                 state.dataSurface->SurfWinProfileAngVert(SurfNum) = ProfileAngVert / DataGlobalConstants::DegToRadians;
   10663     3852155 :                 state.dataSurface->SurfWinTanProfileAngHor(SurfNum) = std::abs(std::tan(ProfileAngHor));
   10664     3852155 :                 state.dataSurface->SurfWinTanProfileAngVert(SurfNum) = std::abs(std::tan(ProfileAngVert));
   10665             :             }
   10666             :         }
   10667             :     }
   10668      822103 : }
   10669             : 
   10670       68875 : void CalcFrameDividerShadow(EnergyPlusData &state,
   10671             :                             int const SurfNum,  // Surface number
   10672             :                             int const FrDivNum, // Frame/divider number
   10673             :                             int const HourNum   // Hour number
   10674             : )
   10675             : {
   10676             : 
   10677             :     // SUBROUTINE INFORMATION:
   10678             :     //       AUTHOR         Fred Winkelmann
   10679             :     //       DATE WRITTEN   June 2000
   10680             :     //       MODIFIED       Aug 2000, FW: add effective shadowing by inside
   10681             :     //                      projections
   10682             :     //       RE-ENGINEERED  na
   10683             : 
   10684             :     // PURPOSE OF THIS SUBROUTINE:
   10685             :     // Called by CalcPerSolarBeam for wholly or partially sunlit exterior windows
   10686             :     // with a frame and/or divider. Using beam solar profile angles,
   10687             :     // calculates fraction of glass shaded by exterior frame and divider projections,
   10688             :     // The frame and divider profiles are assumed to be rectangular.
   10689             :     // A similar shadowing approach is used to calculate the fraction of glass area
   10690             :     // that produces beam solar illumination on interior frame and divider projections.
   10691             :     // This fraction is used in CalcWinFrameAndDividerTemps to determine the
   10692             :     // beam solar absorbed by inside projections. Beam solar reflected by inside projections
   10693             :     // is assumed to stay in the zone (as beam solar) although in actuality roughly
   10694             :     // half of this is reflected back onto the glass and the half that is reflected
   10695             :     // into the zone is diffuse.
   10696             :     // For multipane glazing the effect of solar absorbed by the exposed portion of
   10697             :     // frame or divider between the panes is not calculated. Beam solar incident on
   10698             :     // these portions is assumed to be transmitted into the zone unchanged.
   10699             :     // The shadowing of diffuse solar radiation by projections is not considered.
   10700             : 
   10701             :     Real64 ElevSun;       // Sun elevation; angle between sun and horizontal
   10702             :     Real64 ElevWin;       // Window elevation: angle between window outward normal and horizontal
   10703             :     Real64 AzimWin;       // Window azimuth (radians)
   10704             :     Real64 AzimSun;       // Sun azimuth (radians)
   10705             :     Real64 ProfileAngHor; // Solar profile angle (radians) for horizontally oriented projections
   10706             :     // such as the top and bottom of a frame or horizontal dividers.
   10707             :     // This is the incidence angle in a plane that is normal to the window
   10708             :     // and parallel to the Y-axis of the window (the axis along
   10709             :     // which the height of the window is measured).
   10710             :     Real64 ProfileAngVert; // Solar profile angle (radians) for vertically oriented projections
   10711             :     // such as the top and bottom of a frame or horizontal dividers.
   10712             :     // This is the incidence angle in a plane that is normal to the window
   10713             :     // and parallel to the X-axis of the window (the axis along
   10714             :     // which the width of the window is measured).
   10715             :     Real64 TanProfileAngHor;  // Tangent of ProfileAngHor
   10716             :     Real64 TanProfileAngVert; // Tangent of ProfileAngVert
   10717             :     Real64 FrWidth;           // Frame width (m)
   10718             :     Real64 DivWidth;          // Divider width (m)
   10719             :     Real64 FrProjOut;         // Outside frame projection (m)
   10720             :     Real64 DivProjOut;        // Outside divider projection (m)
   10721             :     Real64 FrProjIn;          // Inside frame projection (m)
   10722             :     Real64 DivProjIn;         // Inside divider projection (m)
   10723             :     int NHorDiv;              // Number of horizontal dividers
   10724             :     int NVertDiv;             // Number of vertical dividers
   10725             :     Real64 GlArea;            // Glazed area (m2)
   10726             :     Real64 Arealite;          // Area of a single lite of glass (m2); glazed area, GlArea,
   10727             :     // if there is no divider (in which case there is only one lite).
   10728             :     Real64 ArealiteCol; // Area of a vertical column of lites (m2)
   10729             :     Real64 ArealiteRow; // Area of a horizontal row of lites (m2)
   10730             :     Real64 AshVDout;    // Shaded area from all vertical divider outside projections (m2)
   10731             :     Real64 AshVDin;     // Shaded area from all vertical divider inside projections (m2)
   10732             :     Real64 AshHDout;    // Shaded area from all horizontal divider outside projections (m2)
   10733             :     Real64 AshHDin;     // Shaded area from all horizontal divider inside projections (m2)
   10734             :     Real64 AshVFout;    // Shaded area from outside projection of vertical sides of frame (m2)
   10735             :     Real64 AshVFin;     // Shaded area from inside projection of vertical sides of frame (m2)
   10736             :     Real64 AshHFout;    // Shaded area from outside projection of horizontal sides
   10737             :     //   (top) of frame (m2)
   10738             :     Real64 AshHFin; // Shaded area from inside projection of horizontal sides
   10739             :     //   (top) of frame (m2)
   10740             :     Real64 AshDDover;   // Divider/divider shadow overlap area (m2)
   10741             :     Real64 AshFFover;   // Frame/frame shadow overlap area (m2)
   10742             :     Real64 AshFVDover;  // Frame/vertical divider overlap area (m2)
   10743             :     Real64 AshFHDover;  // Frame/horizontal divider overlap area (m2)
   10744             :     Real64 AshFDtotOut; // Total outside projection shadow area (m2)
   10745             :     Real64 AshFDtotIn;  // Total inside projection shadow area (m2)
   10746             :     Real64 FracShFDOut; // Fraction of glazing shadowed by frame and divider
   10747             :     //  outside projections
   10748             :     Real64 FracShFDin; // Fraction of glazing that illuminates frame and divider
   10749             :     //  inside projections with beam radiation
   10750             : 
   10751       99923 :     Vector3<Real64> WinNorm(3);  // Window outward normal unit vector
   10752             :     Real64 ThWin;                // Azimuth angle of WinNorm
   10753       99923 :     Vector3<Real64> SunPrime(3); // Projection of sun vector onto plane (perpendicular to
   10754             :     //  window plane) determined by WinNorm and vector along
   10755             :     //  baseline of window
   10756       99923 :     Vector3<Real64> WinNormCrossBase(3); // Cross product of WinNorm and vector along window baseline
   10757             : 
   10758      213404 :     if (state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut == 0.0 && state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn == 0.0 &&
   10759      144529 :         state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut == 0.0 && state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn == 0.0)
   10760       37827 :         return;
   10761             : 
   10762       31048 :     FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut;
   10763       31048 :     FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
   10764       31048 :     DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
   10765       31048 :     DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
   10766             : 
   10767       31048 :     GlArea = state.dataSurface->Surface(SurfNum).Area;
   10768       31048 :     ElevWin = DataGlobalConstants::PiOvr2 - state.dataSurface->Surface(SurfNum).Tilt * DataGlobalConstants::DegToRadians;
   10769       31048 :     ElevSun = DataGlobalConstants::PiOvr2 - std::acos(state.dataSolarShading->SUNCOS(3));
   10770       31048 :     AzimWin = state.dataSurface->Surface(SurfNum).Azimuth * DataGlobalConstants::DegToRadians;
   10771       31048 :     AzimSun = std::atan2(state.dataSolarShading->SUNCOS(1), state.dataSolarShading->SUNCOS(2));
   10772             : 
   10773       31048 :     ProfileAngHor = std::atan(std::sin(ElevSun) / std::abs(std::cos(ElevSun) * std::cos(AzimWin - AzimSun))) - ElevWin;
   10774       31048 :     if (std::abs(ElevWin) < 0.1) { // Near-vertical window
   10775       11473 :         ProfileAngVert = std::abs(AzimWin - AzimSun);
   10776             :     } else {
   10777       19575 :         WinNorm = state.dataSurface->Surface(SurfNum).OutNormVec;
   10778       19575 :         ThWin = AzimWin - DataGlobalConstants::PiOvr2;
   10779       19575 :         WinNormCrossBase(1) = -std::sin(ElevWin) * std::cos(ThWin);
   10780       19575 :         WinNormCrossBase(2) = std::sin(ElevWin) * std::sin(ThWin);
   10781       19575 :         WinNormCrossBase(3) = std::cos(ElevWin);
   10782       19575 :         SunPrime = state.dataSolarShading->SUNCOS - WinNormCrossBase * dot(state.dataSolarShading->SUNCOS, WinNormCrossBase);
   10783       19575 :         ProfileAngVert = std::abs(std::acos(dot(WinNorm, SunPrime) / magnitude(SunPrime)));
   10784             :     }
   10785             :     // Constrain to 0 to pi
   10786       31048 :     if (ProfileAngVert > DataGlobalConstants::Pi) ProfileAngVert = 2 * DataGlobalConstants::Pi - ProfileAngVert;
   10787       31048 :     TanProfileAngHor = std::abs(std::tan(ProfileAngHor));
   10788       31048 :     TanProfileAngVert = std::abs(std::tan(ProfileAngVert));
   10789             : 
   10790       31048 :     NHorDiv = state.dataSurface->FrameDivider(FrDivNum).HorDividers;
   10791       31048 :     NVertDiv = state.dataSurface->FrameDivider(FrDivNum).VertDividers;
   10792       31048 :     FrWidth = state.dataSurface->FrameDivider(FrDivNum).FrameWidth;
   10793       31048 :     DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
   10794             : 
   10795       62096 :     Arealite = (state.dataSurface->Surface(SurfNum).Height / (NHorDiv + 1.0) - DivWidth / 2.0) *
   10796       31048 :                (state.dataSurface->Surface(SurfNum).Width / (NVertDiv + 1.0) - DivWidth / 2.0);
   10797       31048 :     if (DivProjOut > 0.0 || DivProjIn > 0.0) {
   10798       10547 :         ArealiteCol = (NHorDiv + 1) * Arealite;
   10799       10547 :         ArealiteRow = (NVertDiv + 1) * Arealite;
   10800             :     } else {
   10801       20501 :         ArealiteCol = GlArea;
   10802       20501 :         ArealiteRow = GlArea;
   10803             :     }
   10804       31048 :     AshVDout = 0.0;
   10805       31048 :     AshVDin = 0.0;
   10806       31048 :     AshHDout = 0.0;
   10807       31048 :     AshHDin = 0.0;
   10808       31048 :     AshVFout = 0.0;
   10809       31048 :     AshVFin = 0.0;
   10810       31048 :     AshHFout = 0.0;
   10811       31048 :     AshHFin = 0.0;
   10812       31048 :     AshDDover = 0.0;
   10813       31048 :     AshFFover = 0.0;
   10814       31048 :     AshFVDover = 0.0;
   10815       31048 :     AshFHDover = 0.0;
   10816             : 
   10817       31048 :     if (DivProjOut > 0.0 || DivProjIn > 0.0) {
   10818             : 
   10819             :         // Shaded area from all vertical dividers
   10820       10547 :         AshVDout = NVertDiv * min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * DivProjOut * TanProfileAngVert, ArealiteCol);
   10821       10547 :         AshVDin = NVertDiv * min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * DivProjIn * TanProfileAngVert, ArealiteCol);
   10822             : 
   10823             :         // Shaded area from all horizontal dividers
   10824       10547 :         AshHDout = NHorDiv * min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * DivProjOut * TanProfileAngHor, ArealiteRow);
   10825       10547 :         AshHDin = NHorDiv * min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * DivProjIn * TanProfileAngHor, ArealiteRow);
   10826             : 
   10827             :         // Horizontal divider/vertical divider shadow overlap
   10828       10547 :         AshDDover = min(DivProjOut * TanProfileAngHor * DivProjOut * TanProfileAngVert, Arealite) * NHorDiv * NVertDiv;
   10829             :     }
   10830             : 
   10831       31048 :     if (FrProjOut > 0.0 || FrProjIn > 0.0) {
   10832             : 
   10833             :         // Shaded area from sides of frame; to avoid complications from possible overlaps between
   10834             :         // shadow from side of frame and shadow from vertical divider the shaded area from side of
   10835             :         // frame is restricted to the area of one column of lites.
   10836       31048 :         AshVFout = min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * FrProjOut * TanProfileAngVert, ArealiteCol);
   10837       31048 :         AshVFin = min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * FrProjIn * TanProfileAngVert, ArealiteCol);
   10838             : 
   10839             :         // Shaded area from top or bottom of frame; to avoid complications from possible overlaps
   10840             :         // between shadow from top or bottom of frame and shadow from horizontal divider, the shaded
   10841             :         // area from the top or bottom of frame is restricted to the area of one row of lites.
   10842       31048 :         AshHFout = min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * FrProjOut * TanProfileAngHor, ArealiteRow);
   10843       31048 :         AshHFin = min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * FrProjIn * TanProfileAngHor, ArealiteRow);
   10844             : 
   10845             :         // Top/bottom of frame/side of frame shadow overlap
   10846       31048 :         AshFFover = min(FrProjOut * TanProfileAngHor * FrProjOut * TanProfileAngVert, Arealite);
   10847       31048 :         if (DivProjOut > 0.0) {
   10848             :             // Frame/vertical divider shadow overlap
   10849       10547 :             AshFVDover = min(FrProjOut * DivProjOut * TanProfileAngHor * TanProfileAngVert, Arealite) * NVertDiv;
   10850             :             // Frame/horizontal divider shadow overlap
   10851       10547 :             AshFHDover = min(FrProjOut * DivProjOut * TanProfileAngHor * TanProfileAngVert, Arealite) * NHorDiv;
   10852             :         }
   10853             :     }
   10854             : 
   10855       31048 :     AshFDtotOut = AshVDout + AshHDout + AshVFout + AshHFout - (AshDDover + AshFFover + AshFVDover + AshFHDover);
   10856       62096 :     AshFDtotIn = (AshVDin + AshHDin) * state.dataSurface->FrameDivider(FrDivNum).DividerSolAbsorp +
   10857       31048 :                  (AshVFin + AshHFin) * state.dataSurface->FrameDivider(FrDivNum).FrameSolAbsorp;
   10858             : 
   10859             :     // Divide by the glazed area of the window
   10860       31048 :     FracShFDOut = AshFDtotOut / GlArea;
   10861       31048 :     FracShFDin = AshFDtotIn / GlArea;
   10862       31048 :     state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(HourNum) = 1.0 - FracShFDOut;
   10863       31048 :     state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(HourNum) = 1.0 - (FracShFDin + FracShFDOut);
   10864             : }
   10865             : 
   10866           0 : void CalcBeamSolarOnWinRevealSurface(EnergyPlusData &state)
   10867             : {
   10868             : 
   10869             :     // SUBROUTINE INFORMATION:
   10870             :     //       AUTHOR         F. Winkelmann
   10871             :     //       DATE WRITTEN   April 2002
   10872             :     //       MODIFIED:na
   10873             :     //       RE-ENGINEERED:na
   10874             : 
   10875             :     // PURPOSE OF THIS SUBROUTINE
   10876             :     // Called by InitHeatGains when the sun is up.
   10877             :     // Calculates beam solar radiation absorbed and reflected by top, bottom,
   10878             :     // right and left sides of outside and inside window reveal surfaces.
   10879             :     // In doing this calculation, the shadowing on a reveal surface by other reveal surfaces
   10880             :     // is determined using the orientation of the reveal surfaces and the sun position.
   10881             :     // It is assumed that:
   10882             :     // (1) The window is an exterior window and is rectangular.
   10883             :     // (2) The reveal surfaces are perpendicular to the window plane.
   10884             :     // (3) If an exterior shade or blind is in place, there is no beam solar on
   10885             :     //     on exterior or interior reveal surfaces.
   10886             :     // (3) If an interior shade or blind is in place, there is no beam solar on
   10887             :     //     interior reveal surfaces.
   10888             :     // (4) The effect of window divider, if present, is ignored, including shadowing
   10889             :     //     of divider on inside reveal surfaces.
   10890             : 
   10891             :     // In the variable names, the "subscript" 1 = outside reveal, 2 = inside reveal
   10892             :     // The outside reveal surfaces (top, bottom, left, right) are assumed to have the same depth
   10893             :     // (given by Surface%Reveal and determined from vertices of window and vertices of parent
   10894             :     // wall) and the same solar absorptance. The inside reveal surfaces are divided into
   10895             :     // two categories: (1) the bottom reveal surface, called here the "inside sill;" and
   10896             :     // the other reveal surfaces (left, right and top). The left, right and top inside reveal
   10897             :     // surfaces are assumed to have the same depth and solar absorptance.
   10898             :     // The depth of the outside reveal is measured from the outside surface of the glazing;
   10899             :     // The depth of the inside sill and the other reveal surfaces is measured from the inside
   10900             :     // surface of the glazing. The inside sill is
   10901             :     // allowed to have depth and solar absorptance values that are different from the corresponding
   10902             :     // values for the other inside reveal surfaces. The inside sill depth is required to be
   10903             :     // greater than or equal to the depth of the other inside reveal surfaces. If the inside sill
   10904             :     // depth is greater than zero the depth of the other inside reveal surfaces is required to
   10905             :     // to be greater than zero.
   10906             :     // The reflection of beam solar radiation from all reveal surfaces is assumed to be isotropic
   10907             :     // diffuse; there is no specular component. Half of the beam solar reflected from outside
   10908             :     // reveal surfaces is assumed to go towards the window; the other half is assumed to go back
   10909             :     // to the exterior environment (i.e., reflection of this outward-going component from
   10910             :     // other outside reveal surfaces is not considered). The half that goes towards the window
   10911             :     // is added to the other radiation incident on the window.
   10912             :     // Correspondingly, half of the beam solar reflected from inside reveal surfaces is assumed
   10913             :     // to go towards the window, with the other half going into the zone (this half, and the portion
   10914             :     // going towards the window that is reflected) is added in CalcInteriorSolarDistribution
   10915             :     // to the variable BTOTzone, which is the total beam solar entering the zone as beam or diffuse.
   10916             :     // The portion going towards the window that is not reflected is absorbed in the glazing or
   10917             :     // transmitted back out into the exterior environment.
   10918             :     // The beam solar that is absorbed by outside reveal surfaces is added to the solar absorbed
   10919             :     // by the outside surface of the window's parent wall; similarly, the beam solar absorbed
   10920             :     // by the inside reveal surfaces is added to the solar absorbed by the inside surface of the
   10921             :     // parent wall (and is subtracted from BTOTzone).
   10922             :     // The net effect of beam solar reflected from outside reveal surfaces is to INCREASE the
   10923             :     // the heat gain to the zone, whereas the effect of beam solar reflected from interior reveal
   10924             :     // surfaces is to DECREASE the heat gain to the zone since part of this reflected solar is
   10925             :     // transmitted back out the window.
   10926             :     // If the window has a frame, the absorption of reflected beam solar by the inside and outside
   10927             :     // surfaces of the frame is considered. The shadowing of the frame onto interior reveal
   10928             :     // surfaces is also considered.
   10929             : 
   10930             :     // The total glazing thickness is taken to be the sum of the thickness of the glass layers
   10931             :     // and between-glass gas layers. If the window has an exterior, movable, storm window glass layer
   10932             :     // the presence of this layer and its adjacent air gap is considered in calculating the glazing
   10933             :     // properties (solar transmittance, etc.). But the storm window glass is assumed to be close
   10934             :     // enough to the rest of the glazing that its effect on total glazing thickness and outside
   10935             :     // reveal depth can be ignored.
   10936             : 
   10937             :     // METHODOLOGY EMPLOYED
   10938             :     // na
   10939             : 
   10940             :     // REFERENCES
   10941             :     // na
   10942             : 
   10943             :     // USE STATEMENTS
   10944             :     // Using/Aliasing
   10945             :     using General::InterpSw;
   10946             :     using General::POLYF;
   10947             : 
   10948             :     // Locals
   10949             :     // SUBROUTINE ARGUMENT DEFINITIONS:na
   10950             : 
   10951             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS
   10952             : 
   10953             :     int ConstrNum;        // Construction number
   10954             :     int ConstrNumSh;      // Shaded construction number
   10955             :     Real64 CosBetaBottom; // Cosine of beam solar angle of incidence on bottom reveal
   10956             :     Real64 CosBetaLeft;   // Cosine of beam solar angle of incidence on left reveal
   10957             :     Real64 CosBeta;       // ABS of CosBetaBottom or CosBetaLeft
   10958             :     Real64 d1;            // Depth of outside reveal + half of glazing thickness (m)
   10959             :     Real64 d2;            // Depth of inside sill or of inside reveal plus half of glazing thickness (m)
   10960             :     Real64 d2prime;       // Depth of shadow cast on a reveal surface by opposite reveal (m)
   10961             :     Real64 d2prime2;      // Depth of shadow cast by frame onto inside reveal (m)
   10962             :     Real64 d12;           // d12 = d1 + d2 - d2prime (m)
   10963             :     Real64 TanAlpha;      // Tangent of horizontal or vertical profile angle
   10964             :     Real64 TanGamma;      // Tangent of vertical or horizontal profile angle
   10965             :     Real64 H;             // Window height, width (m)
   10966             :     Real64 W;
   10967             :     Real64 L;                    // Window height or width (m)
   10968             :     Real64 A1sh;                 // Shadowed area of outside horizontal or vertical reveal (m2)
   10969             :     Real64 A2sh;                 // Shadowed area of inside horizontal or vertical reveal (m2)
   10970             :     Real64 A1ill;                // Illuminated area of outside horizontal or vertical reveal (m2)
   10971             :     Real64 A2ill;                // Illuminated area of inside horizontal or vertical reveal (m2)
   10972             :     Real64 SolTransGlass;        // Beam solar transmittance of glazing
   10973             :     Real64 SolTransGlassSh;      // For switchable glazing, beam solar trans in switched state
   10974             :     Real64 DiffReflGlass;        // Diffuse back reflectance of glazing
   10975             :     Real64 DiffReflGlassSh;      // For switchable glazing, diffuse back refl in switched state
   10976             :     int HorVertReveal;           // Index: 1 = horizontal reveal, 2 = vertical reveal
   10977             :     Real64 OutsReveal;           // Depth of outside reveal (from outside glazing plane to outside wall plane) (m)
   10978             :     Real64 InsReveal;            // Depth of inside reveal (from inside glazing plane to inside wall plane (m)
   10979             :     Real64 InsSillDepth;         // Depth of inside sill, measured from innermost face of glazing (m)
   10980             :     Real64 GlazingThickness;     // Thickness of glazing, measured from innermost face to outermost face (m)
   10981             :     Real64 InsideRevealSolAbs;   // Solar absorptance of inside reveal or inside sill
   10982             :     Real64 BmSolRefldOutsReveal; // Multiplied by beam solar gives beam solar reflected by horiz or vertical
   10983             :     //  outside reveal surface (m2)
   10984             :     Real64 BmSolRefldInsReveal; // Multiplied by beam solar gives beam solar reflected by horiz or vertical
   10985             :     //  inside reveal surface (m2)
   10986             :     WinShadingType ShadeFlag; // Shading flag
   10987             :     int FrameDivNum;          // Frame/Divider number
   10988             :     Real64 FrameWidth;        // Frame width (m)
   10989             :     Real64 P1;                // Frame outside/inside projection plus half of glazing thickness (m)
   10990             :     Real64 P2;
   10991             :     Real64 f1; // f1=d1-P1, f2=d2-P2 (m)
   10992             :     Real64 f2;
   10993             :     Real64 L1; // Average distance of outside/inside illuminated area to frame;
   10994             :     Real64 L2;
   10995             :     // used in calculating view factor to frame (m)
   10996             :     Real64 FracToGlassOuts;   // View factor from outside horizontal or vertical reveal to glass
   10997             :     Real64 FracToGlassIns;    // View factor from inside horizontal or vertical reveal to glass
   10998             :     Real64 TanProfileAngVert; // Tangent of vertical profile angle (the profile angle appropriate for
   10999             :     // vertical reveal surfaces.
   11000             :     Real64 TanProfileAngHor; // Tangent of horizontal profile angle (the profile angle appropriate for
   11001             :     // horizontal reveal surfaces.
   11002             : 
   11003             :     Real64 tmp_SunlitFracWithoutReveal; // Temporary variable
   11004             : 
   11005           0 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
   11006           0 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
   11007           0 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
   11008           0 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
   11009           0 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
   11010           0 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
   11011             :                 // Added TH for initialization. CR 7596 inside reveal causing high cooling loads
   11012             :                 // for outside reveals
   11013           0 :                 state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
   11014           0 :                 state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
   11015           0 :                 state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
   11016           0 :                 state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
   11017           0 :                 state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
   11018             :                 // for inside reveals
   11019           0 :                 state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
   11020           0 :                 state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
   11021           0 :                 state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
   11022           0 :                 state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
   11023           0 :                 state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
   11024           0 :                 state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
   11025           0 :                 state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
   11026           0 :                 state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
   11027           0 :                 state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
   11028           0 :                 state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
   11029           0 :                 state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
   11030             : 
   11031           0 :                 if ((state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment &&
   11032           0 :                      state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt))
   11033           0 :                     continue;
   11034           0 :                 if (state.dataSurface->Surface(SurfNum).Reveal == 0.0 && state.dataSurface->SurfWinInsideReveal(SurfNum) == 0.0 &&
   11035           0 :                     state.dataSurface->SurfWinInsideSillDepth(SurfNum) == 0.0)
   11036           0 :                     continue;
   11037           0 :                 if (state.dataSurface->Surface(SurfNum).Sides != 4) continue;
   11038           0 :                 if (state.dataSurface->SurfWinInsideSillDepth(SurfNum) < state.dataSurface->SurfWinInsideReveal(SurfNum)) continue;
   11039             : 
   11040           0 :                 ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
   11041           0 :                 if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::ExtShade) | BITF(WinShadingType::ExtBlind))) continue;
   11042             : 
   11043           0 :                 if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue;
   11044             : 
   11045           0 :                 tmp_SunlitFracWithoutReveal =
   11046           0 :                     state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
   11047             : 
   11048             :                 // Calculate cosine of angle of incidence of beam solar on reveal surfaces,
   11049             :                 // assumed to be perpendicular to window plane
   11050             : 
   11051           0 :                 CosBetaBottom =
   11052           0 :                     -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).SinAzim * state.dataSurface->Surface(SurfNum).CosTilt -
   11053           0 :                     state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).CosAzim * state.dataSurface->Surface(SurfNum).CosTilt +
   11054           0 :                     state.dataEnvrn->SOLCOS(3) * state.dataSurface->Surface(SurfNum).SinTilt;
   11055             : 
   11056           0 :                 CosBetaLeft = -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).CosAzim -
   11057           0 :                               state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).SinAzim;
   11058             : 
   11059             :                 // Note: CosBetaTop = -CosBetaBottom, CosBetaRight = -CosBetaLeft
   11060             : 
   11061           0 :                 OutsReveal = state.dataSurface->Surface(SurfNum).Reveal;
   11062           0 :                 InsReveal = state.dataSurface->SurfWinInsideReveal(SurfNum);
   11063           0 :                 InsideRevealSolAbs = 0.0;
   11064           0 :                 GlazingThickness = state.dataSurface->SurfWinTotGlazingThickness(SurfNum);
   11065           0 :                 H = state.dataSurface->Surface(SurfNum).Height;
   11066           0 :                 W = state.dataSurface->Surface(SurfNum).Width;
   11067           0 :                 d1 = OutsReveal + 0.5 * GlazingThickness;
   11068           0 :                 ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
   11069           0 :                 ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
   11070             : 
   11071           0 :                 SolTransGlass = POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum),
   11072           0 :                                       state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
   11073           0 :                 TanProfileAngVert = state.dataSurface->SurfWinTanProfileAngVert(SurfNum);
   11074           0 :                 TanProfileAngHor = state.dataSurface->SurfWinTanProfileAngHor(SurfNum);
   11075           0 :                 FrameDivNum = state.dataSurface->Surface(SurfNum).FrameDivider;
   11076           0 :                 FrameWidth = 0.0;
   11077           0 :                 if (FrameDivNum != 0) {
   11078           0 :                     FrameWidth = state.dataSurface->FrameDivider(FrameDivNum).FrameWidth;
   11079           0 :                     if (FrameWidth > 0.0) {
   11080           0 :                         P1 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionOut + 0.5 * GlazingThickness;
   11081           0 :                         P2 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionIn + 0.5 * GlazingThickness;
   11082           0 :                         if (OutsReveal + 0.5 * GlazingThickness <= P1) d1 = P1 + 0.001;
   11083             :                     }
   11084             :                 }
   11085             :                 // Loop over vertical and horizontal reveal surfaces
   11086           0 :                 for (HorVertReveal = 1; HorVertReveal <= 2; ++HorVertReveal) {
   11087             : 
   11088           0 :                     FracToGlassOuts = 0.5;
   11089           0 :                     FracToGlassIns = 0.5;
   11090           0 :                     BmSolRefldOutsReveal = 0.0;
   11091           0 :                     BmSolRefldInsReveal = 0.0;
   11092           0 :                     A1ill = 0.0;
   11093           0 :                     A2ill = 0.0;
   11094             : 
   11095             :                     // Added TH. 5/27/2009
   11096           0 :                     A1sh = 0.0;
   11097           0 :                     A2sh = 0.0;
   11098             : 
   11099           0 :                     if (HorVertReveal == 1) { // Vertical reveal
   11100           0 :                         TanAlpha = TanProfileAngHor;
   11101           0 :                         TanGamma = TanProfileAngVert;
   11102           0 :                         CosBeta = std::abs(CosBetaLeft);
   11103           0 :                         L = state.dataSurface->Surface(SurfNum).Height;
   11104           0 :                         d2 = InsReveal + 0.5 * GlazingThickness;
   11105           0 :                         d2prime = d1 + d2 - W / TanGamma;
   11106           0 :                         InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum);
   11107             :                     } else { // Horizontal reveal
   11108           0 :                         InsSillDepth = state.dataSurface->SurfWinInsideSillDepth(SurfNum);
   11109           0 :                         TanAlpha = TanProfileAngVert;
   11110           0 :                         TanGamma = TanProfileAngHor;
   11111           0 :                         CosBeta = std::abs(CosBetaBottom);
   11112           0 :                         L = state.dataSurface->Surface(SurfNum).Width;
   11113           0 :                         if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated
   11114           0 :                             d2 = InsSillDepth + 0.5 * GlazingThickness;
   11115           0 :                             InsideRevealSolAbs = state.dataSurface->SurfWinInsideSillSolAbs(SurfNum);
   11116             :                         } else { // Top reveal surfaces may be illuminated
   11117           0 :                             d2 = InsReveal + 0.5 * GlazingThickness;
   11118           0 :                             InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum);
   11119             :                         }
   11120           0 :                         d2prime = d1 + d2 - H / TanGamma;
   11121             :                     }
   11122           0 :                     if (d2prime < 0.0) d2prime = 0.0; // No shadow from opposing reveal
   11123           0 :                     d12 = d1 + d2 - d2prime;
   11124             : 
   11125           0 :                     if (FrameWidth <= 0.001) {
   11126             :                         // Window without frame
   11127             : 
   11128             :                         // Find inside and outside shadowed area of vertical or horizontal reveal surfaces
   11129             :                         // that can be illuminated by beam solar; shadowing is by other reveal surfaces.
   11130             : 
   11131           0 :                         if (d2prime <= d2) {
   11132           0 :                             if (d12 * TanAlpha <= L) {
   11133           0 :                                 A1sh = 0.5 * TanAlpha * pow_2(d1);
   11134           0 :                                 A2sh = d2prime * L + 0.5 * TanAlpha * pow_2(d12) - A1sh;
   11135             :                             } else { // d12*TanAlpha > L
   11136           0 :                                 if (d1 * TanAlpha <= L) {
   11137           0 :                                     A1sh = 0.5 * TanAlpha * pow_2(d1);
   11138           0 :                                     A2sh = d2 * L - 0.5 * TanAlpha * pow_2(L / TanAlpha - d1);
   11139             :                                 } else { // d1*TanAlpha > L
   11140           0 :                                     A1sh = d1 * L - (0.5 / TanAlpha) * pow_2(L);
   11141           0 :                                     A2sh = d2 * L;
   11142             :                                 }
   11143             :                             }
   11144             :                         } else { // d2prime > d2
   11145           0 :                             A2sh = d2 * L;
   11146           0 :                             if (d2prime < d1 + d2) {
   11147           0 :                                 if (d12 * TanAlpha <= L) {
   11148           0 :                                     A1sh = L * (d2prime - d2) + 0.5 * TanAlpha * pow_2(d12);
   11149             :                                 } else { // d12*TanAlpha > L
   11150           0 :                                     A1sh = d1 * L - 0.5 * pow_2(L) / TanAlpha;
   11151             :                                 }
   11152             :                             } else { // d2prime >= d1+d2
   11153           0 :                                 A1sh = d1 * L;
   11154             :                             }
   11155             :                         }
   11156             : 
   11157             :                         // Added TH. 5/27/2009
   11158           0 :                         if (A1sh < 0.0) A1sh = 0.0;
   11159           0 :                         if (A2sh < 0.0) A2sh = 0.0;
   11160             : 
   11161           0 :                         if (OutsReveal >= 0.001) A1ill = d1 * L - A1sh; // A1ill = 0.0 if OutsReveal < 0.001
   11162           0 :                         if (InsReveal >= 0.001) A2ill = d2 * L - A2sh;  // A2ill = 0.0 if InsReveal < 0.001
   11163             : 
   11164             :                     } else { // Window with frame; take into account shadowing
   11165             :                         // of inside reveal surfaces by frame
   11166           0 :                         f1 = d1 - P1;
   11167           0 :                         f2 = d2 - P2;
   11168           0 :                         d2prime2 = FrameWidth / TanGamma;
   11169           0 :                         if (HorVertReveal == 1) { // Vertical reveal
   11170           0 :                             if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001;
   11171             :                         } else {                       // Horizontal
   11172           0 :                             if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated
   11173           0 :                                 if (InsSillDepth + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001;
   11174             :                             } else { // Top reveal surfaces may be illuminated
   11175           0 :                                 if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001;
   11176             :                             }
   11177             :                         }
   11178             : 
   11179           0 :                         if (d2prime <= f2) { // Shadow from opposing reveal does not go beyond inside surface of frame
   11180             : 
   11181           0 :                             if (d12 * TanAlpha <= L) {
   11182           0 :                                 A1sh = 0.5 * TanAlpha * pow_2(f1);
   11183           0 :                                 L1 = f1 * (f1 * TanAlpha / (6.0 * L) + 0.5);
   11184           0 :                                 if (d2 - (d2prime + d2prime2 + P2) >= 0.0) {
   11185           0 :                                     A2sh = (d2prime + d2prime2) * L + 0.5 * TanAlpha * (pow_2(d1 + d2 - d2prime) - pow_2(d1 + P2 + d2prime2));
   11186           0 :                                     L2 = d2prime2 + 0.5 * (d2 - (d2prime + d2prime2 + P2));
   11187             :                                 } else { // d2-(d2prime+d2prime2+P2) < 0.  ! Inside reveal is fully shadowed by
   11188             :                                          // frame and/or opposing reveal
   11189           0 :                                     A2sh = f2 * L;
   11190           0 :                                     L2 = f2;
   11191             :                                 }
   11192             :                             } else { // d12*TanAlpha >= L
   11193           0 :                                 if ((d1 + P2) * TanAlpha <= L) {
   11194           0 :                                     A1sh = 0.5 * TanAlpha * pow_2(f1);
   11195           0 :                                     L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5);
   11196           0 :                                     if ((d1 + P2 + d2prime2) * TanAlpha >= L) {
   11197           0 :                                         A2sh = f2 * L;
   11198           0 :                                         L2 = f2;
   11199             :                                     } else { // (d1+P2+d2prime2)*TanAlpha < L
   11200           0 :                                         A2sh = f2 * L - 0.5 * pow_2(L - (d1 + P2) * TanAlpha) / TanAlpha +
   11201           0 :                                                d2prime2 * (L - (d1 + P2 + d2prime2 / 2.0) * TanAlpha);
   11202           0 :                                         L2 = d2prime2 + (L / TanAlpha - (d1 + P2 + d2prime2)) / 3.0;
   11203             :                                     }
   11204             :                                 } else { // (d1+P2)*TanAlpha > L
   11205           0 :                                     L2 = f2;
   11206           0 :                                     A2sh = f2 * L;
   11207           0 :                                     if (f1 * TanAlpha <= L) {
   11208           0 :                                         A1sh = 0.5 * TanAlpha * pow_2(f1);
   11209           0 :                                         L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5);
   11210             :                                     } else { // f1*TanAlpha > L
   11211           0 :                                         A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha;
   11212           0 :                                         L1 = f1 - (L / TanAlpha) / 3.0;
   11213             :                                     }
   11214             :                                 }
   11215             :                             }
   11216             : 
   11217             :                         } else { // d2prime > f2   ! Shadow from opposing reveal goes beyond inside of frame
   11218             : 
   11219           0 :                             A2sh = f2 * L;
   11220           0 :                             L2 = f2;
   11221           0 :                             if (d2prime >= d1 + d2) {
   11222           0 :                                 A1sh = 0.0;
   11223           0 :                                 L1 = f1;
   11224             :                             } else { // d2prime < d1+d2
   11225           0 :                                 if (d2prime <= d2 + P1) {
   11226           0 :                                     if (f1 * TanAlpha <= L) {
   11227           0 :                                         A1sh = 0.5 * TanAlpha * pow_2(f1);
   11228           0 :                                         L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5);
   11229             :                                     } else { // f1*TanAlpha > L
   11230           0 :                                         A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha;
   11231           0 :                                         L1 = f1 - (L / TanAlpha) / 3.0;
   11232             :                                     }
   11233             :                                 } else { // d2prime > d2+P1
   11234           0 :                                     if (d12 * TanAlpha <= L) {
   11235           0 :                                         A1sh = L * (d2prime - (d2 + P1)) + 0.5 * TanAlpha * pow_2(d12);
   11236           0 :                                         L1 = (L * (f1 - d12 / 2.0) - d12 * TanAlpha * (f1 / 2 - d12 / 3.0)) / (L - d12 * TanAlpha / 2.0);
   11237             :                                     } else { // d12*TanAlpha > L
   11238           0 :                                         A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha;
   11239           0 :                                         L1 = f1 - (L / TanAlpha) / 3.0;
   11240             :                                     }
   11241             :                                 }
   11242             :                             }
   11243             :                         }
   11244             : 
   11245             :                         // Added TH. 5/27/2009
   11246           0 :                         if (A1sh < 0.0) A1sh = 0.0;
   11247           0 :                         if (A2sh < 0.0) A2sh = 0.0;
   11248             : 
   11249           0 :                         if (OutsReveal >= P1 + 0.5 * GlazingThickness + 0.001) A1ill = L * f1 - A1sh;
   11250           0 :                         if (InsReveal >= P2 + 0.5 * GlazingThickness + 0.001) A2ill = L * f2 - A2sh;
   11251           0 :                         if (L1 == 0.0) {
   11252           0 :                             FracToGlassOuts = 0.0;
   11253             :                         } else {
   11254           0 :                             FracToGlassOuts = 0.5 * (1.0 - std::atan(FrameWidth / L1) / DataGlobalConstants::PiOvr2);
   11255             :                         }
   11256           0 :                         if (L2 == 0.0) {
   11257           0 :                             FracToGlassIns = 0.0;
   11258             :                         } else {
   11259           0 :                             FracToGlassIns = 0.5 * (1.0 - std::atan(FrameWidth / L2) / DataGlobalConstants::PiOvr2);
   11260             :                         }
   11261             :                     } // End of check if window has frame
   11262             : 
   11263             :                     // Added TH. 5/27/2009
   11264           0 :                     if (A1ill < 0.0) A1ill = 0.0;
   11265           0 :                     if (A2ill < 0.0) A2ill = 0.0;
   11266             : 
   11267             :                     // Quantities related to outside reveal
   11268           0 :                     if (A1ill > 1.0e-6) {
   11269             : 
   11270           0 :                         state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) +=
   11271           0 :                             A1ill * state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum) * CosBeta * tmp_SunlitFracWithoutReveal;
   11272             : 
   11273           0 :                         BmSolRefldOutsReveal =
   11274           0 :                             A1ill * (1.0 - state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum)) * CosBeta * tmp_SunlitFracWithoutReveal;
   11275             : 
   11276           0 :                         state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) += state.dataEnvrn->BeamSolarRad * BmSolRefldOutsReveal;
   11277           0 :                         state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) =
   11278           0 :                             state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
   11279             : 
   11280             :                         // Reflected solar from outside horizontal and vertical reveal incident on glazing
   11281           0 :                         state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) +=
   11282           0 :                             FracToGlassOuts * BmSolRefldOutsReveal / state.dataSurface->Surface(SurfNum).Area;
   11283             : 
   11284           0 :                         if (FrameWidth > 0.0) {
   11285             :                             // Reflected solar from outside horizontal and vertical reveal incident on frame
   11286           0 :                             state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) +=
   11287           0 :                                 (0.5 - FracToGlassOuts) * BmSolRefldOutsReveal / state.dataSurface->SurfWinFrameArea(SurfNum);
   11288             :                         }
   11289             : 
   11290             :                     } // End of check if A1ill > 0.0 (actually 10^-6)
   11291             : 
   11292             :                     // Quantities related to inside reveal; inside reveal reflection/absorption is assumed
   11293             :                     // to occur only if an interior shade or blind is not in place.
   11294             : 
   11295           0 :                     if (NOT_SHADED(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
   11296             : 
   11297           0 :                         if (A2ill > 1.0e-6) {
   11298             : 
   11299           0 :                             DiffReflGlass = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   11300           0 :                             if (ShadeFlag == WinShadingType::SwitchableGlazing) {
   11301           0 :                                 SolTransGlassSh =
   11302           0 :                                     POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum),
   11303           0 :                                           state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef);
   11304           0 :                                 SolTransGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), SolTransGlass, SolTransGlassSh);
   11305           0 :                                 DiffReflGlassSh = state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack;
   11306           0 :                                 DiffReflGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), DiffReflGlass, DiffReflGlassSh);
   11307             :                             }
   11308             : 
   11309             :                             // Calc beam solar sbsorbed (m2)
   11310           0 :                             state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) +=
   11311           0 :                                 A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal;
   11312             : 
   11313             :                             // Added TH 5/26/2009 for reporting purpose - Beam solar absorbed by the inside reveal
   11314             :                             // (W)
   11315           0 :                             state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) +=
   11316           0 :                                 state.dataEnvrn->BeamSolarRad * A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal;
   11317             : 
   11318             :                             // in m2 = Area * solar transmitted fraction * inside reveal reflection fraction
   11319           0 :                             BmSolRefldInsReveal = A2ill * SolTransGlass * (1.0 - InsideRevealSolAbs) * CosBeta * tmp_SunlitFracWithoutReveal;
   11320             : 
   11321           0 :                             state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) += BmSolRefldInsReveal;
   11322             : 
   11323           0 :                             state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) +=
   11324           0 :                                 state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal; // W, BeamSolarRad in W/m2
   11325           0 :                             state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) =
   11326           0 :                                 state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
   11327             : 
   11328             :                             // Reflected solar from inside horizontal and vertical reveal incident on glazing
   11329           0 :                             state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) +=
   11330           0 :                                 FracToGlassIns * BmSolRefldInsReveal / state.dataSurface->Surface(SurfNum).Area;
   11331             : 
   11332             :                             // Added TH 5/26/2009 for reporting purpose - diffuse on window glass from inside
   11333             :                             // reveal (W)
   11334           0 :                             state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) +=
   11335           0 :                                 state.dataEnvrn->BeamSolarRad * FracToGlassIns * BmSolRefldInsReveal;
   11336             : 
   11337             :                             // Reflected solar from inside horizontal and vertical reveal incident on frame
   11338           0 :                             if (FrameWidth > 0.0) {
   11339           0 :                                 state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) +=
   11340           0 :                                     (0.5 - FracToGlassIns) * BmSolRefldInsReveal / state.dataSurface->SurfWinFrameArea(SurfNum);
   11341             : 
   11342             :                                 // Added TH 5/26/2009 for reporting purpose - diffuse on window frame from inside
   11343             :                                 // reveal (W)
   11344           0 :                                 state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) +=
   11345           0 :                                     state.dataEnvrn->BeamSolarRad * (0.5 - FracToGlassIns) * BmSolRefldInsReveal;
   11346             :                             }
   11347             : 
   11348             :                             // Reflected solar from inside reveal going directly into zone and reflected from
   11349             :                             // glass. Assumes half of solar reflected from inside reveal goes as diffuse radiation
   11350             :                             // into the zone and half goes as diffuse radiation towards window.
   11351           0 :                             state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) += BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns);
   11352             : 
   11353             :                             // Added TH 5/26/2009 for reporting purpose - diffuse into zone from inside reveal (W)
   11354           0 :                             state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) +=
   11355           0 :                                 state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns);
   11356             : 
   11357             :                         } // End of check if A2ill > 0.0 (actually 10^-6)
   11358             : 
   11359             :                     } // End of check if interior shade or blind is in place
   11360             : 
   11361             :                 } // End of loop over vertical and horizontal reveal
   11362             : 
   11363             :             } // End of surface loop
   11364             :         }
   11365             :     }
   11366           0 : }
   11367             : 
   11368     2568313 : void ReportSurfaceShading(EnergyPlusData &state)
   11369             : {
   11370             : 
   11371             :     // SUBROUTINE INFORMATION:
   11372             :     //       AUTHOR         Linda Lawrie
   11373             :     //       DATE WRITTEN   April 2000
   11374             :     //       MODIFIED       na
   11375             :     //       RE-ENGINEERED  na
   11376             : 
   11377             :     // PURPOSE OF THIS SUBROUTINE:
   11378             :     // This subroutine uses the internal variables used in the Shading
   11379             :     // calculations and prepares them for reporting (at timestep level).
   11380             : 
   11381             :     // METHODOLOGY EMPLOYED:
   11382             :     // Because all of the calculations are done on a "daily" basis in this
   11383             :     // module, it is difficult to formulate the values that might be useful
   11384             :     // for reporting.  SunlitFrac was the first of these two arrays to be
   11385             :     // made into "two dimensions".  It is not clear that both have to be
   11386             :     // two dimensions.
   11387             : 
   11388             :     // REFERENCES:
   11389             :     // na
   11390             : 
   11391             :     // Using/Aliasing
   11392             :     using namespace OutputReportPredefined;
   11393             : 
   11394             :     // Locals
   11395             :     // SUBROUTINE ARGUMENT DEFINITIONS:
   11396             :     // na
   11397             : 
   11398             :     // SUBROUTINE PARAMETER DEFINITIONS:
   11399             :     // na
   11400             : 
   11401             :     // INTERFACE BLOCK SPECIFICATIONS
   11402             :     // na
   11403             : 
   11404             :     // DERIVED TYPE DEFINITIONS
   11405             :     // na
   11406             : 
   11407             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   11408             :     int SurfNum; // Loop Counter
   11409             :     int RepCol;  // the column of the predefined report
   11410             : 
   11411   166705567 :     for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
   11412   164137254 :         state.dataSurface->SurfSunlitFrac(SurfNum) =
   11413   164137254 :             state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
   11414   164137254 :         state.dataSurface->SurfSunlitArea(SurfNum) =
   11415   328274508 :             state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
   11416   164137254 :             state.dataSurface->Surface(SurfNum).Area;
   11417             :     }
   11418             :     // added for predefined reporting
   11419     2568313 :     RepCol = 0;
   11420     2568313 :     if (state.dataEnvrn->Month == 3 && state.dataEnvrn->DayOfMonth == 21) {
   11421        1881 :         if ((state.dataGlobal->HourOfDay == 9) && (state.dataGlobal->TimeStep == 4)) {
   11422          16 :             RepCol = state.dataOutRptPredefined->pdchSlfMar21_9;
   11423        1865 :         } else if ((state.dataGlobal->HourOfDay == 12) && (state.dataGlobal->TimeStep == 4)) {
   11424          16 :             RepCol = state.dataOutRptPredefined->pdchSlfMar21_12;
   11425        1849 :         } else if ((state.dataGlobal->HourOfDay == 15) && (state.dataGlobal->TimeStep == 4)) {
   11426          16 :             RepCol = state.dataOutRptPredefined->pdchSlfMar21_15;
   11427             :         }
   11428     2566432 :     } else if (state.dataEnvrn->Month == 6 && state.dataEnvrn->DayOfMonth == 21) {
   11429        1881 :         if ((state.dataGlobal->HourOfDay == 9) && (state.dataGlobal->TimeStep == 4)) {
   11430          16 :             RepCol = state.dataOutRptPredefined->pdchSlfJun21_9;
   11431        1865 :         } else if ((state.dataGlobal->HourOfDay == 12) && (state.dataGlobal->TimeStep == 4)) {
   11432          16 :             RepCol = state.dataOutRptPredefined->pdchSlfJun21_12;
   11433        1849 :         } else if ((state.dataGlobal->HourOfDay == 15) && (state.dataGlobal->TimeStep == 4)) {
   11434          16 :             RepCol = state.dataOutRptPredefined->pdchSlfJun21_15;
   11435             :         }
   11436     2564551 :     } else if (state.dataEnvrn->Month == 12 && state.dataEnvrn->DayOfMonth == 21) {
   11437      172863 :         if ((state.dataGlobal->HourOfDay == 9) && (state.dataGlobal->TimeStep == 4)) {
   11438        1335 :             RepCol = state.dataOutRptPredefined->pdchSlfDec21_9;
   11439      171528 :         } else if ((state.dataGlobal->HourOfDay == 12) && (state.dataGlobal->TimeStep == 4)) {
   11440        1335 :             RepCol = state.dataOutRptPredefined->pdchSlfDec21_12;
   11441      170193 :         } else if ((state.dataGlobal->HourOfDay == 15) && (state.dataGlobal->TimeStep == 4)) {
   11442        1335 :             RepCol = state.dataOutRptPredefined->pdchSlfDec21_15;
   11443             :         }
   11444             :     }
   11445     2568313 :     if (RepCol != 0) {
   11446      423456 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
   11447      419355 :             if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) {
   11448       62388 :                 PreDefTableEntry(state, RepCol, state.dataSurface->Surface(SurfNum).Name, state.dataSurface->SurfSunlitFrac(SurfNum));
   11449             :             }
   11450             :         }
   11451             :     }
   11452     2568313 : }
   11453             : 
   11454         771 : void ReportSurfaceErrors(EnergyPlusData &state)
   11455             : {
   11456             : 
   11457             :     // SUBROUTINE INFORMATION:
   11458             :     //       AUTHOR         Linda Lawrie
   11459             :     //       DATE WRITTEN   November 2004
   11460             :     //       MODIFIED       na
   11461             :     //       RE-ENGINEERED  na
   11462             : 
   11463             :     // PURPOSE OF THIS SUBROUTINE:
   11464             :     // This subroutine reports some recurring type errors that can get mixed up with more important
   11465             :     // errors in the error file.
   11466             : 
   11467             :     using namespace DataErrorTracking; // for error tracking
   11468             : 
   11469         771 :     static Array1D_string const MSG(4, {"misses", "", "within", "overlaps"});
   11470             : 
   11471             :     int Loop1;
   11472             :     int Loop2;
   11473             :     int Count;
   11474             :     int TotCount;
   11475        1542 :     Array1D_bool SurfErrorReported;
   11476        1542 :     Array1D_bool SurfErrorReported2;
   11477             : 
   11478         771 :     if (state.dataSolarShading->NumTooManyFigures + state.dataSolarShading->NumTooManyVertices + state.dataSolarShading->NumBaseSubSurround > 0) {
   11479           0 :         ShowMessage(state, "");
   11480           0 :         ShowMessage(state, "===== Recurring Surface Error Summary =====");
   11481           0 :         ShowMessage(state, "The following surface error messages occurred.");
   11482           0 :         ShowMessage(state, "");
   11483             : 
   11484           0 :         if (state.dataSolarShading->NumBaseSubSurround > 0) {
   11485           0 :             ShowMessage(state, "Base Surface does not surround subsurface errors occurring...");
   11486           0 :             ShowMessage(state,
   11487             :                         "Check that the GlobalGeometryRules object is expressing the proper starting corner and "
   11488             :                         "direction [CounterClockwise/Clockwise]");
   11489           0 :             ShowMessage(state, "");
   11490             :         }
   11491             : 
   11492           0 :         SurfErrorReported.dimension(state.dataSurface->TotSurfaces, false);
   11493           0 :         TotCount = 0;
   11494           0 :         for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumBaseSubSurround; ++Loop1) {
   11495           0 :             Count = 0;
   11496           0 :             if (SurfErrorReported(state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1)) continue;
   11497           0 :             for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumBaseSubSurround; ++Loop2) {
   11498           0 :                 if (state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1 ==
   11499           0 :                         state.dataSolarShading->TrackBaseSubSurround(Loop2).SurfIndex1 &&
   11500           0 :                     state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex == state.dataSolarShading->TrackBaseSubSurround(Loop2).MiscIndex) {
   11501           0 :                     ++Count;
   11502             :                 }
   11503             :             }
   11504           0 :             TotCount += Count;
   11505           0 :             state.dataErrTracking->TotalWarningErrors += Count - 1;
   11506           0 :             ShowWarningError(state,
   11507           0 :                              "Base surface does not surround subsurface (CHKSBS), Overlap Status=" +
   11508           0 :                                  state.dataSolarShading->cOverLapStatus(state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex));
   11509           0 :             ShowContinueError(state, format("  The base surround errors occurred {} times.", Count));
   11510           0 :             for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumBaseSubSurround; ++Loop2) {
   11511           0 :                 if (state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1 ==
   11512           0 :                         state.dataSolarShading->TrackBaseSubSurround(Loop2).SurfIndex1 &&
   11513           0 :                     state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex == state.dataSolarShading->TrackBaseSubSurround(Loop2).MiscIndex) {
   11514           0 :                     ShowContinueError(state,
   11515           0 :                                       "Surface \"" + state.dataSurface->Surface(state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1).Name +
   11516           0 :                                           "\" " + MSG(state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex) + " SubSurface \"" +
   11517           0 :                                           state.dataSurface->Surface(state.dataSolarShading->TrackBaseSubSurround(Loop2).SurfIndex2).Name + "\"");
   11518             :                 }
   11519             :             }
   11520           0 :             SurfErrorReported(state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1) = true;
   11521             :         }
   11522           0 :         if (TotCount > 0) {
   11523           0 :             ShowMessage(state, "");
   11524           0 :             ShowContinueError(state, format("  The base surround errors occurred {} times (total).", TotCount));
   11525           0 :             ShowMessage(state, "");
   11526             :         }
   11527             : 
   11528           0 :         SurfErrorReported2.allocate(state.dataSurface->TotSurfaces);
   11529           0 :         SurfErrorReported = false;
   11530           0 :         TotCount = 0;
   11531           0 :         if (state.dataSolarShading->NumTooManyVertices > 0) {
   11532           0 :             ShowMessage(state, format("Too many vertices [>={}] in shadow overlap errors occurring...", state.dataSolarShading->MaxHCV));
   11533           0 :             ShowMessage(state,
   11534             :                         "These occur throughout the year and may occur several times for the same surfaces. You "
   11535             :                         "may be able to reduce them by "
   11536             :                         "adding Output:Diagnostics,DoNotMirrorDetachedShading;");
   11537             :         }
   11538           0 :         for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumTooManyVertices; ++Loop1) {
   11539           0 :             Count = 0;
   11540           0 :             SurfErrorReported2 = false;
   11541           0 :             if (SurfErrorReported(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1)) continue;
   11542           0 :             for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyVertices; ++Loop2) {
   11543           0 :                 if (state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1 ==
   11544           0 :                     state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex1) {
   11545           0 :                     ++Count;
   11546             :                 }
   11547             :             }
   11548           0 :             TotCount += Count;
   11549           0 :             state.dataErrTracking->TotalWarningErrors += Count - 1;
   11550           0 :             ShowMessage(state, "");
   11551           0 :             ShowWarningError(state, format("Too many vertices [>={}] in a shadow overlap", state.dataSolarShading->MaxHCV));
   11552           0 :             ShowContinueError(
   11553             :                 state,
   11554           0 :                 "Overlapping figure=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1).Name +
   11555           0 :                     ", Surface Class=[" +
   11556           0 :                     cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1).Class) + ']');
   11557           0 :             ShowContinueError(state, format("  This error occurred {} times.", Count));
   11558           0 :             for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyVertices; ++Loop2) {
   11559           0 :                 if (state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1 ==
   11560           0 :                     state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex1) {
   11561           0 :                     if (SurfErrorReported2(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2)) continue;
   11562           0 :                     ShowContinueError(
   11563             :                         state,
   11564           0 :                         "Figure being Overlapped=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2).Name +
   11565           0 :                             ", Surface Class=[" +
   11566           0 :                             cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2).Class) + ']');
   11567           0 :                     SurfErrorReported2(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2) = true;
   11568             :                 }
   11569             :             }
   11570           0 :             SurfErrorReported(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1) = true;
   11571             :         }
   11572           0 :         if (TotCount > 0) {
   11573           0 :             ShowMessage(state, "");
   11574           0 :             ShowContinueError(state, format("  The too many vertices errors occurred {} times (total).", TotCount));
   11575           0 :             ShowMessage(state, "");
   11576             :         }
   11577             : 
   11578           0 :         SurfErrorReported = false;
   11579           0 :         TotCount = 0;
   11580           0 :         if (state.dataSolarShading->NumTooManyFigures > 0) {
   11581           0 :             ShowMessage(state, format("Too many figures [>={}] in shadow overlap errors occurring...", state.dataSolarShading->MaxHCS));
   11582           0 :             ShowMessage(state,
   11583             :                         "These occur throughout the year and may occur several times for the same surfaces. You "
   11584             :                         "may be able to reduce them by "
   11585             :                         "adding OutputDiagnostics,DoNotMirrorDetachedShading;");
   11586             :         }
   11587           0 :         for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumTooManyFigures; ++Loop1) {
   11588           0 :             Count = 0;
   11589           0 :             SurfErrorReported2 = false;
   11590           0 :             if (SurfErrorReported(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1)) continue;
   11591           0 :             for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyFigures; ++Loop2) {
   11592           0 :                 if (state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1 == state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex1) {
   11593           0 :                     ++Count;
   11594             :                 }
   11595             :             }
   11596           0 :             TotCount += Count;
   11597           0 :             state.dataErrTracking->TotalWarningErrors += Count - 1;
   11598           0 :             ShowMessage(state, "");
   11599           0 :             ShowWarningError(state, format("Too many figures [>={}] in a shadow overlap", state.dataSolarShading->MaxHCS));
   11600           0 :             ShowContinueError(state,
   11601           0 :                               "Overlapping figure=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1).Name +
   11602           0 :                                   ", Surface Class=[" +
   11603           0 :                                   cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1).Class) +
   11604             :                                   ']');
   11605           0 :             ShowContinueError(state, format("  This error occurred {} times.", Count));
   11606           0 :             for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyFigures; ++Loop2) {
   11607           0 :                 if (state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1 == state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex1) {
   11608           0 :                     if (SurfErrorReported2(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2)) continue;
   11609           0 :                     ShowContinueError(
   11610             :                         state,
   11611           0 :                         "Figure being Overlapped=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2).Name +
   11612           0 :                             ", Surface Class=[" +
   11613           0 :                             cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2).Class) + ']');
   11614           0 :                     SurfErrorReported2(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2) = true;
   11615             :                 }
   11616             :             }
   11617           0 :             SurfErrorReported(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1) = true;
   11618             :         }
   11619           0 :         if (TotCount > 0) {
   11620           0 :             ShowMessage(state, "");
   11621           0 :             ShowContinueError(state, format("  The too many figures errors occurred {} times (total).", TotCount));
   11622           0 :             ShowMessage(state, "");
   11623             :         }
   11624           0 :         SurfErrorReported.deallocate();
   11625           0 :         SurfErrorReported2.deallocate();
   11626             :     }
   11627         771 : }
   11628             : 
   11629         771 : void ComputeWinShadeAbsorpFactors(EnergyPlusData &state)
   11630             : {
   11631             : 
   11632             :     // SUBROUTINE INFORMATION:
   11633             :     //       AUTHOR         Fred Winkelmann
   11634             :     //       DATE WRITTEN   Mar 2001
   11635             :     //       MODIFIED       Oct 2002,FCW: change ConstrNumSh =
   11636             :     //       WindowShadingControl(WinShadeCtrlNum)%ShadedConstruction
   11637             :     //                      to Surface(SurfNum)%ShadedConstruction
   11638             :     //       RE-ENGINEERED  na
   11639             : 
   11640             :     // PURPOSE OF THIS SUBROUTINE:
   11641             :     // Called by InitSolarCalculations. Finds fractions that apportion radiation absorbed by a
   11642             :     // window shade to the two faces of the shade. For radiation incident from the left,
   11643             :     // ShadeAbsFacFace(1) is the fraction of radiation absorbed in the left-hand half of the
   11644             :     // of the shade and ShadeAbsFacFace(2) is the fraction absorbed in the right-hand half.
   11645             :     // The shade is assumed to be homogeneous.
   11646             : 
   11647             :     // REFERENCES: See EnergyPlus engineering documentation
   11648             :     // USE STATEMENTS: na
   11649             : 
   11650        5585 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
   11651        9632 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
   11652        4818 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
   11653        4818 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
   11654        4818 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
   11655       10792 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
   11656        5974 :                 if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window && state.dataSurface->Surface(SurfNum).HasShadeControl) {
   11657         143 :                     int WinShadeCtrlNum = state.dataSurface->Surface(SurfNum).activeWindowShadingControl; // Window shading control number
   11658             : 
   11659         143 :                     int MatNumSh = 0;       // Shade layer material number
   11660         143 :                     Real64 AbsorpEff = 0.0; // Effective absorptance of isolated shade layer (fraction of
   11661             :                     //  of incident radiation remaining after reflected portion is
   11662             :                     //  removed that is absorbed
   11663         143 :                     if (ANY_SHADE(state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType)) {
   11664          71 :                         int const ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction; // Window construction number with shade
   11665          71 :                         int TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers;                // Total layers in a construction
   11666             : 
   11667          71 :                         if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::IntShade) {
   11668          49 :                             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay); // Interior shade
   11669          22 :                         } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::ExtShade) {
   11670          18 :                             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1); // Exterior shade
   11671           4 :                         } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::BGShade) {
   11672           4 :                             if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) {
   11673             :                                 // Double pane with between-glass shade
   11674           2 :                                 MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3);
   11675             :                             } else {
   11676             :                                 // Triple pane with between-glass shade
   11677           2 :                                 MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5);
   11678             :                             }
   11679             :                         }
   11680         142 :                         AbsorpEff = state.dataMaterial->Material(MatNumSh).AbsorpSolar /
   11681          71 :                                     (state.dataMaterial->Material(MatNumSh).AbsorpSolar + state.dataMaterial->Material(MatNumSh).Trans + 0.0001);
   11682          71 :                         AbsorpEff = min(max(AbsorpEff, 0.0001),
   11683             :                                         0.999); // Constrain to avoid problems with following log eval
   11684          71 :                         state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum) = (1.0 - std::exp(0.5 * std::log(1.0 - AbsorpEff))) / AbsorpEff;
   11685          71 :                         state.dataSurface->SurfWinShadeAbsFacFace2(SurfNum) = 1.0 - state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum);
   11686             :                     }
   11687             :                 }
   11688             :             }
   11689             :         }
   11690             :     }
   11691         771 : }
   11692             : 
   11693      821277 : void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state)
   11694             : {
   11695             : 
   11696             :     // SUBROUTINE INFORMATION:
   11697             :     //       AUTHOR         Rob Hitchcock
   11698             :     //       DATE WRITTEN   July 2007
   11699             :     //       MODIFIED       N/A
   11700             :     //       RE-ENGINEERED  N/A
   11701             : 
   11702             :     // PURPOSE OF THIS SUBROUTINE:
   11703             :     // This subroutine calculates the initial distribution
   11704             :     // of diffuse solar transmitted through exterior windows
   11705             :     // to individual heat transfer surfaces in each zone(or enclosure).
   11706             : 
   11707             :     // METHODOLOGY EMPLOYED:
   11708             :     // Apportions diffuse solar transmitted through each exterior window
   11709             :     // that is then absorbed, reflected, and/or transmitted
   11710             :     // by other heat transfer surfaces in the zone.
   11711             :     // Calculations use:
   11712             :     // 1. WinDifSolar calculated in SUBROUTINE CalcInteriorSolarDistribution,
   11713             :     // 2. view factors between each exterior window and
   11714             :     // other heat transfer surfaces in a zone
   11715             :     // calculated in SUBROUTINE CalcApproximateViewFactors, and
   11716             :     // 3. surface absorptances, reflectances, and transmittances
   11717             :     // determined here using revised code from SUBROUTINE InitIntSolarDistribution
   11718             : 
   11719             :     // Using/Aliasing
   11720             :     using General::InterpSw;
   11721             :     using ScheduleManager::GetCurrentScheduleValue;
   11722             :     using namespace DataViewFactorInformation;
   11723             :     using namespace DataWindowEquivalentLayer;
   11724             : 
   11725             :     Real64 AbsInt;               // Tmp var for Inside surface short-wave absorptance
   11726             :     Real64 InsideDifAbsorptance; // Inside diffuse solar absorptance of a surface
   11727             :     Real64 InsideDifReflectance; // Inside diffuse solar reflectance of a surface
   11728             :     int BlNum;                   // Blind number
   11729             :     Real64 BlAbsDiffBk;          // Glass layer back diffuse solar absorptance when blind in place
   11730             :     Real64 AbsDiffBkBl;          // Blind diffuse back solar absorptance as part of glazing system
   11731             : 
   11732             :     //  REAL(r64)    :: DividerSolAbs      ! Window divider solar absorptance
   11733             :     //  REAL(r64)    :: DividerSolRefl     ! Window divider solar reflectance
   11734             :     //  INTEGER :: MatNumGl           ! Glass layer material number
   11735             :     //  INTEGER :: MatNumSh           ! Shade layer material number
   11736             :     //  REAL(r64)    :: TransGl,ReflGl,AbsGl ! Glass layer solar transmittance, reflectance, absorptance
   11737             : 
   11738             :     Real64 ViewFactor;       // temp var for view factor
   11739             :                              //        Real64 ViewFactorTotal;             // debug var for view factor total
   11740             :     Real64 WinDifSolarTrans; // debug var for WinDifSolar() [W]
   11741             :                              //        Real64 WinDifSolarDistTotl;         // debug var for window total
   11742             :                              //        distributed diffuse solar [W] Real64 WinDifSolarDistAbsorbedTotl; // debug
   11743             :                              //        var for individual exterior window total distributed
   11744             :     //    diffuse solar absorbed [W]
   11745             :     //        Real64 WinDifSolarDistReflectedTotl; // debug var for individual exterior window total distributed
   11746             :     //    diffuse solar reflected [W]
   11747             :     //        Real64 WinDifSolarDistTransmittedTotl; // debug var for individual exterior window total distributed
   11748             :     //    diffuse solar transmitted [W]
   11749             :     Real64 WinDifSolLayAbsW; // temp var for diffuse solar absorbed by individual glass layer [W]
   11750             :                              //        Real64 ZoneDifSolarTrans;               // debug var for WinDifSolar() [W]
   11751             :                              //        Real64 ZoneDifSolarDistTotl;            // debug var for zone total
   11752             :                              //        distributed diffuse solar [W] Real64 ZoneDifSolarDistAbsorbedTotl;    //
   11753             :                              //        debug var for zone total distributed diffuse solar absorbed [W] Real64
   11754             :                              //        ZoneDifSolarDistReflectedTotl;   // debug var for zone total distributed
   11755             :                              //        diffuse solar reflected [W] Real64 ZoneDifSolarDistTransmittedTotl; //
   11756             :                              //        debug var for zone total distributed diffuse solar transmitted [W]
   11757             : 
   11758             :     Real64 DifSolarAbsW;     // temp var for diffuse solar absorbed by surface [W]
   11759             :     Real64 DifSolarAbs;      // temp var for diffuse solar absorbed by surface [W/m2]
   11760             :     Real64 DifSolarReflW;    // temp var for diffuse solar reflected by surface [W]
   11761             :     Real64 DifSolarTransW;   // temp var for diffuse solar transmitted through interior window surface [W]
   11762             :     Real64 ShBlDifSolarAbsW; // temp var for diffuse solar absorbed by shade/blind [W]
   11763             : 
   11764     1642554 :     Array2D<Real64> SurfWinAbsSolBeamEQL(2, CFSMAXNL + 1); // absorbed exterior beam radiation by layers fraction
   11765             :     Array2D<Real64> SurfWinAbsSolDiffEQL(2,
   11766     1642554 :                                          CFSMAXNL + 1);        // absorbed exterior diffuse radiation by layers fraction
   11767     1642554 :     Array2D<Real64> SurfWinAbsSolBeamBackEQL(2, CFSMAXNL + 1); // absorbed interior beam radiation by layers fraction from back
   11768     1642554 :     Array2D<Real64> AbsSolDiffBackEQL(2, CFSMAXNL + 1);        // absorbed exterior diffuse radiation by layers fraction from back
   11769             :     int EQLNum;                                                // equivalent layer fenestration index
   11770             :     int Lay;                                                   // equivalent layer fenestration layer index
   11771             : 
   11772             :     // Init accumulators for absorbed diffuse solar for all surfaces for later heat balance calcs
   11773      821277 :     state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs = 0.0;
   11774      821277 :     state.dataHeatBal->SurfWinInitialDifSolwinAbs = 0.0;
   11775             : 
   11776             :     // Init accumulator for total reflected diffuse solar within each zone for interreflection calcs
   11777      821277 :     state.dataHeatBal->EnclSolInitialDifSolReflW = 0.0;
   11778             : 
   11779             :     // Init accumulator for transmitted diffuse solar for all surfaces for reporting
   11780      821277 :     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans = 0.0;
   11781             : 
   11782             :     // Loop over all zones doing initial distribution of diffuse solar to interior heat transfer surfaces
   11783     6664958 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
   11784     5843681 :         auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
   11785             :         // Init Zone accumulators for debugging
   11786             :         //            ZoneDifSolarTrans = 0.0;
   11787             :         //            ZoneDifSolarDistAbsorbedTotl = 0.0;
   11788             :         //            ZoneDifSolarDistReflectedTotl = 0.0;
   11789             :         //            ZoneDifSolarDistTransmittedTotl = 0.0;
   11790             :         // Loop over all diffuse solar transmitting surfaces (i.e., exterior windows and TDDs) in the current zone
   11791    56358052 :         for (int const DifTransSurfNum : thisEnclosure.SurfacePtr) {
   11792             :             // Skip surfaces that are not exterior, except for TDD_Diffusers
   11793   131969342 :             if (((state.dataSurface->Surface(DifTransSurfNum).ExtBoundCond != ExternalEnvironment) &&
   11794    81419494 :                  (state.dataSurface->Surface(DifTransSurfNum).ExtBoundCond != OtherSideCondModeledExt)) &&
   11795    30905123 :                 state.dataSurface->SurfWinOriginalClass(DifTransSurfNum) != SurfaceClass::TDD_Diffuser)
   11796    30905123 :                 continue;
   11797             : 
   11798             :             // Do I need to do anything special for TDDs?
   11799             :             //                if ( SurfaceWindow( DifTransSurfNum ).OriginalClass == SurfaceClass::TDD_Diffuser )
   11800             :             //                {
   11801             :             //                }
   11802             : 
   11803             :             // Skip surfaces that are not exterior windows or TDD diffusers
   11804    32102073 :             if (state.dataSurface->Surface(DifTransSurfNum).Class != SurfaceClass::Window &&
   11805    12492825 :                 state.dataSurface->SurfWinOriginalClass(DifTransSurfNum) != SurfaceClass::TDD_Diffuser)
   11806    12492825 :                 continue;
   11807             : 
   11808             :             //----------------------------------------------------------------------------------------------------------
   11809             :             // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH EXTERIOR WINDOWS AND TDDS TO INTERIOR HEAT TRANSFER
   11810             :             // SURFACES
   11811             :             //----------------------------------------------------------------------------------------------------------
   11812             : 
   11813             :             // Init transmitted solar debug vars
   11814             :             //                ViewFactorTotal = 0.0;
   11815     7116423 :             WinDifSolarTrans = state.dataSurface->SurfWinDifSolar(DifTransSurfNum);
   11816             :             //                ZoneDifSolarTrans += WinDifSolarTrans;
   11817             : 
   11818             :             // Init Exterior Window accumulators for debugging
   11819             :             //                WinDifSolarDistAbsorbedTotl = 0.0;
   11820             :             //                WinDifSolarDistReflectedTotl = 0.0;
   11821             :             //                WinDifSolarDistTransmittedTotl = 0.0;
   11822             : 
   11823             :             // Loop over all heat transfer surfaces in the current zone that might receive diffuse solar
   11824   102738319 :             for (int const HeatTransSurfNum : thisEnclosure.SurfacePtr) {
   11825             :                 // Skip surfaces that are not heat transfer surfaces
   11826             :                 // Skip tubular daylighting device domes
   11827    95621896 :                 if (state.dataSurface->Surface(HeatTransSurfNum).Class == SurfaceClass::TDD_Dome) continue;
   11828             : 
   11829             :                 // View factor from current (sending) window DifTransSurfNum to current (receiving) surface
   11830             :                 // HeatTransSurfNum
   11831             :                 int const HTenclosureSurfNum =
   11832    95621896 :                     state.dataSurface->Surface(HeatTransSurfNum).SolarEnclSurfIndex; // HT surface index for EnclSolInfo.SurfacePtr and F arrays
   11833    95621896 :                 int const enclosureNum = state.dataSurface->Surface(HeatTransSurfNum).SolarEnclIndex; // index for EnclSolInfo
   11834             :                 int const DTenclSurfNum =
   11835    95621896 :                     state.dataSurface->Surface(DifTransSurfNum).SolarEnclSurfIndex; // Window surface index for EnclSolInfo.SurfacePtr and F arrays
   11836             : 
   11837    95621896 :                 ViewFactor = state.dataViewFactor->EnclSolInfo(enclosureNum).F(HTenclosureSurfNum, DTenclSurfNum);
   11838             :                 // debug ViewFactorTotal
   11839             :                 //                    ViewFactorTotal += ViewFactor; // debug
   11840             : 
   11841             :                 // Skip receiving surfaces with 0.0 view factor
   11842    95621896 :                 if (ViewFactor <= 0.0) continue;
   11843             : 
   11844    54777008 :                 Real64 const WinDifSolarTrans_Factor(WinDifSolarTrans * ViewFactor);
   11845    54777008 :                 Real64 const win_SwitchingFactor(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum));
   11846    54777008 :                 Real64 const per_HTSurfaceArea(1.0 / state.dataSurface->Surface(HeatTransSurfNum).Area);
   11847             : 
   11848             :                 // Calculate diffuse solar from current exterior window absorbed and reflected by current heat
   11849             :                 // transfer surface And calculate transmitted diffuse solar to adjacent zones through interior
   11850             :                 // windows
   11851    54777008 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(HeatTransSurfNum);
   11852    54777008 :                 if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Interior Opaque Surface
   11853             : 
   11854             :                     // Determine the inside (back) diffuse solar absorptance
   11855             :                     // and reflectance of the current heat transfer surface
   11856    47748963 :                     InsideDifAbsorptance = state.dataHeatBalSurf->SurfAbsSolarInt(HeatTransSurfNum);
   11857             :                     // Inside (back) diffuse solar reflectance is assumed to be 1 - absorptance
   11858    47748963 :                     InsideDifReflectance = 1.0 - InsideDifAbsorptance;
   11859             : 
   11860             :                     // Absorbed diffuse solar [W] = current window transmitted diffuse solar [W]
   11861             :                     //    * view factor from current (sending) window DifTransSurfNum to current (receiving)
   11862             :                     //    surface HeatTransSurfNum
   11863             :                     //    * current surface inside solar absorptance
   11864    47748963 :                     DifSolarAbsW = WinDifSolarTrans_Factor * InsideDifAbsorptance; // [W]
   11865             : 
   11866             :                     // Absorbed diffuse solar [W/m2] = Absorbed diffuse solar [W]
   11867             :                     //                                 / current surface net area
   11868    47748963 :                     DifSolarAbs = DifSolarAbsW * per_HTSurfaceArea;
   11869             : 
   11870             :                     // Accumulate absorbed diffuse solar [W/m2] on this surface for heat balance calcs
   11871    47748963 :                     state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(HeatTransSurfNum) += DifSolarAbs;
   11872             : 
   11873             :                     // Reflected diffuse solar [W] = current window transmitted diffuse solar
   11874             :                     //    * view factor from current (sending) window DifTransSurfNum to current (receiving)
   11875             :                     //    surface HeatTransSurfNum
   11876             :                     //    * current window inside solar reflectance
   11877    47748963 :                     DifSolarReflW = WinDifSolarTrans_Factor * InsideDifReflectance;
   11878             : 
   11879             :                     // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   11880             :                     // interreflection calcs
   11881    47748963 :                     state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
   11882             : 
   11883             :                     // Accumulate Window and Zone total distributed diffuse solar to check for conservation of
   11884             :                     // energy For opaque surfaces all incident diffuse is either absorbed or reflected
   11885             : 
   11886             :                 } else { // Exterior or Interior Window
   11887     7028045 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(HeatTransSurfNum);
   11888     7028045 :                     int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
   11889     7028045 :                     WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(HeatTransSurfNum);
   11890             : 
   11891     7028045 :                     if (state.dataSurface->SurfWinWindowModelType(HeatTransSurfNum) != WindowModel::EQL) {
   11892     7024765 :                         if (NOT_SHADED(ShadeFlag)) { // No window shading
   11893             :                             // Init accumulator for transmittance calc below
   11894     6938132 :                             DifSolarAbsW = 0.0;
   11895             : 
   11896             :                             // Calc diffuse solar absorbed by all window glass layers
   11897             :                             // Note: I am assuming here that individual glass layer absorptances have been
   11898             :                             // corrected
   11899             :                             //       to account for layer by layer transmittance and reflection effects.
   11900    16041662 :                             for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
   11901             :                                 // Calc diffuse solar absorbed from the inside by each window glass layer [W]
   11902     9103530 :                                 AbsInt = state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
   11903     9103530 :                                 WinDifSolLayAbsW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
   11904             : 
   11905             :                                 // Accumulate distributed diffuse solar absorbed [W] by overall window for
   11906             :                                 // transmittance calc below
   11907     9103530 :                                 DifSolarAbsW += WinDifSolLayAbsW;
   11908             : 
   11909             :                                 // Accumulate diffuse solar absorbed from the inside by each window glass layer
   11910             :                                 // [W/m2] for heat balance calcs
   11911     9103530 :                                 state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea;
   11912             :                             }
   11913             : 
   11914             :                             // Calc diffuse solar reflected back to zone
   11915             :                             // I don't really care if this is a window or opaque surface since I am just
   11916             :                             // accumulating all reflected diffuse solar in a zone bucket for "interreflected"
   11917             :                             // distribution Reflected diffuse solar [W] = current window transmitted diffuse solar
   11918             :                             //    * view factor from current (sending) window DifTransSurfNum to current
   11919             :                             //    (receiving) surface HeatTransSurfNum
   11920             :                             //    * current window inside solar reflectance
   11921     6938132 :                             InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   11922     6938132 :                             DifSolarReflW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   11923             : 
   11924             :                             // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   11925             :                             // interreflection calcs
   11926     6938132 :                             state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
   11927             : 
   11928             :                             //------------------------------------------------------------------------------
   11929             :                             // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO ADJACENT ZONE
   11930             :                             //------------------------------------------------------------------------------
   11931             : 
   11932             :                             // If this receiving window surface (HeatTransSurfNum) is an interior window,
   11933             :                             // calc distributed solar transmitted to adjacent zone [W]
   11934             :                             // NOTE: This calc is here because interior windows are currently assumed to have no
   11935             :                             // shading
   11936             : 
   11937             :                             // Get the adjacent surface number for this receiving window surface
   11938     6938132 :                             int AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond;
   11939             :                             // If the adjacent surface number is > 0, this is an interior window
   11940     6938132 :                             if (AdjSurfNum > 0) { // this is an interior window surface
   11941             : 
   11942             :                                 // Calc diffuse solar from current exterior window
   11943             :                                 // transmitted through this interior window to adjacent zone [W]
   11944             :                                 // Transmitted diffuse solar [W] = current exterior window transmitted diffuse
   11945             :                                 // solar
   11946             :                                 //    * view factor from current (sending) window DifTransSurfNum to current
   11947             :                                 //    (receiving) surface HeatTransSurfNum
   11948             :                                 //    - diffuse absorbed by this interior window
   11949             :                                 //    - diffuse reflected by this interior window
   11950        7495 :                                 DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
   11951             :                                 // HERE 8/15/07 Note Construct(AdjConstrNum)%TransDiff could be used here since
   11952             :                                 // the "front" transmittance for an interior window in the adjacent zone is the
   11953             :                                 // correct direction as long as I use the Construct() of the Surface in the
   11954             :                                 // adjacent zone. However, the above calculation better conserves energy, although
   11955             :                                 // possibly at the expense of less accurate transmittance calcs. Preliminary tests
   11956             :                                 // showed fairly good agreement between the two DifSolarTransW calculation
   11957             :                                 // methods, but for consistency I stuck with the above. int AdjConstrNum =
   11958             :                                 // Surface(AdjSurfNum).Construction;
   11959             :                                 //              DifSolarTransW = WinDifSolar(DifTransSurfNum) &
   11960             :                                 //                                * ViewFactor &
   11961             :                                 //                                * Construct(AdjConstrNum)%TransDiff
   11962             : 
   11963             :                                 // Get the adjacent zone index
   11964        7495 :                                 int const adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
   11965             : 
   11966             :                                 // Call routine to distribute diffuse solar transmitted through this interior
   11967             :                                 // window into adjacent zone
   11968        7495 :                                 CalcInteriorWinTransDifSolInitialDistribution(state, adjEnclosureNum, AdjSurfNum, DifSolarTransW);
   11969             : 
   11970             :                             } else { // this is an exterior window surface
   11971             : 
   11972             :                                 // Calc transmitted Window and Zone total distributed diffuse solar to check for
   11973             :                                 // conservation of energy This is not very effective since it assigns whatever
   11974             :                                 // distributed diffuse solar has not been absorbed or reflected to transmitted.
   11975     6930637 :                                 DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
   11976             : 
   11977             :                             } // this is an interior window surface
   11978             : 
   11979             :                             // Accumulate transmitted diffuse solar for reporting
   11980     6938132 :                             state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
   11981             : 
   11982       86633 :                         } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing
   11983             :                             // Init accumulator for transmittance calc below
   11984        2226 :                             DifSolarAbsW = 0.0;
   11985             : 
   11986        2226 :                             auto const &construct(state.dataConstruction->Construct(ConstrNum));
   11987        2226 :                             auto const &construct_AbsDiffBack(construct.AbsDiffBack);
   11988        2226 :                             auto const &construct_sh(state.dataConstruction->Construct(ConstrNumSh));
   11989        2226 :                             auto const &construct_sh_AbsDiffBack(construct_sh.AbsDiffBack);
   11990        6678 :                             for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
   11991             :                                 // Calc diffuse solar absorbed in each window glass layer
   11992        4452 :                                 WinDifSolLayAbsW = WinDifSolarTrans_Factor *
   11993        4452 :                                                    InterpSw(win_SwitchingFactor, construct_AbsDiffBack(IGlass), construct_sh_AbsDiffBack(IGlass));
   11994             : 
   11995             :                                 // Accumulate distributed diffuse solar absorbed [W] by overall window for
   11996             :                                 // transmittance calc below
   11997        4452 :                                 DifSolarAbsW += WinDifSolLayAbsW;
   11998             : 
   11999             :                                 // Accumulate diffuse solar absorbed from the inside by each window glass layer
   12000             :                                 // [W/m2] for heat balance calcs
   12001        4452 :                                 state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea;
   12002             :                             }
   12003             : 
   12004             :                             // Calc diffuse solar reflected back to zone
   12005        2226 :                             DifSolarReflW = WinDifSolarTrans_Factor *
   12006        2226 :                                             InterpSw(win_SwitchingFactor, construct.ReflectSolDiffBack, construct_sh.ReflectSolDiffBack);
   12007             : 
   12008             :                             // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   12009             :                             // interreflection calcs
   12010        2226 :                             state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
   12011             : 
   12012             :                             // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
   12013             :                             // conservation of energy This is not very effective since it assigns whatever
   12014             :                             // distributed diffuse solar has not been absorbed or reflected to transmitted.
   12015        2226 :                             DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
   12016             : 
   12017             :                             // Accumulate transmitted diffuse solar for reporting
   12018        2226 :                             state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
   12019             : 
   12020       84407 :                         } else if (ConstrNumSh != 0) {
   12021             :                             // Interior, exterior or between-glass shade, screen or blind in place
   12022             : 
   12023             :                             // Init accumulator for transmittance calc below
   12024       70547 :                             DifSolarAbsW = 0.0;
   12025       70547 :                             WinDifSolLayAbsW = 0.0;
   12026             : 
   12027             :                             // First calc diffuse solar absorbed by each glass layer in this window with
   12028             :                             // shade/blind in place
   12029       70547 :                             auto const &construct_sh(state.dataConstruction->Construct(ConstrNumSh));
   12030       70547 :                             auto const &construct_sh_AbsDiffBack(construct_sh.AbsDiffBack);
   12031       70547 :                             auto const &construct_sh_BlAbsDiffBack(construct_sh.BlAbsDiffBack);
   12032             : 
   12033       70547 :                             int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(HeatTransSurfNum);
   12034       70547 :                             Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(HeatTransSurfNum);
   12035             : 
   12036      182098 :                             for (int IGlass = 1; IGlass <= construct_sh.TotGlassLayers; ++IGlass) {
   12037      111551 :                                 if (ANY_SHADE_SCREEN(ShadeFlag)) {
   12038             :                                     // Calc diffuse solar absorbed in each window glass layer and shade
   12039      110424 :                                     WinDifSolLayAbsW = WinDifSolarTrans_Factor * construct_sh_AbsDiffBack(IGlass);
   12040        1127 :                                 } else if (ANY_BLIND(ShadeFlag)) {
   12041        1127 :                                     if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
   12042           0 :                                         BlAbsDiffBk = General::InterpGeneral(
   12043           0 :                                             construct_sh_BlAbsDiffBack(SurfWinSlatsAngIndex, IGlass),
   12044           0 :                                             construct_sh_BlAbsDiffBack(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), IGlass),
   12045             :                                             SurfWinSlatsAngInterpFac);
   12046             :                                     } else {
   12047        1127 :                                         BlAbsDiffBk = construct_sh_BlAbsDiffBack(1, IGlass);
   12048             :                                     }
   12049             :                                     // Calc diffuse solar absorbed in each window glass layer and shade
   12050        1127 :                                     WinDifSolLayAbsW = WinDifSolarTrans_Factor * BlAbsDiffBk;
   12051             :                                 }
   12052             : 
   12053             :                                 // Accumulate distributed diffuse solar absorbed [W] by overall window for
   12054             :                                 // transmittance calc below
   12055      111551 :                                 DifSolarAbsW += WinDifSolLayAbsW;
   12056             : 
   12057             :                                 // Accumulate diffuse solar absorbed from the inside by each window glass layer
   12058             :                                 // [W/m2] for heat balance calcs
   12059      111551 :                                 state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea;
   12060             :                             }
   12061             : 
   12062             :                             // Next calc diffuse solar reflected back to zone from window with shade or blind on
   12063             :                             // Diffuse back solar reflectance, bare glass or shade on
   12064       70547 :                             InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   12065       70547 :                             if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::IntBlind) | BITF(WinShadingType::ExtBlind))) {
   12066             :                                 // Diffuse back solar reflectance, blind present, vs. slat angle
   12067        1127 :                                 if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
   12068           0 :                                     InsideDifReflectance = General::InterpGeneral(
   12069           0 :                                         state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(SurfWinSlatsAngIndex),
   12070           0 :                                         state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(
   12071           0 :                                             std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
   12072             :                                         SurfWinSlatsAngInterpFac);
   12073             :                                 } else {
   12074        1127 :                                     InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(1);
   12075             :                                 }
   12076             :                             }
   12077       70547 :                             DifSolarReflW = WinDifSolarTrans_Factor * InsideDifReflectance;
   12078             : 
   12079             :                             // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   12080             :                             // interreflection calcs
   12081       70547 :                             state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
   12082             : 
   12083             :                             // Now calc diffuse solar absorbed by shade/blind itself
   12084       70547 :                             BlNum = state.dataSurface->SurfWinBlindNumber(HeatTransSurfNum);
   12085       70547 :                             if (ANY_SHADE_SCREEN(ShadeFlag)) {
   12086             :                                 // Calc diffuse solar absorbed by shade or screen [W]
   12087       69420 :                                 ShBlDifSolarAbsW = WinDifSolarTrans_Factor * construct_sh.AbsDiffBackShade;
   12088        1127 :                             } else if (ANY_BLIND(ShadeFlag)) {
   12089             :                                 // Calc diffuse solar absorbed by blind [W]
   12090        1127 :                                 if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
   12091           0 :                                     AbsDiffBkBl =
   12092           0 :                                         General::InterpGeneral(construct_sh.AbsDiffBackBlind(SurfWinSlatsAngIndex),
   12093           0 :                                                                construct_sh.AbsDiffBackBlind(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
   12094             :                                                                SurfWinSlatsAngInterpFac);
   12095             :                                 } else {
   12096        1127 :                                     AbsDiffBkBl = construct_sh.AbsDiffBackBlind(1);
   12097             :                                 }
   12098        1127 :                                 ShBlDifSolarAbsW = WinDifSolarTrans_Factor * AbsDiffBkBl;
   12099             :                             }
   12100             :                             // Correct for divider shadowing
   12101       70547 :                             if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
   12102       29838 :                                 ShBlDifSolarAbsW *= state.dataSurface->SurfWinGlazedFrac(HeatTransSurfNum);
   12103             :                             }
   12104             : 
   12105             :                             // Accumulate diffuse solar absorbed  by shade or screen [W/m2] for heat balance calcs
   12106       70547 :                             state.dataSurface->SurfWinInitialDifSolAbsByShade(HeatTransSurfNum) += ShBlDifSolarAbsW * per_HTSurfaceArea;
   12107             : 
   12108             :                             // Accumulate distributed diffuse solar absorbed [W] by overall window for
   12109             :                             // transmittance calc below
   12110       70547 :                             DifSolarAbsW += ShBlDifSolarAbsW;
   12111             : 
   12112             :                             // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
   12113             :                             // conservation of energy This is not very effective since it assigns whatever
   12114             :                             // distributed diffuse solar has not been absorbed or reflected to transmitted.
   12115       70547 :                             DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
   12116             : 
   12117             :                             // Accumulate transmitted diffuse solar for reporting
   12118       70547 :                             state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
   12119             :                         } // End of shading flag check
   12120             : 
   12121             :                     } else {
   12122             :                         // SurfaceWindow(HeatTransSurfNum)%WindowModelType == WindowModel:: EQL
   12123             :                         // ConstrNum=Surface(HeatTransSurfNum)%Construction
   12124             :                         // call the ASHWAT fenestration model for diffuse radiation here
   12125        3280 :                         WindowEquivalentLayer::CalcEQLOpticalProperty(state, HeatTransSurfNum, SolarArrays::DIFF, AbsSolDiffBackEQL);
   12126             : 
   12127        3280 :                         EQLNum = state.dataConstruction->Construct(ConstrNum).EQLConsPtr;
   12128       17262 :                         for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
   12129             : 
   12130             :                             // Calc diffuse solar absorbed from the inside by each layer of EQL model [W]
   12131             :                             // WinDifSolLayAbsW = WinDifSolar(DifTransSurfNum)* ViewFactor *
   12132             :                             // Construct(ConstrNum)%AbsDiffBack(Lay)
   12133       13982 :                             WinDifSolLayAbsW = WinDifSolarTrans_Factor * AbsSolDiffBackEQL(2, Lay);
   12134             : 
   12135             :                             // Accumulate distributed diffuse solar absorbed [W] by overall window for
   12136             :                             // transmittance calc below
   12137       13982 :                             DifSolarAbsW += WinDifSolLayAbsW;
   12138             : 
   12139             :                             // Accumulate diffuse solar absorbed from the inside by each window layer [W/m2] for
   12140             :                             // heat balance calcs
   12141       13982 :                             state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, Lay) += WinDifSolLayAbsW * per_HTSurfaceArea;
   12142             : 
   12143             :                             // ASHWAT equivalent layer model may require not the individual layer absorption but
   12144             :                             // the flux InitialDifSolwinEQL(HeatTransSurfNum) = WinDifSolar(DifTransSurfNum)*
   12145             :                             // ViewFactor
   12146             :                         }
   12147             : 
   12148             :                         // Calc diffuse solar reflected back to zone
   12149             :                         // I don't really care if this is a window or opaque surface since I am just
   12150             :                         // accumulating all reflected diffuse solar in a zone bucket for "interreflected"
   12151             :                         // distribution Reflected diffuse solar [W] = current window transmitted diffuse solar
   12152             :                         //    * view factor from current (sending) window DifTransSurfNum to current (receiving)
   12153             :                         //    surface HeatTransSurfNum
   12154             :                         //    * current window inside solar reflectance
   12155        3280 :                         InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   12156        3280 :                         DifSolarReflW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   12157             : 
   12158             :                         // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   12159             :                         // interreflection calcs
   12160        3280 :                         state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
   12161             : 
   12162             :                         //------------------------------------------------------------------------------
   12163             :                         // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO ADJACENT ZONE
   12164             :                         //------------------------------------------------------------------------------
   12165             : 
   12166             :                         // If this receiving window surface (HeatTransSurfNum) is an interior window,
   12167             :                         // calc distributed solar transmitted to adjacent zone [W]
   12168             :                         // NOTE: This calc is here because interior windows are currently assumed to have no
   12169             :                         // shading
   12170             : 
   12171             :                         // Get the adjacent surface number for this receiving window surface
   12172        3280 :                         int const AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond;
   12173             :                         // If the adjacent surface number is > 0, this is an interior window
   12174        3280 :                         if (AdjSurfNum > 0) { // this is an interior window surface
   12175             : 
   12176             :                             // Calc diffuse solar from current exterior window
   12177             :                             // transmitted through this interior window to adjacent zone [W]
   12178             :                             // Transmitted diffuse solar [W] = current exterior window transmitted diffuse solar
   12179             :                             //    * view factor from current (sending) window DifTransSurfNum to current
   12180             :                             //    (receiving) surface HeatTransSurfNum
   12181           0 :                             DifSolarTransW = AbsSolDiffBackEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1) * ViewFactor;
   12182             :                             // int AdjConstrNum = Surface(AdjSurfNum).Construction;
   12183             :                             // Get the adjacent zone index
   12184           0 :                             int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
   12185             :                             // Call routine to distribute diffuse solar transmitted through this interior window
   12186             :                             // into adjacent zone
   12187           0 :                             CalcInteriorWinTransDifSolInitialDistribution(state, adjEnclosureNum, AdjSurfNum, DifSolarTransW);
   12188             : 
   12189             :                         } else { // this is an exterior window surface
   12190             : 
   12191             :                             // Calc transmitted Window and Zone total distributed diffuse solar to check for
   12192             :                             // conservation of energy This is not very effective since it assigns whatever
   12193             :                             // distributed diffuse solar has not been absorbed or reflected to transmitted.
   12194        3280 :                             DifSolarTransW = AbsSolDiffBackEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1) * ViewFactor;
   12195             : 
   12196             :                         } // this is an interior window surface
   12197             : 
   12198             :                         // Accumulate transmitted diffuse solar for reporting
   12199        3280 :                         state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
   12200             : 
   12201             :                     } // IF (SurfaceWindow(HeatTransSurfNum)%WindowModelType /= WindowModel:: EQL) THEN
   12202             : 
   12203             :                     // HERE 8/14/07 Ignore absorptance and reflectance of Frames and Dividers for now.
   12204             :                     // I would need revised view factors that included these surface types.
   12205             :                     // By ignoring them here, the diffuse solar is accounted for on the other surfaces
   12206             : 
   12207             :                     //          IF(SurfaceWindow(HeatTransSurfNum)%FrameArea > 0.0) THEN  ! Window has a frame
   12208             :                     // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
   12209             :                     //          END IF
   12210             : 
   12211             :                     //          IF(SurfaceWindow(HeatTransSurfNum)%DividerArea > 0.0) THEN  ! Window has dividers
   12212             :                     //            DividerSolAbs = SurfaceWindow(HeatTransSurfNum)%DividerSolAbsorp
   12213             :                     //            IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended
   12214             :                     //            divider; account for inside glass
   12215             :                     //              MatNumGl = Construct(ConstrNum)%LayerPoint(Construct(ConstrNum)%TotLayers)
   12216             :                     //              TransGl = dataMaterial.Material(MatNumGl)%Trans
   12217             :                     //              ReflGl = dataMaterial.Material(MatNumGl)%ReflectSolDiffBack
   12218             :                     //              AbsGl = 1.0d0-TransGl-ReflGl
   12219             :                     //              DividerSolRefl = 1.0d0-DividerSolAbs
   12220             :                     //              DividerSolAbs = AbsGl + TransGl*(DividerSolAbs +
   12221             :                     //              DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl)
   12222             :                     //            END IF
   12223             :                     // Correct for interior shade transmittance
   12224             :                     //            IF(ShadeFlag == IntShadeOn) THEN
   12225             :                     //              MatNumSh = Construct(ConstrNumSh)%LayerPoint(Construct(ConstrNumSh)%TotLayers)
   12226             :                     //              DividerSolAbs = DividerSolAbs * dataMaterial.Material(MatNumSh)%Trans
   12227             :                     //            ELSE IF(ShadeFlag == WinShadingType::IntBlind) THEN
   12228             :                     //              DividerSolAbs = DividerSolAbs *
   12229             :                     //              InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, &
   12230             :                     //                  SurfaceWindow(HeatTransSurfNum)%MovableSlats,Blind(BlNum)%SolBackDiffDiffTrans)
   12231             :                     //            END IF
   12232             :                     // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
   12233             : 
   12234             :                     //          END IF  ! Window has dividers
   12235             : 
   12236             :                 } // opaque or window heat transfer surface
   12237             : 
   12238             :             } // HeatTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast
   12239             : 
   12240             :             // Check debug var for view factors here
   12241             :             // ViewFactorTotal
   12242             :             // Check debug vars for individual transmitting surfaces here
   12243             :             //                WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl +
   12244             :             //                WinDifSolarDistTransmittedTotl;
   12245             :             // WinDifSolarTrans
   12246             : 
   12247             :         } // DifTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast
   12248             : 
   12249             :         // Check debug vars for zone totals here
   12250             :         //            ZoneDifSolarDistTotl = ZoneDifSolarDistAbsorbedTotl + ZoneDifSolarDistReflectedTotl +
   12251             :         //            ZoneDifSolarDistTransmittedTotl;
   12252             :         // ZoneDifSolarTrans
   12253             :         // ZoneDifSolarDistAbsorbedTotl
   12254             :         // ZoneDifSolarDistReflectedTotl
   12255             :         // ZoneDifSolarDistTransmittedTotl
   12256             :         //    CALL DisplayString('Diffuse Solar Distribution Zone Totals')
   12257             : 
   12258             :     } // ZoneNum = 1, NumOfZones
   12259      821277 : }
   12260        7495 : void CalcInteriorWinTransDifSolInitialDistribution(EnergyPlusData &state,
   12261             :                                                    int const IntWinEnclosureNum,     // Interior Window Enclosure index number
   12262             :                                                    int const IntWinSurfNum,          // Interior Window Surface number
   12263             :                                                    Real64 const IntWinDifSolarTransW // Diffuse Solar transmitted through Interior Window
   12264             :                                                                                      // IntWinSurfNum from adjacent enclosure [W]
   12265             : )
   12266             : {
   12267             : 
   12268             :     // SUBROUTINE INFORMATION:
   12269             :     //       AUTHOR         Rob Hitchcock
   12270             :     //       DATE WRITTEN   August 2007
   12271             :     //       MODIFIED       N/A
   12272             :     //       RE-ENGINEERED  N/A
   12273             : 
   12274             :     // PURPOSE OF THIS SUBROUTINE:
   12275             :     // This subroutine calculates the initial distribution
   12276             :     // of diffuse solar transmitted through the given interior window
   12277             :     // to individual heat transfer surfaces in the given enclosure.
   12278             :     // Diffuse solar transmitted through interior windows in this enclosure
   12279             :     // to adjacent enclosures, is added to the EnclSolInitialDifSolReflW
   12280             :     // of the adjacent enclosure for subsequent interreflection calcs
   12281             : 
   12282             :     // METHODOLOGY EMPLOYED:
   12283             :     // Similar to method used in CalcWinTransDifSolInitialDistribution.
   12284             :     // Apportions diffuse solar transmitted through an interior window
   12285             :     // that is then absorbed, reflected, and/or transmitted
   12286             :     // by other heat transfer surfaces in the given enclosure.
   12287             :     // Calculations use:
   12288             :     // 1. DifSolarTransW calculated in SUBROUTINE CalcWinTransDifSolInitialDistribution,
   12289             :     // 2. view factors between the interior window and
   12290             :     // other heat transfer surfaces in the given enclosure
   12291             :     // calculated in SUBROUTINE CalcApproximateViewFactors, and
   12292             :     // 3. surface absorptances, reflectances, and transmittances
   12293             :     // determined here using revised code from SUBROUTINE InitIntSolarDistribution
   12294             : 
   12295             :     // Using/Aliasing
   12296             :     using General::InterpSw;
   12297             :     using ScheduleManager::GetCurrentScheduleValue;
   12298             :     using namespace DataViewFactorInformation;
   12299             : 
   12300             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   12301             :     int IGlass;                  // Glass layer counter
   12302             :     int TotGlassLayers;          // Number of glass layers in a window construction
   12303             :     WinShadingType ShadeFlag;    // Shading flag
   12304             :     Real64 AbsInt;               // Tmp var for Inside surface short-wave absorptance
   12305             :     Real64 InsideDifAbsorptance; // Inside diffuse solar absorptance of a surface
   12306             :     Real64 InsideDifReflectance; // Inside diffuse solar reflectance of a surface
   12307             :     int BlNum;                   // Blind number
   12308             :     Real64 BlAbsDiffBk;          // Glass layer back diffuse solar absorptance when blind in place
   12309             :     Real64 AbsDiffBkBl;          // Blind diffuse back solar absorptance as part of glazing system
   12310             : 
   12311             :     //  REAL(r64)    :: DividerSolAbs      ! Window divider solar absorptance
   12312             :     //  REAL(r64)    :: DividerSolRefl     ! Window divider solar reflectance
   12313             :     //  INTEGER :: MatNumGl           ! Glass layer material number
   12314             :     //  INTEGER :: MatNumSh           ! Shade layer material number
   12315             :     //  REAL(r64)    :: TransGl,ReflGl,AbsGl ! Glass layer solar transmittance, reflectance, absorptance
   12316             : 
   12317             :     Real64 ViewFactor;       // temp var for view factor
   12318             :     Real64 ViewFactorTotal;  // debug var for view factor total
   12319             :     Real64 WinDifSolarTrans; // debug var for WinDifSolar() [W]
   12320             :                              //        Real64 WinDifSolarDistTotl; // debug var for window total distributed
   12321             :                              //        diffuse solar [W] Real64 WinDifSolarDistAbsorbedTotl( 0.0 ); // debug var
   12322             :                              //        for individual exterior window total
   12323             :                              // distributed
   12324             :     //           diffuse solar absorbed [W]
   12325             :     //        Real64 WinDifSolarDistReflectedTotl( 0.0 ); // debug var for individual exterior window total
   12326             :     //        distributed
   12327             :     //           diffuse solar reflected [W]
   12328             :     //        Real64 WinDifSolarDistTransmittedTotl( 0.0 ); // debug var for individual exterior window total
   12329             :     //        distributed
   12330             :     //           diffuse solar transmitted [W]
   12331             :     Real64 WinDifSolLayAbsW; // temp var for diffuse solar absorbed by individual glass layer [W]
   12332             :                              //        Real64 ZoneDifSolarTrans( 0.0 ); // debug var for WinDifSolar() [W]
   12333             :     //  REAL(r64)    :: ZoneDifSolarDistTotl    ! debug var for zone total distributed diffuse solar [W]
   12334             :     //        Real64 ZoneDifSolarDistAbsorbedTotl( 0.0 ); // debug var for zone total distributed diffuse solar
   12335             :     //        absorbed [W] Real64 ZoneDifSolarDistReflectedTotl( 0.0 ); // debug var for zone total distributed
   12336             :     //        diffuse solar reflected [W] Real64 ZoneDifSolarDistTransmittedTotl( 0.0 ); // debug var for zone
   12337             :     //        total distributed diffuse solar transmitted [W]
   12338             : 
   12339             :     Real64 DifSolarAbsW;     // temp var for diffuse solar absorbed by surface [W]
   12340             :     Real64 DifSolarAbs;      // temp var for diffuse solar absorbed by surface [W/m2]
   12341             :     Real64 DifSolarReflW;    // temp var for diffuse solar reflected by surface [W]
   12342             :     Real64 DifSolarTransW;   // temp var for diffuse solar transmitted through interior window surface [W]
   12343             :     Real64 ShBlDifSolarAbsW; // temp var for diffuse solar absorbed by shade/blind [W]
   12344             : 
   12345             :     //-------------------------------------------------------------------------------------------------
   12346             :     // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO INTERIOR HEAT TRANSFER SURFACES
   12347             :     //-------------------------------------------------------------------------------------------------
   12348             : 
   12349             :     // Init debug vars
   12350        7495 :     ViewFactorTotal = 0.0;
   12351        7495 :     WinDifSolarTrans = IntWinDifSolarTransW;
   12352             : 
   12353        7495 :     auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(IntWinEnclosureNum));
   12354             :     // Loop over all heat transfer surfaces in the current zone that might receive diffuse solar
   12355        7495 :     Real64 InitialZoneDifSolReflW_zone(0.0);
   12356       70152 :     for (int const HeatTransSurfNum : thisEnclosure.SurfacePtr) {
   12357             :         // Skip surfaces that are not heat transfer surfaces
   12358       62657 :         if (!state.dataSurface->Surface(HeatTransSurfNum).HeatTransSurf) continue;
   12359             :         // Skip tubular daylighting device domes
   12360       62657 :         if (state.dataSurface->Surface(HeatTransSurfNum).Class == SurfaceClass::TDD_Dome) continue;
   12361             : 
   12362             :         // View factor from current (sending) window IntWinSurfNum to current (receiving) surface HeatTransSurfNum
   12363             :         int HTenclosureSurfNum =
   12364       62657 :             state.dataSurface->Surface(HeatTransSurfNum).SolarEnclSurfIndex;            // HT surface index for EnclSolInfo.SurfacePtr and F arrays
   12365       62657 :         int enclosureNum = state.dataSurface->Surface(HeatTransSurfNum).SolarEnclIndex; // index for EnclSolInfo
   12366             :         int IntWinEnclSurfNum =
   12367       62657 :             state.dataSurface->Surface(IntWinSurfNum).SolarEnclSurfIndex; // Window surface index for EnclSolInfo.SurfacePtr and F arrays
   12368             : 
   12369       62657 :         ViewFactor = state.dataViewFactor->EnclSolInfo(enclosureNum).F(HTenclosureSurfNum, IntWinEnclSurfNum);
   12370             :         // debug ViewFactorTotal
   12371       62657 :         ViewFactorTotal += ViewFactor; // debug
   12372             : 
   12373             :         // Skip receiving surfaces with 0.0 view factor
   12374       62657 :         if (ViewFactor <= 0.0) continue;
   12375       43955 :         Real64 const SolarTrans_ViewFactor(IntWinDifSolarTransW * ViewFactor);
   12376             : 
   12377             :         // Calculate diffuse solar from current interior window absorbed and reflected by current heat transfer
   12378             :         // surface And calculate transmitted diffuse solar to adjacent zones through interior windows
   12379       43955 :         int const ConstrNum = state.dataSurface->SurfActiveConstruction(HeatTransSurfNum);
   12380       43955 :         if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Interior Opaque Surface
   12381             : 
   12382             :             // Determine the inside (back) diffuse solar absorptance
   12383             :             // and reflectance of the current heat transfer surface
   12384       37475 :             InsideDifAbsorptance = state.dataHeatBalSurf->SurfAbsSolarInt(HeatTransSurfNum);
   12385             :             // Inside (back) diffuse solar reflectance is assumed to be 1 - absorptance
   12386       37475 :             InsideDifReflectance = 1.0 - InsideDifAbsorptance;
   12387             : 
   12388             :             // Absorbed diffuse solar [W] = current window transmitted diffuse solar [W]
   12389             :             //    * view factor from current (sending) window IntWinSurfNum to current (receiving) surface
   12390             :             //    HeatTransSurfNum
   12391             :             //    * current surface inside solar absorptance
   12392       37475 :             DifSolarAbsW = SolarTrans_ViewFactor * InsideDifAbsorptance; // [W]
   12393             : 
   12394             :             // Absorbed diffuse solar [W/m2] = Absorbed diffuse solar [W]
   12395             :             //                                 / current surface net area
   12396       37475 :             DifSolarAbs = DifSolarAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area;
   12397             : 
   12398             :             // Accumulate absorbed diffuse solar [W/m2] on this surface for heat balance calcs
   12399       37475 :             state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(HeatTransSurfNum) += DifSolarAbs;
   12400             : 
   12401             :             // Reflected diffuse solar [W] = current window transmitted diffuse solar
   12402             :             //    * view factor from current (sending) window IntWinSurfNum to current (receiving) surface
   12403             :             //    HeatTransSurfNum
   12404             :             //    * current window inside solar reflectance
   12405       37475 :             DifSolarReflW = SolarTrans_ViewFactor * InsideDifReflectance;
   12406             : 
   12407             :             // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection
   12408             :             // calcs
   12409       37475 :             InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
   12410             : 
   12411             :             // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12412             :             // For opaque surfaces all incident diffuse is either absorbed or reflected
   12413             :             //                WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug [W]
   12414             :             //                WinDifSolarDistReflectedTotl += DifSolarReflW; // debug [W]
   12415             :             //                ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug [W]
   12416             :             //                ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug [W]
   12417             : 
   12418             :         } else { // Exterior or Interior Window
   12419             : 
   12420        6480 :             int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(HeatTransSurfNum);
   12421             : 
   12422        6480 :             TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
   12423        6480 :             ShadeFlag = state.dataSurface->SurfWinShadingFlag(HeatTransSurfNum);
   12424             : 
   12425        6480 :             if (NOT_SHADED(ShadeFlag)) { // No window shading
   12426             :                 // Init accumulator for transmittance calc below
   12427        6480 :                 DifSolarAbsW = 0.0;
   12428             : 
   12429             :                 // Calc diffuse solar absorbed by all window glass layers
   12430             :                 // Note: I am assuming here that individual glass layer absorptances have been corrected
   12431             :                 //       to account for layer by layer transmittance and reflection effects.
   12432       12960 :                 for (IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
   12433             :                     // Calc diffuse solar absorbed from the inside by each window glass layer [W]
   12434        6480 :                     AbsInt = state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
   12435        6480 :                     WinDifSolLayAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
   12436             : 
   12437             :                     // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
   12438             :                     // below
   12439        6480 :                     DifSolarAbsW += WinDifSolLayAbsW;
   12440             : 
   12441             :                     // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for
   12442             :                     // heat balance calcs
   12443        6480 :                     state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) +=
   12444        6480 :                         (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12445             :                 }
   12446             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12447             :                 //                    WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
   12448             :                 //                    ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
   12449             : 
   12450             :                 // Calc diffuse solar reflected back to zone
   12451             :                 // I don't really care if this is a window or opaque surface since I am just
   12452             :                 // accumulating all reflected diffuse solar in a zone bucket for "interreflected" distribution
   12453             :                 // Reflected diffuse solar [W] = current window transmitted diffuse solar
   12454             :                 //    * view factor from current (sending) window IntWinSurfNum to current (receiving) surface
   12455             :                 //    HeatTransSurfNum
   12456             :                 //    * current window inside solar reflectance
   12457        6480 :                 DifSolarReflW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   12458             : 
   12459             :                 // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   12460             :                 // interreflection calcs
   12461        6480 :                 InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
   12462             : 
   12463             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12464             : 
   12465             :                 //                    WinDifSolarDistReflectedTotl += DifSolarReflW; // debug
   12466             :                 //                    ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug
   12467             : 
   12468             :                 // Calc transmitted Window and Zone total distributed diffuse solar to check for conservation of
   12469             :                 // energy This is not very effective since it assigns whatever distributed diffuse solar has not
   12470             :                 // been absorbed or reflected to transmitted.
   12471        6480 :                 DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW;
   12472             : 
   12473             :                 // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
   12474             :                 // conservation of energy
   12475             :                 //                    WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
   12476             :                 //                    ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
   12477             : 
   12478             :                 // Accumulate transmitted diffuse solar for reporting
   12479        6480 :                 state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) +=
   12480        6480 :                     (DifSolarTransW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12481             : 
   12482             :                 //-----------------------------------------------------------------------------------
   12483             :                 // ADD TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO ADJACENT ZONE
   12484             :                 // TOTAL REFLECTED DIFFUSE SOLAR FOR SUBSEQUENT INTERREFLECTION CALCS
   12485             :                 //-----------------------------------------------------------------------------------
   12486             : 
   12487             :                 // If this receiving window surface (HeatTransSurfNum) is an interior window,
   12488             :                 // add transmitted diffuse solar to adjacent zone total reflected distributed
   12489             :                 // diffuse solar for subsequent interreflection calcs
   12490             :                 // NOTE: This calc is here because interior windows are currently assumed to have no shading
   12491             : 
   12492             :                 // Get the adjacent surface number for this receiving window surface
   12493        6480 :                 int const AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond;
   12494             :                 // If the adjacent surface number is > 0, this is an interior window
   12495        6480 :                 if (AdjSurfNum > 0) { // this is an interior window surface
   12496             : 
   12497             :                     // Get the adjacent zone/enclosure index
   12498             :                     // Add transmitted diffuse solar to total reflected distributed diffuse solar for each zone
   12499             :                     // for subsequent interreflection calcs
   12500           0 :                     state.dataHeatBal->EnclSolInitialDifSolReflW(state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex) += DifSolarTransW; // [W]
   12501             :                 }
   12502             : 
   12503           0 :             } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing
   12504             :                 // Init accumulator for transmittance calc below
   12505           0 :                 DifSolarAbsW = 0.0;
   12506             : 
   12507           0 :                 for (IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
   12508             :                     // Calc diffuse solar absorbed in each window glass layer
   12509           0 :                     WinDifSolLayAbsW = SolarTrans_ViewFactor * InterpSw(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum),
   12510           0 :                                                                         state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass),
   12511           0 :                                                                         state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass));
   12512             : 
   12513             :                     // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
   12514             :                     // below
   12515           0 :                     DifSolarAbsW += WinDifSolLayAbsW;
   12516             : 
   12517             :                     // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for
   12518             :                     // heat balance calcs
   12519           0 :                     state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) +=
   12520           0 :                         (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12521             :                 }
   12522             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12523             :                 //                                      WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
   12524             :                 //                                      ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
   12525             : 
   12526             :                 // Calc diffuse solar reflected back to zone
   12527           0 :                 DifSolarReflW = SolarTrans_ViewFactor * InterpSw(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum),
   12528           0 :                                                                  state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack,
   12529           0 :                                                                  state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack);
   12530             : 
   12531             :                 // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   12532             :                 // interreflection calcs
   12533           0 :                 InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
   12534             : 
   12535             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12536             :                 //                                      WinDifSolarDistReflectedTotl += DifSolarReflW; // debug
   12537             :                 //                                      ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug
   12538             : 
   12539             :                 // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
   12540             :                 // conservation of energy This is not very effective since it assigns whatever distributed diffuse
   12541             :                 // solar has not been absorbed or reflected to transmitted.
   12542           0 :                 DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW;
   12543             :                 //                                      WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
   12544             :                 //                                      ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug
   12545             :                 //[W]
   12546             : 
   12547             :                 // Accumulate transmitted diffuse solar for reporting
   12548           0 :                 state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) +=
   12549           0 :                     (DifSolarTransW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12550             : 
   12551             :             } else {
   12552             :                 // Interior, exterior or between-glass shade, screen or blind in place
   12553             : 
   12554             :                 // Init accumulator for transmittance calc below
   12555           0 :                 DifSolarAbsW = 0.0;
   12556           0 :                 WinDifSolLayAbsW = 0.0;
   12557           0 :                 int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(HeatTransSurfNum);
   12558           0 :                 Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(HeatTransSurfNum);
   12559             : 
   12560             :                 // First calc diffuse solar absorbed by each glass layer in this window with shade/blind in place
   12561           0 :                 for (IGlass = 1; IGlass <= state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; ++IGlass) {
   12562           0 :                     if (ANY_SHADE_SCREEN(ShadeFlag)) {
   12563             :                         // Calc diffuse solar absorbed in each window glass layer and shade
   12564           0 :                         WinDifSolLayAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass);
   12565           0 :                     } else if (ANY_BLIND(ShadeFlag)) {
   12566           0 :                         if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
   12567           0 :                             BlAbsDiffBk = General::InterpGeneral(
   12568           0 :                                 state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(SurfWinSlatsAngIndex, IGlass),
   12569           0 :                                 state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), IGlass),
   12570             :                                 SurfWinSlatsAngInterpFac);
   12571             :                         } else {
   12572           0 :                             BlAbsDiffBk = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(1, IGlass);
   12573             :                         }
   12574             :                         // Calc diffuse solar absorbed in each window glass layer and shade
   12575           0 :                         WinDifSolLayAbsW = SolarTrans_ViewFactor * BlAbsDiffBk;
   12576             :                     }
   12577             : 
   12578             :                     // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
   12579             :                     // below
   12580           0 :                     DifSolarAbsW += WinDifSolLayAbsW;
   12581             : 
   12582             :                     // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for
   12583             :                     // heat balance calcs
   12584           0 :                     state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) +=
   12585           0 :                         (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12586             :                 }
   12587             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12588             :                 //                    WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
   12589             :                 //                    ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
   12590             : 
   12591             :                 // Next calc diffuse solar reflected back to zone from window with shade or blind on
   12592             :                 // Diffuse back solar reflectance, bare glass or shade on
   12593           0 :                 InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
   12594           0 :                 if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::IntBlind) | BITF(WinShadingType::ExtBlind))) {
   12595             :                     // Diffuse back solar reflectance, blind present, vs. slat angle
   12596           0 :                     if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
   12597           0 :                         InsideDifReflectance = General::InterpGeneral(
   12598           0 :                             state.dataConstruction->Construct(ConstrNumSh).BlReflectSolDiffBack(SurfWinSlatsAngIndex),
   12599           0 :                             state.dataConstruction->Construct(ConstrNumSh).BlReflectSolDiffBack(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
   12600             :                             SurfWinSlatsAngInterpFac);
   12601             :                     } else {
   12602           0 :                         InsideDifReflectance = state.dataConstruction->Construct(ConstrNumSh).BlReflectSolDiffBack(1);
   12603             :                     }
   12604             :                 }
   12605           0 :                 DifSolarReflW = SolarTrans_ViewFactor * InsideDifReflectance;
   12606             : 
   12607             :                 // Accumulate total reflected distributed diffuse solar for each zone for subsequent
   12608             :                 // interreflection calcs
   12609           0 :                 InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
   12610             : 
   12611             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12612             :                 //                    WinDifSolarDistReflectedTotl += DifSolarReflW; // debug
   12613             :                 //                    ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug
   12614             : 
   12615             :                 // Now calc diffuse solar absorbed by shade/blind itself
   12616           0 :                 BlNum = state.dataSurface->SurfWinBlindNumber(HeatTransSurfNum);
   12617           0 :                 if (ANY_SHADE_SCREEN(ShadeFlag)) {
   12618             :                     // Calc diffuse solar absorbed by shade or screen [W]
   12619           0 :                     ShBlDifSolarAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackShade;
   12620           0 :                 } else if (ANY_BLIND(ShadeFlag)) {
   12621             :                     // Calc diffuse solar absorbed by blind [W]
   12622           0 :                     if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
   12623           0 :                         AbsDiffBkBl = General::InterpGeneral(
   12624           0 :                             state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(SurfWinSlatsAngIndex),
   12625           0 :                             state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
   12626             :                             SurfWinSlatsAngInterpFac);
   12627             :                     } else {
   12628           0 :                         AbsDiffBkBl = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(1);
   12629             :                     }
   12630           0 :                     ShBlDifSolarAbsW = SolarTrans_ViewFactor * AbsDiffBkBl;
   12631             :                 }
   12632             :                 // Correct for divider shadowing
   12633           0 :                 if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
   12634           0 :                     ShBlDifSolarAbsW *= state.dataSurface->SurfWinGlazedFrac(HeatTransSurfNum);
   12635             :                 }
   12636             : 
   12637             :                 // Accumulate diffuse solar absorbed  by shade or screen [W/m2] for heat balance calcs
   12638           0 :                 state.dataSurface->SurfWinInitialDifSolAbsByShade(HeatTransSurfNum) +=
   12639           0 :                     (ShBlDifSolarAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12640             : 
   12641             :                 // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
   12642             :                 // below
   12643           0 :                 DifSolarAbsW += ShBlDifSolarAbsW;
   12644             : 
   12645             :                 // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
   12646             :                 //                    WinDifSolarDistAbsorbedTotl += ShBlDifSolarAbsW; // debug
   12647             :                 //                    ZoneDifSolarDistAbsorbedTotl += ShBlDifSolarAbsW; // debug
   12648             : 
   12649             :                 // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
   12650             :                 // conservation of energy This is not very effective since it assigns whatever distributed diffuse
   12651             :                 // solar has not been absorbed or reflected to transmitted.
   12652           0 :                 DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW;
   12653             :                 //                    WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
   12654             :                 //                    ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
   12655             : 
   12656             :                 // Accumulate transmitted diffuse solar for reporting
   12657           0 :                 state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) +=
   12658           0 :                     (DifSolarTransW / state.dataSurface->Surface(HeatTransSurfNum).Area);
   12659             : 
   12660             :             } // End of shading flag check
   12661             : 
   12662             :             // HERE 8/14/07 Ignore absorptance and reflectance of Frames and Dividers for now.
   12663             :             // I would need revised view factors that included these surface types.
   12664             :             // By ignoring them here, the diffuse solar is accounted for on the other surfaces
   12665             : 
   12666             :             //          IF(SurfaceWindow(HeatTransSurfNum)%FrameArea > 0.0) THEN  ! Window has a frame
   12667             :             // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
   12668             :             //          END IF
   12669             : 
   12670             :             //          IF(SurfaceWindow(HeatTransSurfNum)%DividerArea > 0.0) THEN  ! Window has dividers
   12671             :             //            DividerSolAbs = SurfaceWindow(HeatTransSurfNum)%DividerSolAbsorp
   12672             :             //            IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended divider;
   12673             :             //            account for inside glass
   12674             :             //              MatNumGl = Construct(ConstrNum)%LayerPoint(Construct(ConstrNum)%TotLayers)
   12675             :             //              TransGl = dataMaterial.Material(MatNumGl)%Trans
   12676             :             //              ReflGl = dataMaterial.Material(MatNumGl)%ReflectSolDiffBack
   12677             :             //              AbsGl = 1.0d0-TransGl-ReflGl
   12678             :             //              DividerSolRefl = 1.0d0-DividerSolAbs
   12679             :             //              DividerSolAbs = AbsGl + TransGl*(DividerSolAbs +
   12680             :             //              DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl)
   12681             :             //            END IF
   12682             :             // Correct for interior shade transmittance
   12683             :             //            IF(ShadeFlag == IntShadeOn) THEN
   12684             :             //              MatNumSh = Construct(ConstrNumSh)%LayerPoint(Construct(ConstrNumSh)%TotLayers)
   12685             :             //              DividerSolAbs = DividerSolAbs * dataMaterial.Material(MatNumSh)%Trans
   12686             :             //            ELSE IF(ShadeFlag == WinShadingType::IntBlind) THEN
   12687             :             //              DividerSolAbs = DividerSolAbs *
   12688             :             //              InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, &
   12689             :             //                  SurfaceWindow(HeatTransSurfNum)%MovableSlats,Blind(BlNum)%SolBackDiffDiffTrans)
   12690             :             //            END IF
   12691             :             // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
   12692             : 
   12693             :             //          END IF  ! Window has dividers
   12694             :         } // opaque or window heat transfer surface
   12695             : 
   12696             :     } // HeatTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast
   12697        7495 :     state.dataHeatBal->EnclSolInitialDifSolReflW(IntWinEnclosureNum) += InitialZoneDifSolReflW_zone;
   12698             : 
   12699             :     // Check debug var for view factors here
   12700             :     // ViewFactorTotal
   12701             :     // Check debug vars for individual transmitting surfaces here
   12702             :     //        WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl +
   12703             :     //        WinDifSolarDistTransmittedTotl; //Debug
   12704             :     // WinDifSolarTrans
   12705        7495 : }
   12706             : 
   12707          24 : void CalcComplexWindowOverlap(EnergyPlusData &state,
   12708             :                               BSDFGeomDescr &Geom,               // State Geometry
   12709             :                               BSDFWindowGeomDescr const &Window, // Window Geometry
   12710             :                               int const ISurf                    // Surface number of the complex fenestration
   12711             : )
   12712             : {
   12713             :     // SUBROUTINE INFORMATION:
   12714             :     //       AUTHOR         Simon Vidanovic
   12715             :     //       DATE WRITTEN   May 2012
   12716             :     //       MODIFIED       Simon Vidanovic (May 2013) - added overlaps calculations for daylighting
   12717             :     //       RE-ENGINEERED  na
   12718             : 
   12719             :     // PURPOSE OF THIS SUBROUTINE:
   12720             :     // For each of basis directions on back surface of the window calculates
   12721             :     // overlap areas. It also calculates overlap areas and reflectances for daylighting calculations
   12722             : 
   12723             :     using namespace Vectors;
   12724             : 
   12725             :     Real64 XShadowProjection; // temporary buffer
   12726             :     Real64 YShadowProjection; // temporary buffer
   12727             : 
   12728             :     Real64 XSp;            // for calc BSDF projection direction
   12729             :     Real64 YSp;            // for calc BSDF projection direction
   12730             :     Real64 ZSp;            // for calc BSDF projection direction
   12731             :     Real64 SdotX;          // temporary variable for manipulating .dot. product
   12732             :     Real64 SdotY;          // temporary variable for manipulating .dot. product
   12733             :     Real64 SdotZ;          // temporary variable for manipulating .dot. product
   12734             :     int BackSurfaceNumber; // current back surface number
   12735             :     int NVT;               // Number of vertices of back surface
   12736             :     int NS1;               // Number of the figure being overlapped
   12737             :     int NS2;               // Number of the figure doing overlapping
   12738             :     int NS3;               // Location to place results of overlap
   12739             :     int IRay;              // Current ray of BSDF direction
   12740             :     int KBkSurf;           // Current back surface
   12741             :     int N;
   12742             : 
   12743             :     // Daylighting
   12744             :     int IConst;                // Construction number of back surface
   12745             :     int InsideConLay;          // Construction's inside material layer number
   12746             :     Real64 VisibleReflectance; // Visible reflectance for inside surface material
   12747             :     Real64 TotAOverlap;        // Total overlap area for given outgoing direction
   12748             :     Real64 TotARhoVisOverlap;  // Total overlap area time reflectance for given outgoing direction
   12749             : 
   12750          24 :     state.dataSolarShading->XVertex.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
   12751          24 :     state.dataSolarShading->YVertex.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
   12752          24 :     state.dataSolarShading->ZVertex.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
   12753             : 
   12754          24 :     Geom.AOverlap.dimension(Window.NBkSurf, Geom.Trn.NBasis, 0.0);
   12755          24 :     Geom.ARhoVisOverlap.dimension(Window.NBkSurf, Geom.Trn.NBasis, 0.0);
   12756          24 :     Geom.AveRhoVisOverlap.dimension(Geom.Trn.NBasis, 0.0);
   12757             : 
   12758             :     // First to calculate and store coordinates of the window surface
   12759          24 :     state.dataSolarShading->LOCHCA = 1;
   12760          24 :     int BaseSurf = state.dataSurface->Surface(ISurf).BaseSurf; // Base surface number
   12761             : 
   12762             :     // Base surface contains current window surface (ISurf).
   12763             :     // Since that is case, below transformation should always return ZVT = 0.0
   12764             :     // for every possible transformation
   12765          24 :     CTRANS(state, ISurf, BaseSurf, NVT, state.dataSolarShading->XVertex, state.dataSolarShading->YVertex, state.dataSolarShading->ZVertex);
   12766             : 
   12767             :     // HTRANS routine is using coordinates stored in XVS and YVS in order to calculate
   12768             :     // surface area.  Since both projections are equal to zero, then simply
   12769             :     // compy these values into XVS and YVS arrays
   12770         120 :     for (N = 1; N <= NVT; ++N) {
   12771          96 :         state.dataSolarShading->XVS(N) = state.dataSolarShading->XVertex(N);
   12772          96 :         state.dataSolarShading->YVS(N) = state.dataSolarShading->YVertex(N);
   12773             :     }
   12774             : 
   12775             :     // This calculates the area stored in XVS and YVS
   12776          24 :     HTRANS1(state, state.dataSolarShading->LOCHCA, NVT);
   12777             : 
   12778             :     // Calculation of overlap areas for each outgoing basis direction
   12779        1944 :     for (IRay = 1; IRay <= Geom.Trn.NBasis; ++IRay) { // basis directions loop (on back surface)
   12780             :         // For current basis direction calculate dot product between window surface
   12781             :         // and basis direction.  This will be used to calculate projection of each
   12782             :         // of the back surfaces to window surface for given basis direciton
   12783        1920 :         SdotX = dot(state.dataSurface->Surface(ISurf).lcsx, Geom.sTrn(IRay));
   12784        1920 :         SdotY = dot(state.dataSurface->Surface(ISurf).lcsy, Geom.sTrn(IRay));
   12785        1920 :         SdotZ = dot(state.dataSurface->Surface(ISurf).lcsz, Geom.sTrn(IRay));
   12786        1920 :         XSp = -SdotX;
   12787        1920 :         YSp = -SdotY;
   12788        1920 :         ZSp = -SdotZ;
   12789             : 
   12790             :         // Projection of shadows for current basis direciton
   12791        1920 :         if (std::abs(ZSp) > 1.e-4) {
   12792        1920 :             XShadowProjection = XSp / ZSp;
   12793        1920 :             YShadowProjection = YSp / ZSp;
   12794        1920 :             if (std::abs(XShadowProjection) < 1.e-8) XShadowProjection = 0.0;
   12795        1920 :             if (std::abs(YShadowProjection) < 1.e-8) YShadowProjection = 0.0;
   12796             :         } else {
   12797           0 :             XShadowProjection = 0.0;
   12798           0 :             YShadowProjection = 0.0;
   12799             :         }
   12800             : 
   12801       14244 :         for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop
   12802             :             // BaseSurf = Surface(ISurf).BaseSurf
   12803       12324 :             BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(KBkSurf);
   12804             : 
   12805             :             // Transform coordinates of back surface from general system to the
   12806             :             // plane of the receiving surface
   12807       36972 :             CTRANS(state,
   12808             :                    BackSurfaceNumber,
   12809             :                    BaseSurf,
   12810             :                    NVT,
   12811       12324 :                    state.dataSolarShading->XVertex,
   12812       12324 :                    state.dataSolarShading->YVertex,
   12813       12324 :                    state.dataSolarShading->ZVertex);
   12814             : 
   12815             :             // Project "shadow" from back surface along sun's rays to receiving surface.  Back surface vertices
   12816             :             // become clockwise sequential.
   12817             : 
   12818       61620 :             for (N = 1; N <= NVT; ++N) {
   12819       49296 :                 state.dataSolarShading->YVS(N) = state.dataSolarShading->YVertex(N) - YShadowProjection * state.dataSolarShading->ZVertex(N);
   12820       49296 :                 state.dataSolarShading->XVS(N) = state.dataSolarShading->XVertex(N) - XShadowProjection * state.dataSolarShading->ZVertex(N);
   12821             :             }
   12822             : 
   12823             :             // Transform to the homogeneous coordinate system.
   12824             : 
   12825       12324 :             NS3 = state.dataSolarShading->LOCHCA + 1;
   12826       12324 :             state.dataSolarShading->HCT(NS3) = 0.0;
   12827       12324 :             HTRANS1(state, NS3, NVT);
   12828             : 
   12829             :             // Determine area of overlap of projected back surface and receiving surface.
   12830             : 
   12831       12324 :             NS1 = 1;
   12832       12324 :             NS2 = NS3;
   12833       12324 :             state.dataSolarShading->HCT(NS3) = 1.0;
   12834       12324 :             DeterminePolygonOverlap(state, NS1, NS2, NS3);
   12835             : 
   12836       12324 :             if (state.dataSolarShading->OverlapStatus == NoOverlap) continue; // to next back surface
   12837        4624 :             if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
   12838           0 :                 break; // back surfaces DO loop
   12839             : 
   12840        4624 :             state.dataSolarShading->LOCHCA = NS3;
   12841        4624 :             state.dataSolarShading->HCNS(state.dataSolarShading->LOCHCA) = BackSurfaceNumber;
   12842        4624 :             state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA) = -state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
   12843             : 
   12844        4624 :             Geom.AOverlap(KBkSurf, IRay) = state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
   12845             :         } // DO KBkSurf  = 1 , NBkSurf
   12846             : 
   12847             :         // If some of back surfaces is contained in base surface, then need to substract shadow of subsurface
   12848             :         // from shadow on base surface.  Reson is that above shadowing algorithm is calculating shadow wihtout
   12849             :         // influence of subsurfaces
   12850       14244 :         for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop
   12851       12324 :             BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(KBkSurf);
   12852             :             // CurBaseSurf is Current base surface number for shadow overlap calcualtions
   12853       12324 :             int CurBaseSurf = state.dataSurface->Surface(BackSurfaceNumber).BaseSurf;
   12854       12324 :             if (CurBaseSurf != BackSurfaceNumber) {
   12855             :                 // Search if that base surface in list of back surfaces for current window
   12856             :                 // CurBackSurface is Current back surface number for base surface
   12857        2724 :                 int CurBackSurface = 0;
   12858        5366 :                 for (N = 1; N <= Window.NBkSurf; ++N) {
   12859        5366 :                     if (state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(N) == CurBaseSurf) {
   12860        2724 :                         CurBackSurface = N;
   12861        2724 :                         break;
   12862             :                     }
   12863             :                 }
   12864        2724 :                 if (CurBackSurface != 0) {
   12865        2724 :                     Geom.AOverlap(CurBackSurface, IRay) -= Geom.AOverlap(KBkSurf, IRay);
   12866             :                 }
   12867             :             }
   12868             :         }
   12869             : 
   12870             :         // Calculate overlap area times reflectance.  This is necessary for complex fenestration daylighting
   12871             :         // calculations
   12872        1920 :         TotAOverlap = 0.0;
   12873        1920 :         TotARhoVisOverlap = 0.0;
   12874       14244 :         for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop
   12875       12324 :             BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(KBkSurf);
   12876       12324 :             IConst = state.dataSurface->Surface(BackSurfaceNumber).Construction;
   12877       12324 :             InsideConLay = state.dataConstruction->Construct(IConst).TotLayers;
   12878       12324 :             if (state.dataSurface->SurfWinWindowModelType(BackSurfaceNumber) == WindowModel::BSDF) {
   12879        2724 :                 VisibleReflectance = state.dataConstruction->Construct(IConst).ReflectVisDiffBack;
   12880             :             } else {
   12881        9600 :                 VisibleReflectance = (1.0 - state.dataMaterial->Material(InsideConLay).AbsorpVisible);
   12882             :             }
   12883       12324 :             Geom.ARhoVisOverlap(KBkSurf, IRay) = Geom.AOverlap(KBkSurf, IRay) * VisibleReflectance;
   12884       12324 :             TotAOverlap += Geom.AOverlap(KBkSurf, IRay);
   12885       12324 :             TotARhoVisOverlap += Geom.ARhoVisOverlap(KBkSurf, IRay);
   12886             :         }
   12887             : 
   12888        1920 :         if (TotAOverlap != 0.0) {
   12889        1920 :             Geom.AveRhoVisOverlap(IRay) = TotARhoVisOverlap / TotAOverlap;
   12890             :         }
   12891             : 
   12892             :     } // DO IRay = 1, Geom%Trn%NBasis
   12893             : 
   12894             :     // Reset back shadowing counter since complex windows do not need it anymore
   12895          24 :     state.dataSolarShading->LOCHCA = 1;
   12896          24 : }
   12897             : 
   12898     2568509 : void TimestepInitComplexFenestration(EnergyPlusData &state)
   12899             : {
   12900             :     // SUBROUTINE INFORMATION:
   12901             :     //       AUTHOR         Simon Vidanovic
   12902             :     //       DATE WRITTEN   May 2012
   12903             :     //       MODIFIED       May 2012 (Initialize complex fenestration in case of EMS)
   12904             :     //       RE-ENGINEERED  na
   12905             : 
   12906             :     // PURPOSE OF THIS SUBROUTINE:
   12907             :     // Performs initialization of complex fenestration. It also performs check if current surface containing
   12908             :     // complex fenestration have construction changed (by EMS) in which case performs addition of current states
   12909             :     // into complex fenestration array
   12910             : 
   12911             :     using WindowComplexManager::CheckCFSStates;
   12912             : 
   12913             :     // Locals
   12914             :     int iSurf;       // Current surface number
   12915             :     int iState;      // current state number
   12916             :     int NumOfStates; // number of states for current window
   12917             : 
   12918   166715563 :     for (iSurf = 1; iSurf <= state.dataSurface->TotSurfaces; ++iSurf) {
   12919   164147054 :         if (state.dataSurface->SurfWinWindowModelType(iSurf) == WindowModel::BSDF) {
   12920             :             // This will check complex fenestrations state and add new one if necessary (EMS case)
   12921       39540 :             CheckCFSStates(state, iSurf);
   12922             : 
   12923       39540 :             NumOfStates = state.dataBSDFWindow->ComplexWind(iSurf).NumStates;
   12924             : 
   12925             :             // Check for overlap areas and initialize if necessary
   12926       79080 :             for (iState = 1; iState <= NumOfStates; ++iState) {
   12927             :                 // do initialization only once
   12928       39540 :                 if (state.dataBSDFWindow->ComplexWind(iSurf).Geom(iState).InitState) {
   12929          24 :                     CalcComplexWindowOverlap(
   12930          24 :                         state, state.dataBSDFWindow->ComplexWind(iSurf).Geom(iState), state.dataBSDFWindow->ComplexWind(iSurf), iSurf);
   12931          24 :                     state.dataBSDFWindow->ComplexWind(iSurf).Geom(iState).InitState = false;
   12932             :                 }
   12933             :             }
   12934             :         }
   12935             :     }
   12936     2568509 : }
   12937             : 
   12938        2313 : } // namespace EnergyPlus::SolarShading

Generated by: LCOV version 1.13