LCOV - code coverage report
Current view: top level - EnergyPlus - WindowManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 4005 4552 88.0 %
Date: 2023-01-17 19:17:23 Functions: 51 54 94.4 %

          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 <algorithm>
      50             : #include <cassert>
      51             : #include <cmath>
      52             : #include <memory>
      53             : #include <string>
      54             : 
      55             : // ObjexxFCL Headers
      56             : #include <ObjexxFCL/Array.functions.hh>
      57             : #include <ObjexxFCL/Fmath.hh>
      58             : 
      59             : // EnergyPlus Headers
      60             : #include <EnergyPlus/Construction.hh>
      61             : #include <EnergyPlus/ConvectionCoefficients.hh>
      62             : #include <EnergyPlus/CurveManager.hh>
      63             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      64             : #include <EnergyPlus/DataBSDFWindow.hh>
      65             : #include <EnergyPlus/DataEnvironment.hh>
      66             : #include <EnergyPlus/DataHeatBalSurface.hh>
      67             : #include <EnergyPlus/DataHeatBalance.hh>
      68             : #include <EnergyPlus/DataIPShortCuts.hh>
      69             : #include <EnergyPlus/DataLoopNode.hh>
      70             : #include <EnergyPlus/DataSurfaces.hh>
      71             : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
      72             : #include <EnergyPlus/DataZoneEquipment.hh>
      73             : #include <EnergyPlus/General.hh>
      74             : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      75             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      76             : #include <EnergyPlus/Psychrometrics.hh>
      77             : #include <EnergyPlus/ScheduleManager.hh>
      78             : #include <EnergyPlus/UtilityRoutines.hh>
      79             : #include <EnergyPlus/WindowComplexManager.hh>
      80             : #include <EnergyPlus/WindowEquivalentLayer.hh>
      81             : #include <EnergyPlus/WindowManager.hh>
      82             : #include <EnergyPlus/WindowManagerExteriorOptical.hh>
      83             : #include <EnergyPlus/WindowManagerExteriorThermal.hh>
      84             : #include <EnergyPlus/WindowModel.hh>
      85             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      86             : 
      87             : namespace EnergyPlus {
      88             : 
      89             : namespace WindowManager {
      90             : 
      91             :     // MODULE INFORMATION
      92             :     //       AUTHOR         Fred Winkelmann
      93             :     //       DATE WRITTEN   September 1999
      94             :     //       MODIFIED       August 2001 (FW): add window shade thermal calculation;
      95             :     //                                        add window blind optical and thermal model.
      96             :     //                      February 2003 (FW/LKL): Name changed to WindowManager
      97             :     //       RE-ENGINEERED  na
      98             : 
      99             :     // PURPOSE OF THIS MODULE:
     100             :     // Manages the window optical and thermal calculations derived
     101             :     // from WINDOW 4 and WINDOW 5.
     102             : 
     103             :     // METHODOLOGY EMPLOYED:
     104             : 
     105             :     // REFERENCES:
     106             :     // WINDOW 4:
     107             :     // D.Arasteh, M.Reilly and M.Rubin. A versative procedure for
     108             :     // calculating heat transfer through windows. ASHRAE Trans. 1989, Vol. 95, Pt. 2.
     109             : 
     110             :     // E.Finlayson, D.Arasteh, C.Huizenga, M.Rubin, and M.Reilly. WINDOW 4.0:
     111             :     // Documentation of calculation procedures. LBL-33943. July 1993.
     112             : 
     113             :     // WINDOW 5:
     114             :     // ASHRAE Standard 142P (draft 1/13/98): Standard method for determining and expressing
     115             :     // the heat transfer and total optical properties of fenestration products.
     116             : 
     117             :     // Shade and blind thermal model:
     118             :     // ISO/DIS 15099, Thermal Performance of Windows, Doors and Shading Devices,
     119             :     // Detailed Calculations, 1/12/00.
     120             : 
     121             :     // Blind optical model:
     122             :     // H. Simmler, U. Fischer and Frederick Winkelmann, Solar-Thermal Window Blind Model
     123             :     // for DOE-2, Lawrence Berkeley National Laboratory, Jan. 1996.
     124             : 
     125             :     // Using/Aliasing
     126             :     using namespace DataEnvironment;
     127             :     using namespace DataHeatBalance;
     128             :     using namespace DataSurfaces;
     129             : 
     130             :     // SUBROUTINE SPECIFICATIONS FOR MODULE WindowManager:
     131             :     //   Optical Calculation Routines
     132             :     //   Heat Balance Routines
     133             : 
     134         771 :     void InitWindowOpticalCalculations(EnergyPlusData &state)
     135             :     {
     136             :         // SUBROUTINE INFORMATION:
     137             :         //       AUTHOR         Simon Vidanovic
     138             :         //       DATE WRITTEN   September 2016
     139             :         //       MODIFIED       na
     140             :         //       RE-ENGINEERED  na
     141             : 
     142             :         // PURPOSE OF THIS SUBROUTINE:
     143             :         // Manages if optical calculation will be performed with internal or external routines
     144             : 
     145             :         // check and read custom solar and/or visible spectrum data if any
     146         771 :         CheckAndReadCustomSprectrumData(state);
     147             : 
     148             :         // allocate surface level adj ratio data member
     149         771 :         state.dataHeatBalSurf->SurfWinCoeffAdjRatio.dimension(state.dataSurface->TotSurfaces, 1.0);
     150             : 
     151         771 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
     152           3 :             InitWCE_SimplifiedOpticalData(state);
     153             :         } else {
     154         768 :             InitGlassOpticalCalculations(state);
     155             :         }
     156         771 :     }
     157             : 
     158         768 :     void InitGlassOpticalCalculations(EnergyPlusData &state)
     159             :     {
     160             : 
     161             :         // SUBROUTINE INFORMATION:
     162             :         //       AUTHOR         F. Winkelmann
     163             :         //       DATE WRITTEN   August 1999
     164             :         //       MODIFIED       May 2001 (FW): add window blinds
     165             :         //                      Jan 2002 (FW): add blinds with variable slat angle
     166             :         //                      Jan 2003 (FW): add between-glass shade/blind
     167             :         //                      May 2006 (RR): add exterior window screen
     168             :         //                      Aug 2010 (TH): allow spectral data for between-glass shade/blind
     169             :         //                      Aug 2013 (TH): allow user defined solar and visible spectrum data
     170             :         //       RE-ENGINEERED  na
     171             : 
     172             :         // PURPOSE OF THIS SUBROUTINE:
     173             :         // Manages the calculation of the solar and visible properties of a multi-layer glazing
     174             :         // system from the properties of the individual glazing and shading layers
     175             : 
     176             :         // Using/Aliasing
     177             :         using namespace Vectors;
     178             : 
     179             :         using WindowEquivalentLayer::InitEquivalentLayerWindowCalculations;
     180             : 
     181             :         int CoefNum;                    // Polynomial coefficient number
     182             :         int j;                          // Wavelength counter
     183             :         int TotLay;                     // Total solid and gas layers in a window construction
     184             :         int ConstrNum;                  // Construction number
     185             :         int ConstrNumSh;                // Shaded construction number
     186             :         int SurfNum;                    // Surface number
     187             :         int ShadeLayNum;                // Layer number for shade or blind, if present
     188             :         int ShadeLayPtr;                // Material number for shade or blind
     189             :         bool lquasi;                    // True if one or more glass layers have no spectral data
     190             :         bool AllGlassIsSpectralAverage; // True if all glazing in a construction is spectral average
     191             :         bool IntShade;                  // True if construction has an interior,exterior or between-glass shade
     192             :         bool ExtShade;
     193             :         bool BGShade;
     194             :         bool IntBlind; // True if construction has an interior,exterior or between-glass blind
     195             :         bool ExtBlind;
     196             :         bool BGBlind;
     197             :         bool ExtScreen;                                         // True if construction has an exterior screen
     198             :         bool ScreenOn;                                          // True if construction has an exterior screen
     199             :         bool BlindOn;                                           // True if IntBlind, ExtBlind or BGBlind is true
     200             :         bool ShadeOn;                                           // True if IntShade, ExtShade or BGShade is true
     201             :         int BlNum;                                              // Blind number
     202             :         int ScNum;                                              // Screen number
     203        1536 :         Array1D<Real64> sabsPhi(state.dataWindowManager->nume); // Glazing system absorptance for a glass layer
     204             :         //  and angle of incidence, for each wavelength
     205             :         //   glass layer for an angle of incidence, for each wavelength
     206        1536 :         Array1D<Real64> solabsDiff(5); // Glazing system layer solar absorptance for each glass layer
     207             :         Array1D<Real64> solabsPhiLay(
     208        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Glazing system solar absorptance for a layer at each incidence angle
     209             :         Array1D<Real64> tsolPhiFit(
     210        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Glazing system solar transmittance from fit at each incidence angle
     211             :         Array1D<Real64> tvisPhiFit(
     212        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Glazing system visible transmittance from fit at each incidence angle
     213             :         Array2D<Real64> tBareSolPhi(5,
     214        1536 :                                     state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass solar transmittance for each incidence angle
     215             :         Real64 t1;                                                                    // = tBareSolPhi(,1)(,2)
     216             :         Real64 t2;
     217             :         Array2D<Real64> tBareVisPhi(5,
     218        1536 :                                     state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass visible transmittance for each incidence angle
     219             :         Real64 t1v;                                                                   // = tBareVisPhi(,1)(,2)
     220             :         Real64 t2v;
     221             :         Array2D<Real64> rfBareSolPhi(
     222             :             5,
     223        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass front solar reflectance for each incidence angle
     224             :         Array2D<Real64> rfBareVisPhi(
     225             :             5,
     226        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass front visible reflectance for each incidence angle
     227             :         Array2D<Real64> rbBareSolPhi(
     228             :             5,
     229        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass back solar reflectance for each incidence angle
     230             :         Array2D<Real64> rbBareVisPhi(
     231             :             5,
     232        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass back visible reflectance for each incidence angle
     233             :         Array2D<Real64> afBareSolPhi(
     234             :             5,
     235        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass front solar absorptance for each incidence angle
     236             :         Real64 af1;                                           // = afBareSolPhi(,1)(,2)
     237             :         Real64 af2;
     238             :         Real64 rbmf2; // Isolated glass #2 front beam reflectance
     239             :         Array2D<Real64> abBareSolPhi(
     240             :             5,
     241        1536 :             state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass back solar absorptance for each incidence angle
     242             :         Real64 ab1;                                           // = abBareSolPhi(,1)(,2)
     243             :         Real64 ab2;
     244             :         Real64 td1; // Isolated glass diffuse solar transmittance
     245             :         Real64 td2;
     246             :         Real64 td3;
     247             :         Real64 td1v; // Isolated glass diffuse visible transmittance
     248             :         Real64 td2v;
     249             :         Real64 td3v;
     250             :         Real64 rf1; // Isolated glass diffuse solar front reflectance
     251             :         Real64 rf2;
     252             :         Real64 rf3;
     253             :         Real64 rf1v; // Isolated glass diffuse visible front reflectance
     254             :         Real64 rf2v;
     255             :         Real64 rf3v;
     256             :         Real64 rb1; // Isolated glass diffuse solar back reflectance
     257             :         Real64 rb2;
     258             :         Real64 rb3;
     259             :         Real64 rb1v; // Isolated glass diffuse visible back reflectance
     260             :         Real64 rb2v;
     261             :         Real64 rb3v;
     262             :         Real64 afd1; // Isolated glass diffuse solar front absorptance
     263             :         Real64 afd2;
     264             :         Real64 afd3;
     265             :         Real64 abd1; // Isolated glass diffuse solar back absorptance
     266             :         Real64 abd2;
     267             :         Real64 abd3;
     268             :         Real64 TauShIR;  // IR transmittance of isolated shade
     269             :         Real64 EpsShIR;  // IR absorptance of isolated shade
     270             :         Real64 RhoShIR;  // IR reflectance of isolated shade
     271             :         Real64 EpsGlIR;  // IR absorptance of front or back of isolated glass
     272             :         Real64 RhoGlIR;  // IR reflectance of inside face of inside glass
     273             :         int NGlass;      // Number of glass layers in a construction
     274             :         int IGlass;      // Glass layer counter
     275             :         int LayNum;      // Layer number for a glass layer
     276             :         int LayPtr;      // Material number corresponding to LayNum
     277             :         int IPhi;        // Incidence angle counter
     278             :         Real64 Phi;      // Incidence angle (deg)
     279             :         Real64 CosPhi;   // Cosine of incidence angle
     280             :         int ILam;        // Wavelength counter
     281             :         Real64 tsolDiff; // Glazing system diffuse solar transmittance
     282             :         Real64 tvisDiff; // Glazing system diffuse visible transmittance
     283             :         int IGlassBack;  // Glass layer number counted from back of window
     284             :         Real64 ShadeAbs; // Solar absorptance of isolated shade
     285             :         Real64 ash;      // = ShadeAbs
     286             :         Real64 afsh;     // Diffuse solar front absorptance of isolated blind
     287             :         Real64 afshGnd;  // Ground and sky diffuse solar front absorptance of isolated blind
     288             :         Real64 afshSky;
     289             :         Real64 absh;          // Diffuse solar back absorptance of isolated blind
     290             :         Real64 ShadeTrans;    // Solar transmittance of isolated shade/blind
     291             :         Real64 ShadeTransGnd; // Diffuse-diffuse transmittance of isolated vertical blind with
     292             :         // horizontal slats for isotropic ground solar
     293             :         Real64 ShadeTransSky; // Diffuse-diffuse transmittance of isolated vertical blind with
     294             :         // horizontal slats for isotropic sky solar
     295             :         Real64 tsh;    // = ShadeTrans
     296             :         Real64 tshGnd; // = ShadeTransGnd,ShadeTransSky
     297             :         Real64 tshSky;
     298             :         Real64 tsh2;         // = tsh**2
     299             :         Real64 ShadeRefl;    // Solar reflectance of isolated shade
     300             :         Real64 ShadeReflGnd; // Front blind reflectance for ground diffuse solar
     301             :         Real64 ShadeReflSky; // Front blind reflectance for sky diffuse solar
     302             :         Real64 rsh;          // = ShadeRefl
     303             :         Real64 rfsh;         // Diffuse solar front reflectance of isolated blind
     304             :         Real64 rfshGnd;      // Ground and sky diffuse solar front reflectance of isolated blind
     305             :         Real64 rfshSky;
     306             :         Real64 rbsh;            // Diffuse solar back reflectance of isolated blind
     307             :         Real64 ShadeReflFac;    // Shade/blind solar reflection factor
     308             :         Real64 ShadeTransVis;   // Visible transmittance of isolated shade/blind
     309             :         Real64 tshv;            // = ShadeTransVis
     310             :         Real64 tshv2;           // = tshv**2
     311             :         Real64 ShadeReflVis;    // Visible reflectance of isolated shade
     312             :         Real64 rshv;            // = ShadeReflVis
     313             :         Real64 rfshv;           // Diffuse visible front reflectance of isolated blind
     314             :         Real64 rbshv;           // Diffuse visible back reflectance of isolated blind
     315             :         Real64 ShadeReflFacVis; // Shade/blind visible reflection factor
     316             :         int SpecDataNum;        // Spectral data set number
     317             :         int numptDAT;           // Number of wavelengths in a spectral data set
     318             :         int ISlatAng;           // Slat angle counter
     319             :         bool StormWinConst;     // True if a construction with a storm window
     320             :         bool Triangle;          // True if window is triangular
     321             :         bool Rectangle;         // True if window is rectangular
     322        1536 :         Array1D<Real64> W1(3);  // Window vertices (m)
     323        1536 :         Array1D<Real64> W2(3);
     324        1536 :         Array1D<Real64> W3(3);
     325        1536 :         Array1D<Real64> W21(3); // W1-W2, W3-W2, resp. (m)
     326        1536 :         Array1D<Real64> W23(3);
     327             : 
     328         768 :         W5InitGlassParameters(state);
     329             : 
     330             :         // Calculate optical properties of blind-type layers entered with MATERIAL:WindowBlind
     331         768 :         if (state.dataHeatBal->TotBlinds > 0) CalcWindowBlindProperties(state);
     332             : 
     333             :         // Initialize SurfaceScreen structure
     334         768 :         if (state.dataHeatBal->NumSurfaceScreens > 0) CalcWindowScreenProperties(state);
     335             : 
     336             :         // Get glazing system optical properties of constructions with glass or glass plus
     337             :         //   shade, screen or blind
     338             :         // Loop over constructions and find those that are glazing constructions
     339        6616 :         for (ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) {
     340       10385 :             if (!state.dataConstruction->Construct(ConstrNum).TypeIsWindow) continue;
     341        1327 :             if (state.dataConstruction->Construct(ConstrNum).WindowTypeBSDF) continue; // Skip Complex Fenestrations, they have separate
     342        1314 :             if (state.dataConstruction->Construct(ConstrNum).WindowTypeEQL) continue;  // skip Equivalent Layer Fenestration
     343             :             // handling of optical properties
     344             : 
     345       14421 :             for (IPhi = 1; IPhi <= 10; ++IPhi) {
     346       13110 :                 state.dataWindowManager->CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * DataGlobalConstants::DegToRadians);
     347             :             }
     348             : 
     349        1311 :             TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers;
     350             : 
     351             :             // First layer must be glass, shade, screen or blind to be a glazing construction
     352        2622 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
     353         129 :                     DataHeatBalance::MaterialGroup::WindowGlass &&
     354         129 :                 state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
     355         126 :                     DataHeatBalance::MaterialGroup::Shade &&
     356         126 :                 state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
     357         124 :                     DataHeatBalance::MaterialGroup::Screen &&
     358         124 :                 state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
     359        1433 :                     DataHeatBalance::MaterialGroup::WindowBlind &&
     360         122 :                 state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
     361             :                     DataHeatBalance::MaterialGroup::WindowSimpleGlazing)
     362           0 :                 continue;
     363             : 
     364        1311 :             ShadeLayNum = 0;
     365        1311 :             ExtShade = false;
     366        1311 :             IntShade = false;
     367        1311 :             BGShade = false;
     368        1311 :             ExtBlind = false;
     369        1311 :             IntBlind = false;
     370        1311 :             BGBlind = false;
     371        1311 :             ExtScreen = false;
     372        1311 :             StormWinConst = false;
     373        1311 :             state.dataWindowManager->lSimpleGlazingSystem = false;
     374             : 
     375        1311 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
     376             :                 DataHeatBalance::MaterialGroup::WindowSimpleGlazing) {
     377             :                 // what if outside layer is shade, blind, or screen?
     378         122 :                 state.dataWindowManager->lSimpleGlazingSystem = true;
     379         122 :                 state.dataWindowManager->SimpleGlazingSHGC =
     380         122 :                     state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).SimpleWindowSHGC;
     381         122 :                 state.dataWindowManager->SimpleGlazingU =
     382         122 :                     state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).SimpleWindowUfactor;
     383             :             }
     384             : 
     385        3932 :             if (has_prefix(state.dataConstruction->Construct(ConstrNum).Name, "BARECONSTRUCTIONWITHSTORMWIN") ||
     386        2621 :                 has_prefix(state.dataConstruction->Construct(ConstrNum).Name, "SHADEDCONSTRUCTIONWITHSTORMWIN"))
     387           1 :                 StormWinConst = true;
     388             : 
     389             :             // Get layer number of shade/blind
     390        1311 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
     391             :                 DataHeatBalance::MaterialGroup::Shade) {
     392           3 :                 ExtShade = true;
     393           3 :                 ShadeLayNum = 1;
     394        1308 :             } else if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay)).Group ==
     395             :                        DataHeatBalance::MaterialGroup::Shade) {
     396          24 :                 IntShade = true;
     397          24 :                 ShadeLayNum = TotLay;
     398        1284 :             } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 5) {
     399          68 :                 if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
     400             :                     DataHeatBalance::MaterialGroup::Shade) {
     401           1 :                     BGShade = true;
     402           1 :                     ShadeLayNum = 3;
     403             :                 }
     404        1216 :             } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 7) {
     405           8 :                 if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
     406             :                     DataHeatBalance::MaterialGroup::Shade) {
     407           1 :                     BGShade = true;
     408           1 :                     ShadeLayNum = 5;
     409             :                 }
     410             :             }
     411             : 
     412        1311 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
     413             :                 DataHeatBalance::MaterialGroup::WindowBlind) {
     414           2 :                 ExtBlind = true;
     415           2 :                 ShadeLayNum = 1;
     416           2 :                 BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
     417        1309 :             } else if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay)).Group ==
     418             :                        DataHeatBalance::MaterialGroup::WindowBlind) {
     419          11 :                 IntBlind = true;
     420          11 :                 ShadeLayNum = TotLay;
     421          11 :                 BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
     422        1298 :             } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 5) {
     423          68 :                 if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
     424             :                     DataHeatBalance::MaterialGroup::WindowBlind) {
     425           2 :                     BGBlind = true;
     426           2 :                     ShadeLayNum = 3;
     427           2 :                     BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
     428             :                 }
     429        1230 :             } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 7) {
     430           8 :                 if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
     431             :                     DataHeatBalance::MaterialGroup::WindowBlind) {
     432           1 :                     BGBlind = true;
     433           1 :                     ShadeLayNum = 5;
     434           1 :                     BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
     435             :                 }
     436             :             }
     437             : 
     438        1311 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
     439             :                 DataHeatBalance::MaterialGroup::Screen) {
     440           2 :                 ShadeLayNum = 1;
     441           2 :                 ScNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).ScreenDataPtr;
     442             :                 //   Disregard orphaned constructs with exterior screen
     443           2 :                 if (ScNum == 0) continue;
     444           2 :                 ExtScreen = true;
     445             :             }
     446             : 
     447        1311 :             ScreenOn = ExtScreen;
     448        1311 :             BlindOn = IntBlind || ExtBlind || BGBlind;
     449        1311 :             ShadeOn = IntShade || ExtShade || BGShade;
     450        1311 :             state.dataWindowManager->BGFlag = BGBlind || BGShade;
     451             : 
     452             :             // For construction with interior or exterior shade, get shade thermal absorptance (emissivity)
     453             :             // (accounting for inter-reflection with glazing) and correct the inside glass InsideAbsorpThermal
     454             :             // for presence of interior shade. Assumes inner and outer glass layers have zero thermal transmittance.
     455             : 
     456        1311 :             if (IntShade || ExtShade || ExtScreen) {
     457          29 :                 ShadeLayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum);
     458          29 :                 if (ExtScreen) {
     459           2 :                     TauShIR = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans;
     460             :                 } else {
     461          27 :                     TauShIR = state.dataMaterial->Material(ShadeLayPtr).TransThermal;
     462             :                 }
     463          29 :                 EpsShIR = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
     464          29 :                 RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
     465          29 :                 if (ExtShade || ExtScreen) { // Exterior shade or screen
     466           5 :                     EpsGlIR = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(2)).AbsorpThermalFront;
     467             :                 } else { // Interior shade
     468          24 :                     EpsGlIR = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay - 1)).AbsorpThermalBack;
     469             :                 }
     470          29 :                 RhoGlIR = max(0.0, 1.0 - EpsGlIR);
     471          29 :                 state.dataConstruction->Construct(ConstrNum).ShadeAbsorpThermal = EpsShIR * (1.0 + TauShIR * RhoGlIR / (1.0 - RhoShIR * RhoGlIR));
     472          29 :                 if (IntShade) state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal *= TauShIR / (1.0 - RhoShIR * RhoGlIR);
     473             :             }
     474             : 
     475             :             // From the individual glass layer properties, get the glazing system optical properties
     476             :             // for BARE GLASS (i.e., interior, exterior or between-glass shade or blind, or exterior screen, if present, not in place).
     477             :             // Get one set of system properties for solar incident on front of
     478             :             // window and a second set for solar incident on back of window. (The back-incident
     479             :             // properties are used with interior short-wave radiation striking the window from inside.)
     480             : 
     481             :             // After the front and back system optical properties are calculated for bare glass,
     482             :             // a correction is made for the effect of a shade, screen or blind if one of these
     483             :             // is present in the construction.
     484             : 
     485        1311 :             NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
     486             : 
     487             :             //--------------------------------------------------------------------------------------------
     488             :             // Front calculation (solar incident from outside of room); bare glass portion of construction
     489             :             //--------------------------------------------------------------------------------------------
     490             : 
     491        1311 :             lquasi = false;
     492        1311 :             AllGlassIsSpectralAverage = true;
     493        1311 :             int TotalIPhi = 10;
     494        1311 :             state.dataWindowManager->LayerNum = {0};
     495             : 
     496             :             // Loop over glass layers in the construction
     497        3277 :             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     498        1966 :                 LayNum = 1 + 2 * (IGlass - 1);
     499        1966 :                 if (ExtShade || ExtBlind || ExtScreen) LayNum = 2 + 2 * (IGlass - 1);
     500        1966 :                 if (BGShade || BGBlind) {
     501          12 :                     LayNum = 1;
     502          12 :                     if (NGlass == 2) {
     503           6 :                         if (IGlass == 2) LayNum = 5;
     504             :                     } else { // NGlass = 3
     505           6 :                         if (IGlass == 2) LayNum = 3;
     506           6 :                         if (IGlass == 3) LayNum = 7;
     507             :                     }
     508             :                 }
     509             : 
     510        1966 :                 state.dataWindowManager->LayerNum[IGlass - 1] = LayNum;
     511        1966 :                 LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(LayNum);
     512        1966 :                 SpecDataNum = state.dataMaterial->Material(LayPtr).GlassSpectralDataPtr;
     513        1966 :                 if (SpecDataNum != 0) {
     514         213 :                     if (!state.dataWindowManager->BGFlag) AllGlassIsSpectralAverage = false;
     515             : 
     516             :                     // Get the spectral data for the transmittance, front reflectance and
     517             :                     // back reflectance (all at normal incidence) for this layer.
     518             :                     // In this case, "front" means incident from the outside and "back"
     519             :                     // means incident from the inside.
     520         213 :                     numptDAT = state.dataHeatBal->SpectralData(SpecDataNum).NumOfWavelengths;
     521         213 :                     state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
     522             : 
     523       42312 :                     for (ILam = 1; ILam <= numptDAT; ++ILam) {
     524       42099 :                         state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).WaveLength(ILam);
     525       42099 :                         state.dataWindowManager->t[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).Trans(ILam);
     526       42099 :                         if ((IGlass == 1 || (IGlass == 2 && StormWinConst)) && (!state.dataWindowManager->BGFlag))
     527        6549 :                             state.dataWindowManager->t[IGlass - 1][ILam - 1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
     528       42099 :                         state.dataWindowManager->rff[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflFront(ILam);
     529       42099 :                         state.dataWindowManager->rbb[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflBack(ILam);
     530             :                     }
     531             : 
     532             :                     // If there is spectral data for between-glass shades or blinds, calc the average spectral properties for use.
     533         213 :                     if (state.dataWindowManager->BGFlag) {
     534             :                         // Add warning message for the glazing defined with full spectral data.
     535           0 :                         ShowWarningError(state,
     536           0 :                                          "Window glazing material \"" + state.dataMaterial->Material(LayPtr).Name +
     537             :                                              "\" was defined with full spectral data and has been converted to average spectral data");
     538           0 :                         ShowContinueError(state,
     539           0 :                                           "due to its use with between-glass shades or blinds of the window construction \"" +
     540           0 :                                               state.dataConstruction->Construct(ConstrNum).Name + "\".");
     541           0 :                         ShowContinueError(state, "All occurrences of this glazing material will be modeled as SpectralAverage.");
     542           0 :                         ShowContinueError(state,
     543             :                                           "If this material is also used in other window constructions  without between-glass shades or blinds,");
     544           0 :                         ShowContinueError(state,
     545             :                                           "then make a duplicate material (with new name) if you want to model those windows  (and reference the new "
     546             :                                           "material) using the full spectral data.");
     547             :                         // calc Trans, TransVis, ReflectSolBeamFront, ReflectSolBeamBack, ReflectVisBeamFront, ReflectVisBeamBack
     548             :                         //  assuming wlt same as wle
     549           0 :                         state.dataWindowManager->tmpTrans = solarSpectrumAverage(state, state.dataWindowManager->t[0]);
     550           0 :                         state.dataWindowManager->tmpReflectSolBeamFront = solarSpectrumAverage(state, state.dataWindowManager->rff[0]);
     551           0 :                         state.dataWindowManager->tmpReflectSolBeamBack = solarSpectrumAverage(state, state.dataWindowManager->rbb[0]);
     552             : 
     553             :                         // visible properties
     554           0 :                         state.dataWindowManager->tmpTransVis = visibleSpectrumAverage(state, state.dataWindowManager->t[0]);
     555           0 :                         state.dataWindowManager->tmpReflectVisBeamFront = visibleSpectrumAverage(state, state.dataWindowManager->rff[0]);
     556           0 :                         state.dataWindowManager->tmpReflectVisBeamBack = visibleSpectrumAverage(state, state.dataWindowManager->rbb[0]);
     557             : 
     558             :                         // set this material to average spectral data
     559           0 :                         state.dataMaterial->Material(LayPtr).GlassSpectralDataPtr = 0;
     560           0 :                         state.dataMaterial->Material(LayPtr).Trans = state.dataWindowManager->tmpTrans;
     561           0 :                         state.dataMaterial->Material(LayPtr).TransVis = state.dataWindowManager->tmpTransVis;
     562           0 :                         state.dataMaterial->Material(LayPtr).ReflectSolBeamFront = state.dataWindowManager->tmpReflectSolBeamFront;
     563           0 :                         state.dataMaterial->Material(LayPtr).ReflectSolBeamBack = state.dataWindowManager->tmpReflectSolBeamBack;
     564           0 :                         state.dataMaterial->Material(LayPtr).ReflectVisBeamFront = state.dataWindowManager->tmpReflectVisBeamFront;
     565           0 :                         state.dataMaterial->Material(LayPtr).ReflectVisBeamBack = state.dataWindowManager->tmpReflectVisBeamBack;
     566           0 :                         SpecDataNum = 0;
     567             :                     }
     568             :                 }
     569             : 
     570        3719 :                 if (SpecDataNum == 0 &&
     571        1753 :                     !state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) { // No spectral data for this layer; use spectral average values
     572        1751 :                     lquasi = true;
     573        1751 :                     state.dataWindowManager->numpt[IGlass - 1] = 2;
     574        1751 :                     state.dataWindowManager->t[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).Trans;
     575        1751 :                     if (IGlass == 1 || (IGlass == 2 && StormWinConst))
     576        1251 :                         state.dataWindowManager->t[IGlass - 1][0] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
     577        1751 :                     state.dataWindowManager->t[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).TransVis;
     578        1751 :                     if (IGlass == 1 || (IGlass == 2 && StormWinConst))
     579        1251 :                         state.dataWindowManager->t[IGlass - 1][1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
     580        1751 :                     state.dataWindowManager->rff[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamFront;
     581        1751 :                     state.dataWindowManager->rbb[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamBack;
     582        1751 :                     state.dataWindowManager->rff[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamFront;
     583        1751 :                     state.dataWindowManager->rbb[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamBack;
     584             :                 }
     585        1966 :                 if (state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
     586           2 :                     if (!state.dataWindowManager->BGFlag) AllGlassIsSpectralAverage = false;
     587           2 :                     numptDAT = state.dataWindowManager->wle.size();
     588           2 :                     state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
     589           2 :                     if (state.dataWindowManager->BGFlag) {
     590             :                         // 5/16/2012 CR 8793. Add warning message for the glazing defined with full spectral data.
     591           0 :                         ShowWarningError(state,
     592           0 :                                          "Window glazing material \"" + state.dataMaterial->Material(LayPtr).Name +
     593             :                                              "\" was defined with full spectral and angular data and has been converted to average spectral data");
     594           0 :                         ShowContinueError(state,
     595           0 :                                           "due to its use with between-glass shades or blinds of the window construction \"" +
     596           0 :                                               state.dataConstruction->Construct(ConstrNum).Name + "\".");
     597           0 :                         ShowContinueError(state, "All occurrences of this glazing material will be modeled as SpectralAverage.");
     598           0 :                         ShowContinueError(state,
     599             :                                           "If this material is also used in other window constructions  without between-glass shades or blinds,");
     600           0 :                         ShowContinueError(state,
     601             :                                           "then make a duplicate material (with new name) if you want to model those windows  (and reference the new "
     602             :                                           "material) using the full spectral data.");
     603             :                         // calc Trans, TransVis, ReflectSolBeamFront, ReflectSolBeamBack, ReflectVisBeamFront, ReflectVisBeamBack
     604             :                         //  assuming wlt same as wle
     605           0 :                         for (ILam = 1; ILam <= (int)state.dataWindowManager->wle.size(); ++ILam) {
     606           0 :                             auto lam = state.dataWindowManager->wle[ILam - 1];
     607           0 :                             state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = lam;
     608           0 :                             state.dataWindowManager->t[IGlass - 1][ILam - 1] =
     609           0 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngTransDataPtr, 0.0, lam);
     610           0 :                             state.dataWindowManager->rff[IGlass - 1][ILam - 1] =
     611           0 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngFRefleDataPtr, 0.0, lam);
     612           0 :                             state.dataWindowManager->rbb[IGlass - 1][ILam - 1] =
     613           0 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngBRefleDataPtr, 0.0, lam);
     614             :                         }
     615           0 :                         state.dataWindowManager->tmpTrans = solarSpectrumAverage(state, state.dataWindowManager->t[0]);
     616           0 :                         state.dataWindowManager->tmpReflectSolBeamFront = solarSpectrumAverage(state, state.dataWindowManager->rff[0]);
     617           0 :                         state.dataWindowManager->tmpReflectSolBeamBack = solarSpectrumAverage(state, state.dataWindowManager->rbb[0]);
     618             : 
     619             :                         // visible properties
     620           0 :                         state.dataWindowManager->tmpTransVis = visibleSpectrumAverage(state, state.dataWindowManager->t[0]);
     621           0 :                         state.dataWindowManager->tmpReflectVisBeamFront = visibleSpectrumAverage(state, state.dataWindowManager->rff[0]);
     622           0 :                         state.dataWindowManager->tmpReflectVisBeamBack = visibleSpectrumAverage(state, state.dataWindowManager->rbb[0]);
     623             : 
     624             :                         // set this material to average spectral data
     625           0 :                         state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle = false;
     626           0 :                         state.dataMaterial->Material(LayPtr).Trans = state.dataWindowManager->tmpTrans;
     627           0 :                         state.dataMaterial->Material(LayPtr).TransVis = state.dataWindowManager->tmpTransVis;
     628           0 :                         state.dataMaterial->Material(LayPtr).ReflectSolBeamFront = state.dataWindowManager->tmpReflectSolBeamFront;
     629           0 :                         state.dataMaterial->Material(LayPtr).ReflectSolBeamBack = state.dataWindowManager->tmpReflectSolBeamBack;
     630           0 :                         state.dataMaterial->Material(LayPtr).ReflectVisBeamFront = state.dataWindowManager->tmpReflectVisBeamFront;
     631           0 :                         state.dataMaterial->Material(LayPtr).ReflectVisBeamBack = state.dataWindowManager->tmpReflectVisBeamBack;
     632           0 :                         SpecDataNum = 0;
     633             :                     }
     634             :                 }
     635             :             } // End of loop over glass layers in the construction for front calculation
     636             : 
     637        1311 :             if (TotalIPhi > state.dataWindowManager->MaxNumOfIncidentAngles) {
     638           0 :                 ShowSevereError(state,
     639           0 :                                 format("WindowManage::InitGlassOpticalCalculations = {}, Invalid maximum value of common incidet angles = {}.",
     640           0 :                                        state.dataConstruction->Construct(ConstrNum).Name,
     641           0 :                                        TotalIPhi));
     642           0 :                 ShowContinueError(state,
     643           0 :                                   format("The maximum number of incident angles for each construct is {}. Please rearrange the dataset.",
     644           0 :                                          state.dataWindowManager->MaxNumOfIncidentAngles));
     645           0 :                 ShowFatalError(state, "Errors found getting inputs. Previous error(s) cause program termination.");
     646             :             }
     647             : 
     648             :             // Loop over incidence angle from 0 to 90 deg in 10 deg increments.
     649             :             // Get glass layer properties, then glazing system properties (which include the
     650             :             // effect of inter-reflection among glass layers) at each incidence angle.
     651             : 
     652       14421 :             for (IPhi = 1; IPhi <= TotalIPhi; ++IPhi) {
     653             :                 // 10 degree increment for incident angle is only value for a construction without a layer = SpectralAndAngle
     654       13110 :                 Phi = double(IPhi - 1) * 10.0;
     655       13110 :                 CosPhi = std::cos(Phi * DataGlobalConstants::DegToRadians);
     656       13110 :                 if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0;
     657             : 
     658             :                 // For each wavelength, get glass layer properties at this angle of incidence
     659             :                 // from properties at normal incidence
     660       32770 :                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     661       19660 :                     LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataWindowManager->LayerNum[IGlass - 1]);
     662       19660 :                     if (!state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
     663      475650 :                         for (ILam = 1; ILam <= state.dataWindowManager->numpt[IGlass - 1]; ++ILam) {
     664     2736060 :                             TransAndReflAtPhi(CosPhi,
     665      456010 :                                               state.dataWindowManager->t[IGlass - 1][ILam - 1],
     666      456010 :                                               state.dataWindowManager->rff[IGlass - 1][ILam - 1],
     667      456010 :                                               state.dataWindowManager->rbb[IGlass - 1][ILam - 1],
     668      456010 :                                               state.dataWindowManager->tPhi[IGlass - 1][ILam - 1],
     669      456010 :                                               state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1],
     670      456010 :                                               state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1],
     671      456010 :                                               state.dataWindowManager->lSimpleGlazingSystem,
     672      456010 :                                               state.dataWindowManager->SimpleGlazingSHGC,
     673      456010 :                                               state.dataWindowManager->SimpleGlazingU);
     674             :                         }
     675             :                     } else {
     676        2160 :                         for (ILam = 1; ILam <= (int)state.dataWindowManager->wle.size(); ++ILam) {
     677        2140 :                             auto lam = state.dataWindowManager->wle[ILam - 1];
     678        2140 :                             state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = lam;
     679        2140 :                             state.dataWindowManager->tPhi[IGlass - 1][ILam - 1] =
     680        4280 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngTransDataPtr, Phi, lam);
     681        2140 :                             state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1] =
     682        4280 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngFRefleDataPtr, Phi, lam);
     683        2140 :                             state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1] =
     684        4280 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngBRefleDataPtr, Phi, lam);
     685             :                         }
     686             :                     }
     687             :                     // For use with between-glass shade/blind, save angular properties of isolated glass
     688             :                     // for case that all glass layers were input with spectral-average properties
     689             :                     //  only used by between-glass shades or blinds
     690       19660 :                     if (AllGlassIsSpectralAverage) {
     691       17150 :                         tBareSolPhi(IGlass, IPhi) = state.dataWindowManager->tPhi[IGlass - 1][0];
     692       17150 :                         tBareVisPhi(IGlass, IPhi) = state.dataWindowManager->tPhi[IGlass - 1][1];
     693       17150 :                         rfBareSolPhi(IGlass, IPhi) = state.dataWindowManager->rfPhi[IGlass - 1][0];
     694       17150 :                         rfBareVisPhi(IGlass, IPhi) = state.dataWindowManager->rfPhi[IGlass - 1][1];
     695       17150 :                         rbBareSolPhi(IGlass, IPhi) = state.dataWindowManager->rbPhi[IGlass - 1][0];
     696       17150 :                         rbBareVisPhi(IGlass, IPhi) = state.dataWindowManager->rbPhi[IGlass - 1][1];
     697       17150 :                         afBareSolPhi(IGlass, IPhi) = max(0.0, 1.0 - (tBareSolPhi(IGlass, IPhi) + rfBareSolPhi(IGlass, IPhi)));
     698       17150 :                         abBareSolPhi(IGlass, IPhi) = max(0.0, 1.0 - (tBareSolPhi(IGlass, IPhi) + rbBareSolPhi(IGlass, IPhi)));
     699             :                     }
     700             :                 }
     701             : 
     702             :                 // For each wavelength in the solar spectrum, calculate system properties
     703             :                 // stPhi, srfPhi, srbPhi and saPhi at this angle of incidence.
     704             :                 // In the following the argument "1" indicates that spectral average solar values
     705             :                 // should be used for layers without spectral data.
     706       13110 :                 SystemSpectralPropertiesAtPhi(state, 1, NGlass, 0.0, 2.54);
     707             : 
     708             :                 // Get solar properties of system by integrating over solar irradiance spectrum.
     709             :                 // For now it is assumed that the exterior and interior irradiance spectra are the same.
     710       13110 :                 state.dataWindowManager->tsolPhi(IPhi) = solarSpectrumAverage(state, state.dataWindowManager->stPhi);
     711       13110 :                 state.dataWindowManager->rfsolPhi(IPhi) = solarSpectrumAverage(state, state.dataWindowManager->srfPhi);
     712       13110 :                 state.dataWindowManager->rbsolPhi(IPhi) = solarSpectrumAverage(state, state.dataWindowManager->srbPhi);
     713             : 
     714       32770 :                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     715     2123280 :                     for (ILam = 1; ILam <= state.dataWindowManager->nume; ++ILam) {
     716     2103620 :                         sabsPhi(ILam) = state.dataWindowManager->saPhi(IGlass, ILam);
     717             :                     }
     718       19660 :                     SolarSprectrumAverage(state, sabsPhi, state.dataWindowManager->solabsPhi(IGlass, IPhi));
     719             :                 }
     720             : 
     721             :                 // Get visible properties of system by integrating over solar irradiance
     722             :                 // spectrum weighted by photopic response.
     723             :                 // Need to redo the calculation of system spectral properties here only if
     724             :                 // one or more glass layers have no spectral data (lquasi = .TRUE.); in this
     725             :                 // case the spectral average visible properties will be used for the layers
     726             :                 // without spectral data, as indicated by the argument "2".
     727             : 
     728       13110 :                 if (lquasi) SystemSpectralPropertiesAtPhi(state, 2, NGlass, 0.37, 0.78);
     729       13110 :                 state.dataWindowManager->tvisPhi(IPhi) = visibleSpectrumAverage(state, state.dataWindowManager->stPhi);
     730       13110 :                 state.dataWindowManager->rfvisPhi(IPhi) = visibleSpectrumAverage(state, state.dataWindowManager->srfPhi);
     731       13110 :                 state.dataWindowManager->rbvisPhi(IPhi) = visibleSpectrumAverage(state, state.dataWindowManager->srbPhi);
     732             : 
     733             :             } // End of loop over incidence angles for front calculation
     734             : 
     735             :             //  only used by between-glass shades or blinds
     736        1311 :             if (AllGlassIsSpectralAverage) {
     737        2929 :                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     738        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     739        3430 :                              tBareSolPhi(IGlass, _),
     740             :                              6,
     741             :                              1,
     742             :                              TotalIPhi,
     743        1715 :                              state.dataConstruction->Construct(ConstrNum).tBareSolCoef(IGlass));
     744        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     745        3430 :                              tBareVisPhi(IGlass, _),
     746             :                              6,
     747             :                              1,
     748             :                              TotalIPhi,
     749        1715 :                              state.dataConstruction->Construct(ConstrNum).tBareVisCoef(IGlass));
     750        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     751        3430 :                              rfBareSolPhi(IGlass, _),
     752             :                              6,
     753             :                              1,
     754             :                              TotalIPhi,
     755        1715 :                              state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(IGlass));
     756        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     757        3430 :                              rfBareVisPhi(IGlass, _),
     758             :                              6,
     759             :                              1,
     760             :                              TotalIPhi,
     761        1715 :                              state.dataConstruction->Construct(ConstrNum).rfBareVisCoef(IGlass));
     762        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     763        3430 :                              rbBareSolPhi(IGlass, _),
     764             :                              6,
     765             :                              1,
     766             :                              TotalIPhi,
     767        1715 :                              state.dataConstruction->Construct(ConstrNum).rbBareSolCoef(IGlass));
     768        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     769        3430 :                              rbBareVisPhi(IGlass, _),
     770             :                              6,
     771             :                              1,
     772             :                              TotalIPhi,
     773        1715 :                              state.dataConstruction->Construct(ConstrNum).rbBareVisCoef(IGlass));
     774        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     775        3430 :                              afBareSolPhi(IGlass, _),
     776             :                              6,
     777             :                              1,
     778             :                              TotalIPhi,
     779        1715 :                              state.dataConstruction->Construct(ConstrNum).afBareSolCoef(IGlass));
     780        5145 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
     781        3430 :                              abBareSolPhi(IGlass, _),
     782             :                              6,
     783             :                              1,
     784             :                              TotalIPhi,
     785        1715 :                              state.dataConstruction->Construct(ConstrNum).abBareSolCoef(IGlass));
     786             :                 }
     787             :             }
     788             : 
     789        1311 :             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront = DiffuseAverage(state.dataWindowManager->rfsolPhi);
     790        1311 :             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack = DiffuseAverage(state.dataWindowManager->rbsolPhi);
     791        1311 :             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront = DiffuseAverage(state.dataWindowManager->rfvisPhi);
     792        1311 :             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack = DiffuseAverage(state.dataWindowManager->rbvisPhi);
     793             : 
     794        1311 :             tsolDiff = DiffuseAverage(state.dataWindowManager->tsolPhi);
     795        1311 :             tvisDiff = DiffuseAverage(state.dataWindowManager->tvisPhi);
     796        1311 :             state.dataConstruction->Construct(ConstrNum).TransDiff = tsolDiff;
     797        1311 :             state.dataConstruction->Construct(ConstrNum).TransDiffVis = tvisDiff;
     798        3277 :             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     799        1966 :                 solabsPhiLay({1, TotalIPhi}) = state.dataWindowManager->solabsPhi(IGlass, {1, TotalIPhi});
     800        1966 :                 solabsDiff(IGlass) = DiffuseAverage(solabsPhiLay);
     801        1966 :                 state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) = solabsDiff(IGlass);
     802             : 
     803             :                 // For use with between-glass shade/blind, get diffuse properties of isolated glass for case when
     804             :                 // all glass layers were input with spectral-average properties
     805             :                 //  only used by between-glass shades or blinds
     806        1966 :                 if (AllGlassIsSpectralAverage) {
     807        1715 :                     state.dataConstruction->Construct(ConstrNum).tBareSolDiff(IGlass) = DiffuseAverage(tBareSolPhi(IGlass, {1, TotalIPhi}));
     808        1715 :                     state.dataConstruction->Construct(ConstrNum).tBareVisDiff(IGlass) = DiffuseAverage(tBareVisPhi(IGlass, {1, TotalIPhi}));
     809        1715 :                     state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(IGlass) = DiffuseAverage(rfBareSolPhi(IGlass, {1, TotalIPhi}));
     810        1715 :                     state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(IGlass) = DiffuseAverage(rfBareVisPhi(IGlass, {1, TotalIPhi}));
     811        1715 :                     state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(IGlass) = DiffuseAverage(rbBareSolPhi(IGlass, {1, TotalIPhi}));
     812        1715 :                     state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(IGlass) = DiffuseAverage(rbBareVisPhi(IGlass, {1, TotalIPhi}));
     813        1715 :                     state.dataConstruction->Construct(ConstrNum).afBareSolDiff(IGlass) =
     814        1715 :                         max(0.0,
     815        3430 :                             1.0 - (state.dataConstruction->Construct(ConstrNum).tBareSolDiff(IGlass) +
     816        1715 :                                    state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(IGlass)));
     817        1715 :                     state.dataConstruction->Construct(ConstrNum).abBareSolDiff(IGlass) =
     818        1715 :                         max(0.0,
     819        3430 :                             1.0 - (state.dataConstruction->Construct(ConstrNum).tBareSolDiff(IGlass) +
     820        1715 :                                    state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(IGlass)));
     821             :                 }
     822             :             }
     823             : 
     824             :             //------------------------------------------------------------------------------------------
     825             :             // Back calculation (solar incident from inside of room); bare glass portion of construction
     826             :             //------------------------------------------------------------------------------------------
     827             : 
     828        1311 :             lquasi = false;
     829        1311 :             state.dataWindowManager->LayerNum = {0};
     830             : 
     831             :             // Loop over glass layers in the construction.
     832        3277 :             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     833        1966 :                 LayNum = 1 + (NGlass - IGlass) * 2;
     834        1966 :                 if (ExtShade || ExtBlind || ExtScreen) LayNum = 2 + (NGlass - IGlass) * 2;
     835        1966 :                 if (BGShade || BGBlind) {
     836          12 :                     if (NGlass == 2) {
     837           6 :                         if (IGlass == 1) LayNum = 5;
     838           6 :                         if (IGlass == 2) LayNum = 1;
     839             :                     } else { // NGlass = 3
     840           6 :                         if (IGlass == 1) LayNum = 7;
     841           6 :                         if (IGlass == 2) LayNum = 3;
     842           6 :                         if (IGlass == 3) LayNum = 1;
     843             :                     }
     844             :                 }
     845        1966 :                 state.dataWindowManager->LayerNum[IGlass - 1] = LayNum;
     846        1966 :                 LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(LayNum);
     847             : 
     848        1966 :                 SpecDataNum = state.dataMaterial->Material(LayPtr).GlassSpectralDataPtr;
     849        1966 :                 if (SpecDataNum != 0) {
     850             : 
     851             :                     // Get the spectral data for the transmittance, front reflectance and
     852             :                     // back reflectance (all at normal incidence) for this layer.
     853             :                     // In this case, "front" means incident from the inside and "back"
     854             :                     // means incident from the outside.
     855             : 
     856         213 :                     numptDAT = state.dataHeatBal->SpectralData(SpecDataNum).NumOfWavelengths;
     857         213 :                     state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
     858             : 
     859       42312 :                     for (ILam = 1; ILam <= numptDAT; ++ILam) {
     860       42099 :                         state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).WaveLength(ILam);
     861       42099 :                         state.dataWindowManager->t[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).Trans(ILam);
     862       42099 :                         if (IGlass == NGlass || (IGlass == (NGlass - 1) && StormWinConst))
     863        6549 :                             state.dataWindowManager->t[IGlass - 1][ILam - 1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
     864       42099 :                         state.dataWindowManager->rff[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflBack(ILam);
     865       42099 :                         state.dataWindowManager->rbb[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflFront(ILam);
     866             :                     }
     867             : 
     868             :                 } else { // No spectral data for this layer; use spectral average values
     869        1753 :                     if (!state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
     870        1751 :                         lquasi = true;
     871        1751 :                         state.dataWindowManager->numpt[IGlass - 1] = 2;
     872        1751 :                         state.dataWindowManager->t[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).Trans;
     873        1751 :                         if (IGlass == NGlass || (IGlass == (NGlass - 1) && StormWinConst))
     874        1251 :                             state.dataWindowManager->t[IGlass - 1][0] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
     875        1751 :                         state.dataWindowManager->t[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).TransVis;
     876        1751 :                         if (IGlass == NGlass || (IGlass == (NGlass - 1) && StormWinConst))
     877        1251 :                             state.dataWindowManager->t[IGlass - 1][1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
     878        1751 :                         state.dataWindowManager->rff[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamBack;
     879        1751 :                         state.dataWindowManager->rbb[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamFront;
     880        1751 :                         state.dataWindowManager->rff[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamBack;
     881        1751 :                         state.dataWindowManager->rbb[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamFront;
     882             :                     }
     883             :                 }
     884        1966 :                 if (state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
     885           2 :                     numptDAT = state.dataWindowManager->wle.size();
     886           2 :                     state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
     887             :                 }
     888             :             } // End of loop over glass layers in the construction for back calculation
     889             : 
     890             :             // Loop over incidence angle from 0 to 90 deg in 10 deg increments.
     891             :             // Get bare glass layer properties, then glazing system properties at each incidence angle.
     892             :             // The glazing system properties include the effect of inter-reflection among glass layers,
     893             :             // but exclude the effect of a shade or blind if present in the construction.
     894             :             // When a construction has a layer = SpectralAndAngle, the 10 degree increment will be overridden.
     895       14421 :             for (IPhi = 1; IPhi <= TotalIPhi; ++IPhi) {
     896       13110 :                 Phi = double(IPhi - 1) * 10.0;
     897       13110 :                 CosPhi = std::cos(Phi * DataGlobalConstants::DegToRadians);
     898       13110 :                 if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0;
     899             : 
     900             :                 // For each wavelength, get glass layer properties at this angle of incidence
     901             :                 // from properties at normal incidence
     902       32770 :                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     903       19660 :                     LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataWindowManager->LayerNum[IGlass - 1]);
     904       19660 :                     if (!state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
     905      475650 :                         for (ILam = 1; ILam <= state.dataWindowManager->numpt[IGlass - 1]; ++ILam) {
     906             : 
     907     2736060 :                             TransAndReflAtPhi(CosPhi,
     908      456010 :                                               state.dataWindowManager->t[IGlass - 1][ILam - 1],
     909      456010 :                                               state.dataWindowManager->rff[IGlass - 1][ILam - 1],
     910      456010 :                                               state.dataWindowManager->rbb[IGlass - 1][ILam - 1],
     911      456010 :                                               state.dataWindowManager->tPhi[IGlass - 1][ILam - 1],
     912      456010 :                                               state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1],
     913      456010 :                                               state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1],
     914      456010 :                                               state.dataWindowManager->lSimpleGlazingSystem,
     915      456010 :                                               state.dataWindowManager->SimpleGlazingSHGC,
     916      456010 :                                               state.dataWindowManager->SimpleGlazingU);
     917             :                         }
     918             :                     } else {
     919        2160 :                         for (ILam = 1; ILam <= (int)state.dataWindowManager->wle.size(); ++ILam) {
     920        2140 :                             auto lam = state.dataWindowManager->wle[ILam - 1];
     921        2140 :                             state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = lam;
     922        2140 :                             state.dataWindowManager->tPhi[IGlass - 1][ILam - 1] =
     923        4280 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngTransDataPtr, Phi, lam);
     924        2140 :                             state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1] =
     925        4280 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngFRefleDataPtr, Phi, lam);
     926        2140 :                             state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1] =
     927        4280 :                                 Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngBRefleDataPtr, Phi, lam);
     928             :                         }
     929             :                     }
     930             :                 }
     931             : 
     932             :                 // For each wavelength in the solar spectrum, calculate system properties
     933             :                 // stPhi, srfPhi, srbPhi and saPhi at this angle of incidence
     934       13110 :                 SystemSpectralPropertiesAtPhi(state, 1, NGlass, 0.0, 2.54);
     935             : 
     936             :                 // Get back absorptance properties of system by integrating over solar irradiance spectrum.
     937             :                 // For now it is assumed that the exterior and interior irradiance spectra are the same.
     938             : 
     939       32770 :                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     940     2123280 :                     for (j = 1; j <= state.dataWindowManager->nume; ++j) {
     941     2103620 :                         sabsPhi(j) = state.dataWindowManager->saPhi(IGlass, j);
     942             :                     }
     943       19660 :                     SolarSprectrumAverage(state, sabsPhi, state.dataWindowManager->solabsBackPhi(IGlass, IPhi));
     944             :                 }
     945             : 
     946             :             } // End of loop over incidence angles for back calculation
     947             : 
     948        3277 :             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
     949        1966 :                 IGlassBack = NGlass - IGlass + 1;
     950        1966 :                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) =
     951        3932 :                     DiffuseAverage(state.dataWindowManager->solabsBackPhi(IGlassBack, {1, 10}));
     952             :             }
     953             : 
     954             :             //-----------------------------------------------------------------------
     955             :             // Correction for effect of shade, screen or blind if present in the construction
     956             :             //-----------------------------------------------------------------------
     957             : 
     958             :             // For construction with shade, screen or blind, get system shading device absorptance
     959             :             // and correct the system glass layer absorptances for the effect of reflection
     960             :             // and transmission by shade, screen or blind. Get system reflectance (front and back,
     961             :             // solar and visible)
     962             : 
     963        1311 :             if (ShadeOn || BlindOn || ScreenOn) {
     964             : 
     965             :                 // Solar and visible properties of isolated shade or blind
     966             :                 // (Note: for shades or screen we go through the following loop over slat angles only once.)
     967             : 
     968          47 :                 Real64 const tsolDiff_2(pow_2(tsolDiff));
     969          47 :                 Real64 const tvisDiff_2(pow_2(tvisDiff));
     970         104 :                 for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
     971             : 
     972         101 :                     if (ShadeOn) {
     973          29 :                         ShadeAbs = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).AbsorpSolar;
     974          29 :                         ShadeTrans = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).Trans;
     975          29 :                         ShadeTransVis = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).TransVis;
     976          29 :                         ShadeRefl = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).ReflectShade;
     977          29 :                         ShadeReflVis =
     978          29 :                             state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).ReflectShadeVis;
     979          29 :                         rsh = ShadeRefl;
     980          29 :                         rshv = ShadeReflVis;
     981          29 :                         tsh = ShadeTrans;
     982          29 :                         tshv = ShadeTransVis;
     983          29 :                         ash = ShadeAbs;
     984          72 :                     } else if (IntBlind || ExtBlind) {
     985          67 :                         ShadeTrans = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(ISlatAng);
     986          67 :                         ShadeTransGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransGnd(ISlatAng);
     987          67 :                         ShadeTransSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransSky(ISlatAng);
     988          67 :                         ShadeTransVis = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffTrans(ISlatAng);
     989         134 :                         if (IntBlind) { // Interior blind
     990          47 :                             ShadeAbs = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(ISlatAng);
     991          47 :                             ShadeRefl = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(ISlatAng);
     992          47 :                             ShadeReflGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflGnd(ISlatAng);
     993          47 :                             ShadeReflSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflSky(ISlatAng);
     994          47 :                             ShadeReflVis = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffRefl(ISlatAng);
     995             :                         } else { // Exterior blind
     996          20 :                             ShadeAbs = state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(ISlatAng);
     997          20 :                             ShadeRefl = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(ISlatAng);
     998          20 :                             ShadeReflVis = state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl(ISlatAng);
     999             :                         }
    1000           5 :                     } else if (BGBlind) {
    1001           3 :                         tsh = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(ISlatAng);
    1002           3 :                         tshGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransGnd(ISlatAng);
    1003           3 :                         tshSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransSky(ISlatAng);
    1004           3 :                         tshv = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffTrans(ISlatAng);
    1005           3 :                         rfsh = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(ISlatAng);
    1006           3 :                         rfshGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflGnd(ISlatAng);
    1007           3 :                         rfshSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflSky(ISlatAng);
    1008           3 :                         rfshv = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffRefl(ISlatAng);
    1009           3 :                         rbsh = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(ISlatAng);
    1010           3 :                         rbshv = state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl(ISlatAng);
    1011           3 :                         afsh = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(ISlatAng);
    1012           3 :                         afshGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsGnd(ISlatAng);
    1013           3 :                         afshSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsSky(ISlatAng);
    1014           3 :                         absh = state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(ISlatAng);
    1015           2 :                     } else if (ScreenOn && ScNum > 0) {
    1016             :                         //       diffuse screen properties are calculated during initialization (quarter-hemispherical integration of beam properties)
    1017           2 :                         ShadeAbs = state.dataHeatBal->SurfaceScreens(ScNum).DifScreenAbsorp;
    1018           2 :                         ShadeTrans = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans;
    1019           2 :                         ShadeTransVis = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTransVis;
    1020           2 :                         ShadeRefl = state.dataHeatBal->SurfaceScreens(ScNum).DifReflect;
    1021           2 :                         ShadeReflVis = state.dataHeatBal->SurfaceScreens(ScNum).DifReflectVis;
    1022           2 :                         rsh = ShadeRefl;
    1023           2 :                         rshv = ShadeReflVis;
    1024           2 :                         tsh = ShadeTrans;
    1025           2 :                         tshv = ShadeTransVis;
    1026           2 :                         ash = ShadeAbs;
    1027             :                     }
    1028             : 
    1029             :                     // Correction factors for inter-reflections between glass and shading device
    1030             : 
    1031         101 :                     if (ExtShade || ExtBlind || ExtScreen) {
    1032          25 :                         ShadeReflFac = 1.0 / (1.0 - ShadeRefl * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront);
    1033          25 :                         ShadeReflFacVis = 1.0 / (1.0 - ShadeReflVis * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront);
    1034          76 :                     } else if (IntShade || IntBlind) {
    1035          71 :                         ShadeReflFac = 1.0 / (1.0 - ShadeRefl * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack);
    1036          71 :                         ShadeReflFacVis = 1.0 / (1.0 - ShadeReflVis * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack);
    1037             :                     }
    1038             : 
    1039         101 :                     if (ExtShade || ExtBlind || ExtScreen) { // Exterior shade or blind
    1040             : 
    1041             :                         // Front incident solar, beam, exterior shade, screen or blind
    1042             : 
    1043          25 :                         if (ExtShade) {
    1044          33 :                             for (IPhi = 1; IPhi <= 10; ++IPhi) {
    1045          80 :                                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1046          50 :                                     state.dataWindowManager->solabsPhi(IGlass, IPhi) = ShadeTrans * solabsDiff(IGlass) * ShadeReflFac;
    1047             :                                 }
    1048          30 :                                 state.dataWindowManager->tsolPhi(IPhi) = ShadeTrans * ShadeReflFac * tsolDiff;
    1049          30 :                                 state.dataWindowManager->tvisPhi(IPhi) = ShadeTransVis * ShadeReflFacVis * tvisDiff;
    1050          30 :                                 state.dataWindowManager->solabsShadePhi(IPhi) =
    1051          30 :                                     ShadeAbs * (1.0 + ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront);
    1052             :                             }
    1053             :                         }
    1054             : 
    1055             :                         // Front incident solar, diffuse, exterior shade/screen/blind
    1056             : 
    1057          53 :                         for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1058          28 :                             if (ExtBlind) {
    1059          20 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, IGlass) =
    1060          20 :                                     ShadeTrans * ShadeReflFac * solabsDiff(IGlass);
    1061          20 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, IGlass) =
    1062          20 :                                     ShadeTransGnd * ShadeReflFac * solabsDiff(IGlass);
    1063          20 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, IGlass) =
    1064          20 :                                     ShadeTransSky * ShadeReflFac * solabsDiff(IGlass);
    1065             :                             }
    1066          28 :                             if (ExtShade || ExtScreen)
    1067           8 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) = ShadeTrans * ShadeReflFac * solabsDiff(IGlass);
    1068             :                         }
    1069          25 :                         if (ExtBlind) {
    1070          20 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) =
    1071          40 :                                 state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(ISlatAng) +
    1072          20 :                                 ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeAbs;
    1073          20 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
    1074          40 :                                 state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsGnd(ISlatAng) +
    1075          20 :                                 ShadeTransGnd * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeAbs;
    1076          20 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
    1077          40 :                                 state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsSky(ISlatAng) +
    1078          20 :                                 ShadeTransSky * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeAbs;
    1079          20 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTrans;
    1080          20 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransGnd;
    1081          20 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransSky;
    1082          20 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) = tvisDiff * ShadeReflFacVis * ShadeTransVis;
    1083          20 :                             state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
    1084          20 :                                 ShadeRefl + pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeReflFac;
    1085          20 :                             state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
    1086          20 :                                 ShadeReflVis +
    1087          20 :                                 pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront * ShadeReflFacVis;
    1088             :                         }
    1089          25 :                         if (ExtShade || ExtScreen) {
    1090           5 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffShade =
    1091           5 :                                 ShadeAbs * (1.0 + ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront);
    1092           5 :                             state.dataConstruction->Construct(ConstrNum).TransDiff = tsolDiff * ShadeReflFac * ShadeTrans;
    1093           5 :                             state.dataConstruction->Construct(ConstrNum).TransDiffVis = tvisDiff * ShadeReflFacVis * ShadeTransVis;
    1094           5 :                             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront =
    1095           5 :                                 ShadeRefl + pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeReflFac;
    1096           5 :                             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront =
    1097           5 :                                 ShadeReflVis +
    1098           5 :                                 pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront * ShadeReflFacVis;
    1099             :                         }
    1100             : 
    1101             :                         // Back incident solar, diffuse, exterior shade/blind
    1102             : 
    1103          25 :                         if (ExtBlind) {
    1104          40 :                             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1105          20 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, IGlass) =
    1106          40 :                                     state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) +
    1107          20 :                                     tsolDiff * ShadeRefl * ShadeReflFac * solabsDiff(IGlass);
    1108             :                             }
    1109          20 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) = tsolDiff * ShadeReflFac * ShadeAbs;
    1110          20 :                             state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
    1111          20 :                                 state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack + tsolDiff_2 * ShadeRefl * ShadeReflFac;
    1112          20 :                             state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
    1113          20 :                                 state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack + tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
    1114             :                         }
    1115          25 :                         if (ExtShade || ExtScreen) {
    1116          13 :                             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1117           8 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) +=
    1118           8 :                                     tsolDiff * ShadeRefl * ShadeReflFac * solabsDiff(IGlass);
    1119             :                             }
    1120           5 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = tsolDiff * ShadeReflFac * ShadeAbs;
    1121           5 :                             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack += tsolDiff_2 * ShadeRefl * ShadeReflFac;
    1122           5 :                             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack += tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
    1123             :                         }
    1124             : 
    1125             :                     } // End check if exterior shade, screen or blind
    1126             : 
    1127         101 :                     if (IntShade || IntBlind) { // Interior shade or blind
    1128             : 
    1129             :                         // Front incident solar, beam, interior shade
    1130             : 
    1131          71 :                         if (IntShade) {
    1132         264 :                             for (IPhi = 1; IPhi <= 10; ++IPhi) {
    1133         620 :                                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1134         380 :                                     state.dataWindowManager->solabsPhi(IGlass, IPhi) +=
    1135         760 :                                         state.dataWindowManager->tsolPhi(IPhi) * ShadeRefl * ShadeReflFac *
    1136         380 :                                         state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    1137             :                                 }
    1138         240 :                                 state.dataWindowManager->solabsShadePhi(IPhi) = state.dataWindowManager->tsolPhi(IPhi) * ShadeReflFac * ShadeAbs;
    1139         240 :                                 state.dataWindowManager->tsolPhi(IPhi) *= ShadeReflFac * ShadeTrans;
    1140         240 :                                 state.dataWindowManager->tvisPhi(IPhi) *= ShadeReflFacVis * ShadeTransVis;
    1141             :                             }
    1142             :                         } // End of check if interior shade
    1143             : 
    1144             :                         // Front incident solar, diffuse, interior blind
    1145             : 
    1146          71 :                         if (IntBlind) {
    1147          94 :                             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1148          47 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, IGlass) =
    1149          94 :                                     state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +
    1150          47 :                                     tsolDiff * ShadeRefl * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    1151          47 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, IGlass) =
    1152          94 :                                     state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +
    1153          47 :                                     tsolDiff * ShadeReflGnd * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    1154          47 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, IGlass) =
    1155          94 :                                     state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +
    1156          47 :                                     tsolDiff * ShadeReflSky * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    1157             :                             }
    1158             : 
    1159          47 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) = tsolDiff * ShadeReflFac * ShadeAbs;
    1160          47 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
    1161          47 :                                 tsolDiff * ShadeReflFac * state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsGnd(ISlatAng);
    1162          47 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
    1163          47 :                                 tsolDiff * ShadeReflFac * state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsSky(ISlatAng);
    1164          47 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTrans;
    1165          47 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransGnd;
    1166          47 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransSky;
    1167          47 :                             state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) = tvisDiff * ShadeReflFacVis * ShadeTransVis;
    1168          47 :                             state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
    1169          47 :                                 state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront + tsolDiff_2 * ShadeRefl * ShadeReflFac;
    1170          47 :                             state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
    1171          47 :                                 state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront + tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
    1172             : 
    1173             :                             // Back incident solar, diffuse, interior blind
    1174             : 
    1175          94 :                             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1176          47 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, IGlass) =
    1177          47 :                                     state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) * ShadeTrans * ShadeReflFac;
    1178             :                             }
    1179             : 
    1180          47 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) =
    1181          94 :                                 state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(ISlatAng) +
    1182          47 :                                 ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack * ShadeAbs;
    1183          47 :                             state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
    1184          94 :                                 state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(ISlatAng) +
    1185          47 :                                 pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack * ShadeReflFac;
    1186          47 :                             state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
    1187          94 :                                 state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl(ISlatAng) +
    1188          47 :                                 pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack * ShadeReflFacVis;
    1189             :                         } // End of check if interior blind
    1190             : 
    1191             :                         // Front incident solar, diffuse, interior shade
    1192             : 
    1193          71 :                         if (IntShade) {
    1194          62 :                             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1195          38 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +=
    1196          38 :                                     tsolDiff * ShadeRefl * ShadeReflFac * solabsDiff(IGlass);
    1197             :                             }
    1198             : 
    1199          24 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffShade = tsolDiff * ShadeReflFac * ShadeAbs;
    1200          24 :                             state.dataConstruction->Construct(ConstrNum).TransDiff = tsolDiff * ShadeReflFac * ShadeTrans;
    1201          24 :                             state.dataConstruction->Construct(ConstrNum).TransDiffVis = tvisDiff * ShadeReflFacVis * ShadeTransVis;
    1202          24 :                             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront += tsolDiff_2 * ShadeRefl * ShadeReflFac;
    1203          24 :                             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront += tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
    1204             : 
    1205             :                             // Back incident solar, diffuse, interior shade
    1206             : 
    1207          62 :                             for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1208          38 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) *= ShadeTrans * ShadeReflFac;
    1209             :                             }
    1210             : 
    1211          24 :                             state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade =
    1212          24 :                                 ShadeAbs * (1 + ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack);
    1213          24 :                             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack =
    1214          24 :                                 ShadeRefl + pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack * ShadeReflFac;
    1215          24 :                             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack =
    1216          24 :                                 ShadeReflVis +
    1217          24 :                                 pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack * ShadeReflFacVis;
    1218             :                         } // End of check if interior shade
    1219             : 
    1220             :                     } // End check if interior shade or blind
    1221             : 
    1222         101 :                     if (BGShade || BGBlind) { // Between-glass shade/blind; assumed to be between glass #2 and glass #3
    1223             : 
    1224           5 :                         tsh2 = pow_2(tsh);
    1225           5 :                         tshv2 = pow_2(tshv);
    1226           5 :                         td1 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(1);
    1227           5 :                         td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
    1228           5 :                         td1v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(1);
    1229           5 :                         td2v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(2);
    1230           5 :                         afd1 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(1);
    1231           5 :                         afd2 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(2);
    1232           5 :                         abd1 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(1);
    1233           5 :                         abd2 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(2);
    1234           5 :                         rb1 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(1);
    1235           5 :                         rb2 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(2);
    1236           5 :                         rb1v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(1);
    1237           5 :                         rb2v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(2);
    1238           5 :                         rf1 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(1);
    1239           5 :                         rf2 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(2);
    1240           5 :                         rf1v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(1);
    1241           5 :                         rf2v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(2);
    1242             : 
    1243           5 :                         if (BGShade) {
    1244           2 :                             if (NGlass == 2) {
    1245             : 
    1246             :                                 // Front incident solar, beam, between-glass shade, NGlass = 2
    1247             : 
    1248          11 :                                 for (IPhi = 1; IPhi <= 10; ++IPhi) {
    1249          10 :                                     t1 = tBareSolPhi(1, IPhi);
    1250          10 :                                     t1v = tBareVisPhi(1, IPhi);
    1251          10 :                                     af1 = afBareSolPhi(1, IPhi);
    1252          10 :                                     ab1 = abBareSolPhi(1, IPhi);
    1253          10 :                                     state.dataWindowManager->tsolPhi(IPhi) = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * td2;
    1254          10 :                                     state.dataWindowManager->tvisPhi(IPhi) = t1v * (tshv + rshv * rb1v * tshv + tshv * rf2v * rshv) * td2v;
    1255          10 :                                     state.dataWindowManager->solabsShadePhi(IPhi) = t1 * (ash + rsh * rb1 + tsh * rf2) * ash;
    1256          10 :                                     state.dataWindowManager->solabsPhi(1, IPhi) = af1 + t1 * (rsh + rsh * rb1 * rsh + tsh * rf2 * tsh) * abd1;
    1257          10 :                                     state.dataWindowManager->solabsPhi(2, IPhi) = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * afd2;
    1258             :                                 } // End of loop over incidence angles
    1259             : 
    1260             :                                 // Front incident solar, diffuse, between-glass shade, NGlass = 2
    1261             : 
    1262           1 :                                 state.dataConstruction->Construct(ConstrNum).TransDiff = td1 * (tsh + rsh * rb1 * tsh + tsh * rb2 * rsh) * td2;
    1263           1 :                                 state.dataConstruction->Construct(ConstrNum).TransDiffVis =
    1264           1 :                                     td1v * (tshv + rshv * rb1v * tshv + tshv * rb2v * rshv) * td2v;
    1265           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffShade = td1 * (ash + rsh * rb1 * ash + tsh * rf2 * ash);
    1266           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(1) = afd1 + td1 * (rsh + tsh * rb2 * tsh) * abd1;
    1267           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(2) = td1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * afd2;
    1268           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront =
    1269           1 :                                     rf1 + td1 * (rsh + rsh * rb1 * rsh + tsh * rf2 * tsh) * td1;
    1270           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront =
    1271           1 :                                     rf1v + td1v * (rshv + rshv * rb1v * rshv + tshv * rf2v * tshv) * td1v;
    1272             : 
    1273             :                                 // Back incident solar, diffuse, between-glass shade, NGlass = 2
    1274             : 
    1275           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = td2 * (ash + rsh * rf2 * ash + tsh * rb1 * ash);
    1276           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(1) = td2 * (tsh + rsh * rf2 * tsh + tsh * rb1 * rsh) * abd1;
    1277           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(2) =
    1278           1 :                                     abd2 + td2 * (rsh + rsh * rf2 * rsh + tsh * rb1 * tsh) * afd2;
    1279           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack =
    1280           1 :                                     rb2 + td2 * (rsh + rsh * rf2 * rsh + tsh * rb1 * tsh) * td2;
    1281           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack =
    1282           1 :                                     rb2v + td2v * (rshv + rshv * rf2v * rshv + tshv * rb1v * tshv) * td2v;
    1283             : 
    1284             :                             } // End of check if NGlass = 2
    1285             : 
    1286           2 :                             if (NGlass == 3) {
    1287             : 
    1288           1 :                                 td3 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(3);
    1289           1 :                                 td3v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(3);
    1290           1 :                                 afd3 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(3);
    1291           1 :                                 abd3 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(3);
    1292           1 :                                 rb3 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(3);
    1293           1 :                                 rb3v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(3);
    1294           1 :                                 rf3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
    1295           1 :                                 rf3v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(3);
    1296             : 
    1297             :                                 // Front incident solar, beam, between-glass shade, NGlass = 3
    1298             : 
    1299          11 :                                 for (IPhi = 1; IPhi <= 10; ++IPhi) {
    1300          10 :                                     t1 = tBareSolPhi(1, IPhi);
    1301          10 :                                     t1v = tBareVisPhi(1, IPhi);
    1302          10 :                                     t2 = tBareSolPhi(2, IPhi);
    1303          10 :                                     t2v = tBareVisPhi(2, IPhi);
    1304          10 :                                     af1 = afBareSolPhi(1, IPhi);
    1305          10 :                                     af2 = afBareSolPhi(2, IPhi);
    1306          10 :                                     ab1 = abBareSolPhi(1, IPhi);
    1307          10 :                                     ab2 = abBareSolPhi(2, IPhi);
    1308          10 :                                     rbmf2 = max(0.0, 1.0 - (t2 + af2));
    1309             : 
    1310          10 :                                     state.dataWindowManager->tsolPhi(IPhi) =
    1311          10 :                                         t1 * t2 * (tsh + tsh * rf3 * rsh + rsh * td2 * rb1 * td2 * tsh + rsh * rb2 * tsh) * td3;
    1312          10 :                                     state.dataWindowManager->tvisPhi(IPhi) =
    1313          10 :                                         t1v * t2v * (tshv + tshv * rf3v * rshv + rshv * td2v * rb1v * td2v * tshv + rshv * rb2v * tshv) * td3v;
    1314          10 :                                     state.dataWindowManager->solabsShadePhi(IPhi) = t1 * t2 * (1 + rsh * td2 * rb1 * td2 + rsh * rb2) * ash;
    1315          10 :                                     state.dataWindowManager->solabsPhi(1, IPhi) =
    1316          10 :                                         af1 + rbmf2 * ab1 + t1 * t2 * rsh * (1 + rf3 * tsh + rb2 * rsh + td2 * rb1 * td2 * rsh) * td2 * abd1;
    1317          10 :                                     state.dataWindowManager->solabsPhi(2, IPhi) =
    1318          10 :                                         t1 * af2 + t1 * t2 * ((rsh + tsh * rf3 * tsh + rsh * rb2 * rsh) * abd2 + rsh * td2 * rb1 * afd2);
    1319          10 :                                     state.dataWindowManager->solabsPhi(3, IPhi) =
    1320          10 :                                         t1 * t2 * (tsh + rsh * (rb2 * tsh + td2 * rb2 * td2 * tsh + rf3 * rsh)) * afd3;
    1321             :                                 } // End of loop over incidence angle
    1322             : 
    1323             :                                 // Front incident solar, diffuse, between-glass shade, NGlass = 3
    1324             : 
    1325           1 :                                 state.dataConstruction->Construct(ConstrNum).TransDiff =
    1326           1 :                                     td1 * td2 * (tsh + rsh * td2 * rb1 * td2 * tsh + rsh * rb2 * tsh + tsh * rf3 * rsh) * td3;
    1327           1 :                                 state.dataConstruction->Construct(ConstrNum).TransDiffVis =
    1328           1 :                                     td1v * td2v * (tshv + rshv * td2v * rb1v * td2v * tshv + rshv * rb2v * tshv + tshv * rf3v * rshv) * td3v;
    1329           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffShade =
    1330           1 :                                     td1 * td2 * (ash * (1 + rsh * td2 * rb1 * td2 + rsh * rb2 * ash) + tsh * rf3 * ash);
    1331           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(1) =
    1332           1 :                                     afd1 + td1 * (rf2 + td2 * (rsh + rsh * rb2 * rsh + tsh * rf3 * tsh + rsh * td2 * rb1 * td2 * rsh) * td2) * abd1;
    1333           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(2) =
    1334           1 :                                     td1 * (afd2 + td2 * (rsh + rsh * rb2 * rsh + tsh * rf3 * tsh) * abd2);
    1335           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiff(3) =
    1336           1 :                                     td1 * td2 * (tsh + rsh * rb2 * tsh + rsh * td2 * rb1 * td2 * tsh + tsh * rf3 * rsh) * afd3;
    1337           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront =
    1338           2 :                                     rf1 + td1 * rf2 * td1 +
    1339           1 :                                     td1 * td2 * (rsh + tsh * rf3 * tsh + rsh * rb2 * rsh + rsh * td2 * rb1 * td2 * rsh) * td2 * td1;
    1340           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront =
    1341           2 :                                     rf1v + td1v * rf2v * td1v +
    1342           1 :                                     td1v * td2v * (rshv + tshv * rf3v * tshv + rshv * rb2v * rshv + rshv * td2v * rb1v * td2v * rshv) * td2v * td1v;
    1343             : 
    1344             :                                 // Back incident solar, diffuse, between-glass shade, NGlass = 3
    1345             : 
    1346           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade =
    1347           1 :                                     td3 * ((1 + rsh * rf3) * ash + (tsh * td2 * rb1 * td2 + tsh * rb2) * ash);
    1348           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(1) =
    1349           1 :                                     td3 * (tsh + rsh * rf3 * tsh + tsh * rb2 * rsh + tsh * td2 * rb1 * td2 * rsh) * td2 * abd1;
    1350           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(2) =
    1351           1 :                                     td3 * ((tsh + rsh * rf3 * tsh) * abd2 + (tsh * td2 * rb1 * td2 + tsh * rb2) * afd2);
    1352           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBack(3) =
    1353           1 :                                     abd3 + td3 * (rsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * afd3;
    1354           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack =
    1355           1 :                                     rb3 + td3 * (rsh + rsh * rf3 * rsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * td3;
    1356           1 :                                 state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack =
    1357           1 :                                     rb3v + td3v * (rshv + rshv * rf3 * rshv + tshv * rb2v * tshv + tshv * td2v * rb1v * td2v * tshv) * td3v;
    1358             : 
    1359             :                             } // End of check if NGlass = 3
    1360             : 
    1361             :                         } // End of check if between-glass shade
    1362             : 
    1363           5 :                         if (BGBlind) {
    1364             : 
    1365           3 :                             if (NGlass == 2) {
    1366             : 
    1367             :                                 // Front incident solar, diffuse, between-glass blind, NGlass = 2
    1368             : 
    1369           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 1) =
    1370           2 :                                     afd1 + td1 * (rfsh + rfsh * rb1 * rfsh + tsh * rb2 * tsh) * abd1;
    1371           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 1) =
    1372           2 :                                     afd1 + td1 * (rfshGnd + rfshGnd * rb1 * rfshGnd + tshGnd * rb2 * tsh) * abd1;
    1373           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 1) =
    1374           2 :                                     afd1 + td1 * (rfshSky + rfshSky * rb1 * rfshSky + tshSky * rb2 * tsh) * abd1;
    1375           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 2) =
    1376           2 :                                     td1 * (tsh + rfsh * rb1 * tsh + tsh * rf2 * rbsh) * afd2;
    1377           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 2) =
    1378           2 :                                     td1 * (tshGnd + rfshGnd * rb1 * tsh + tshGnd * rf2 * rbsh) * afd2;
    1379           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 2) =
    1380           2 :                                     td1 * (tshSky + rfshSky * rb1 * tsh + tshSky * rf2 * rbsh) * afd2;
    1381           2 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) =
    1382           2 :                                     td1 * (afsh + rfsh * rb1 * afsh + tsh * rf2 * absh);
    1383           2 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
    1384           2 :                                     td1 * (afshGnd + rfsh * rb1 * afsh + tshGnd * rf2 * absh);
    1385           2 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
    1386           2 :                                     td1 * (afshSky + rfsh * rb1 * afsh + tshSky * rf2 * absh);
    1387           2 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) =
    1388           2 :                                     td1 * (tsh + rfsh * rb1 * tsh + tsh * rb2 * rbsh) * td2;
    1389           2 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) =
    1390           2 :                                     td1 * (tshGnd + rfsh * rb1 * tshGnd + tshGnd * rb2 * rbsh) * td2;
    1391           2 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) =
    1392           2 :                                     td1 * (tshSky + rfsh * rb1 * tshSky + tshSky * rb2 * rbsh) * td2;
    1393           2 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) =
    1394           2 :                                     td1v * (tshv + rfshv * rb1v * tshv + tshv * rb2v * rbshv) * td2v;
    1395           2 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
    1396           2 :                                     rf1 + td1 * (rfsh + rfsh * rb1 * rfsh + tsh * rf2 * tsh) * td1;
    1397           2 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
    1398           2 :                                     rf1v + td1v * (rfshv + rfshv * rb1v * rfshv + tshv * rf2v * tshv) * td1v;
    1399             : 
    1400             :                                 // Back incident solar, diffuse, between-glass blind, NGlass = 2
    1401             : 
    1402           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 1) =
    1403           2 :                                     td2 * (tsh + rbsh * rf2 * tsh + tsh * rb1 * rfsh) * abd1;
    1404           2 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 2) =
    1405           2 :                                     abd2 + td2 * (rbsh + rbsh * rf2 * rbsh + tsh * rb1 * tsh) * afd2;
    1406           2 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) =
    1407           2 :                                     td2 * (absh + rbsh * rf2 * absh + tsh * rb1 * afsh);
    1408           2 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
    1409           2 :                                     rb2 + td2 * (rbsh + rbsh * rf2 * rbsh + tsh * rb1 * tsh) * td2;
    1410           2 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
    1411           2 :                                     rb2v + td2v * (rbshv + rbshv * rf2v * rbshv + tshv * rb1v * tshv) * td2v;
    1412             : 
    1413             :                             } // End of check if NGlass = 2
    1414             : 
    1415           3 :                             if (NGlass == 3) {
    1416             : 
    1417           1 :                                 td3 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(3);
    1418           1 :                                 td3v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(3);
    1419           1 :                                 afd3 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(3);
    1420           1 :                                 abd3 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(3);
    1421           1 :                                 rb3 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(3);
    1422           1 :                                 rb3v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(3);
    1423           1 :                                 rf3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
    1424           1 :                                 rf3v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(3);
    1425             : 
    1426             :                                 // Front incident solar, diffuse, between-glass blind, NGlass = 3
    1427             : 
    1428           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 1) =
    1429           1 :                                     afd1 +
    1430           1 :                                     td1 * (rf2 + td2 * (rfsh + rfsh * rb2 * rfsh + tsh * rf3 * tsh + rfsh * td2 * rb1 * td2 * rfsh) * td2) * abd1;
    1431           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 1) =
    1432           1 :                                     afd1 +
    1433           1 :                                     td1 *
    1434           2 :                                         (rf2 + td2 * (rfshGnd + rfshGnd * rb2 * rfsh + tshGnd * rf3 * tsh + rfshGnd * td2 * rb1 * td2 * rfsh) * td2) *
    1435             :                                         abd1;
    1436           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 1) =
    1437           1 :                                     afd1 +
    1438           1 :                                     td1 *
    1439           2 :                                         (rf2 + td2 * (rfshSky + rfshSky * rb2 * rfsh + tshSky * rf3 * tsh + rfshSky * td2 * rb1 * td2 * rfsh) * td2) *
    1440             :                                         abd1;
    1441           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 2) =
    1442           1 :                                     td1 * (afd2 + td2 * (rfsh + rfsh * rb2 * rfsh + tsh * rf3 * tsh) * abd2);
    1443           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 2) =
    1444           1 :                                     td1 * (afd2 + td2 * (rfshGnd + rfshGnd * rb2 * rfsh + tshGnd * rf3 * tsh) * abd2);
    1445           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 2) =
    1446           1 :                                     td1 * (afd2 + td2 * (rfshSky + rfshSky * rb2 * rfsh + tshSky * rf3 * tsh) * abd2);
    1447           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 3) =
    1448           1 :                                     td1 * td2 * (tsh + rfsh * rb2 * tsh + rfsh * td2 * rb1 * td2 * tsh + tsh * rf3 * rbsh) * afd3;
    1449           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 3) =
    1450           1 :                                     td1 * td2 * (tshGnd + rfshGnd * rb2 * tsh + rfshGnd * td2 * rb1 * td2 * tsh + tshGnd * rf3 * rbsh) * afd3;
    1451           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 3) =
    1452           1 :                                     td1 * td2 * (tshSky + rfshSky * rb2 * tsh + rfshSky * td2 * rb1 * td2 * tsh + tshSky * rf3 * rbsh) * afd3;
    1453           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) =
    1454           1 :                                     td1 * td2 * (afsh * (1 + rfsh * td2 * rb1 * td2) + rfsh * rb2 * afsh + tsh * rf3 * absh);
    1455           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
    1456           1 :                                     td1 * td2 * (afshGnd + afsh * rfsh * (td2 * rb1 * td2 + rb2) + tshGnd * rf3 * absh);
    1457           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
    1458           1 :                                     td1 * td2 * (afshSky + afsh * rfsh * (td2 * rb1 * td2 + rb2) + tshSky * rf3 * absh);
    1459           1 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) =
    1460           1 :                                     td1 * td2 * (tsh + rfsh * td2 * rb1 * td2 * tsh + rfsh * rb2 * tsh + tsh * rf3 * rbsh) * td3;
    1461           1 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) =
    1462           1 :                                     td1 * td2 * (tshGnd + rfsh * td2 * rb1 * td2 * tshGnd + rfsh * rb2 * tshGnd + tshGnd * rf3 * rbsh) * td3;
    1463           1 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) =
    1464           1 :                                     td1 * td2 * (tshSky + rfsh * td2 * rb1 * td2 * tshSky + rfsh * rb2 * tshSky + tshSky * rf3 * rbsh) * td3;
    1465           1 :                                 state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) =
    1466           1 :                                     td1v * td2v * (tshv + rfshv * td2v * rb1v * td2v * tshv + rfshv * rb2v * tshv + tshv * rf3v * rbshv) * td3v;
    1467           1 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
    1468           2 :                                     rf1 + td1 * rf2 * td1 +
    1469           1 :                                     td1 * td2 * (rfsh + tsh * rf3 * tsh + rfsh * rb2 * rfsh + rfsh * td2 * rb1 * td2 * rfsh) * td2 * td1;
    1470           1 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
    1471           2 :                                     rf1v + td1v * rf2v * td1v +
    1472           1 :                                     td1v * td2v * (rfshv + tshv * rf3v * tshv + rfshv * rb2v * rfshv + rfshv * td2v * rb1v * td2v * rfshv) * td2v *
    1473             :                                         td1v;
    1474             : 
    1475             :                                 // Back incident solar, diffuse, between-glass blind, NGlass = 3
    1476             : 
    1477           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 1) =
    1478           1 :                                     td3 * (tsh + rbsh * rf3 * tsh + tsh * rb2 * rfsh + tsh * td2 * rb1 * td2 * rfsh) * td2 * abd1;
    1479           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 2) =
    1480           1 :                                     td3 * ((tsh + rbsh * rf3 * tsh) * abd2 + (tsh * td2 * rb1 * td2 + tsh * rb2) * afd2);
    1481           1 :                                 state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 3) =
    1482           1 :                                     abd3 + td3 * (rbsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * afd3;
    1483           1 :                                 state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) =
    1484           1 :                                     td3 * ((1 + rbsh * rf3) * absh + (tsh * td2 * rb1 * td2 + tsh * rb2) * afsh);
    1485           1 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
    1486           1 :                                     rb3 + td3 * (rbsh + rbsh * rf3 * rbsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * td3;
    1487           1 :                                 state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
    1488           1 :                                     rb3v + td3v * (rbshv + rbshv * rf3v * rbshv + tshv * rb2v * tshv + tshv * td2v * rb1v * td2v * tshv) * td3v;
    1489             : 
    1490             :                             } // End of check if NGlass = 3
    1491             : 
    1492             :                         } // End of check if between-glass blind
    1493             : 
    1494             :                     } // End of check if between-glass shade or blind
    1495             : 
    1496             :                     // Continue loop over slat angles only for blinds with variable slat angle
    1497         101 :                     if (ShadeOn || ScreenOn) break;
    1498          70 :                     if (BlindOn) {
    1499          70 :                         if (state.dataHeatBal->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
    1500             :                     }
    1501             :                 } // End of slat angle loop
    1502             :             }     // End of check if construction has a shade or blind
    1503             : 
    1504             :             // Curve fits to get solar transmittance, reflectance, layer absorptance and
    1505             :             // visible transmittance as polynomials in cosine of incidence angle
    1506             : 
    1507        1311 :             if (!BlindOn && !ScreenOn) { // Bare glass or shade on
    1508        2586 :                 W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1509        1293 :                          state.dataWindowManager->tsolPhi,
    1510             :                          6,
    1511             :                          1,
    1512             :                          TotalIPhi,
    1513        1293 :                          state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
    1514        2586 :                 W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1515        1293 :                          state.dataWindowManager->rfsolPhi,
    1516             :                          6,
    1517             :                          1,
    1518             :                          TotalIPhi,
    1519        1293 :                          state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef);
    1520        2586 :                 W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1521        1293 :                          state.dataWindowManager->rbsolPhi,
    1522             :                          6,
    1523             :                          1,
    1524             :                          TotalIPhi,
    1525        1293 :                          state.dataConstruction->Construct(ConstrNum).ReflSolBeamBackCoef);
    1526        2586 :                 W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1527        1293 :                          state.dataWindowManager->tvisPhi,
    1528             :                          6,
    1529             :                          1,
    1530             :                          TotalIPhi,
    1531        1293 :                          state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
    1532        3236 :                 for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
    1533             :                     // Front absorptance coefficients for glass layers
    1534        1943 :                     state.dataWindowManager->DepVarCurveFit({1, TotalIPhi}) = state.dataWindowManager->solabsPhi(IGlass, {1, TotalIPhi});
    1535        3886 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1536        1943 :                              state.dataWindowManager->DepVarCurveFit,
    1537             :                              6,
    1538             :                              1,
    1539             :                              TotalIPhi,
    1540        1943 :                              state.dataWindowManager->CoeffsCurveFit);
    1541        1943 :                     state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(IGlass) = state.dataWindowManager->CoeffsCurveFit;
    1542             :                     // Back absorptance coefficients for glass layers
    1543        1943 :                     IGlassBack = NGlass - IGlass + 1;
    1544        1943 :                     state.dataWindowManager->DepVarCurveFit({1, TotalIPhi}) = state.dataWindowManager->solabsBackPhi(IGlassBack, {1, TotalIPhi});
    1545        3886 :                     W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1546        1943 :                              state.dataWindowManager->DepVarCurveFit,
    1547             :                              6,
    1548             :                              1,
    1549             :                              TotalIPhi,
    1550        1943 :                              state.dataWindowManager->CoeffsCurveFit);
    1551        1943 :                     state.dataConstruction->Construct(ConstrNum).AbsBeamBackCoef(IGlass) = state.dataWindowManager->CoeffsCurveFit;
    1552             :                 }
    1553             : 
    1554             :                 // To check goodness of fit //Tuned
    1555        1293 :                 auto const &solBeamCoef(state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
    1556        1293 :                 auto const &visBeamCoef(state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
    1557       14223 :                 for (IPhi = 1; IPhi <= TotalIPhi; ++IPhi) {
    1558       12930 :                     tsolPhiFit(IPhi) = 0.0;
    1559       12930 :                     tvisPhiFit(IPhi) = 0.0;
    1560             : 
    1561       12930 :                     Phi = double(IPhi - 1) * 10.0;
    1562       12930 :                     CosPhi = std::cos(Phi * DataGlobalConstants::DegToRadians);
    1563       12930 :                     if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0;
    1564       12930 :                     Real64 cos_pow(1.0);
    1565       90510 :                     for (CoefNum = 1; CoefNum <= 6; ++CoefNum) {
    1566       77580 :                         cos_pow *= CosPhi;
    1567       77580 :                         tsolPhiFit(IPhi) += solBeamCoef(CoefNum) * cos_pow;
    1568       77580 :                         tvisPhiFit(IPhi) += visBeamCoef(CoefNum) * cos_pow;
    1569             :                     }
    1570             :                 }
    1571             :             }
    1572             : 
    1573        1311 :             if (ShadeOn)
    1574          58 :                 W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
    1575          29 :                          state.dataWindowManager->solabsShadePhi,
    1576             :                          6,
    1577             :                          1,
    1578             :                          TotalIPhi,
    1579          29 :                          state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef);
    1580             : 
    1581             :         } // End of loop over constructions
    1582             : 
    1583             :         // Get effective glass and shade/blind emissivities for windows that have interior blind or
    1584             :         // shade. These are used to calculate zone MRT contribution from window when
    1585             :         // interior blind/shade is deployed.
    1586             : 
    1587             :         // Loop for ordinary windows
    1588       44509 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    1589       43741 :             if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue;
    1590       42185 :             if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow) continue;
    1591        5973 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) continue; // Irrelevant for Complex Fen
    1592        5973 :             if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) continue; // not required
    1593        5970 :             ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
    1594        5970 :             if (ConstrNumSh == 0) continue;
    1595         141 :             TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers;
    1596         141 :             IntShade = false;
    1597         141 :             IntBlind = false;
    1598         141 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)).Group ==
    1599             :                 DataHeatBalance::MaterialGroup::Shade) {
    1600          48 :                 IntShade = true;
    1601          48 :                 ShadeLayPtr = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay);
    1602             :             }
    1603         141 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)).Group ==
    1604             :                 DataHeatBalance::MaterialGroup::WindowBlind) {
    1605          26 :                 IntBlind = true;
    1606          26 :                 BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)).BlindDataPtr;
    1607             :             }
    1608             : 
    1609         141 :             if (IntShade || IntBlind) {
    1610         112 :                 for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
    1611         110 :                     if (IntShade || IntBlind) {
    1612         110 :                         EpsGlIR =
    1613         110 :                             state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay - 1)).AbsorpThermalBack;
    1614         110 :                         RhoGlIR = 1 - EpsGlIR;
    1615             :                     }
    1616         110 :                     if (IntShade) {
    1617          48 :                         TauShIR = state.dataMaterial->Material(ShadeLayPtr).TransThermal;
    1618          48 :                         EpsShIR = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
    1619          48 :                         RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
    1620          48 :                         state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1) =
    1621          48 :                             EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR));
    1622          48 :                         state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(1) = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR);
    1623             :                     }
    1624         110 :                     if (IntBlind) {
    1625          62 :                         TauShIR = state.dataHeatBal->Blind(BlNum).IRFrontTrans(ISlatAng);
    1626          62 :                         EpsShIR = state.dataHeatBal->Blind(BlNum).IRBackEmiss(ISlatAng);
    1627          62 :                         RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
    1628          62 :                         state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(ISlatAng) =
    1629          62 :                             EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR));
    1630          62 :                         state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(ISlatAng) = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR);
    1631             :                     }
    1632             :                     // Loop over remaining slat angles only if blind with movable slats
    1633         110 :                     if (IntShade) break; // Loop over remaining slat angles only if blind
    1634          62 :                     if (IntBlind) {
    1635          62 :                         if (state.dataHeatBal->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
    1636             :                     }
    1637             :                 } // End of slat angle loop
    1638             :             }     // End of check if interior shade or interior blind
    1639             :         }         // End of surface loop
    1640             : 
    1641       44509 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    1642       43741 :             if (state.dataSurface->Surface(SurfNum).Construction <= 0) continue;
    1643       42199 :             if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow) continue;
    1644        5973 :             ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    1645             :             // Total thickness of glazing system (used in calculation of inside reveal reflection/absorption
    1646        5973 :             state.dataSurface->SurfWinTotGlazingThickness(SurfNum) = 0.0;
    1647       15982 :             for (LayNum = 1; LayNum <= state.dataConstruction->Construct(ConstrNum).TotLayers; ++LayNum) {
    1648       10009 :                 state.dataSurface->SurfWinTotGlazingThickness(SurfNum) +=
    1649       10009 :                     state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(LayNum)).Thickness;
    1650             :             }
    1651             :             // Sine and cosine of azimuth and tilt
    1652             :             //    SurfaceWindow(SurfNum)%SinAzim = Surface(SurfNum)%SinAzim
    1653             :             //    SurfaceWindow(SurfNum)%CosAzim = Surface(SurfNum)%CosAzim
    1654             :             //    SurfaceWindow(SurfNum)%SinTilt = Surface(SurfNum)%SinTilt
    1655             :             //    SurfaceWindow(SurfNum)%CosTilt = Surface(SurfNum)%CosTilt
    1656             :             //    ! Outward normal unit vector (pointing away from room)
    1657             :             //    SurfaceWindow(SurfNum)%OutNormVec(1) = Surface(SurfNum)%OutNormVec(1)
    1658             :             //    SurfaceWindow(SurfNum)%OutNormVec(2) = Surface(SurfNum)%OutNormVec(2)
    1659             :             //    SurfaceWindow(SurfNum)%OutNormVec(3) = Surface(SurfNum)%OutNormVec(3)
    1660             :             //    write(outputfiledebug,*) 'window='//TRIM(surface(SurfNum)%name)
    1661             :             //    write(outputfiledebug,*) '  swindow%outnormvec=',surfacewindow(SurfNum)%outnormvec
    1662             :             //    write(outputfiledebug,*) '  surface%outnormvec=',surface(SurfNum)%outnormvec
    1663             :             // Window center
    1664        5973 :             Rectangle = false;
    1665        5973 :             Triangle = false;
    1666        5973 :             if (state.dataSurface->Surface(SurfNum).Sides == 3) Triangle = true;
    1667        5973 :             if (state.dataSurface->Surface(SurfNum).Sides == 4) Rectangle = true;
    1668        5973 :             if (Rectangle) {
    1669             :                 // Vertices of window (numbered counter-clockwise starting at upper left as viewed from inside of room).
    1670             :                 // Assumes original vertices are numbered counter-clockwise from upper left as viewed from outside.
    1671        5971 :                 W3 = state.dataSurface->Surface(SurfNum).Vertex(2);
    1672        5971 :                 W2 = state.dataSurface->Surface(SurfNum).Vertex(3);
    1673        5971 :                 W1 = state.dataSurface->Surface(SurfNum).Vertex(4);
    1674           2 :             } else if (Triangle) {
    1675           2 :                 W3 = state.dataSurface->Surface(SurfNum).Vertex(2);
    1676           2 :                 W2 = state.dataSurface->Surface(SurfNum).Vertex(3);
    1677           2 :                 W1 = state.dataSurface->Surface(SurfNum).Vertex(1);
    1678             :             }
    1679        5973 :             W21 = W1 - W2;
    1680        5973 :             W23 = W3 - W2;
    1681        5973 :             if (Rectangle) {
    1682        5971 :                 state.dataSurface->SurfaceWindow(SurfNum).WinCenter = W2 + (W23 + W21) / 2.0;
    1683           2 :             } else if (Triangle) {
    1684           2 :                 state.dataSurface->SurfaceWindow(SurfNum).WinCenter = W2 + (W23 + W21) / 3.0;
    1685             :             }
    1686             :         } // End of surface loop
    1687             : 
    1688         768 :         ReportGlass(state);
    1689         768 :     }
    1690             : 
    1691             :     //*****************************************************************************************
    1692             : 
    1693         768 :     void W5InitGlassParameters(EnergyPlusData &state)
    1694             :     {
    1695             :         // Initializes variables used in the window optical and thermal calculation.
    1696             : 
    1697             :         int ConstrNum;        // Construction number
    1698             :         int SurfNum;          // Surface number
    1699             :         int IPhi;             // Angle of incidence counter
    1700             :         int FrDivNum;         // Pointer to frame/divider
    1701             :         Real64 FrWidth;       // Window frame width {m}
    1702             :         Real64 FrEdgeWidth;   // Frame edge width {m}
    1703             :         Real64 DivWidth;      // Window divider width {m}
    1704             :         Real64 DivEdgeWidth;  // Divider edge width {m}
    1705             :         Real64 GlHeight;      // Height of glazed part of window {m}
    1706             :         Real64 GlWidth;       // Width of glazed part of window {m}
    1707             :         int NumHorDividers;   // Number of horizontal divider elements
    1708             :         int NumVertDividers;  // Number of vertical divider elements
    1709             :         int BaseSurfNum;      // Base surface number
    1710             :         int MatNum;           // Material number
    1711             :         int DifOverrideCount; // Count the number of SolarDiffusing material overrides
    1712             : 
    1713        6616 :         for (ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) {
    1714        5848 :             if (state.dataConstruction->Construct(ConstrNum).FromWindow5DataFile) continue;
    1715        5843 :             if (state.dataConstruction->Construct(ConstrNum).WindowTypeBSDF) continue;
    1716        5830 :             state.dataConstruction->Construct(ConstrNum).TransDiff = 0.0;
    1717        5830 :             state.dataConstruction->Construct(ConstrNum).TransDiffVis = 0.0;
    1718        5830 :             state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = 0.0;
    1719        5830 :             state.dataConstruction->Construct(ConstrNum).ShadeAbsorpThermal = 0.0;
    1720        5830 :             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack = 0.0;
    1721        5830 :             state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront = 0.0;
    1722        5830 :             state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront = 0.0;
    1723        5830 :             state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef = 0.0;
    1724        5830 :             state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef = 0.0;
    1725        5830 :             state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef = 0.0;
    1726        5830 :             state.dataConstruction->Construct(ConstrNum).ReflSolBeamBackCoef = 0.0;
    1727        5830 :             state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef = 0.0;
    1728        5830 :             state.dataConstruction->Construct(ConstrNum).AbsDiff = 0.0;
    1729        5830 :             state.dataConstruction->Construct(ConstrNum).AbsDiffBack = 0.0;
    1730       46812 :             for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) {
    1731      286874 :                 for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) {
    1732      245892 :                     state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamCoef(Layer)(index) = 0.0;
    1733      245892 :                     state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamBackCoef(Layer)(index) = 0.0;
    1734             :                 }
    1735             :             }
    1736             :         }
    1737             : 
    1738       44509 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    1739             :             // For a window with shading device, get number of shaded construction and, if window
    1740             :             // has a blind (interior, exterior or between glass), get blind data pointer.
    1741             : 
    1742       43741 :             if (state.dataSurface->Surface(SurfNum).HasShadeControl) {
    1743         278 :                 for (int winShadCtrl : state.dataSurface->Surface(SurfNum).windowShadingControlList) {
    1744         145 :                     WinShadingType ShadingType = state.dataSurface->WindowShadingControl(winShadCtrl).ShadingType;
    1745         145 :                     if (ShadingType == WinShadingType::ExtScreen) {
    1746             :                         //     Count number of exterior window screens, initialize in InitGlassOpticalCalculations after returning
    1747             :                         //     from this subroutine. The blind structure is initialized first and then the screen structure is initialized.
    1748           8 :                         ++state.dataHeatBal->NumSurfaceScreens;
    1749           8 :                         break; // only need to find the first window shading control since they should be identical
    1750             :                     }
    1751             :                 }
    1752             :             }
    1753             :         }
    1754             : 
    1755             :         // Set some static exterior-window frame and divider SurfaceWindow values
    1756             :         // from values in FrameDivider derived type
    1757       44509 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    1758       43741 :             FrDivNum = state.dataSurface->Surface(SurfNum).FrameDivider;
    1759       43741 :             if (FrDivNum > 0) { // Surface is a window with a frame and/or divider
    1760         381 :                 FrWidth = state.dataSurface->FrameDivider(FrDivNum).FrameWidth;
    1761         381 :                 GlHeight = state.dataSurface->Surface(SurfNum).Height;
    1762         381 :                 GlWidth = state.dataSurface->Surface(SurfNum).Width;
    1763         381 :                 NumVertDividers = state.dataSurface->FrameDivider(FrDivNum).VertDividers;
    1764         381 :                 NumHorDividers = state.dataSurface->FrameDivider(FrDivNum).HorDividers;
    1765         381 :                 BaseSurfNum = state.dataSurface->Surface(SurfNum).BaseSurf;
    1766         381 :                 state.dataSurface->SurfWinFrameConductance(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameConductance;
    1767         381 :                 state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameSolAbsorp;
    1768         381 :                 state.dataSurface->SurfWinFrameVisAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameVisAbsorp;
    1769         381 :                 state.dataSurface->SurfWinFrameEmis(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameEmis;
    1770         381 :                 state.dataSurface->SurfWinFrEdgeToCenterGlCondRatio(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrEdgeToCenterGlCondRatio;
    1771         381 :                 state.dataSurface->SurfWinDividerType(SurfNum) = DataSurfaces::FrameDividerType::DividedLite;
    1772         381 :                 if (state.dataSurface->FrameDivider(FrDivNum).DividerType == DataSurfaces::FrameDividerType::Suspended)
    1773          11 :                     state.dataSurface->SurfWinDividerType(SurfNum) = DataSurfaces::FrameDividerType::Suspended;
    1774         381 :                 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
    1775         381 :                 state.dataSurface->SurfWinDividerConductance(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerConductance;
    1776         381 :                 state.dataSurface->SurfWinDividerSolAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerSolAbsorp;
    1777         381 :                 state.dataSurface->SurfWinDividerVisAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerVisAbsorp;
    1778         381 :                 state.dataSurface->SurfWinDividerEmis(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerEmis;
    1779         381 :                 state.dataSurface->SurfWinDivEdgeToCenterGlCondRatio(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DivEdgeToCenterGlCondRatio;
    1780             : 
    1781         381 :                 state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).OutsideRevealSolAbs;
    1782         381 :                 state.dataSurface->SurfWinInsideSillDepth(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideSillDepth;
    1783         381 :                 state.dataSurface->SurfWinInsideReveal(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideReveal;
    1784         381 :                 state.dataSurface->SurfWinInsideSillSolAbs(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideSillSolAbs;
    1785         381 :                 state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideRevealSolAbs;
    1786             : 
    1787         381 :                 FrEdgeWidth = state.dataSurface->FrameDivider(FrDivNum).FrameEdgeWidth;
    1788         381 :                 DivEdgeWidth = state.dataSurface->FrameDivider(FrDivNum).DividerEdgeWidth;
    1789         381 :                 state.dataSurface->SurfWinFrameEdgeArea(SurfNum) =
    1790         381 :                     2 * FrEdgeWidth * (GlHeight - FrEdgeWidth - NumHorDividers * DivWidth + GlWidth - FrEdgeWidth - NumVertDividers * DivWidth);
    1791         381 :                 state.dataSurface->SurfWinDividerEdgeArea(SurfNum) =
    1792         762 :                     2 * DivEdgeWidth * (NumHorDividers * (GlWidth - 2 * FrEdgeWidth) + NumVertDividers * (GlHeight - 2 * FrEdgeWidth)) -
    1793         381 :                     NumHorDividers * NumVertDividers * (4 * pow_2(DivEdgeWidth) + 4 * FrEdgeWidth * DivWidth);
    1794        1143 :                 state.dataSurface->SurfWinCenterGlArea(SurfNum) = state.dataSurface->Surface(SurfNum).Area -
    1795         762 :                                                                   state.dataSurface->SurfWinFrameEdgeArea(SurfNum) -
    1796         381 :                                                                   state.dataSurface->SurfWinDividerEdgeArea(SurfNum);
    1797         381 :                 state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) =
    1798         762 :                     (state.dataSurface->SurfWinFrameEdgeArea(SurfNum) * state.dataSurface->SurfWinFrEdgeToCenterGlCondRatio(SurfNum) +
    1799         762 :                      state.dataSurface->SurfWinDividerEdgeArea(SurfNum) * state.dataSurface->SurfWinDivEdgeToCenterGlCondRatio(SurfNum) +
    1800         762 :                      state.dataSurface->SurfWinCenterGlArea(SurfNum)) /
    1801         762 :                     (state.dataSurface->SurfWinFrameEdgeArea(SurfNum) + state.dataSurface->SurfWinDividerEdgeArea(SurfNum) +
    1802         381 :                      state.dataSurface->SurfWinCenterGlArea(SurfNum));
    1803             :             }
    1804             :         }
    1805             : 
    1806             :         // Set SolarDiffusing to true for exterior windows that have a construction with an innermost diffusing glass layer
    1807         768 :         DifOverrideCount = 0;
    1808       44509 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    1809       43741 :             state.dataSurface->SurfWinSolarDiffusing(SurfNum) = false;
    1810       93453 :             if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window &&
    1811       49698 :                 state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment && state.dataSurface->SurfWinStormWinConstr(SurfNum) == 0) {
    1812        5956 :                 ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    1813        5956 :                 MatNum = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataConstruction->Construct(ConstrNum).TotLayers);
    1814        5956 :                 if (state.dataMaterial->Material(MatNum).SolarDiffusing) {
    1815           0 :                     if (!state.dataSurface->Surface(SurfNum).HasShadeControl) {
    1816           0 :                         state.dataSurface->SurfWinSolarDiffusing(SurfNum) = true;
    1817             :                     } else { // There is a shading control
    1818           0 :                         if (state.dataSurface->WindowShadingControl(state.dataSurface->Surface(SurfNum).activeWindowShadingControl).ShadingType ==
    1819             :                             WinShadingType::SwitchableGlazing) {
    1820           0 :                             state.dataSurface->SurfWinSolarDiffusing(SurfNum) = true;
    1821             :                         } else {
    1822           0 :                             state.dataSurface->SurfWinSolarDiffusing(SurfNum) = false;
    1823           0 :                             ++DifOverrideCount;
    1824           0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    1825           0 :                                 ShowWarningError(
    1826             :                                     state,
    1827           0 :                                     "W5InitGlassParameters: Window=\"" + state.dataSurface->Surface(SurfNum).Name +
    1828             :                                         "\" has interior material with Solar Diffusing=Yes, but existing Window Shading Device sets Diffusing=No.");
    1829             :                             }
    1830             :                         }
    1831             :                     }
    1832             :                 }
    1833             :             }
    1834             :         }
    1835             : 
    1836         768 :         if (DifOverrideCount > 0) {
    1837           0 :             if (!state.dataGlobal->DisplayExtraWarnings) {
    1838           0 :                 ShowWarningError(state,
    1839           0 :                                  format("W5InitGlassParameters: {} Windows had Solar Diffusing=Yes overridden by presence of Window Shading Device.",
    1840           0 :                                         DifOverrideCount));
    1841             :             } else {
    1842           0 :                 ShowMessage(state,
    1843           0 :                             format("W5InitGlassParameters: {} Windows had Solar Diffusing=Yes overridden by presence of Window Shading Device.",
    1844           0 :                                    DifOverrideCount));
    1845             :             }
    1846             :         }
    1847             : 
    1848        8448 :         for (IPhi = 1; IPhi <= 10; ++IPhi) {
    1849        7680 :             state.dataWindowManager->CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * DataGlobalConstants::DegToRadians);
    1850             :         }
    1851         768 :     }
    1852             : 
    1853             :     //****************************************************************************
    1854             :     // WINDOW 5 Optical Calculation Subroutines
    1855             :     //****************************************************************************
    1856             : 
    1857       38720 :     void SystemSpectralPropertiesAtPhi(EnergyPlusData &state,
    1858             :                                        int const iquasi,   // When there is no spectral data, this is the wavelength
    1859             :                                        int const ngllayer, // Number of glass layers in construction
    1860             :                                        Real64 const wlbot, // Lowest and highest wavelength considered
    1861             :                                        Real64 const wltop)
    1862             :     {
    1863             : 
    1864             :         // SUBROUTINE INFORMATION:
    1865             :         //       AUTHOR         Adapted by F.Winkelmann from WINDOW 5
    1866             :         //                      subroutine opcalc
    1867             :         //       DATE WRITTEN   August 1999
    1868             :         //       MODIFIED       na
    1869             :         //       RE-ENGINEERED  na
    1870             : 
    1871             :         // PURPOSE OF THIS SUBROUTINE:
    1872             :         // For a particular angle of incidence, calculates system properties
    1873             :         // for a multi-layer glazing for each wavelength in the solar spectrum.
    1874             :         // Handles the special case of one or more layers that do not have spectral data.
    1875             : 
    1876             :         // Returns, for a particular angle of incidence:
    1877             :         //   stPhi     transmissivity of system at each wavelength in swl
    1878             :         //   srfPhi    front reflectance of system at each wavelength in swl
    1879             :         //   srbPhi    back reflectance of system at each wavelength in swl
    1880             :         //   sabsPhi   absorptance by layer at each wavelength in swl
    1881             : 
    1882       77440 :         Array1D<Real64> sabsPhi(5); // System solar absorptance in each glass layer for
    1883             :         //   particular angle of incidence
    1884             :         int in; // Glass layer counter
    1885             :         int i;
    1886             :         int iwl; // Wavelength counter
    1887             :         int j;
    1888             :         Real64 wl; // Wavelength
    1889             :         //   index to use in tPhi, rfPhi and rbPhi
    1890             : 
    1891             :         // For each glass layer find tPhi, rfPhi, and rbPhi at each wavelength
    1892             : 
    1893       95910 :         for (in = 1; in <= ngllayer; ++in) {
    1894     6176520 :             for (iwl = 1; iwl <= state.dataWindowManager->nume; ++iwl) {
    1895     6119330 :                 wl = state.dataWindowManager->wle[iwl - 1];
    1896     6119330 :                 if (wl < wlbot || wl > wltop) continue;
    1897             :                 // In the following numpt is the number of spectral data points for each layer;
    1898             :                 // numpt = 2 if there is no spectral data for a layer.
    1899     4832690 :                 if (state.dataWindowManager->numpt[in - 1] <= 2) {
    1900     4359990 :                     state.dataWindowManager->tadjPhi[in - 1][iwl - 1] = state.dataWindowManager->tPhi[in - 1][iquasi - 1];
    1901     4359990 :                     state.dataWindowManager->rfadjPhi[in - 1][iwl - 1] = state.dataWindowManager->rfPhi[in - 1][iquasi - 1];
    1902     4359990 :                     state.dataWindowManager->rbadjPhi[in - 1][iwl - 1] = state.dataWindowManager->rbPhi[in - 1][iquasi - 1];
    1903             :                 } else {
    1904             :                     // Interpolate to get properties at the solar spectrum wavelengths
    1905     1418100 :                     state.dataWindowManager->tadjPhi[in - 1][iwl - 1] = Interpolate(
    1906     1418100 :                         state.dataWindowManager->wlt[in - 1], state.dataWindowManager->tPhi[in - 1], state.dataWindowManager->numpt[in - 1], wl);
    1907     1418100 :                     state.dataWindowManager->rfadjPhi[in - 1][iwl - 1] = Interpolate(
    1908     1418100 :                         state.dataWindowManager->wlt[in - 1], state.dataWindowManager->rfPhi[in - 1], state.dataWindowManager->numpt[in - 1], wl);
    1909     1418100 :                     state.dataWindowManager->rbadjPhi[in - 1][iwl - 1] = Interpolate(
    1910     1418100 :                         state.dataWindowManager->wlt[in - 1], state.dataWindowManager->rbPhi[in - 1], state.dataWindowManager->numpt[in - 1], wl);
    1911             :                 }
    1912             :             }
    1913             :         }
    1914             : 
    1915             :         // Calculate system properties at each wavelength
    1916     4181760 :         for (j = 1; j <= state.dataWindowManager->nume; ++j) {
    1917     4143040 :             wl = state.dataWindowManager->wle[j - 1];
    1918     4143040 :             if (wl < wlbot || wl > wltop) continue;
    1919             : 
    1920             :             // Set diagonal of matrix for subroutine SystemPropertiesAtLambdaAndPhi
    1921     8075730 :             for (i = 1; i <= ngllayer; ++i) {
    1922     4832690 :                 state.dataWindowManager->top[i - 1][i - 1] = state.dataWindowManager->tadjPhi[i - 1][j - 1];
    1923     4832690 :                 state.dataWindowManager->rfop[i - 1][i - 1] = state.dataWindowManager->rfadjPhi[i - 1][j - 1];
    1924     4832690 :                 state.dataWindowManager->rbop[i - 1][i - 1] = state.dataWindowManager->rbadjPhi[i - 1][j - 1];
    1925             :             }
    1926             : 
    1927             :             // Calculate glazing system properties
    1928     3243040 :             if (ngllayer == 1) { // Single-layer system
    1929     1832290 :                 state.dataWindowManager->stPhi[j - 1] = state.dataWindowManager->top[0][0];
    1930     1832290 :                 state.dataWindowManager->srfPhi[j - 1] = state.dataWindowManager->rfop[0][0];
    1931     1832290 :                 state.dataWindowManager->srbPhi[j - 1] = state.dataWindowManager->rbop[0][0];
    1932     1832290 :                 sabsPhi(1) = 1.0 - state.dataWindowManager->stPhi[j - 1] - state.dataWindowManager->srfPhi[j - 1];
    1933             :             } else { // Multilayer system
    1934             :                 // Get glazing system properties stPhi, etc., at this wavelength and incidence angle
    1935     2821500 :                 SystemPropertiesAtLambdaAndPhi(state,
    1936             :                                                ngllayer,
    1937     1410750 :                                                state.dataWindowManager->stPhi[j - 1],
    1938     1410750 :                                                state.dataWindowManager->srfPhi[j - 1],
    1939     1410750 :                                                state.dataWindowManager->srbPhi[j - 1],
    1940             :                                                sabsPhi);
    1941             :             }
    1942             : 
    1943     8075730 :             for (i = 1; i <= ngllayer; ++i) {
    1944     4832690 :                 state.dataWindowManager->saPhi(i, j) = sabsPhi(i);
    1945             :             }
    1946             : 
    1947             :         } // End of wavelength loop
    1948       38720 :     }
    1949             : 
    1950             :     //************************************************************************
    1951             : 
    1952     1410750 :     void SystemPropertiesAtLambdaAndPhi(EnergyPlusData &state,
    1953             :                                         int const n, // Number of glass layers
    1954             :                                         Real64 &tt,  // System transmittance
    1955             :                                         Real64 &rft, // System front and back reflectance
    1956             :                                         Real64 &rbt,
    1957             :                                         Array1A<Real64> aft // System absorptance of each glass layer
    1958             :     )
    1959             :     {
    1960             : 
    1961             :         // SUBROUTINE INFORMATION:
    1962             :         //       AUTHOR         Adapted by F. Winkelmann from WINDOW 5
    1963             :         //                      subroutine op
    1964             :         //       DATE WRITTEN   August 1999
    1965             :         //       MODIFIED       na
    1966             :         //       RE-ENGINEERED  na
    1967             : 
    1968             :         // PURPOSE OF THIS SUBROUTINE:
    1969             :         // For a given angle of incidence, finds the overall properties of
    1970             :         // of a series of layers at a particular wavelength
    1971             : 
    1972             :         // Argument array dimensioning
    1973     1410750 :         aft.dim(5);
    1974             : 
    1975             :         int i; // Glass layer counters
    1976             :         int j;
    1977             :         Real64 denom; // Intermediate variables
    1978             :         Real64 denom1;
    1979             :         Real64 denom2;
    1980             :         Real64 t0; // Transmittance, back reflectance and front
    1981             :         Real64 rb0;
    1982             :         Real64 rf0;
    1983             :         //   reflectance variables
    1984             :         Real64 af; // Front and back absorptance variables
    1985             :         Real64 ab;
    1986             : 
    1987             :         // Calculate perimeter elements of rt matrix
    1988     3000400 :         for (i = 1; i <= n - 1; ++i) {
    1989     3373140 :             for (j = i + 1; j <= n; ++j) {
    1990     1783490 :                 denom = 1.0 - state.dataWindowManager->rfop[j - 1][j - 1] * state.dataWindowManager->rbop[i - 1][j - 2];
    1991     1783490 :                 if (denom == 0.0) {
    1992      178349 :                     state.dataWindowManager->top[j - 1][i - 1] = 0.0;
    1993      178349 :                     state.dataWindowManager->rfop[j - 1][i - 1] = 1.0;
    1994      178349 :                     state.dataWindowManager->rbop[i - 1][j - 1] = 1.0;
    1995             :                 } else {
    1996     1605141 :                     state.dataWindowManager->top[j - 1][i - 1] =
    1997     1605141 :                         state.dataWindowManager->top[j - 2][i - 1] * state.dataWindowManager->top[j - 1][j - 1] / denom;
    1998     1605141 :                     state.dataWindowManager->rfop[j - 1][i - 1] =
    1999     3210282 :                         state.dataWindowManager->rfop[j - 2][i - 1] +
    2000     1605141 :                         pow_2(state.dataWindowManager->top[j - 2][i - 1]) * state.dataWindowManager->rfop[j - 1][j - 1] / denom;
    2001     1605141 :                     state.dataWindowManager->rbop[i - 1][j - 1] =
    2002     3210282 :                         state.dataWindowManager->rbop[j - 1][j - 1] +
    2003     1605141 :                         pow_2(state.dataWindowManager->top[j - 1][j - 1]) * state.dataWindowManager->rbop[i - 1][j - 2] / denom;
    2004             :                 }
    2005             :             }
    2006             :         }
    2007             :         // System properties: transmittance, front and back reflectance
    2008     1410750 :         tt = state.dataWindowManager->top[n - 1][0];
    2009     1410750 :         rft = state.dataWindowManager->rfop[n - 1][0];
    2010     1410750 :         rbt = state.dataWindowManager->rbop[0][n - 1];
    2011             : 
    2012             :         // Absorptance in each layer
    2013     4411150 :         for (j = 1; j <= n; ++j) {
    2014     3000400 :             if (j == 1) {
    2015     1410750 :                 t0 = 1.0;
    2016     1410750 :                 rb0 = 0.0;
    2017             :             } else {
    2018     1589650 :                 t0 = state.dataWindowManager->top[j - 2][0];
    2019     1589650 :                 rb0 = state.dataWindowManager->rbop[0][j - 2];
    2020             :             }
    2021             : 
    2022     3000400 :             if (j == n) {
    2023     1410750 :                 rf0 = 0.0;
    2024             :             } else {
    2025     1589650 :                 rf0 = state.dataWindowManager->rfop[n - 1][j];
    2026             :             }
    2027             : 
    2028     3000400 :             af = 1.0 - state.dataWindowManager->top[j - 1][j - 1] - state.dataWindowManager->rfop[j - 1][j - 1];
    2029     3000400 :             ab = 1.0 - state.dataWindowManager->top[j - 1][j - 1] - state.dataWindowManager->rbop[j - 1][j - 1];
    2030     3000400 :             denom1 = 1.0 - state.dataWindowManager->rfop[n - 1][j - 1] * rb0;
    2031     3000400 :             denom2 = 1.0 - state.dataWindowManager->rbop[0][j - 1] * rf0;
    2032             : 
    2033     3000400 :             if (denom1 == 0.0 || denom2 == 0.0) {
    2034      300040 :                 aft(j) = 0.0;
    2035             :             } else {
    2036     2700360 :                 aft(j) = (t0 * af) / denom1 + (state.dataWindowManager->top[j - 1][0] * rf0 * ab) / denom2;
    2037             :             }
    2038             :         }
    2039     1410750 :     }
    2040             : 
    2041             :     //*************************************************************************
    2042             : 
    2043       39320 :     void SolarSprectrumAverage(EnergyPlusData &state,
    2044             :                                Array1A<Real64> p, // Quantity to be weighted by solar spectrum
    2045             :                                Real64 &psol       // Quantity p weighted by solar spectrum
    2046             :     )
    2047             :     {
    2048             : 
    2049             :         // SUBROUTINE INFORMATION:
    2050             :         //       AUTHOR         Adapted by F.Winkelmann from WINDOW 5 subroutine solar
    2051             :         //       DATE WRITTEN   August 1999
    2052             :         //       MODIFIED       na
    2053             :         //       RE-ENGINEERED  na
    2054             : 
    2055             :         // PURPOSE OF THIS SUBROUTINE:
    2056             :         // Calculates average of property p weighted by solar spectral irradiance, e
    2057             : 
    2058             :         // Argument array dimensioning
    2059       39320 :         p.dim(state.dataWindowManager->nume);
    2060             : 
    2061             :         // Locals
    2062             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2063             : 
    2064             :         Real64 up; // Intermediate variables
    2065             :         Real64 down;
    2066             :         int i;       // Wavelength counter
    2067             :         Real64 esol; // Solar spectrum value times delta wavelength
    2068             : 
    2069       39320 :         up = 0.0;
    2070       39320 :         down = 0.0;
    2071             : 
    2072     4207240 :         for (i = 1; i <= state.dataWindowManager->nume - 1; ++i) {
    2073     8335840 :             esol = (state.dataWindowManager->wle[i] - state.dataWindowManager->wle[i - 1]) * 0.5 *
    2074     4167920 :                    (state.dataWindowManager->e[i - 1] + state.dataWindowManager->e[i]);
    2075     4167920 :             up += 0.5 * (p(i) + p(i + 1)) * esol;
    2076     4167920 :             down += esol;
    2077             :         }
    2078             : 
    2079       39320 :         psol = up / down;
    2080       39320 :     }
    2081             : 
    2082       39330 :     Real64 solarSpectrumAverage(EnergyPlusData &state, gsl::span<Real64> p)
    2083             :     {
    2084       39330 :         Real64 num = 0.0;
    2085       39330 :         Real64 denom = 0.0;
    2086     4208310 :         for (int i = 1; i <= state.dataWindowManager->nume - 1; ++i) {
    2087     4168980 :             Real64 const esol = (state.dataWindowManager->wle[i] - state.dataWindowManager->wle[i - 1]) * 0.5 *
    2088     4168980 :                                 (state.dataWindowManager->e[i - 1] + state.dataWindowManager->e[i]);
    2089     4168980 :             num += 0.5 * (p[i - 1] + p[i]) * esol;
    2090     4168980 :             denom += esol;
    2091             :         }
    2092       39330 :         return num / denom; // dangerous, doesn't check for zero denominator
    2093             :     }
    2094             : 
    2095       39330 :     Real64 visibleSpectrumAverage(EnergyPlusData &state, gsl::span<Real64> p)
    2096             :     {
    2097             :         //       AUTHOR         Adapted by F.Winkelmann from WINDOW 5
    2098             :         //                      subroutine w4vis
    2099             :         //       DATE WRITTEN   August 1999
    2100             : 
    2101             :         // Calculates visible average of property p by weighting with solar
    2102             :         // spectral irradiance, e, and photopic response, y30
    2103             : 
    2104       39330 :         Real64 num = 0.0;
    2105       39330 :         Real64 denom = 0.0;
    2106       39330 :         Real64 y30new = 0.0;
    2107       39330 :         Real64 y30ils1 = 0.0;
    2108     4208310 :         for (int i = 2; i <= state.dataWindowManager->nume;
    2109             :              ++i) { // Autodesk:BoundsViolation e|wle|p(i-1) @ i=1: Changed start index from 1 to 2: wle
    2110             :             // values prevented this violation from occurring in practice
    2111             :             // Restrict to visible range
    2112     4168980 :             if (state.dataWindowManager->wle[i - 1] >= 0.37 && state.dataWindowManager->wle[i - 1] <= 0.78) {
    2113     4129650 :                 y30new = Interpolate(
    2114     4129650 :                     state.dataWindowManager->wlt3, state.dataWindowManager->y30, state.dataWindowManager->numt3, state.dataWindowManager->wle[i - 1]);
    2115     1376550 :                 Real64 evis = state.dataWindowManager->e[i - 2] * 0.5 * (y30new + y30ils1) *
    2116     1376550 :                               (state.dataWindowManager->wle[i - 1] - state.dataWindowManager->wle[i - 2]);
    2117     1376550 :                 num += 0.5 * (p[i - 1] + p[i - 2]) * evis;
    2118     1376550 :                 denom += evis;
    2119     1376550 :                 y30ils1 = y30new;
    2120             :             }
    2121             :         }
    2122       39330 :         return num / denom; // dangerous, doesn't check for zero denominator
    2123             :     }
    2124             : 
    2125     2794650 :     Real64 Interpolate(gsl::span<Real64> x, // Array of data points for independent variable
    2126             :                        gsl::span<Real64> y, // Array of data points for dependent variable
    2127             :                        int const npts,      // Number of data pairs
    2128             :                        Real64 const xin     // Given value of x
    2129             :     )
    2130             :     {
    2131             : 
    2132             :         // SUBROUTINE INFORMATION:
    2133             :         //       AUTHOR         Adapted by F.Winkelmann from WINDOW 5 subroutine interp
    2134             :         //       DATE WRITTEN   August 1999
    2135             :         //       MODIFIED       na
    2136             :         //       RE-ENGINEERED  na
    2137             : 
    2138             :         // PURPOSE OF THIS SUBROUTINE:
    2139             :         // Linearly interpolates between data points. Outputs yout, interpolated
    2140             :         // value of y corresponding to xin
    2141             : 
    2142   169381500 :         for (int i = 1; i <= npts; ++i) {
    2143   169368720 :             if (xin <= x[i - 1]) {
    2144     2781870 :                 if (i - 1 == 0) {
    2145       91560 :                     return y[0];
    2146             :                 } else {
    2147     2690310 :                     return y[i - 2] + (y[i - 1] - y[i - 2]) * (xin - x[i - 2]) / (x[i - 1] - x[i - 2]);
    2148             :                 }
    2149             :             }
    2150             :         }
    2151             : 
    2152             :         // Past the end of the array, so return endpoint
    2153       12780 :         return y[npts - 1];
    2154             :     }
    2155             : 
    2156             :     //***********************************************************************************
    2157             :     // Window Thermal Calculation Subroutines
    2158             :     //***********************************************************************************
    2159             : 
    2160    22760394 :     void CalcWindowHeatBalance(EnergyPlusData &state,
    2161             :                                int const SurfNum,          // Surface number
    2162             :                                Real64 const HextConvCoeff, // Outside air film conductance coefficient
    2163             :                                Real64 &SurfInsideTemp,     // Inside window surface temperature
    2164             :                                Real64 &SurfOutsideTemp     // Outside surface temperature (C)
    2165             :     )
    2166             :     {
    2167             :         // SUBROUTINE INFORMATION:
    2168             :         //       AUTHOR         S. Vidanovic
    2169             :         //       DATE WRITTEN   June 2016
    2170             :         //       MODIFIED       na
    2171             :         //       RE-ENGINEERED  na
    2172             :         //
    2173             :         // PURPOSE OF THIS SUBROUTINE:
    2174             :         // Subroutine to direct whether to use exterior or interior window routines
    2175    22760394 :         if (state.dataGlobal->KickOffSizing || state.dataGlobal->KickOffSimulation) return;
    2176             : 
    2177    22657349 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    2178        4032 :             CalcWindowHeatBalanceExternalRoutines(state, SurfNum, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp);
    2179             :         } else {
    2180    22653317 :             CalcWindowHeatBalanceInternalRoutines(state, SurfNum, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp);
    2181             :         }
    2182             :     }
    2183             : 
    2184    22653317 :     void CalcWindowHeatBalanceInternalRoutines(EnergyPlusData &state,
    2185             :                                                int const SurfNum,          // Surface number
    2186             :                                                Real64 const HextConvCoeff, // Outside air film conductance coefficient
    2187             :                                                Real64 &SurfInsideTemp,     // Inside window surface temperature
    2188             :                                                Real64 &SurfOutsideTemp     // Outside surface temperature (C)
    2189             :     )
    2190             :     {
    2191             : 
    2192             :         // SUBROUTINE INFORMATION:
    2193             :         //       AUTHOR         F. Winkelmann
    2194             :         //       DATE WRITTEN   November 1999
    2195             :         //       MODIFIED       FW, July 2000 (call better solution method)
    2196             :         //                      FW, June 2001 (handle window blinds)
    2197             :         //                      FW, Dec  2002 (add between-glass shades and blinds)
    2198             :         //                      FW, Mar  2003 (extend condensation flag to airflow windows)
    2199             :         //                      CC, Jul  2003 (set the reference temperatures for inside surface heat balance
    2200             :         //                                    depending on convection algorithms and/or air models used)
    2201             :         //                      FW, Sep  2003 (increment ZoneWinHeatGain only for exterior windows)
    2202             :         //                      RR, May  2006 (add exterior window screen)
    2203             :         //                      TH, Dec  2008 (add thermochromic windows)
    2204             :         //       RE-ENGINEERED  na
    2205             : 
    2206             :         // PURPOSE OF THIS SUBROUTINE:
    2207             :         // Sets up information needed to calculate the window thermal behavior.
    2208             :         // Calls SolveForWindowTemperatures, which calculates the inside and outside
    2209             :         // face temperature of each glass layer by solving the heat balance
    2210             :         // equations on each face. Also calls CalcWinFrameAndDividerTemps,
    2211             :         // which calculates the outside and inside face temperatures of the
    2212             :         // window frame and divider if either of these are present.
    2213             :         // The resulting inside face temperature of the inner glass pane and the
    2214             :         // inside surface temperatures of frame and divider are used in the zone
    2215             :         // heat balance calculation. The inside face temperature of an interior shade
    2216             :         // or blind, if present, and the natural convection air flow between the
    2217             :         // shade/blind and inside glass face also appear in the zone heat balance calculation.
    2218             :         // The logical variable NRSolution is currently set to false, which means
    2219             :         // that the Newton-Raphson solution method for the glass layer heat balance
    2220             :         // is not used (because it sometimes didn't converge for 3- and 4-pane
    2221             :         // constructions with one or more low-emissivity layers). Instead, a more
    2222             :         // robust solution method is used that successively solves linearized heat
    2223             :         // balance equations until convergence is reached (see SolveForWindowTemperatures).
    2224             :         // CalcWindowHeatBalance is called by CalcHeatBalanceInsideSurface once each
    2225             :         // time step for each window.
    2226             : 
    2227             :         // Using/Aliasing
    2228             :         using namespace DataBSDFWindow;
    2229             :         using Psychrometrics::PsyCpAirFnW;
    2230             :         using Psychrometrics::PsyTdpFnWPb;
    2231             :         // unused0909  USE DataEnvironment, ONLY: CurMnDyHr
    2232             :         using ScheduleManager::GetCurrentScheduleValue;
    2233             :         using WindowComplexManager::CalcComplexWindowThermal;
    2234             :         using WindowEquivalentLayer::EQLWindowSurfaceHeatBalance;
    2235             : 
    2236             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2237             :         // (temperature of innermost face) [C]
    2238             : 
    2239             :         int BlNum;      // Window blind number
    2240             :         int SurfNumAdj; // An interzone surface's number in the adjacent zone
    2241             :         int ZoneNumAdj; // An interzone surface's adjacent zone number
    2242             :         int TotLay;     // Total number of layers in a construction
    2243             :         //   (sum of solid layers and gap layers)
    2244             :         int TotGlassLay;          // Total number of glass layers in a construction
    2245             :         int Lay;                  // Layer number
    2246             :         int LayPtr;               // Material number for a layer
    2247             :         int IGlass;               // glass layer number (1,2,3,...)
    2248             :         int IGap;                 // Gap layer number (1,2,...)
    2249             :         int IMix;                 // Gas number in a mixture of gases
    2250             :         int ICoeff;               // Gas property index (1,2,3)
    2251             :         WinShadingType ShadeFlag; // Flag indicating whether shade or blind is on, and shade/blind position
    2252             :         int k;                    // Layer counter
    2253             :         // REAL(r64) :: tsky                         ! Sky temperature [K]
    2254             :         int ShadeLayPtr; // Material number corresponding to a shade layer
    2255             :         Real64 dth1;     // Temperature difference across glass layers [K]
    2256             :         Real64 dth2;
    2257             :         Real64 dth3;
    2258             :         Real64 dth4;
    2259             :         Real64 EffShBlEmiss;    // Effective interior shade or blind emissivity
    2260             :         Real64 EffGlEmiss;      // Effective inside glass emissivity when interior shade or blind
    2261             :         Real64 RoomHumRat;      // Room air humidity ratio
    2262             :         Real64 RoomDewPoint;    // Room air dewpoint temperature (C)
    2263             :         Real64 InsideGlassTemp; // Temperature of room side of innermost glass layer (C)
    2264             :         Real64 Tleft;           // For airflow windows, temperature of the glass faces adjacent
    2265             :         Real64 Tright;
    2266             : 
    2267             :         Real64 SrdSurfTempAbs; // Absolute temperature of a surrounding surface
    2268             :         Real64 SrdSurfViewFac; // View factor of a surrounding surface
    2269             :         Real64 OutSrdIR;       // LWR from surrouding srfs
    2270             : 
    2271             :         // New variables for thermochromic windows calc
    2272             :         Real64 locTCSpecTemp;  // The temperature corresponding to the specified optical properties of the TC layer
    2273             :         Real64 locTCLayerTemp; // TC layer temperature at each time step. C
    2274             :         int i;
    2275    22653317 :         auto &deltaTemp = state.dataWindowManager->deltaTemp;
    2276    22653317 :         auto &iMinDT = state.dataWindowManager->iMinDT;
    2277    22653317 :         auto &IDConst = state.dataWindowManager->IDConst;
    2278    22653317 :         Real64 dT0(0.0);
    2279    22653317 :         Real64 dT1(0.0);
    2280             :         Real64 SurfOutsideEmiss; // temporary for result of outside surface emissivity
    2281             :         Real64 Tsout;            // temporary for result of outside surface temp in Kelvin
    2282             :         int temp;
    2283             : 
    2284             :         // Shorthand references
    2285    22653317 :         auto &window(state.dataSurface->SurfaceWindow(SurfNum));
    2286    22653317 :         auto &surface(state.dataSurface->Surface(SurfNum));
    2287    22653317 :         int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    2288    22653317 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone);
    2289             : 
    2290    22653317 :         if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
    2291             : 
    2292       37968 :             temp = 0;
    2293             : 
    2294             :             // Simon: Complex fenestration state works only with tarcog
    2295       37968 :             CalcComplexWindowThermal(
    2296             :                 state, SurfNum, temp, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp, SurfOutsideEmiss, DataBSDFWindow::Condition::Invalid);
    2297             : 
    2298       37968 :             TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    2299       37968 :             state.dataWindowManager->ngllayer =
    2300       37968 :                 state.dataConstruction->Construct(ConstrNum).TotSolidLayers; // Simon: This is necessary to keep for frame calculations
    2301             :             // Simon: need to transfer surface temperatures because of frames calculation
    2302      250992 :             for (i = 1; i <= 2 * state.dataConstruction->Construct(ConstrNum).TotSolidLayers; ++i) {
    2303      213024 :                 state.dataWindowManager->thetas[i - 1] = window.ThetaFace(i);
    2304             :             }
    2305       37968 :             state.dataWindowManager->hcout = HextConvCoeff;
    2306       37968 :             state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    2307       37968 :             state.dataWindowManager->tin = thisZoneHB.MAT + state.dataWindowManager->TKelvin; // Inside air temperature
    2308             : 
    2309             :             // This is code repeating and it is necessary to calculate report variables.  Do not know
    2310             :             // how to solve this in more elegant way :(
    2311       37968 :             if (surface.ExtWind) {             // Window is exposed to wind (and possibly rain)
    2312       37968 :                 if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    2313           0 :                     state.dataWindowManager->tout = state.dataSurface->SurfOutWetBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2314             :                 } else { // Dry
    2315       37968 :                     state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2316             :                 }
    2317             :             } else { // Window not exposed to wind
    2318           0 :                 state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2319             :             }
    2320             : 
    2321       37968 :             state.dataWindowManager->Ebout = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tout);
    2322       37968 :             state.dataWindowManager->Outir =
    2323       75936 :                 surface.ViewFactorSkyIR *
    2324      113904 :                     (state.dataSurface->SurfAirSkyRadSplit(SurfNum) * state.dataWindowManager->sigma * pow_4(state.dataEnvrn->SkyTempKelvin) +
    2325       75936 :                      (1.0 - state.dataSurface->SurfAirSkyRadSplit(SurfNum)) * state.dataWindowManager->Ebout) +
    2326       37968 :                 surface.ViewFactorGroundIR * state.dataWindowManager->Ebout;
    2327             : 
    2328    22615349 :         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
    2329             : 
    2330        8064 :             EQLWindowSurfaceHeatBalance(
    2331             :                 state, SurfNum, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp, SurfOutsideEmiss, DataBSDFWindow::Condition::Invalid);
    2332        8064 :             state.dataWindowManager->hcout = HextConvCoeff;
    2333             :             // Required for report variables calculations.
    2334        8064 :             if (surface.ExtWind) {             // Window is exposed to wind (and possibly rain)
    2335        8064 :                 if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    2336           0 :                     state.dataWindowManager->tout = state.dataSurface->SurfOutWetBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2337             :                 } else { // Dry
    2338        8064 :                     state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2339             :                 }
    2340             :             } else { // Window not exposed to wind
    2341           0 :                 state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2342             :             }
    2343             : 
    2344             :         } else { // regular window, not BSDF, not EQL Window
    2345             :             // Added for thermochromic windows
    2346    22607285 :             state.dataWindowManager->locTCFlag = (state.dataConstruction->Construct(ConstrNum).TCFlag == 1);
    2347             : 
    2348    22607285 :             if (state.dataWindowManager->locTCFlag) {
    2349        4032 :                 locTCSpecTemp = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).TCLayer).SpecTemp;
    2350        4032 :                 state.dataSurface->SurfWinSpecTemp(SurfNum) = locTCSpecTemp;
    2351             :                 // Check to see whether needs to switch to a new TC window construction
    2352        4032 :                 locTCLayerTemp = state.dataSurface->SurfWinTCLayerTemp(SurfNum);
    2353        4032 :                 dT0 = std::abs(locTCLayerTemp - locTCSpecTemp);
    2354        4032 :                 if (dT0 >= 1) {
    2355             :                     // Find the TC construction that is closed to the TCLayerTemp
    2356        2509 :                     i = 0;
    2357        2509 :                     deltaTemp = 0.0;
    2358        2509 :                     IDConst = 0;
    2359       82797 :                     for (k = 1; k <= state.dataHeatBal->TotConstructs; ++k) {
    2360       80288 :                         if (state.dataConstruction->Construct(k).TCMasterConst == state.dataConstruction->Construct(ConstrNum).TCMasterConst) {
    2361       50180 :                             dT1 = std::abs(locTCLayerTemp - state.dataMaterial->Material(state.dataConstruction->Construct(k).TCLayer).SpecTemp);
    2362       50180 :                             if (dT1 < dT0) {
    2363         327 :                                 ++i;
    2364         327 :                                 deltaTemp(i) = dT1;
    2365         327 :                                 IDConst(i) = k;
    2366             :                             }
    2367             :                         }
    2368             :                     }
    2369        2509 :                     if (i >= 1) {
    2370             :                         // Find the closest item
    2371         313 :                         iMinDT = minloc(deltaTemp, deltaTemp > 0.0);
    2372             :                         // Use the new TC window construction
    2373         313 :                         ConstrNum = IDConst(iMinDT(1));
    2374         313 :                         surface.Construction = ConstrNum;
    2375         313 :                         state.dataSurface->SurfActiveConstruction(SurfNum) = ConstrNum;
    2376         313 :                         state.dataSurface->SurfWinSpecTemp(SurfNum) =
    2377         313 :                             state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).TCLayer).SpecTemp;
    2378             :                     }
    2379             :                 }
    2380             :             }
    2381             :             // end new TC code
    2382             : 
    2383    22607285 :             TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers;
    2384    22607285 :             TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    2385    22607285 :             state.dataWindowManager->ngllayer = TotGlassLay;
    2386    22607285 :             state.dataWindowManager->nglface = 2 * state.dataWindowManager->ngllayer;
    2387    22607285 :             ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    2388    22607285 :             state.dataWindowManager->tilt = surface.Tilt;
    2389    22607285 :             state.dataWindowManager->tiltr = state.dataWindowManager->tilt * DataGlobalConstants::DegToRadians;
    2390    22607285 :             SurfNumAdj = surface.ExtBoundCond;
    2391    22607285 :             state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum); // Room-side surface convective film conductance
    2392    22607285 :             Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
    2393    22607285 :             state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = RefAirTemp;
    2394    22607285 :             state.dataWindowManager->tin = RefAirTemp + state.dataWindowManager->TKelvin; // Inside air temperature
    2395             : 
    2396             :             // Reset hcin if necessary since too small a value sometimes causes non-convergence
    2397             :             // of window layer heat balance solution.
    2398    22607285 :             if (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == 0) {
    2399    45214570 :                 if (state.dataWindowManager->hcin <=
    2400    22607285 :                     state.dataHeatBal->LowHConvLimit) { // may be redundent now, check is also in HeatBalanceConvectionCoeffs.cc
    2401             :                     //  hcin = 3.076d0  !BG this is rather high value and abrupt change. changed to set to lower limit
    2402       22278 :                     state.dataWindowManager->hcin = state.dataHeatBal->LowHConvLimit;
    2403       22278 :                     state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataWindowManager->hcin; // store for accurate reporting.
    2404             :                 }
    2405             :             }
    2406             : 
    2407             :             // IR incident on window from zone surfaces and high-temp radiant sources
    2408    22607285 :             state.dataWindowManager->Rmir =
    2409    22607285 :                 state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum);
    2410             : 
    2411             :             // Short-wave radiation (from interior and exterior solar and zone lights)
    2412             :             // absorbed at each face. Assumes equal split between faces of short-wave absorbed in glass layer.
    2413             : 
    2414    51818397 :             for (IGlass = 1; IGlass <= TotGlassLay; ++IGlass) {
    2415    29211112 :                 state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 2] = state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) / 2.0;
    2416    29211112 :                 state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 1] = state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) / 2.0;
    2417             :             }
    2418             : 
    2419             :             // IR from zone internal gains (lights, equipment and people) absorbed on zone-side face
    2420             :             // (assumes inside glass layer is opaque to IR, so no contribution to other layers)
    2421    22607285 :             state.dataWindowManager->AbsRadGlassFace[2 * TotGlassLay - 1] += state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum);
    2422             : 
    2423             :             // Fill the layer properties needed for the thermal calculation.
    2424             :             // For switchable glazing it is assumed that thermal properties, such
    2425             :             // as surface emissivity, are the same for the unswitched and switched state,
    2426             :             // so the thermal properties of the unswitched state are used.
    2427             :             // For windows with a blind or shade it is assumed
    2428             :             // that the blind or shade does not affect the thermal properties of the glazing,
    2429             :             // so the thermal properties of the construction without the blind or shade are used.
    2430             : 
    2431             :             // The layer and face numbering are as follows (for the triple glazing case):
    2432             :             // Glass layers are 1,2 and 3, where 1 is the outside (outside environment facing)
    2433             :             //   layer and 3 is the inside (room-facing) layer;
    2434             :             // Faces (also called surfaces) are 1,2,3,4,5 and 6, where face 1 is the
    2435             :             //   outside (front) face of glass layer 1, face 2 is the inside (back)
    2436             :             //   face of glass layer 1, face 3 is the outer face of glass layer 2, face 4 is the
    2437             :             //   inner face of glass layer 2, etc.
    2438             :             // Gap layers are 1 and 2, where gap layer 1 is between glass layers 1 and 2
    2439             :             //   and gap layer 2 is between glass layers 2 and 3.
    2440             :             // If an exterior, interior or between-glass blind or shade is in place, 7 and 8
    2441             :             //   are the blind/shade faces, from outside to inside. If an exterior or interior
    2442             :             //   blind/shade is in place, gap layer 3 is between the blind/shade and adjacent
    2443             :             //   glass layer and is assumed to be air.
    2444             :             // Between-glass blind/shade is modeled only for double and triple glazing.
    2445             :             //   For double glazing, gap 1 is between glass 1 and blind/shade and gap 2 is between
    2446             :             //   blind/shade and glass 2.
    2447             :             //   For triple glazing, the blind/shade is assumed to be between the inner two glass
    2448             :             //   layers, i.e., between glass layers 2 and 3. In this case gap 1 is between glass 1
    2449             :             //   and glass 2, gap 2 is between glass 2 and blind/shade, and gap 3 is between
    2450             :             //   blind/shade and glass 3.
    2451             : 
    2452    22607285 :             int IConst = ConstrNum;
    2453    22607285 :             if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) {
    2454       71522 :                 IConst = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    2455             :             }
    2456    22607285 :             TotLay = state.dataConstruction->Construct(IConst).TotLayers;
    2457    22607285 :             IGlass = 0;
    2458    22607285 :             IGap = 0;
    2459             : 
    2460             :             // Fill window layer properties needed for window layer heat balance calculation
    2461             : 
    2462    58510616 :             for (Lay = 1; Lay <= TotLay; ++Lay) {
    2463    35903331 :                 LayPtr = state.dataConstruction->Construct(IConst).LayerPoint(Lay);
    2464             : 
    2465    51395182 :                 if ((state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGlass) ||
    2466    15491851 :                     (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowSimpleGlazing)) {
    2467    29211112 :                     ++IGlass;
    2468    29211112 :                     state.dataWindowManager->thick[IGlass - 1] = state.dataMaterial->Material(LayPtr).Thickness;
    2469    29211112 :                     state.dataWindowManager->scon[IGlass - 1] =
    2470    29211112 :                         state.dataMaterial->Material(LayPtr).Conductivity / state.dataMaterial->Material(LayPtr).Thickness;
    2471    29211112 :                     state.dataWindowManager->emis[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).AbsorpThermalFront;
    2472    29211112 :                     state.dataWindowManager->emis[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).AbsorpThermalBack;
    2473    29211112 :                     state.dataWindowManager->tir[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).TransThermal;
    2474    29211112 :                     state.dataWindowManager->tir[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).TransThermal;
    2475             :                 }
    2476             : 
    2477   107673651 :                 if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::Shade ||
    2478    71740516 :                     state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowBlind ||
    2479    35837185 :                     state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::Screen) {
    2480       71522 :                     if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag))
    2481       40940 :                         ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(state.dataConstruction->Construct(IConst).TotLayers);
    2482       71522 :                     if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(1);
    2483       71522 :                     if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    2484       16870 :                         ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(3);
    2485       16870 :                         if (TotGlassLay == 3) ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(5);
    2486             :                     }
    2487       71522 :                     if (ANY_SHADE_SCREEN(ShadeFlag)) {
    2488             :                         // Shade or screen on
    2489       41718 :                         if (state.dataGlobal
    2490       41718 :                                 ->AnyEnergyManagementSystemInModel) { // check to make sure the user hasn't messed up the shade control values
    2491           0 :                             if (state.dataMaterial->Material(ShadeLayPtr).Group == DataHeatBalance::MaterialGroup::WindowBlind) {
    2492           0 :                                 ShowSevereError(state,
    2493           0 :                                                 "CalcWindowHeatBalance: ShadeFlag indicates Shade but Blind=\"" +
    2494           0 :                                                     state.dataMaterial->Material(ShadeLayPtr).Name + "\" is being used.");
    2495           0 :                                 ShowContinueError(state, "This is most likely a fault of the EMS values for shading control.");
    2496           0 :                                 ShowFatalError(state, "Preceding condition terminates program.");
    2497             :                             }
    2498             :                         }
    2499       41718 :                         state.dataWindowManager->thick[TotGlassLay] = state.dataMaterial->Material(ShadeLayPtr).Thickness;
    2500       41718 :                         state.dataWindowManager->scon[TotGlassLay] =
    2501       41718 :                             state.dataMaterial->Material(ShadeLayPtr).Conductivity / state.dataMaterial->Material(ShadeLayPtr).Thickness;
    2502       41718 :                         if (ShadeFlag == WinShadingType::ExtScreen) {
    2503        5376 :                             state.dataWindowManager->emis[state.dataWindowManager->nglface] =
    2504        5376 :                                 state.dataMaterial->Material(ShadeLayPtr).AbsorpThermalFront;
    2505        5376 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface] =
    2506        5376 :                                 state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(ShadeLayPtr).ScreenDataPtr).DifDifTrans;
    2507        5376 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] =
    2508        5376 :                                 state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(ShadeLayPtr).ScreenDataPtr).DifDifTrans;
    2509             :                         } else {
    2510       36342 :                             state.dataWindowManager->emis[state.dataWindowManager->nglface] = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
    2511       36342 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface] = state.dataMaterial->Material(ShadeLayPtr).TransThermal;
    2512       36342 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] =
    2513       36342 :                                 state.dataMaterial->Material(ShadeLayPtr).TransThermal;
    2514             :                         }
    2515       41718 :                         state.dataWindowManager->emis[state.dataWindowManager->nglface + 1] = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
    2516             : 
    2517             :                     } else {
    2518       29804 :                         if (state.dataGlobal
    2519       29804 :                                 ->AnyEnergyManagementSystemInModel) { // check to make sure the user hasn't messed up the shade control values
    2520       32392 :                             if (state.dataMaterial->Material(ShadeLayPtr).Group == DataHeatBalance::MaterialGroup::Shade ||
    2521       16196 :                                 state.dataMaterial->Material(ShadeLayPtr).Group == DataHeatBalance::MaterialGroup::Screen) {
    2522           0 :                                 ShowSevereError(state,
    2523           0 :                                                 "CalcWindowHeatBalance: ShadeFlag indicates Blind but Shade/Screen=\"" +
    2524           0 :                                                     state.dataMaterial->Material(ShadeLayPtr).Name + "\" is being used.");
    2525           0 :                                 ShowContinueError(state, "This is most likely a fault of the EMS values for shading control.");
    2526           0 :                                 ShowFatalError(state, "Preceding condition terminates program.");
    2527             :                             }
    2528             :                         }
    2529             :                         // Blind on
    2530       29804 :                         BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
    2531       29804 :                         state.dataWindowManager->thick[TotGlassLay] = state.dataHeatBal->Blind(BlNum).SlatThickness;
    2532       29804 :                         state.dataWindowManager->scon[TotGlassLay] =
    2533       29804 :                             state.dataHeatBal->Blind(BlNum).SlatConductivity / state.dataHeatBal->Blind(BlNum).SlatThickness;
    2534             : 
    2535       29804 :                         if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    2536        3122 :                             int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
    2537        3122 :                             Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
    2538        3122 :                             state.dataWindowManager->emis[state.dataWindowManager->nglface] =
    2539        3122 :                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRFrontEmiss(SurfWinSlatsAngIndex),
    2540        6244 :                                                        state.dataHeatBal->Blind(BlNum).IRFrontEmiss(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    2541             :                                                        SurfWinSlatsAngInterpFac);
    2542        3122 :                             state.dataWindowManager->emis[state.dataWindowManager->nglface + 1] =
    2543        3122 :                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRBackEmiss(SurfWinSlatsAngIndex),
    2544        6244 :                                                        state.dataHeatBal->Blind(BlNum).IRBackEmiss(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    2545             :                                                        SurfWinSlatsAngInterpFac);
    2546        3122 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface] =
    2547        3122 :                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRFrontTrans(SurfWinSlatsAngIndex),
    2548        6244 :                                                        state.dataHeatBal->Blind(BlNum).IRFrontTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    2549             :                                                        SurfWinSlatsAngInterpFac);
    2550        3122 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] =
    2551        3122 :                                 General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRBackTrans(SurfWinSlatsAngIndex),
    2552        6244 :                                                        state.dataHeatBal->Blind(BlNum).IRBackTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
    2553             :                                                        SurfWinSlatsAngInterpFac);
    2554             :                         } else {
    2555       26682 :                             state.dataWindowManager->emis[state.dataWindowManager->nglface] = state.dataHeatBal->Blind(BlNum).IRFrontEmiss(1);
    2556       26682 :                             state.dataWindowManager->emis[state.dataWindowManager->nglface + 1] = state.dataHeatBal->Blind(BlNum).IRBackEmiss(1);
    2557       26682 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface] = state.dataHeatBal->Blind(BlNum).IRFrontTrans(1);
    2558       26682 :                             state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] = state.dataHeatBal->Blind(BlNum).IRBackTrans(1);
    2559             :                         }
    2560             :                     }
    2561             :                 }
    2562             : 
    2563    65242413 :                 if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGas ||
    2564    29339082 :                     state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGasMixture) {
    2565     6620697 :                     ++IGap;
    2566     6620697 :                     state.dataWindowManager->gap[IGap - 1] = state.dataMaterial->Material(LayPtr).Thickness;
    2567     6620697 :                     state.dataWindowManager->gnmix[IGap - 1] = state.dataMaterial->Material(LayPtr).NumberOfGasesInMixture;
    2568    13297842 :                     for (IMix = 1; IMix <= state.dataWindowManager->gnmix[IGap - 1]; ++IMix) {
    2569     6677145 :                         state.dataWindowManager->gwght[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasWght(IMix);
    2570     6677145 :                         state.dataWindowManager->gfract[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasFract(IMix);
    2571    26708580 :                         for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
    2572    20031435 :                             state.dataWindowManager->gcon[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCon(ICoeff, IMix);
    2573    20031435 :                             state.dataWindowManager->gvis[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasVis(ICoeff, IMix);
    2574    20031435 :                             state.dataWindowManager->gcp[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCp(ICoeff, IMix);
    2575             :                         }
    2576             :                     }
    2577             :                 }
    2578             : 
    2579             :             } // End of loop over glass, gap and blind/shade layers in a window construction
    2580             : 
    2581    22607285 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) || ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    2582             :                 // Interior or exterior blind, shade or screen is on.
    2583             :                 // Fill gap between blind/shade and adjacent glass with air properties.
    2584       54652 :                 ++IGap;
    2585       54652 :                 if (ShadeFlag == WinShadingType::IntShade || ShadeFlag == WinShadingType::ExtShade ||
    2586             :                     ShadeFlag == WinShadingType::ExtScreen) { // Interior or exterior shade
    2587       33654 :                     state.dataWindowManager->gap[IGap - 1] = state.dataMaterial->Material(ShadeLayPtr).WinShadeToGlassDist;
    2588             :                 } else { // Interior or exterior blind
    2589       20998 :                     state.dataWindowManager->gap[IGap - 1] =
    2590       20998 :                         state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).BlindToGlassDist;
    2591             :                 }
    2592       54652 :                 state.dataWindowManager->gnmix[IGap - 1] = 1;
    2593       54652 :                 state.dataWindowManager->gwght[0][IGap - 1] = GasWght[0];
    2594      218608 :                 for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
    2595      163956 :                     state.dataWindowManager->gcon[ICoeff - 1][0][IGap - 1] = GasCoeffsCon[ICoeff - 1][0];
    2596      163956 :                     state.dataWindowManager->gvis[ICoeff - 1][0][IGap - 1] = GasCoeffsVis[ICoeff - 1][0];
    2597      163956 :                     state.dataWindowManager->gcp[ICoeff - 1][0][IGap - 1] = GasCoeffsCp[ICoeff - 1][0];
    2598             :                 }
    2599             :             }
    2600             : 
    2601             :             // Exterior convection coefficient, exterior air temperature and IR radiance
    2602             :             // of exterior surround. Depend on whether window is interzone (in an interzone
    2603             :             // wall or exterior (in an exterior wall).
    2604             : 
    2605    22607285 :             state.dataWindowManager->hcout = HextConvCoeff; // Exterior convection coefficient is passed in from outer routine
    2606             :             // tsky = SkyTemp + TKelvin
    2607             : 
    2608    22607285 :             if (SurfNumAdj > 0) { // Interzone window
    2609             : 
    2610       27072 :                 ZoneNumAdj = state.dataSurface->Surface(SurfNumAdj).Zone;
    2611       27072 :                 Real64 RefAirTemp = state.dataSurface->Surface(SurfNumAdj).getInsideAirTemperature(state, SurfNumAdj);
    2612       27072 :                 state.dataHeatBal->SurfTempEffBulkAir(SurfNumAdj) = RefAirTemp;
    2613       27072 :                 state.dataWindowManager->tout = RefAirTemp + state.dataWindowManager->TKelvin; // outside air temperature
    2614             : 
    2615             :                 // Add long-wave radiation from adjacent zone absorbed by glass layer closest to the adjacent zone.
    2616       27072 :                 state.dataWindowManager->AbsRadGlassFace[0] += state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNumAdj);
    2617             : 
    2618             :                 // The IR radiance of this window's "exterior" surround is the IR radiance
    2619             :                 // from surfaces and high-temp radiant sources in the adjacent zone
    2620             : 
    2621       27072 :                 state.dataWindowManager->Outir =
    2622       27072 :                     state.dataSurface->SurfWinIRfromParentZone(SurfNumAdj) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNumAdj);
    2623             : 
    2624             :             } else { // Exterior window (Ext BoundCond = 0)
    2625             :                 // Calculate LWR from surrounding surfaces if defined for an exterior window
    2626    22580213 :                 OutSrdIR = 0;
    2627    22580213 :                 if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
    2628      133056 :                     if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
    2629        2688 :                         int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
    2630        2688 :                         auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
    2631        8064 :                         for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    2632        5376 :                             SrdSurfViewFac = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
    2633        5376 :                             SrdSurfTempAbs = GetCurrentScheduleValue(state, SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).TempSchNum) +
    2634             :                                              DataGlobalConstants::KelvinConv;
    2635        5376 :                             OutSrdIR += state.dataWindowManager->sigma * SrdSurfViewFac * pow_4(SrdSurfTempAbs);
    2636             :                         }
    2637             :                     }
    2638             :                 }
    2639    22580213 :                 if (surface.ExtWind) {             // Window is exposed to wind (and possibly rain)
    2640    22580213 :                     if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    2641        4686 :                         state.dataWindowManager->tout = state.dataSurface->SurfOutWetBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2642             :                     } else { // Dry
    2643    22575527 :                         state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2644             :                     }
    2645             :                 } else { // Window not exposed to wind
    2646           0 :                     state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
    2647             :                 }
    2648    22580213 :                 state.dataWindowManager->Ebout = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tout);
    2649    22580213 :                 state.dataWindowManager->Outir =
    2650    45160426 :                     surface.ViewFactorSkyIR *
    2651    67740639 :                         (state.dataSurface->SurfAirSkyRadSplit(SurfNum) * state.dataWindowManager->sigma * pow_4(state.dataEnvrn->SkyTempKelvin) +
    2652    45160426 :                          (1.0 - state.dataSurface->SurfAirSkyRadSplit(SurfNum)) * state.dataWindowManager->Ebout) +
    2653    45160426 :                     surface.ViewFactorGroundIR * state.dataWindowManager->Ebout + OutSrdIR;
    2654             :             }
    2655             : 
    2656             :             // Factors used in window layer temperature solution
    2657    22607285 :             if (state.dataWindowManager->ngllayer >= 2) {
    2658     6460787 :                 state.dataWindowManager->A23P =
    2659     6460787 :                     -state.dataWindowManager->emis[2] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
    2660     6460787 :                 state.dataWindowManager->A32P =
    2661     6460787 :                     state.dataWindowManager->emis[1] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
    2662     6460787 :                 state.dataWindowManager->A23 = state.dataWindowManager->emis[1] * state.dataWindowManager->sigma * state.dataWindowManager->A23P;
    2663             :             }
    2664             : 
    2665    22607285 :             if (state.dataWindowManager->ngllayer >= 3) {
    2666       92352 :                 state.dataWindowManager->A45P =
    2667       92352 :                     -state.dataWindowManager->emis[4] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
    2668       92352 :                 state.dataWindowManager->A54P =
    2669       92352 :                     state.dataWindowManager->emis[3] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
    2670       92352 :                 state.dataWindowManager->A45 = state.dataWindowManager->emis[3] * state.dataWindowManager->sigma * state.dataWindowManager->A45P;
    2671             :             }
    2672             : 
    2673    22607285 :             if (state.dataWindowManager->ngllayer == 4) {
    2674       50688 :                 state.dataWindowManager->A67P =
    2675       50688 :                     -state.dataWindowManager->emis[6] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
    2676       50688 :                 state.dataWindowManager->A76P =
    2677       50688 :                     state.dataWindowManager->emis[5] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
    2678       50688 :                 state.dataWindowManager->A67 = state.dataWindowManager->emis[5] * state.dataWindowManager->sigma * state.dataWindowManager->A67P;
    2679             :             }
    2680             : 
    2681    22607285 :             state.dataWindowManager->thetas = {0.0};
    2682    22607285 :             state.dataWindowManager->thetasPrev = {0.0};
    2683    22607285 :             state.dataWindowManager->fvec = {0.0};
    2684             : 
    2685             :             // Calculate window face temperatures
    2686             : 
    2687    22607285 :             SolveForWindowTemperatures(state, SurfNum);
    2688             : 
    2689             :             // Temperature difference across glass layers (for debugging)
    2690             : 
    2691    22607285 :             dth1 = state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0];
    2692    22607285 :             dth2 = state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2];
    2693    22607285 :             dth3 = state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[4];
    2694    22607285 :             dth4 = state.dataWindowManager->thetas[7] - state.dataWindowManager->thetas[6];
    2695             : 
    2696    22607285 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    2697       40940 :                 SurfInsideTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer + 1] - state.dataWindowManager->TKelvin;
    2698       40940 :                 if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    2699        2569 :                     EffShBlEmiss =
    2700        5138 :                         General::InterpGeneral(window.EffShBlindEmiss(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
    2701        5138 :                                                window.EffShBlindEmiss(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
    2702        2569 :                                                state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    2703        2569 :                     EffGlEmiss =
    2704        5138 :                         General::InterpGeneral(window.EffGlassEmiss(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
    2705        5138 :                                                window.EffGlassEmiss(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
    2706        2569 :                                                state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    2707             :                 } else {
    2708       38371 :                     EffShBlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1);
    2709       38371 :                     EffGlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(1);
    2710             :                 }
    2711       40940 :                 state.dataSurface->SurfWinEffInsSurfTemp(SurfNum) =
    2712       81880 :                     (EffShBlEmiss * SurfInsideTemp +
    2713      122820 :                      EffGlEmiss * (state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin)) /
    2714       40940 :                     (EffShBlEmiss + EffGlEmiss);
    2715             :             } else {
    2716    22566345 :                 SurfInsideTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin;
    2717             :             }
    2718    22607285 :             if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    2719       13712 :                 SurfOutsideTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer] -
    2720       13712 :                                   state.dataWindowManager->TKelvin; // this index looks suspicious (CR 8202)
    2721             :                 // SurfOutsideEmiss = emis(1)  ! this index should be coordinated with previous line
    2722       13712 :                 SurfOutsideEmiss = state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer]; // fix for CR 8202
    2723             :             } else {
    2724    22593573 :                 SurfOutsideEmiss = state.dataWindowManager->emis[0];
    2725    22593573 :                 SurfOutsideTemp = state.dataWindowManager->thetas[0] - state.dataWindowManager->TKelvin;
    2726             :             }
    2727             : 
    2728             :             // Save temperatures for use next time step
    2729             : 
    2730    81172553 :             for (k = 1; k <= state.dataWindowManager->nglfacep; ++k) {
    2731    58565268 :                 window.ThetaFace(k) = state.dataWindowManager->thetas[k - 1];
    2732             :             }
    2733             : 
    2734             :             // Added TH 12/23/2008 for thermochromic windows to save the current TC layer temperature
    2735    22607285 :             if (state.dataWindowManager->locTCFlag) {
    2736        4032 :                 state.dataSurface->SurfWinTCLayerTemp(SurfNum) =
    2737        8064 :                     (state.dataWindowManager->thetas[2 * state.dataConstruction->Construct(ConstrNum).TCGlassID - 2] +
    2738        8064 :                      state.dataWindowManager->thetas[2 * state.dataConstruction->Construct(ConstrNum).TCGlassID - 1]) /
    2739        4032 :                         2 -
    2740        4032 :                     state.dataWindowManager->TKelvin; // degree C
    2741             :             }
    2742             :         } // regular window, not BSDF, not EQL
    2743             : 
    2744             :         // Set condensation flag to 1 if condensation expected to occur on the innermost glass face,
    2745             :         // or, for airflow windows, on either or the two glass faces in the airflow gap
    2746    22653317 :         if (!state.dataConstruction->Construct(surface.Construction).WindowTypeEQL) {
    2747    22645253 :             InsideGlassTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin;
    2748    22645253 :             RoomHumRat = thisZoneHB.ZoneAirHumRat;
    2749    22645253 :             RoomDewPoint = PsyTdpFnWPb(state, RoomHumRat, state.dataEnvrn->OutBaroPress);
    2750    22645253 :             state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0;
    2751    22645253 :             if (InsideGlassTemp < RoomDewPoint) state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1;
    2752             :             // If airflow window, is there condensation on either glass face of the airflow gap?
    2753    22645253 :             if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
    2754       16128 :                 Tleft = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 3] - state.dataWindowManager->TKelvin;
    2755       16128 :                 Tright = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 2] - state.dataWindowManager->TKelvin;
    2756       16128 :                 if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
    2757       16128 :                     if (Tleft < RoomDewPoint || Tright < RoomDewPoint) state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1;
    2758           0 :                 } else if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Outdoor) {
    2759           0 :                     if (Tleft < state.dataEnvrn->OutDewPointTemp || Tright < state.dataEnvrn->OutDewPointTemp)
    2760           0 :                         state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1;
    2761             :                 }
    2762             :             }
    2763             : 
    2764             :             // Do frame and divider calculation
    2765    22645253 :             if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0 || state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0)
    2766     2948880 :                 CalcWinFrameAndDividerTemps(state,
    2767             :                                             SurfNum,
    2768      589776 :                                             state.dataWindowManager->tout,
    2769      589776 :                                             state.dataWindowManager->tin,
    2770      589776 :                                             state.dataWindowManager->hcout,
    2771      589776 :                                             state.dataWindowManager->hcin,
    2772      589776 :                                             state.dataWindowManager->Outir,
    2773             :                                             ConstrNum);
    2774    22645253 :             if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    2775      589776 :                 state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 0;
    2776      589776 :                 if (state.dataSurface->SurfWinFrameTempIn(SurfNum) < RoomDewPoint) state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 1;
    2777             :             }
    2778    22645253 :             if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    2779      261168 :                 state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 0;
    2780      261168 :                 if (state.dataSurface->SurfWinDividerTempIn(SurfNum) < RoomDewPoint)
    2781       69781 :                     state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 1;
    2782             :             }
    2783             :         }
    2784             :         // update exterior environment surface heat loss reporting
    2785    22653317 :         Tsout = SurfOutsideTemp + state.dataWindowManager->TKelvin;
    2786    22653317 :         state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = -state.dataWindowManager->hcout * (Tsout - state.dataWindowManager->tout);
    2787             : 
    2788    22653317 :         Real64 const Tsout_4(pow_4(Tsout)); // Tuned To reduce pow calls and redundancies
    2789    22653317 :         Real64 const Tout_4(pow_4(state.dataWindowManager->tout));
    2790    22653317 :         Real64 const emiss_sigma_product(SurfOutsideEmiss * state.dataWindowManager->sigma);
    2791    22653317 :         Real64 rad_out_lw_srd_per_area = 0;
    2792             : 
    2793    22653317 :         if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
    2794      133056 :             if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
    2795        2688 :                 int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
    2796        8064 :                 for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface; SrdSurfNum++) {
    2797        5376 :                     SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
    2798        5376 :                     SrdSurfTempAbs = GetCurrentScheduleValue(
    2799        5376 :                                          state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).TempSchNum) +
    2800             :                                      DataGlobalConstants::KelvinConv;
    2801        5376 :                     rad_out_lw_srd_per_area += -emiss_sigma_product * SrdSurfViewFac * (Tsout_4 - pow_4(SrdSurfTempAbs));
    2802             :                 }
    2803             :             }
    2804             :         }
    2805             : 
    2806             :         Real64 const rad_out_air_per_area =
    2807    22653317 :             -emiss_sigma_product * (1.0 - state.dataSurface->SurfAirSkyRadSplit(SurfNum)) * surface.ViewFactorSkyIR * (Tsout_4 - Tout_4);
    2808    22653317 :         Real64 const rad_out_ground_per_area = -emiss_sigma_product * surface.ViewFactorGroundIR * (Tsout_4 - Tout_4);
    2809    22653317 :         Real64 const rad_out_sky_per_area = -emiss_sigma_product * state.dataSurface->SurfAirSkyRadSplit(SurfNum) * surface.ViewFactorSkyIR *
    2810    22653317 :                                             (Tsout_4 - pow_4(state.dataEnvrn->SkyTempKelvin));
    2811    22653317 :         Real64 const rad_out_per_area = rad_out_air_per_area + rad_out_sky_per_area + rad_out_ground_per_area + rad_out_lw_srd_per_area;
    2812             : 
    2813    22653317 :         state.dataHeatBalSurf->SurfHAirExt(SurfNum) = rad_out_air_per_area / (Tsout - state.dataWindowManager->tout);
    2814    22653317 :         state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = rad_out_lw_srd_per_area;
    2815    22653317 :         state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = rad_out_per_area;
    2816    22653317 :     }
    2817             : 
    2818             :     //****************************************************************************
    2819             : 
    2820           0 :     void WindowHeatBalanceEquations(EnergyPlusData &state, int const SurfNum) // Surface number
    2821             :     {
    2822             : 
    2823             :         // SUBROUTINE INFORMATION:
    2824             :         //       AUTHOR         F. Winkelmann
    2825             :         //       DATE WRITTEN   February 2000
    2826             :         //       MODIFIED       na
    2827             :         //       RE-ENGINEERED  na
    2828             : 
    2829             :         // PURPOSE OF THIS SUBROUTINE:
    2830             :         // Evaluates heat balance functions at each glass face.
    2831             :         // Also evaluates Jacobian.
    2832             :         // Currently limited to three glass layers.
    2833             : 
    2834           0 :         Array1D<Real64> hgap(5); // Gap gas conductance
    2835             :         Real64 gr;               // Gap gas Grashof number
    2836             :         Real64 con;              // Gap gas conductivity
    2837             :         Real64 pr;               // Gap gas Prandtl number
    2838             :         Real64 nu;               // Gap gas Nusselt number
    2839             :         Real64 thetas_2_3_4;
    2840             :         Real64 thetas_4_5_4;
    2841             :         Real64 thetas_6_7_4;
    2842             : 
    2843             :         // Have to zero fvec each time since LUdecompostion and LUsolution may
    2844             :         // add values to this array in unexpected places
    2845           0 :         state.dataWindowManager->fvec = {0.0};
    2846             : 
    2847           0 :         switch (state.dataWindowManager->ngllayer) {
    2848             : 
    2849           0 :         case 1: // single pane
    2850           0 :             state.dataWindowManager->fvec[0] =
    2851           0 :                 state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
    2852           0 :                 state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
    2853           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
    2854           0 :                 state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
    2855           0 :                 state.dataWindowManager->AbsRadGlassFace[0];
    2856           0 :             state.dataWindowManager->fvec[1] =
    2857           0 :                 state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] -
    2858           0 :                 state.dataWindowManager->emis[1] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[1]) +
    2859           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
    2860           0 :                 state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[1]) +
    2861           0 :                 state.dataWindowManager->AbsRadGlassFace[1];
    2862           0 :             break;
    2863           0 :         case 2: // double pane
    2864           0 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    2865           0 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    2866           0 :             hgap(1) = (con / state.dataWindowManager->gap[0] * nu) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
    2867             : 
    2868           0 :             state.dataWindowManager->fvec[0] =
    2869           0 :                 state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
    2870           0 :                 state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
    2871           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
    2872           0 :                 state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
    2873           0 :                 state.dataWindowManager->AbsRadGlassFace[0];
    2874           0 :             thetas_2_3_4 = pow_4(state.dataWindowManager->thetas[1]) - pow_4(state.dataWindowManager->thetas[2]);
    2875           0 :             state.dataWindowManager->fvec[1] =
    2876           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
    2877           0 :                 hgap(1) * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[1]) + state.dataWindowManager->A23 * thetas_2_3_4 +
    2878           0 :                 state.dataWindowManager->AbsRadGlassFace[1];
    2879           0 :             state.dataWindowManager->fvec[2] =
    2880           0 :                 hgap(1) * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[2]) +
    2881           0 :                 state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2]) -
    2882           0 :                 state.dataWindowManager->A23 * thetas_2_3_4 + state.dataWindowManager->AbsRadGlassFace[2];
    2883           0 :             state.dataWindowManager->fvec[3] =
    2884           0 :                 state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] -
    2885           0 :                 state.dataWindowManager->emis[3] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[3]) +
    2886           0 :                 state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[3]) +
    2887           0 :                 state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[3]) +
    2888           0 :                 state.dataWindowManager->AbsRadGlassFace[3];
    2889           0 :             break;
    2890           0 :         case 3: // Triple Pane
    2891           0 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    2892           0 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    2893           0 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
    2894             : 
    2895           0 :             WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
    2896           0 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
    2897           0 :             hgap(2) = con / state.dataWindowManager->gap[1] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
    2898             : 
    2899           0 :             thetas_2_3_4 = pow_4(state.dataWindowManager->thetas[1]) - pow_4(state.dataWindowManager->thetas[2]);
    2900           0 :             thetas_4_5_4 = pow_4(state.dataWindowManager->thetas[3]) - pow_4(state.dataWindowManager->thetas[4]);
    2901           0 :             state.dataWindowManager->fvec[0] =
    2902           0 :                 state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
    2903           0 :                 state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
    2904           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
    2905           0 :                 state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
    2906           0 :                 state.dataWindowManager->AbsRadGlassFace[0];
    2907           0 :             state.dataWindowManager->fvec[1] =
    2908           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
    2909           0 :                 hgap(1) * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[1]) + state.dataWindowManager->A23 * thetas_2_3_4 +
    2910           0 :                 state.dataWindowManager->AbsRadGlassFace[1];
    2911           0 :             state.dataWindowManager->fvec[2] =
    2912           0 :                 hgap(1) * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[2]) +
    2913           0 :                 state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2]) -
    2914           0 :                 state.dataWindowManager->A23 * thetas_2_3_4 + state.dataWindowManager->AbsRadGlassFace[2];
    2915           0 :             state.dataWindowManager->fvec[3] =
    2916           0 :                 state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[3]) +
    2917           0 :                 hgap(2) * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[3]) + state.dataWindowManager->A45 * thetas_4_5_4 +
    2918           0 :                 state.dataWindowManager->AbsRadGlassFace[3];
    2919           0 :             state.dataWindowManager->fvec[4] =
    2920           0 :                 hgap(2) * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[4]) +
    2921           0 :                 state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[4]) -
    2922           0 :                 state.dataWindowManager->A45 * thetas_4_5_4 + state.dataWindowManager->AbsRadGlassFace[4];
    2923           0 :             state.dataWindowManager->fvec[5] =
    2924           0 :                 state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] -
    2925           0 :                 state.dataWindowManager->emis[5] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[5]) +
    2926           0 :                 state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[5]) +
    2927           0 :                 state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[5]) +
    2928           0 :                 state.dataWindowManager->AbsRadGlassFace[5];
    2929           0 :             break;
    2930           0 :         case 4: // Quad Pane
    2931           0 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    2932           0 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    2933           0 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
    2934             : 
    2935           0 :             WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
    2936           0 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
    2937           0 :             hgap(2) = con / state.dataWindowManager->gap[1] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
    2938             : 
    2939           0 :             WindowGasConductance(state, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, con, pr, gr);
    2940           0 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, gr, pr, nu);
    2941           0 :             hgap(3) = con / state.dataWindowManager->gap[2] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
    2942             : 
    2943           0 :             thetas_2_3_4 = pow_4(state.dataWindowManager->thetas[1]) - pow_4(state.dataWindowManager->thetas[2]);
    2944           0 :             thetas_4_5_4 = pow_4(state.dataWindowManager->thetas[3]) - pow_4(state.dataWindowManager->thetas[4]);
    2945           0 :             thetas_6_7_4 = pow_4(state.dataWindowManager->thetas[5]) - pow_4(state.dataWindowManager->thetas[6]);
    2946           0 :             state.dataWindowManager->fvec[0] =
    2947           0 :                 state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
    2948           0 :                 state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
    2949           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
    2950           0 :                 state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
    2951           0 :                 state.dataWindowManager->AbsRadGlassFace[0];
    2952           0 :             state.dataWindowManager->fvec[1] =
    2953           0 :                 state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
    2954           0 :                 hgap(1) * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[1]) + state.dataWindowManager->A23 * thetas_2_3_4 +
    2955           0 :                 state.dataWindowManager->AbsRadGlassFace[1];
    2956           0 :             state.dataWindowManager->fvec[2] =
    2957           0 :                 hgap(1) * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[2]) +
    2958           0 :                 state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2]) -
    2959           0 :                 state.dataWindowManager->A23 * thetas_2_3_4 + state.dataWindowManager->AbsRadGlassFace[2];
    2960           0 :             state.dataWindowManager->fvec[3] =
    2961           0 :                 state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[3]) +
    2962           0 :                 hgap(2) * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[3]) + state.dataWindowManager->A45 * thetas_4_5_4 +
    2963           0 :                 state.dataWindowManager->AbsRadGlassFace[3];
    2964           0 :             state.dataWindowManager->fvec[4] =
    2965           0 :                 hgap(2) * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[4]) +
    2966           0 :                 state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[4]) -
    2967           0 :                 state.dataWindowManager->A45 * thetas_4_5_4 + state.dataWindowManager->AbsRadGlassFace[4];
    2968           0 :             state.dataWindowManager->fvec[5] =
    2969           0 :                 state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[5]) +
    2970           0 :                 hgap(3) * (state.dataWindowManager->thetas[6] - state.dataWindowManager->thetas[5]) + state.dataWindowManager->A67 * thetas_6_7_4 +
    2971           0 :                 state.dataWindowManager->AbsRadGlassFace[5];
    2972           0 :             state.dataWindowManager->fvec[6] =
    2973           0 :                 hgap(3) * (state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[6]) +
    2974           0 :                 state.dataWindowManager->scon[3] * (state.dataWindowManager->thetas[7] - state.dataWindowManager->thetas[6]) -
    2975           0 :                 state.dataWindowManager->A67 * thetas_6_7_4 + state.dataWindowManager->AbsRadGlassFace[6];
    2976           0 :             state.dataWindowManager->fvec[7] =
    2977           0 :                 state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] -
    2978           0 :                 state.dataWindowManager->emis[7] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[7]) +
    2979           0 :                 state.dataWindowManager->scon[3] * (state.dataWindowManager->thetas[6] - state.dataWindowManager->thetas[7]) +
    2980           0 :                 state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[7]) +
    2981           0 :                 state.dataWindowManager->AbsRadGlassFace[7];
    2982           0 :             break;
    2983             :         }
    2984           0 :     }
    2985             : 
    2986             :     //****************************************************************************
    2987             : 
    2988       14952 :     void GetHeatBalanceEqCoefMatrixSimple(EnergyPlusData &state,
    2989             :                                           int const nglasslayer,     // Number of glass layers
    2990             :                                           Array1D<Real64> const &hr, // Radiative conductance (W/m2-K)
    2991             :                                           Array1A<Real64> &hgap,     // Gap gas conductive conductance (W/m2-K)
    2992             :                                           Array2D<Real64> &Aface,    // Coefficient in equation Aface*thetas = Bface
    2993             :                                           Array1D<Real64> &Bface     // Coefficient in equation Aface*thetas = Bface
    2994             :     )
    2995             :     {
    2996             :         Real64 gr;  // Grashof number of gas in a gap
    2997             :         Real64 con; // Gap gas conductivity
    2998             :         Real64 pr;  // Gap gas Prandtl number
    2999             :         Real64 nu;  // Gap gas Nusselt number
    3000             : 
    3001       14952 :         if (nglasslayer == 1) {
    3002       23781 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3003       15854 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3004       23781 :             Bface(2) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] +
    3005       15854 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[1];
    3006             : 
    3007        7927 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3008        7927 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3009        7927 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3010        7927 :             Aface(2, 2) = hr(2) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcin;
    3011             : 
    3012        7025 :         } else if (nglasslayer == 2) {
    3013        5907 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    3014        5907 :             NusseltNumber(state, 0, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    3015        5907 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu;
    3016             : 
    3017       17721 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3018       11814 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3019        5907 :             Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
    3020        5907 :             Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
    3021       17721 :             Bface(4) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] +
    3022       11814 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[3];
    3023             : 
    3024        5907 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3025        5907 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3026             : 
    3027        5907 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3028        5907 :             Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
    3029        5907 :             Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
    3030             : 
    3031        5907 :             Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
    3032        5907 :             Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3033        5907 :             Aface(4, 3) = -state.dataWindowManager->scon[1];
    3034             : 
    3035        5907 :             Aface(3, 4) = -state.dataWindowManager->scon[1];
    3036        5907 :             Aface(4, 4) = hr(4) + state.dataWindowManager->scon[1] + state.dataWindowManager->hcin;
    3037             : 
    3038        1118 :         } else if (nglasslayer == 3) {
    3039        1037 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    3040        1037 :             NusseltNumber(state, 0, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    3041        1037 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu;
    3042             : 
    3043        1037 :             WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
    3044        1037 :             NusseltNumber(state, 0, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
    3045        1037 :             hgap(2) = con / state.dataWindowManager->gap[1] * nu;
    3046             : 
    3047        3111 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3048        2074 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3049        1037 :             Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
    3050        1037 :             Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
    3051        1037 :             Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
    3052        1037 :             Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
    3053        3111 :             Bface(6) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] +
    3054        2074 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[5];
    3055             : 
    3056        1037 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3057        1037 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3058             : 
    3059        1037 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3060        1037 :             Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
    3061        1037 :             Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
    3062             : 
    3063        1037 :             Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
    3064        1037 :             Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3065        1037 :             Aface(4, 3) = -state.dataWindowManager->scon[1];
    3066             : 
    3067        1037 :             Aface(3, 4) = -state.dataWindowManager->scon[1];
    3068        1037 :             Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
    3069        1037 :             Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
    3070             : 
    3071        1037 :             Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
    3072        1037 :             Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
    3073        1037 :             Aface(6, 5) = -state.dataWindowManager->scon[2];
    3074             : 
    3075        1037 :             Aface(5, 6) = -state.dataWindowManager->scon[2];
    3076        1037 :             Aface(6, 6) = hr(6) + state.dataWindowManager->scon[2] + state.dataWindowManager->hcin;
    3077             : 
    3078          81 :         } else if (nglasslayer == 4) {
    3079          81 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    3080          81 :             NusseltNumber(state, 0, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    3081          81 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu;
    3082             : 
    3083          81 :             WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
    3084          81 :             NusseltNumber(state, 0, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
    3085          81 :             hgap(2) = con / state.dataWindowManager->gap[1] * nu;
    3086             : 
    3087          81 :             WindowGasConductance(state, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, con, pr, gr);
    3088          81 :             NusseltNumber(state, 0, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, gr, pr, nu);
    3089          81 :             hgap(3) = con / state.dataWindowManager->gap[2] * nu;
    3090             : 
    3091         243 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3092         162 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3093          81 :             Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
    3094          81 :             Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
    3095          81 :             Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
    3096          81 :             Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
    3097          81 :             Bface(6) = state.dataWindowManager->AbsRadGlassFace[5];
    3098          81 :             Bface(7) = state.dataWindowManager->AbsRadGlassFace[6];
    3099         243 :             Bface(8) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] +
    3100         162 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[7];
    3101             : 
    3102          81 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3103          81 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3104             : 
    3105          81 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3106          81 :             Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
    3107          81 :             Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
    3108             : 
    3109          81 :             Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
    3110          81 :             Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3111          81 :             Aface(4, 3) = -state.dataWindowManager->scon[1];
    3112             : 
    3113          81 :             Aface(3, 4) = -state.dataWindowManager->scon[1];
    3114          81 :             Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
    3115          81 :             Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
    3116             : 
    3117          81 :             Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
    3118          81 :             Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
    3119          81 :             Aface(6, 5) = -state.dataWindowManager->scon[2];
    3120             : 
    3121          81 :             Aface(5, 6) = -state.dataWindowManager->scon[2];
    3122          81 :             Aface(6, 6) = state.dataWindowManager->scon[2] + hgap(3) - state.dataWindowManager->A67P * hr(6);
    3123          81 :             Aface(7, 6) = -hgap(3) - state.dataWindowManager->A76P * hr(7);
    3124             : 
    3125          81 :             Aface(6, 7) = -hgap(3) + state.dataWindowManager->A67P * hr(6);
    3126          81 :             Aface(7, 7) = hgap(3) + state.dataWindowManager->scon[3] + state.dataWindowManager->A76P * hr(7);
    3127          81 :             Aface(8, 7) = -state.dataWindowManager->scon[3];
    3128             : 
    3129          81 :             Aface(7, 8) = -state.dataWindowManager->scon[3];
    3130          81 :             Aface(8, 8) = hr(8) + state.dataWindowManager->scon[3] + state.dataWindowManager->hcin;
    3131             :         }
    3132       14952 :     }
    3133             : 
    3134    42038057 :     void GetHeatBalanceEqCoefMatrix(EnergyPlusData &state,
    3135             :                                     int const SurfNum,
    3136             :                                     int const nglasslayer,
    3137             :                                     WinShadingType const ShadeFlag,
    3138             :                                     Real64 const sconsh,
    3139             :                                     Real64 const TauShIR,
    3140             :                                     Real64 const EpsShIR1,
    3141             :                                     Real64 const EpsShIR2,
    3142             :                                     Real64 const RhoShIR1,
    3143             :                                     Real64 const RhoShIR2,
    3144             :                                     Real64 const ShGlReflFacIR,
    3145             :                                     Real64 const RhoGlIR1,
    3146             :                                     Real64 const RhoGlIR2,
    3147             :                                     Real64 const hcv,             // Convection coefficient from gap glass or shade/blind to gap air (W/m2-K)
    3148             :                                     Real64 const TGapNew,         // Current-iteration average air temp in airflow gap (K)
    3149             :                                     Real64 const TAirflowGapNew,  // Average air temp in airflow gap between glass panes (K)
    3150             :                                     Real64 const hcvAirflowGap,   // Convection coefficient from airflow gap glass to airflow gap air (W/m2-K)
    3151             :                                     Array1A<Real64> const &hcvBG, // Convection coefficient from gap glass or shade to gap gas (W/m2-K)
    3152             :                                     Array1A<Real64> const &TGapNewBG,
    3153             :                                     Array1A<Real64> const &AbsRadShadeFace,
    3154             :                                     Array1D<Real64> const &hr,
    3155             :                                     Array2D<Real64> &Aface,
    3156             :                                     Array1D<Real64> &Bface)
    3157             :     {
    3158    42038057 :         auto &hgap = state.dataWindowManager->hgap;
    3159    42038057 :         auto &RhoIR = state.dataWindowManager->RhoIR;
    3160             : 
    3161             :         Real64 gr;  // Grashof number of gas in a gap
    3162             :         Real64 con; // Gap gas conductivity
    3163             :         Real64 pr;  // Gap gas Prandtl number
    3164             :         Real64 nu;  // Gap gas Nusselt number
    3165             : 
    3166             :         Real64 FacRhoIR25;         // Intermediate variable
    3167             :         Real64 FacRhoIR63;         // Intermediate variable
    3168             :         Real64 RhoIRfp;            // Intermediate variable
    3169             :         Real64 RhoIRbp;            // Intermediate variable
    3170             :         Real64 FacRhoIR2fp;        // Intermediate variable
    3171             :         Real64 FacRhoIR3bp;        // Intermediate variable
    3172             :         Real64 FacRhoIR2fpRhoIR63; // Intermediate variable
    3173             :         Real64 FacRhoIR3bpRhoIR25; // Intermediate variable
    3174             :         Real64 FacRhoIR47;         // Intermediate variable
    3175             :         Real64 FacRhoIR85;         // Intermediate variable
    3176             :         Real64 FacRhoIR4fp;        // Intermediate variable
    3177             :         Real64 FacRhoIR5bp;        // Intermediate variable
    3178             :         Real64 FacRhoIR4fpRhoIR85; // Intermediate variable
    3179             :         Real64 FacRhoIR5bpRhoIR47; // Intermediate variable
    3180             : 
    3181             :         int i; // Counter
    3182             : 
    3183    42038057 :         if (nglasslayer == 1) {
    3184    87014145 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3185    58009430 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3186    87014145 :             Bface(2) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] +
    3187    58009430 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[1];
    3188             : 
    3189    29004715 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3190    29004715 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3191    29004715 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3192    29004715 :             Aface(2, 2) = hr(2) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcin;
    3193             : 
    3194    29004715 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3195             :                 // interior shade, single pane
    3196             :                 //            ||   ||
    3197             :                 //  outside  1||2 3||4
    3198             :                 //            ||   ||
    3199             :                 //            gl  bl/sh/sc
    3200      221096 :                 Bface(2) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3201      110548 :                            state.dataWindowManager->AbsRadGlassFace[1];
    3202      110548 :                 Bface(3) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
    3203      110548 :                 Bface(4) =
    3204      110548 :                     state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
    3205             : 
    3206      110548 :                 Aface(2, 2) = hr(2) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
    3207      110548 :                 Aface(3, 2) = -state.dataWindowManager->emis[1] * hr(3) / ShGlReflFacIR;
    3208      110548 :                 Aface(2, 3) = -hr(2) * EpsShIR1 / ShGlReflFacIR;
    3209      110548 :                 Aface(3, 3) = hr(3) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
    3210      110548 :                 Aface(4, 3) = -sconsh;
    3211      110548 :                 Aface(3, 4) = -sconsh;
    3212      110548 :                 Aface(4, 4) = hr(4) + sconsh + state.dataWindowManager->hcin;
    3213             :             }
    3214             : 
    3215    29004715 :             if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3216             :                 // exterior shade, single pane
    3217             :                 //           ||      ||
    3218             :                 //  outside 3||4    1||2
    3219             :                 //           ||      ||
    3220             :                 //        bl/sh/sc   gl
    3221      144502 :                 Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3222       72251 :                            state.dataWindowManager->AbsRadGlassFace[0];
    3223       72251 :                 Bface(3) =
    3224       72251 :                     state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
    3225       72251 :                 Bface(4) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
    3226             : 
    3227       72251 :                 Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
    3228       72251 :                 Aface(4, 1) = -state.dataWindowManager->emis[0] * hr(4) / ShGlReflFacIR;
    3229       72251 :                 Aface(3, 3) = hr(3) + sconsh + state.dataWindowManager->hcout;
    3230       72251 :                 Aface(4, 3) = -sconsh;
    3231       72251 :                 Aface(1, 4) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
    3232       72251 :                 Aface(3, 4) = -sconsh;
    3233       72251 :                 Aface(4, 4) = hr(4) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
    3234             :             }
    3235             : 
    3236    13033342 :         } else if (nglasslayer == 2) {
    3237    12803273 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    3238    12803273 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    3239    12803273 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu;
    3240    12803273 :             if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
    3241     1325129 :                 state.dataWindowManager->hrgap[0] =
    3242     1325129 :                     0.5 * std::abs(state.dataWindowManager->A23) * pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
    3243     2650258 :                 hgap(1) = hgap(1) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
    3244     1325129 :                           state.dataWindowManager->hrgap[0] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
    3245             :             }
    3246             : 
    3247    38409819 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3248    25606546 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3249    12803273 :             Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
    3250    12803273 :             Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
    3251    38409819 :             Bface(4) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] +
    3252    25606546 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[3];
    3253             : 
    3254    12803273 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3255    12803273 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3256             : 
    3257    12803273 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3258    12803273 :             Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
    3259    12803273 :             Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
    3260             : 
    3261    12803273 :             Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
    3262    12803273 :             Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3263    12803273 :             Aface(4, 3) = -state.dataWindowManager->scon[1];
    3264             : 
    3265    12803273 :             Aface(3, 4) = -state.dataWindowManager->scon[1];
    3266    12803273 :             Aface(4, 4) = hr(4) + state.dataWindowManager->scon[1] + state.dataWindowManager->hcin;
    3267             : 
    3268    12803273 :             if (!ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
    3269        8045 :                 Bface(2) = state.dataWindowManager->AbsRadGlassFace[1] + hcvAirflowGap * TAirflowGapNew;
    3270        8045 :                 Bface(3) = state.dataWindowManager->AbsRadGlassFace[2] + hcvAirflowGap * TAirflowGapNew;
    3271        8045 :                 Aface(2, 2) = state.dataWindowManager->scon[0] + hcvAirflowGap - state.dataWindowManager->A23P * hr(2);
    3272        8045 :                 Aface(3, 2) = -state.dataWindowManager->A32P * hr(3);
    3273        8045 :                 Aface(2, 3) = state.dataWindowManager->A23P * hr(2);
    3274        8045 :                 Aface(3, 3) = hcvAirflowGap + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3275             :             }
    3276             : 
    3277    12803273 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3278      180098 :                 Bface(4) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3279       90049 :                            state.dataWindowManager->AbsRadGlassFace[3];
    3280       90049 :                 Bface(5) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
    3281       90049 :                 Bface(6) =
    3282       90049 :                     state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
    3283             : 
    3284       90049 :                 Aface(4, 4) = hr(4) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[1] + hcv;
    3285       90049 :                 Aface(5, 4) = -state.dataWindowManager->emis[3] * hr(5) / ShGlReflFacIR;
    3286       90049 :                 Aface(4, 5) = -hr(4) * EpsShIR1 / ShGlReflFacIR;
    3287       90049 :                 Aface(5, 5) = hr(5) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
    3288       90049 :                 Aface(6, 5) = -sconsh;
    3289       90049 :                 Aface(5, 6) = -sconsh;
    3290       90049 :                 Aface(6, 6) = hr(6) + sconsh + state.dataWindowManager->hcin;
    3291             :             }
    3292             : 
    3293    12803273 :             if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3294      117896 :                 Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3295       58948 :                            state.dataWindowManager->AbsRadGlassFace[0];
    3296       58948 :                 Bface(5) =
    3297       58948 :                     state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
    3298       58948 :                 Bface(6) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
    3299             : 
    3300       58948 :                 Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
    3301       58948 :                 Aface(6, 1) = -state.dataWindowManager->emis[0] * hr(6) / ShGlReflFacIR;
    3302       58948 :                 Aface(5, 5) = hr(5) + sconsh + state.dataWindowManager->hcout;
    3303       58948 :                 Aface(6, 5) = -sconsh;
    3304       58948 :                 Aface(1, 6) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
    3305       58948 :                 Aface(5, 6) = -sconsh;
    3306       58948 :                 Aface(6, 6) = hr(6) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
    3307             :             }
    3308             : 
    3309    12803273 :             if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3310      427238 :                 for (i = 1; i <= 6; ++i) {
    3311      366204 :                     RhoIR(i) = max(0.0, 1.0 - state.dataWindowManager->tir[i - 1] - state.dataWindowManager->emis[i - 1]);
    3312             :                 }
    3313       61034 :                 FacRhoIR25 = 1.0 - RhoIR(2) * RhoIR(5);
    3314       61034 :                 FacRhoIR63 = 1.0 - RhoIR(6) * RhoIR(3);
    3315       61034 :                 Real64 const tir_5_squared(pow_2(state.dataWindowManager->tir[4]));
    3316       61034 :                 RhoIRfp = RhoIR(5) + tir_5_squared * RhoIR(3) / FacRhoIR63;
    3317       61034 :                 RhoIRbp = RhoIR(6) + tir_5_squared * RhoIR(2) / FacRhoIR25;
    3318       61034 :                 FacRhoIR2fp = 1.0 - RhoIRfp * RhoIR(2);
    3319       61034 :                 FacRhoIR3bp = 1.0 - RhoIRbp * RhoIR(3);
    3320       61034 :                 FacRhoIR2fpRhoIR63 = FacRhoIR2fp * FacRhoIR63;
    3321       61034 :                 FacRhoIR3bpRhoIR25 = FacRhoIR3bp * FacRhoIR25;
    3322       61034 :                 Aface(2, 2) =
    3323       61034 :                     state.dataWindowManager->scon[0] + hcvBG(1) + hr(2) * (1 - RhoIRfp * (state.dataWindowManager->emis[1] + RhoIR(2))) / FacRhoIR2fp;
    3324       61034 :                 Aface(3, 2) = -state.dataWindowManager->emis[1] * hr(3) * state.dataWindowManager->tir[4] / FacRhoIR2fpRhoIR63;
    3325       61034 :                 Aface(5, 2) = -state.dataWindowManager->emis[1] * hr(5) / FacRhoIR2fp;
    3326       61034 :                 Aface(6, 2) = -state.dataWindowManager->emis[1] * hr(6) * RhoIR(3) * state.dataWindowManager->tir[4] / FacRhoIR2fpRhoIR63;
    3327       61034 :                 Bface(2) = hcvBG(1) * TGapNewBG(1) + state.dataWindowManager->AbsRadGlassFace[1];
    3328       61034 :                 Aface(2, 3) = -state.dataWindowManager->emis[2] * hr(2) * state.dataWindowManager->tir[4] / FacRhoIR3bpRhoIR25;
    3329       61034 :                 Aface(3, 3) =
    3330       61034 :                     state.dataWindowManager->scon[1] + hcvBG(2) + hr(3) * (1 - RhoIRbp * (state.dataWindowManager->emis[2] + RhoIR(3))) / FacRhoIR3bp;
    3331       61034 :                 Aface(5, 3) = -state.dataWindowManager->emis[2] * hr(5) * RhoIR(2) * state.dataWindowManager->tir[4] / FacRhoIR3bpRhoIR25;
    3332       61034 :                 Aface(6, 3) = -state.dataWindowManager->emis[2] * hr(6) / FacRhoIR3bp;
    3333       61034 :                 Bface(3) = hcvBG(2) * TGapNewBG(2) + state.dataWindowManager->AbsRadGlassFace[2];
    3334       61034 :                 Aface(2, 5) = -state.dataWindowManager->emis[4] * hr(2) / FacRhoIR2fp;
    3335       61034 :                 Aface(3, 5) = -hr(3) * state.dataWindowManager->tir[4] * RhoIR(2) * state.dataWindowManager->emis[4] / FacRhoIR2fpRhoIR63;
    3336       61034 :                 Aface(5, 5) = sconsh + hcvBG(1) + hr(5) * (1 - RhoIR(2) * state.dataWindowManager->emis[4] / FacRhoIR2fp);
    3337       61034 :                 Aface(6, 5) =
    3338       61034 :                     -sconsh - hr(6) * RhoIR(2) * state.dataWindowManager->tir[4] * RhoIR(3) * state.dataWindowManager->emis[4] / FacRhoIR2fpRhoIR63;
    3339       61034 :                 Bface(5) = hcvBG(1) * TGapNewBG(1) + AbsRadShadeFace(1);
    3340       61034 :                 Aface(2, 6) = -hr(2) * state.dataWindowManager->tir[4] * RhoIR(3) * state.dataWindowManager->emis[5] / FacRhoIR3bpRhoIR25;
    3341       61034 :                 Aface(3, 6) = -state.dataWindowManager->emis[5] * hr(3) / FacRhoIR3bp;
    3342       61034 :                 Aface(5, 6) =
    3343       61034 :                     -sconsh - hr(5) * RhoIR(3) * state.dataWindowManager->tir[4] * RhoIR(2) * state.dataWindowManager->emis[5] / FacRhoIR3bpRhoIR25;
    3344       61034 :                 Aface(6, 6) = sconsh + hcvBG(2) + hr(6) * (1 - RhoIR(3) * state.dataWindowManager->emis[5] / FacRhoIR3bp);
    3345       61034 :                 Bface(6) = hcvBG(2) * TGapNewBG(2) + AbsRadShadeFace(2);
    3346             :             }
    3347             : 
    3348      230069 :         } else if (nglasslayer == 3) {
    3349      123781 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    3350      123781 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    3351      123781 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu;
    3352      123781 :             if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
    3353       15026 :                 state.dataWindowManager->hrgap[0] =
    3354       15026 :                     0.5 * std::abs(state.dataWindowManager->A23) * pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
    3355       30052 :                 hgap(1) = hgap(1) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
    3356       15026 :                           state.dataWindowManager->hrgap[0] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
    3357             :             }
    3358             : 
    3359      123781 :             WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
    3360      123781 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
    3361      123781 :             hgap(2) = con / state.dataWindowManager->gap[1] * nu;
    3362      123781 :             if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
    3363       15026 :                 state.dataWindowManager->hrgap[1] =
    3364       15026 :                     0.5 * std::abs(state.dataWindowManager->A45) * pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
    3365       30052 :                 hgap(2) = hgap(2) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
    3366       15026 :                           state.dataWindowManager->hrgap[1] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
    3367             :             }
    3368             : 
    3369      371343 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3370      247562 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3371      123781 :             Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
    3372      123781 :             Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
    3373      123781 :             Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
    3374      123781 :             Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
    3375      371343 :             Bface(6) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] +
    3376      247562 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[5];
    3377             : 
    3378      123781 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3379      123781 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3380             : 
    3381      123781 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3382      123781 :             Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
    3383      123781 :             Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
    3384             : 
    3385      123781 :             Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
    3386      123781 :             Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3387      123781 :             Aface(4, 3) = -state.dataWindowManager->scon[1];
    3388             : 
    3389      123781 :             Aface(3, 4) = -state.dataWindowManager->scon[1];
    3390      123781 :             Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
    3391      123781 :             Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
    3392             : 
    3393      123781 :             Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
    3394      123781 :             Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
    3395      123781 :             Aface(6, 5) = -state.dataWindowManager->scon[2];
    3396             : 
    3397      123781 :             Aface(5, 6) = -state.dataWindowManager->scon[2];
    3398      123781 :             Aface(6, 6) = hr(6) + state.dataWindowManager->scon[2] + state.dataWindowManager->hcin;
    3399             : 
    3400      123781 :             if (!ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
    3401        8377 :                 Bface(4) = state.dataWindowManager->AbsRadGlassFace[3] + hcvAirflowGap * TAirflowGapNew;
    3402        8377 :                 Bface(5) = state.dataWindowManager->AbsRadGlassFace[4] + hcvAirflowGap * TAirflowGapNew;
    3403        8377 :                 Aface(4, 4) = state.dataWindowManager->scon[1] + hcvAirflowGap - state.dataWindowManager->A45P * hr(4);
    3404        8377 :                 Aface(5, 4) = -state.dataWindowManager->A54P * hr(5);
    3405        8377 :                 Aface(4, 5) = state.dataWindowManager->A45P * hr(4);
    3406        8377 :                 Aface(5, 5) = hcvAirflowGap + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
    3407             :             }
    3408             : 
    3409      123781 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3410       13120 :                 Bface(6) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3411        6560 :                            state.dataWindowManager->AbsRadGlassFace[5];
    3412        6560 :                 Bface(7) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
    3413        6560 :                 Bface(8) =
    3414        6560 :                     state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
    3415             : 
    3416        6560 :                 Aface(6, 6) = hr(6) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[2] + hcv;
    3417        6560 :                 Aface(7, 6) = -state.dataWindowManager->emis[5] * hr(7) / ShGlReflFacIR;
    3418        6560 :                 Aface(6, 7) = -hr(6) * EpsShIR1 / ShGlReflFacIR;
    3419        6560 :                 Aface(7, 7) = hr(7) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
    3420        6560 :                 Aface(8, 7) = -sconsh;
    3421        6560 :                 Aface(7, 8) = -sconsh;
    3422        6560 :                 Aface(8, 8) = hr(8) + sconsh + state.dataWindowManager->hcin;
    3423      117221 :             } else if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3424           0 :                 Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3425           0 :                            state.dataWindowManager->AbsRadGlassFace[0];
    3426           0 :                 Bface(7) =
    3427           0 :                     state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
    3428           0 :                 Bface(8) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
    3429             : 
    3430           0 :                 Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
    3431           0 :                 Aface(8, 1) = -state.dataWindowManager->emis[0] * hr(8) / ShGlReflFacIR;
    3432           0 :                 Aface(7, 7) = hr(7) + sconsh + state.dataWindowManager->hcout;
    3433           0 :                 Aface(8, 7) = -sconsh;
    3434           0 :                 Aface(1, 8) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
    3435           0 :                 Aface(7, 8) = -sconsh;
    3436           0 :                 Aface(8, 8) = hr(8) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
    3437      117221 :             } else if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3438      426726 :                 for (i = 1; i <= 8; ++i) {
    3439      379312 :                     RhoIR(i) = max(0.0, 1.0 - state.dataWindowManager->tir[i - 1] - state.dataWindowManager->emis[i - 1]);
    3440             :                 }
    3441       47414 :                 FacRhoIR47 = 1 - RhoIR(4) * RhoIR(7);
    3442       47414 :                 FacRhoIR85 = 1 - RhoIR(8) * RhoIR(5);
    3443       47414 :                 Real64 const tir_7_squared(pow_2(state.dataWindowManager->tir[6]));
    3444       47414 :                 RhoIRfp = RhoIR(7) + tir_7_squared * RhoIR(5) / FacRhoIR85;
    3445       47414 :                 RhoIRbp = RhoIR(8) + tir_7_squared * RhoIR(4) / FacRhoIR47;
    3446       47414 :                 FacRhoIR4fp = 1 - RhoIRfp * RhoIR(4);
    3447       47414 :                 FacRhoIR5bp = 1 - RhoIRbp * RhoIR(5);
    3448       47414 :                 FacRhoIR4fpRhoIR85 = FacRhoIR4fp * FacRhoIR85;
    3449       47414 :                 FacRhoIR5bpRhoIR47 = FacRhoIR5bp * FacRhoIR47;
    3450       47414 :                 Aface(4, 4) =
    3451       47414 :                     state.dataWindowManager->scon[1] + hcvBG(1) + hr(4) * (1 - RhoIRfp * (state.dataWindowManager->emis[3] + RhoIR(4))) / FacRhoIR4fp;
    3452       47414 :                 Aface(5, 4) = -state.dataWindowManager->emis[3] * hr(5) * state.dataWindowManager->tir[6] / FacRhoIR4fpRhoIR85;
    3453       47414 :                 Aface(7, 4) = -state.dataWindowManager->emis[3] * hr(7) / FacRhoIR4fp;
    3454       47414 :                 Aface(8, 4) = -state.dataWindowManager->emis[3] * hr(8) * RhoIR(5) * state.dataWindowManager->tir[6] / FacRhoIR4fpRhoIR85;
    3455       47414 :                 Bface(4) = hcvBG(1) * TGapNewBG(1) + state.dataWindowManager->AbsRadGlassFace[3];
    3456       47414 :                 Aface(4, 5) = -state.dataWindowManager->emis[4] * hr(4) * state.dataWindowManager->tir[6] / FacRhoIR5bpRhoIR47;
    3457       47414 :                 Aface(5, 5) =
    3458       47414 :                     state.dataWindowManager->scon[2] + hcvBG(2) + hr(5) * (1 - RhoIRbp * (state.dataWindowManager->emis[4] + RhoIR(5))) / FacRhoIR5bp;
    3459       47414 :                 Aface(7, 5) = -state.dataWindowManager->emis[4] * hr(7) * RhoIR(4) * state.dataWindowManager->tir[6] / FacRhoIR5bpRhoIR47;
    3460       47414 :                 Aface(8, 5) = -state.dataWindowManager->emis[4] * hr(8) / FacRhoIR5bp;
    3461       47414 :                 Bface(5) = hcvBG(2) * TGapNewBG(2) + state.dataWindowManager->AbsRadGlassFace[4];
    3462       47414 :                 Aface(4, 7) = -state.dataWindowManager->emis[6] * hr(4) / FacRhoIR4fp;
    3463       47414 :                 Aface(5, 7) = -hr(5) * state.dataWindowManager->tir[6] * RhoIR(4) * state.dataWindowManager->emis[6] / FacRhoIR4fpRhoIR85;
    3464       47414 :                 Aface(7, 7) = sconsh + hcvBG(1) + hr(7) * (1 - RhoIR(4) * state.dataWindowManager->emis[6] / FacRhoIR4fp);
    3465       47414 :                 Aface(8, 7) =
    3466       47414 :                     -sconsh - hr(8) * RhoIR(4) * state.dataWindowManager->tir[6] * RhoIR(5) * state.dataWindowManager->emis[6] / FacRhoIR4fpRhoIR85;
    3467       47414 :                 Bface(7) = hcvBG(1) * TGapNewBG(1) + AbsRadShadeFace(1);
    3468       47414 :                 Aface(4, 8) = -hr(4) * state.dataWindowManager->tir[6] * RhoIR(5) * state.dataWindowManager->emis[7] / FacRhoIR5bpRhoIR47;
    3469       47414 :                 Aface(5, 8) = -state.dataWindowManager->emis[7] * hr(5) / FacRhoIR5bp;
    3470       47414 :                 Aface(7, 8) =
    3471       47414 :                     -sconsh - hr(7) * RhoIR(5) * state.dataWindowManager->tir[6] * RhoIR(4) * state.dataWindowManager->emis[7] / FacRhoIR5bpRhoIR47;
    3472       47414 :                 Aface(8, 8) = sconsh + hcvBG(2) + hr(8) * (1 - RhoIR(5) * state.dataWindowManager->emis[7] / FacRhoIR5bp);
    3473       47414 :                 Bface(8) = hcvBG(2) * TGapNewBG(2) + AbsRadShadeFace(2);
    3474             :             }
    3475             : 
    3476      106288 :         } else if (nglasslayer == 4) {
    3477      106288 :             WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
    3478      106288 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
    3479      106288 :             hgap(1) = con / state.dataWindowManager->gap[0] * nu;
    3480      106288 :             if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
    3481           0 :                 state.dataWindowManager->hrgap[0] =
    3482           0 :                     0.5 * std::abs(state.dataWindowManager->A23) * pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
    3483           0 :                 hgap(1) = hgap(1) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
    3484           0 :                           state.dataWindowManager->hrgap[0] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
    3485             :             }
    3486             : 
    3487      106288 :             WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
    3488      106288 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
    3489      106288 :             hgap(2) = con / state.dataWindowManager->gap[1] * nu;
    3490      106288 :             if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
    3491           0 :                 state.dataWindowManager->hrgap[1] =
    3492           0 :                     0.5 * std::abs(state.dataWindowManager->A45) * pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
    3493           0 :                 hgap(2) = hgap(2) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
    3494           0 :                           state.dataWindowManager->hrgap[1] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
    3495             :             }
    3496             : 
    3497      106288 :             WindowGasConductance(state, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, con, pr, gr);
    3498      106288 :             NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, gr, pr, nu);
    3499      106288 :             hgap(3) = con / state.dataWindowManager->gap[2] * nu;
    3500      106288 :             if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
    3501           0 :                 state.dataWindowManager->hrgap[2] =
    3502           0 :                     0.5 * std::abs(state.dataWindowManager->A67) * pow_3(state.dataWindowManager->thetas[5] + state.dataWindowManager->thetas[6]);
    3503           0 :                 hgap(3) = hgap(3) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
    3504           0 :                           state.dataWindowManager->hrgap[2] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
    3505             :             }
    3506      318864 :             Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
    3507      212576 :                        state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
    3508      106288 :             Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
    3509      106288 :             Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
    3510      106288 :             Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
    3511      106288 :             Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
    3512      106288 :             Bface(6) = state.dataWindowManager->AbsRadGlassFace[5];
    3513      106288 :             Bface(7) = state.dataWindowManager->AbsRadGlassFace[6];
    3514      318864 :             Bface(8) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] +
    3515      212576 :                        state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[7];
    3516             : 
    3517      106288 :             Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
    3518      106288 :             Aface(2, 1) = -state.dataWindowManager->scon[0];
    3519             : 
    3520      106288 :             Aface(1, 2) = -state.dataWindowManager->scon[0];
    3521      106288 :             Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
    3522      106288 :             Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
    3523             : 
    3524      106288 :             Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
    3525      106288 :             Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
    3526      106288 :             Aface(4, 3) = -state.dataWindowManager->scon[1];
    3527             : 
    3528      106288 :             Aface(3, 4) = -state.dataWindowManager->scon[1];
    3529      106288 :             Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
    3530      106288 :             Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
    3531             : 
    3532      106288 :             Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
    3533      106288 :             Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
    3534      106288 :             Aface(6, 5) = -state.dataWindowManager->scon[2];
    3535             : 
    3536      106288 :             Aface(5, 6) = -state.dataWindowManager->scon[2];
    3537      106288 :             Aface(6, 6) = state.dataWindowManager->scon[2] + hgap(3) - state.dataWindowManager->A67P * hr(6);
    3538      106288 :             Aface(7, 6) = -hgap(3) - state.dataWindowManager->A76P * hr(7);
    3539             : 
    3540      106288 :             Aface(6, 7) = -hgap(3) + state.dataWindowManager->A67P * hr(6);
    3541      106288 :             Aface(7, 7) = hgap(3) + state.dataWindowManager->scon[3] + state.dataWindowManager->A76P * hr(7);
    3542      106288 :             Aface(8, 7) = -state.dataWindowManager->scon[3];
    3543             : 
    3544      106288 :             Aface(7, 8) = -state.dataWindowManager->scon[3];
    3545      106288 :             Aface(8, 8) = hr(8) + state.dataWindowManager->scon[3] + state.dataWindowManager->hcin;
    3546             : 
    3547      106288 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3548           0 :                 Bface(8) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3549           0 :                            state.dataWindowManager->AbsRadGlassFace[7];
    3550           0 :                 Bface(9) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
    3551           0 :                 Bface(10) =
    3552           0 :                     state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
    3553             : 
    3554           0 :                 Aface(8, 8) = hr(8) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[3] + hcv;
    3555           0 :                 Aface(9, 8) = -state.dataWindowManager->emis[7] * hr(9) / ShGlReflFacIR;
    3556           0 :                 Aface(8, 9) = -hr(8) * EpsShIR1 / ShGlReflFacIR;
    3557           0 :                 Aface(9, 9) = hr(9) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
    3558           0 :                 Aface(10, 9) = -sconsh;
    3559           0 :                 Aface(9, 10) = -sconsh;
    3560           0 :                 Aface(10, 10) = hr(10) + sconsh + state.dataWindowManager->hcin;
    3561             :             }
    3562             : 
    3563      106288 :             if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3564           0 :                 Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
    3565           0 :                            state.dataWindowManager->AbsRadGlassFace[0];
    3566           0 :                 Bface(9) =
    3567           0 :                     state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
    3568           0 :                 Bface(10) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
    3569             : 
    3570           0 :                 Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
    3571           0 :                 Aface(10, 1) = -state.dataWindowManager->emis[0] * hr(10) / ShGlReflFacIR;
    3572           0 :                 Aface(9, 9) = hr(9) + sconsh + state.dataWindowManager->hcout;
    3573           0 :                 Aface(10, 9) = -sconsh;
    3574           0 :                 Aface(1, 10) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
    3575           0 :                 Aface(9, 10) = -sconsh;
    3576           0 :                 Aface(10, 10) = hr(10) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
    3577             :             }
    3578             : 
    3579             :         } else {
    3580           0 :             ShowFatalError(
    3581           0 :                 state, format("SolveForWindowTemperatures: Invalid number of Glass Layers={}, up to 4 allowed.", state.dataWindowManager->ngllayer));
    3582             :         }
    3583    42038057 :     }
    3584             : 
    3585    22607285 :     void SolveForWindowTemperatures(EnergyPlusData &state, int const SurfNum) // Surface number
    3586             :     {
    3587             : 
    3588             :         // SUBROUTINE INFORMATION:
    3589             :         //       AUTHOR         F. Winkelmann
    3590             :         //       DATE WRITTEN   July 2000
    3591             :         //       MODIFIED       Oct 2000, FW: modify edge-of-glass correction to account
    3592             :         //                       for gap radiative conductance affects
    3593             :         //                      Feb 2001, FW: add interior or exterior shade to layer
    3594             :         //                       heat balance calculation.
    3595             :         //                      Mar 2001, FW: relax error tolerance if MaxIterations reached.
    3596             :         //                      Jun 2001, FW: add interior or exterior blind
    3597             :         //                      Nov 2002, FW: add relaxation on face temperatures
    3598             :         //                       to improve convergence for multipane cases where outer pane
    3599             :         //                       has high solar absorptance: temp --> 0.5*(temp + previous temp);
    3600             :         //                       also, increase MaxIterations from 50 to 100.
    3601             :         //                      Dec 2002, FW: add between-glass shade/blind for double and triple glazing.
    3602             :         //                      Mar 2003, FW: remove redundant relaxation on radiative conductances
    3603             :         //                      Mar 2003, FW: increase convergence tolerance from 0.01 to 0.02 to enhance
    3604             :         //                                    convergence in difficult cases.
    3605             :         //                      June 2003, FW: correct the expression for convective gain to zone air
    3606             :         //                       from airflow windows with airflow destination = InsideAir. Previously
    3607             :         //                       convective gain of air as it passed through gap was used, which is correct
    3608             :         //                       for airflow source = InsideAir but incorrect for airflow source = OutsideAir.
    3609             :         //                       Save SurfaceWindow%TAirflowGapOutlet for use in calculating convective heat
    3610             :         //                       gain to return air when airflow source = InsideAir, destination = ReturnAir.
    3611             :         //                      Dec 2003, FW: enhance converge for difficult cases by increasing relaxation
    3612             :         //                       in layer surface temperatures for iterations > MaxIterations/4
    3613             :         //                      May 2006, RR: add exterior window screen
    3614             :         //                      January 2009, BG: inserted call to recalc inside face convection inside iteration loop
    3615             :         //                        per ISO 15099 Section 8.3.2.2
    3616             :         //       RE-ENGINEERED  na
    3617             : 
    3618             :         // PURPOSE OF THIS SUBROUTINE:
    3619             :         // Evaluates the coefficients Aface and Bface in the system of linear
    3620             :         // algebraic equations
    3621             :         //     Sum [Aface(i,j)*thetas(j)] = Bface(i), i = 1,nglfacep, j=1,nglfacep
    3622             :         // where
    3623             :         // nglface  = number of glass faces (= 2 * number of glass layers), or, if shade or blind is present,
    3624             :         // nglgacep = number of glass faces + 2
    3625             :         // thetas(j) = temperature of face j
    3626             :         // If an interior, exterior or between-glass shade or blind, or exterior screen is present
    3627             :         // the face numbering is as follows:
    3628             :         //   1 to 2*nglface are glass faces, from outside to inside;
    3629             :         //   2*nglface+1 and 2*nglface+2 are the shade or blind faces, from outside to inside
    3630             :         // For example, the following diagram shows the face number for an exterior shade, screen or blind
    3631             :         // on double glazing:
    3632             :         //     ||   ||   ||
    3633             :         //    5||6 1||2 3||4
    3634             :         //     ||   ||   ||
    3635             :         // bl/sh/sc gl   gl
    3636             : 
    3637             :         // And for a between-glass shade/blind in triple glazing:
    3638             :         //     ||   ||   ||   ||
    3639             :         //    1||2 3||4 7||8 5||6
    3640             :         //     ||   ||   ||   ||
    3641             :         //     gl   gl  bl/sh gl
    3642             : 
    3643             :         // METHODOLOGY EMPLOYED:
    3644             :         // The Aface and Bface coefficients are determined by the equations for
    3645             :         // heat balance at the glass and shade/blind faces. The system of linear equations is solved
    3646             :         // by LU decomposition.
    3647             : 
    3648             :         // Using/Aliasing
    3649             :         using ConvectionCoefficients::CalcISO15099WindowIntConvCoeff;
    3650             :         using General::InterpSw;
    3651             :         using Psychrometrics::PsyCpAirFnW;
    3652             :         using Psychrometrics::PsyHFnTdbW;
    3653             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
    3654             :         using Psychrometrics::PsyTdbFnHW;
    3655             : 
    3656    22607285 :         constexpr int MaxIterations(100); // Maximum allowed number of iterations (increased 9/01 from 15 to 50,
    3657             :         //   increased 11/02 from 50 to 100)
    3658    22607285 :         constexpr Real64 errtemptol(0.02); // Tolerance on errtemp for convergence (increased from 0.01, 3/4/03)
    3659             : 
    3660             :         int ZoneNum; // Zone number corresponding to SurfNum
    3661             :         int i;       // Counter
    3662             :         Real64 d;    // +1 if number of row interchanges is even,
    3663             :         // -1 if odd (in LU decomposition)
    3664             : 
    3665    22607285 :         auto &hr = state.dataWindowManager->hr;
    3666    22607285 :         auto &indx = state.dataWindowManager->indx;
    3667    22607285 :         auto &Aface = state.dataWindowManager->Aface;
    3668    22607285 :         auto &Bface = state.dataWindowManager->Bface;
    3669    22607285 :         auto &TGapNewBG = state.dataWindowManager->TGapNewBG;
    3670    22607285 :         auto &hcvBG = state.dataWindowManager->hcvBG;
    3671    22607285 :         auto &AbsRadShadeFace = state.dataWindowManager->AbsRadShadeFace;
    3672             : 
    3673    22607285 :         int iter = 0;                    // Iteration number
    3674    22607285 :         Real64 errtemp = 0.0;            // Absolute value of sum of face temperature differences between iterations, divided by number of faces
    3675    22607285 :         Real64 VGap = 0.0;               // Air velocity in gap between glass and shade/blind (m/s)
    3676    22607285 :         Real64 VAirflowGap = 0.0;        // Air velocity in airflow gap between glass panes (m/s)
    3677    22607285 :         Real64 VGapPrev = 0.0;           // Value of VGap from previous iteration
    3678    22607285 :         Real64 TGapNew = 0.0;            // Average air temp in gap between glass and shade/blind (K)
    3679    22607285 :         Real64 TAirflowGapNew = 0.0;     // Average air temp in airflow gap between glass panes (K)
    3680    22607285 :         Real64 TGapOutlet = 0.0;         // Temperature of air leaving gap between glass and shade/blind (K)
    3681    22607285 :         Real64 TAirflowGapOutlet = 0.0;  // Temperature of air leaving airflow gap between glass panes (K)
    3682    22607285 :         Real64 TAirflowGapOutletC = 0.0; // Temperature of air leaving airflow gap between glass panes (C)
    3683    22607285 :         Real64 hcv = 0.0;                // Convection coefficient from gap glass or shade/blind to gap air (W/m2-K)
    3684    22607285 :         Real64 hcvAirflowGap = 0.0;      // Convection coefficient from airflow gap glass to airflow gap air (W/m2-K)
    3685    22607285 :         Real64 hcvPrev = 0.0;            // Value of hcv from previous iteration
    3686    22607285 :         Real64 ConvHeatFlowForced = 0.0; // Convective heat flow from forced airflow gap (W)
    3687    22607285 :         Real64 ShGlReflFacIR = 0.0;      // Factor for long-wave inter-reflection between shade/blind and adjacent glass
    3688    22607285 :         Real64 RhoGlIR1 = 0.0;           // Long-wave reflectance of glass surface facing shade/blind; 1=exterior shade/blind,
    3689    22607285 :         Real64 RhoGlIR2 = 0.0;
    3690             :         //  2=exterior shade/blind
    3691    22607285 :         Real64 EpsShIR1 = 0.0; // Long-wave emissivity of shade/blind surface facing glass; 1=interior shade/blind,
    3692    22607285 :         Real64 EpsShIR2 = 0.0;
    3693             :         //  2=interior shade/blind
    3694    22607285 :         Real64 RhoShIR1 = 0.0; // Long-wave reflectance of shade/blind surface facing glass; 1=interior shade/blind,
    3695    22607285 :         Real64 RhoShIR2 = 0.0;
    3696             :         //  2=exterior shade/blind
    3697    22607285 :         Real64 TauShIR = 0.0; // Long-wave transmittance of isolated shade/blind
    3698    22607285 :         Real64 sconsh = 0.0;  // shade/blind conductance (W/m2-K)
    3699             : 
    3700    22607285 :         WinShadingType ShadeFlag = WinShadingType::NoShade; // Shading flag
    3701             :         //  radiation from lights and zone equipment absorbed by faces of shade/blind (W/m2)
    3702    22607285 :         Real64 ShadeArea = 0.0; // shade/blind area (m2)
    3703             :         // Real64 CondHeatGainGlass = 0.0; // Conduction through inner glass layer, outside to inside (W)
    3704             :         // Real64 CondHeatGainShade = 0.0; // Conduction through shade/blind, outside to inside (W)
    3705             :         //  shade/blind is present. Zero if shade/blind has zero IR transmittance (W)
    3706             :         // Real64 IncidentSolar = 0.0;         // Solar incident on outside of window (W)
    3707    22607285 :         Real64 TransDiff = 0.0;      // Diffuse shortwave transmittance
    3708    22607285 :         Real64 TotAirflowGap = 0.0;  // Total volumetric airflow through window gap (m3/s)
    3709    22607285 :         Real64 CpAirOutlet = 0.0;    // Heat capacity of air from window gap (J/kg-K)
    3710    22607285 :         Real64 CpAirZone = 0.0;      // Heat capacity of zone air (J/kg-K)
    3711    22607285 :         Real64 InletAirHumRat = 0.0; // Humidity ratio of air from window gap entering fan
    3712    22607285 :         int InsideFaceIndex = 0;     // intermediate variable for index of inside face in thetas
    3713             : 
    3714    22607285 :         state.dataWindowManager->nglfacep = state.dataWindowManager->nglface;
    3715    22607285 :         ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3716    22607285 :         ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
    3717    22607285 :         AbsRadShadeFace = 0.0;
    3718             : 
    3719    22607285 :         if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) {
    3720       71522 :             state.dataWindowManager->nglfacep = state.dataWindowManager->nglface + 2;
    3721       71522 :             AbsRadShadeFace(1) = DataSurfaces::AbsFrontSide(state, SurfNum);
    3722       71522 :             AbsRadShadeFace(2) = DataSurfaces::AbsBackSide(state, SurfNum);
    3723       71522 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) AbsRadShadeFace(2) += state.dataSurface->SurfWinIntLWAbsByShade(SurfNum);
    3724       71522 :             sconsh = state.dataWindowManager->scon[state.dataWindowManager->ngllayer];
    3725       71522 :             TauShIR = state.dataWindowManager->tir[state.dataWindowManager->nglface];
    3726       71522 :             EpsShIR1 = state.dataWindowManager->emis[state.dataWindowManager->nglface];
    3727       71522 :             EpsShIR2 = state.dataWindowManager->emis[state.dataWindowManager->nglface + 1];
    3728       71522 :             RhoShIR1 = max(0.0, 1.0 - TauShIR - EpsShIR1);
    3729       71522 :             RhoShIR2 = max(0.0, 1.0 - TauShIR - EpsShIR2);
    3730       71522 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3731       40940 :                 RhoGlIR2 = 1.0 - state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer - 1];
    3732       40940 :                 ShGlReflFacIR = 1.0 - RhoGlIR2 * RhoShIR1;
    3733       30582 :             } else if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3734       13712 :                 RhoGlIR1 = 1.0 - state.dataWindowManager->emis[0];
    3735       13712 :                 ShGlReflFacIR = 1.0 - RhoGlIR1 * RhoShIR2;
    3736             :             }
    3737             :         } // End of check if shade or blind is on
    3738             : 
    3739             :         // Initialize face temperatures.
    3740             : 
    3741    22607285 :         StartingWindowTemps(state, SurfNum, AbsRadShadeFace);
    3742             : 
    3743    22607285 :         hcvPrev = 0.0;
    3744    22607285 :         VGapPrev = 0.0;
    3745             : 
    3746             :         // Calculate radiative conductances
    3747             : 
    3748    22607285 :         errtemp = errtemptol * 2.0;
    3749             : 
    3750   106683399 :         while (iter < MaxIterations && errtemp > errtemptol) {
    3751             : 
    3752   153747177 :             for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
    3753   111709120 :                 hr(i) = state.dataWindowManager->emis[i - 1] * state.dataWindowManager->sigma * pow_3(state.dataWindowManager->thetas[i - 1]);
    3754             :                 // Following line is redundant since thetas is being relaxed;
    3755             :                 // removed by FCW, 3/4/03
    3756             :                 //! fw if ( iter >= 1 ) hr(i) = 0.5*(hrprev(i)+hr(i))
    3757             :             }
    3758             : 
    3759             :             // call for new interior film coeff (since it is temperature dependent) if using Detailed inside coef model
    3760   126114171 :             if (((state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == 0) &&
    3761    51652553 :                  (state.dataHeatBal->Zone(ZoneNum).InsideConvectionAlgo == ConvectionConstants::HcInt_ASHRAETARP)) ||
    3762     9614496 :                 (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == -2)) {
    3763             :                 // coef model is "detailed" and not prescribed by user
    3764             :                 // need to find inside face index, varies with shade/blind etc.
    3765    32423561 :                 if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3766      207157 :                     InsideFaceIndex = state.dataWindowManager->nglfacep;
    3767             :                 } else {
    3768    32216404 :                     InsideFaceIndex = state.dataWindowManager->nglface;
    3769             :                 }
    3770    64847122 :                 CalcISO15099WindowIntConvCoeff(state,
    3771             :                                                SurfNum,
    3772    32423561 :                                                state.dataWindowManager->thetas[InsideFaceIndex - 1] - DataGlobalConstants::KelvinConv,
    3773    32423561 :                                                state.dataWindowManager->tin - DataGlobalConstants::KelvinConv);
    3774    32423561 :                 state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    3775             :             }
    3776             : 
    3777    42038057 :             Aface = 0.0;
    3778    42038057 :             Bface = 0.0;
    3779             : 
    3780             :             // If interior or exterior shade or blind is present, get heat transfer
    3781             :             // coefficient from glass and shade/blind to gap between glass and shade/blind,
    3782             :             // effective gap air temperature, velocity of air in gap and gap outlet temperature.
    3783             : 
    3784    42038057 :             if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) || ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3785      338356 :                 ExtOrIntShadeNaturalFlow(
    3786      338356 :                     state, SurfNum, iter, VGap, TGapNew, TGapOutlet, hcv, state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum));
    3787      338356 :                 if (iter >= 1) {
    3788      283704 :                     hcv = 0.5 * (hcvPrev + hcv);
    3789      283704 :                     VGap = 0.5 * (VGapPrev + VGap);
    3790             :                 }
    3791      338356 :                 hcvPrev = hcv;
    3792      338356 :                 VGapPrev = VGap;
    3793             :             }
    3794             : 
    3795    42038057 :             TAirflowGapOutlet = 0.0;
    3796             :             // If between-glass shade or blind is not present and this is an airflow window
    3797             :             // (i.e., with forced airflow in the gap for double glass or in the inner gap for triple glass)
    3798             :             // get glass-to-air forced convection heat transfer coefficient, average gap air temperature, and
    3799             :             // convective heat flow from gap.
    3800             : 
    3801    42038057 :             if (!ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
    3802       16422 :                 BetweenGlassForcedFlow(state, SurfNum, iter, VAirflowGap, TAirflowGapNew, TAirflowGapOutlet, hcvAirflowGap, ConvHeatFlowForced);
    3803             :             }
    3804             : 
    3805             :             // If between-glass shade or blind is present, get convective heat transfer
    3806             :             // coefficients from glass and shade/blind to the two gaps on either side of the shade/blind.
    3807             :             // Also get average gas temperature in the two gaps, and, for airflow window, the sum of the
    3808             :             // convective heat flows from the gaps.
    3809             : 
    3810    42038057 :             if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3811      108448 :                 if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) == 0.0) { // Natural convection in gaps
    3812       88448 :                     BetweenGlassShadeNaturalFlow(state, SurfNum, iter, VGap, TGapNewBG, hcvBG);
    3813             :                 } else { // Forced convection in gaps
    3814       20000 :                     BetweenGlassShadeForcedFlow(state, SurfNum, iter, VGap, TGapNewBG, TAirflowGapOutlet, hcvBG, ConvHeatFlowForced);
    3815             :                 }
    3816             :             }
    3817             : 
    3818    42038057 :             ++iter;
    3819             : 
    3820             :             // Calculations based on number of glass layers
    3821    84076114 :             GetHeatBalanceEqCoefMatrix(state,
    3822             :                                        SurfNum,
    3823    42038057 :                                        state.dataWindowManager->ngllayer,
    3824             :                                        ShadeFlag,
    3825             :                                        sconsh,
    3826             :                                        TauShIR,
    3827             :                                        EpsShIR1,
    3828             :                                        EpsShIR2,
    3829             :                                        RhoShIR1,
    3830             :                                        RhoShIR2,
    3831             :                                        ShGlReflFacIR,
    3832             :                                        RhoGlIR1,
    3833             :                                        RhoGlIR2,
    3834             :                                        hcv,
    3835             :                                        TGapNew,
    3836             :                                        TAirflowGapNew,
    3837             :                                        hcvAirflowGap,
    3838             :                                        hcvBG,
    3839             :                                        TGapNewBG,
    3840             :                                        AbsRadShadeFace,
    3841             :                                        hr,
    3842             :                                        Aface,
    3843             :                                        Bface);
    3844    42038057 :             LUdecomposition(state, Aface, state.dataWindowManager->nglfacep, indx,
    3845             :                             d); // Note that these routines change Aface;
    3846    42038057 :             LUsolution(Aface, state.dataWindowManager->nglfacep, indx,
    3847             :                        Bface); // face temperatures are returned in Bface
    3848             : 
    3849   153747177 :             for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
    3850   111709120 :                 state.dataWindowManager->thetasPrev[i - 1] = state.dataWindowManager->thetas[i - 1];
    3851   111709120 :                 if (iter < MaxIterations / 4) {
    3852   111709088 :                     state.dataWindowManager->thetas[i - 1] = 0.5 * state.dataWindowManager->thetas[i - 1] + 0.5 * Bface(i);
    3853             :                 } else {
    3854          32 :                     state.dataWindowManager->thetas[i - 1] = 0.75 * state.dataWindowManager->thetas[i - 1] + 0.25 * Bface(i);
    3855             :                 }
    3856             :             }
    3857             : 
    3858    42038057 :             errtemp = 0.0;
    3859   153747177 :             for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
    3860   111709120 :                 errtemp += std::abs(state.dataWindowManager->thetas[i - 1] - state.dataWindowManager->thetasPrev[i - 1]);
    3861             :             }
    3862    42038057 :             errtemp /= state.dataWindowManager->nglfacep;
    3863             :         }
    3864             : 
    3865    22607285 :         state.dataSurface->SurfWinWindowCalcIterationsRep(SurfNum) = iter;
    3866             : 
    3867             :         // We have reached iteration limit or we have converged. If we have reached the
    3868             :         // iteration limit the following test relaxes the convergence tolerance.
    3869             :         // If we have converged (errtemp <= errtemptol) the following test has not effect.
    3870             : 
    3871    22607285 :         if (errtemp < 10 * errtemptol) {
    3872             : 
    3873             :             // Window heat balance solution has converged.
    3874             : 
    3875             :             // For interior shade, add convective gain from glass/shade gap air flow to zone convective gain;
    3876             :             // For all cases, get total window heat gain for reporting. See CalcWinFrameAndDividerTemps for
    3877             :             // contribution of frame and divider.
    3878             :             // IncidentSolar = state.dataSurface->Surface(SurfNum).Area * state.dataHeatBal->SurfQRadSWOutIncident(SurfNum);
    3879    22607285 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    3880             :                 // Interior shade or blind
    3881             :                 // Window heat gain from glazing and shade/blind to zone. Consists of transmitted solar, convection
    3882             :                 //   from air exiting gap, convection from zone-side of shade/blind, net IR to zone from shade and net IR to
    3883             :                 //   zone from the glass adjacent to the shade/blind (zero if shade/blind IR transmittance is zero).
    3884             :                 // Following assumes glazed area = window area (i.e., dividers ignored) in calculating
    3885             :                 //   IR to zone from glass when interior shade/blind is present.
    3886       40940 :                 ShadeArea = state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum);
    3887             :                 // CondHeatGainShade = ShadeArea * sconsh *
    3888             :                 //                     (state.dataWindowManager->thetas(state.dataWindowManager->nglfacep - 1) -
    3889             :                 //                     state.dataWindowManager->thetas[state.dataWindowManager->nglfacep-1]);
    3890       40940 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) =
    3891       81880 :                     ShadeArea * EpsShIR2 *
    3892      122820 :                         (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[state.dataWindowManager->nglfacep - 1]) -
    3893       81880 :                          state.dataWindowManager->Rmir) +
    3894       40940 :                     EpsShIR1 *
    3895      122820 :                         (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[state.dataWindowManager->nglfacep - 2]) -
    3896       81880 :                          state.dataWindowManager->Rmir) *
    3897       40940 :                         RhoGlIR2 * TauShIR / ShGlReflFacIR;
    3898       40940 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
    3899       81880 :                     ShadeArea * (state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer - 1] * TauShIR / ShGlReflFacIR) *
    3900      122820 :                     (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1]) -
    3901       40940 :                      state.dataWindowManager->Rmir);
    3902       40940 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) =
    3903       81880 :                     ShadeArea * state.dataWindowManager->hcin *
    3904       40940 :                     (state.dataWindowManager->thetas[state.dataWindowManager->nglfacep - 1] - state.dataWindowManager->tin);
    3905       40940 :                 state.dataSurface->SurfWinHeatGain(SurfNum) =
    3906       81880 :                     state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) +
    3907      122820 :                     state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) + state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) +
    3908       40940 :                     state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum);
    3909             :             } else {
    3910             :                 // Interior shade or blind not present; innermost layer is glass
    3911             :                 // CondHeatGainGlass = state.dataSurface->Surface(SurfNum).Area * state.dataWindowManager->scon(state.dataWindowManager->ngllayer) *
    3912             :                 //                     (state.dataWindowManager->thetas(2 * state.dataWindowManager->ngllayer - 1) -
    3913             :                 //                     state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1]);
    3914    22566345 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
    3915    45132690 :                     state.dataSurface->Surface(SurfNum).Area * state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer - 1] *
    3916    67699035 :                     (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1]) -
    3917    22566345 :                      state.dataWindowManager->Rmir);
    3918    22566345 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
    3919    45132690 :                     state.dataSurface->Surface(SurfNum).Area * state.dataWindowManager->hcin *
    3920    22566345 :                     (state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->tin);
    3921    67699035 :                 state.dataSurface->SurfWinHeatGain(SurfNum) = state.dataSurface->SurfWinTransSolar(SurfNum) +
    3922    45132690 :                                                               state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
    3923    22566345 :                                                               state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum);
    3924             :             }
    3925             : 
    3926             :             // Add convective heat gain from airflow window
    3927             :             // Note: effect of fan heat on gap outlet temperature is neglected since fan power (based
    3928             :             // on pressure drop through the gap) is extremely small
    3929             : 
    3930    22607285 :             state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
    3931    22607285 :             state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
    3932    22607285 :             TotAirflowGap = state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width;
    3933    22607285 :             TAirflowGapOutletC = TAirflowGapOutlet - state.dataWindowManager->TKelvin;
    3934    22607285 :             state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum) = TAirflowGapOutletC;
    3935    22607285 :             if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
    3936       16128 :                 state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = ConvHeatFlowForced;
    3937       16128 :                 state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) =
    3938       16128 :                     state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3939             :                 // Add heat from gap airflow to zone air if destination is inside air; save the heat gain to return
    3940             :                 // air in case it needs to be sent to the zone (due to no return air determined in HVAC simulation)
    3941       32256 :                 if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor ||
    3942       16128 :                     state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Return) {
    3943           0 :                     auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    3944           0 :                     if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
    3945           0 :                         InletAirHumRat = thisZoneHB.ZoneAirHumRat;
    3946             :                     } else { // AirflowSource = outside air
    3947           0 :                         InletAirHumRat = state.dataEnvrn->OutHumRat;
    3948             :                     }
    3949           0 :                     Real64 ZoneTemp = thisZoneHB.MAT; // this should be Tin (account for different reference temps)
    3950           0 :                     CpAirOutlet = PsyCpAirFnW(InletAirHumRat);
    3951           0 :                     CpAirZone = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat);
    3952           0 :                     state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) =
    3953           0 :                         TotAirflowGap * (CpAirOutlet * (TAirflowGapOutletC)-CpAirZone * ZoneTemp);
    3954           0 :                     if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor) {
    3955           0 :                         state.dataSurface->SurfWinHeatGain(SurfNum) += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum);
    3956             :                     }
    3957             :                 }
    3958             :                 // For AirflowDestination = ReturnAir in a controlled (i.e., conditioned) zone with return air, see CalcZoneLeavingConditions
    3959             :                 // for calculation of modification of return-air temperature due to airflow from window gaps into return air.
    3960             :             }
    3961             : 
    3962             :             // Correct WinHeatGain for interior diffuse shortwave (solar and shortwave from lights) transmitted
    3963             :             // back out window
    3964    22607285 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3965    22607285 :             int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    3966             : 
    3967    22607285 :             TransDiff = state.dataConstruction->Construct(ConstrNum).TransDiff; // Default value for TransDiff here
    3968    22607285 :             if (NOT_SHADED(ShadeFlag)) {
    3969    22464509 :                 TransDiff = state.dataConstruction->Construct(ConstrNum).TransDiff;
    3970      142776 :             } else if (ANY_SHADE_SCREEN(ShadeFlag)) {
    3971       41718 :                 TransDiff = state.dataConstruction->Construct(ConstrNumSh).TransDiff;
    3972      101058 :             } else if (ANY_BLIND(ShadeFlag)) {
    3973       29804 :                 if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
    3974        9366 :                     TransDiff = General::InterpGeneral(
    3975        3122 :                         state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
    3976        3122 :                         state.dataConstruction->Construct(ConstrNumSh)
    3977        6244 :                             .BlTransDiff(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
    3978        3122 :                         state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
    3979             :                 } else {
    3980       26682 :                     TransDiff = state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(1);
    3981             :                 }
    3982       71254 :             } else if (ShadeFlag == WinShadingType::SwitchableGlazing) {
    3983      142508 :                 TransDiff = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    3984       71254 :                                      state.dataConstruction->Construct(ConstrNum).TransDiff,
    3985       71254 :                                      state.dataConstruction->Construct(ConstrNumSh).TransDiff);
    3986             :             }
    3987             :             // shouldn't this be + outward flowing fraction of absorbed SW? -- do not know whose comment this is?  LKL (9/2012)
    3988    22607285 :             state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
    3989    22607285 :                 state.dataHeatBal->EnclSolQSWRad(state.dataSurface->Surface(SurfNum).SolarEnclIndex) * state.dataSurface->Surface(SurfNum).Area *
    3990             :                 TransDiff;
    3991    22607285 :             state.dataSurface->SurfWinHeatGain(SurfNum) -= state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum);
    3992             : 
    3993    22607285 :             if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) {
    3994       71522 :                 state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) =
    3995      143044 :                     (state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum)) *
    3996       71522 :                     (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum));
    3997       71522 :                 state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) =
    3998       71522 :                     state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3999             :             }
    4000    22607285 :             if (state.dataEnvrn->SunIsUp) {
    4001             : 
    4002    11473140 :                 state.dataSurface->SurfWinSysSolTransmittance(SurfNum) =
    4003    22946280 :                     state.dataSurface->SurfWinTransSolar(SurfNum) /
    4004    22946280 :                     (state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) *
    4005    22946280 :                          (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum)) +
    4006             :                      0.0001);
    4007    11473140 :                 state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) =
    4008    22946280 :                     (state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) + state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum)) /
    4009    22946280 :                     (state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) *
    4010    22946280 :                          (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum)) +
    4011             :                      0.0001);
    4012    11473140 :                 state.dataSurface->SurfWinSysSolReflectance(SurfNum) =
    4013    11473140 :                     1.0 - state.dataSurface->SurfWinSysSolTransmittance(SurfNum) - state.dataSurface->SurfWinSysSolAbsorptance(SurfNum);
    4014             :             } else {
    4015    11134145 :                 state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
    4016    11134145 :                 state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
    4017    11134145 :                 state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
    4018             :             }
    4019             : 
    4020             :             // Save hcv for use in divider calc with interior or exterior shade (see CalcWinFrameAndDividerTemps)
    4021    22607285 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) || ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag))
    4022       54652 :                 state.dataSurface->SurfWinConvCoeffWithShade(SurfNum) = hcv;
    4023             :         } else {
    4024             :             // No convergence after MaxIterations even with relaxed error tolerance
    4025           0 :             ShowSevereError(state, "Convergence error in SolveForWindowTemperatures for window " + state.dataSurface->Surface(SurfNum).Name);
    4026           0 :             ShowContinueErrorTimeStamp(state, "");
    4027             : 
    4028           0 :             if (state.dataGlobal->DisplayExtraWarnings) {
    4029             :                 // report out temperatures
    4030           0 :                 for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
    4031           0 :                     ShowContinueError(state,
    4032           0 :                                       format("Glazing face index = {} ; new temperature ={:.4R}C  ; previous temperature = {:.4R}C",
    4033             :                                              i,
    4034           0 :                                              state.dataWindowManager->thetas[i - 1] - DataGlobalConstants::KelvinConv,
    4035           0 :                                              state.dataWindowManager->thetasPrev[i - 1] - DataGlobalConstants::KelvinConv));
    4036             :                 }
    4037             :             }
    4038             : 
    4039           0 :             ShowFatalError(state,
    4040           0 :                            "Program halted because of convergence error in SolveForWindowTemperatures for window " +
    4041           0 :                                state.dataSurface->Surface(SurfNum).Name);
    4042             :         }
    4043    22607285 :     }
    4044             : 
    4045             :     //****************************************************************************
    4046             : 
    4047      338356 :     void ExtOrIntShadeNaturalFlow(EnergyPlusData &state,
    4048             :                                   int const SurfNum,  // Surface number
    4049             :                                   int const iter,     // Iteration number for glass heat balance calculation
    4050             :                                   Real64 &VGap,       // Air velocity in glass-shade/blind gap (m/s)
    4051             :                                   Real64 &TGapNew,    // Current-iteration average air temp in glass-shade/blind gap (K)
    4052             :                                   Real64 &TGapOutlet, // Temperature of air leaving glass-shade/blind gap at top for upward
    4053             :                                   Real64 &hcv,        // Convection coefficient from gap glass or shade to gap air (W/m2-K)
    4054             :                                   Real64 &QConvGap    // Convective heat gain from glass-shade/blind gap for interior shade (W)
    4055             :     )
    4056             :     {
    4057             : 
    4058             :         // SUBROUTINE INFORMATION:
    4059             :         //       AUTHOR         F. Winkelmann
    4060             :         //       DATE WRITTEN   December 2000
    4061             :         //       MODIFIED       June 2001: add window blinds
    4062             :         //                      May 2006 (RR): add exterior window screens
    4063             :         //       RE-ENGINEERED  na
    4064             : 
    4065             :         // PURPOSE OF THIS SUBROUTINE:
    4066             :         // Called by SolveForWindowTemperatures for windows that have an interior
    4067             :         // or exterior blind or shade in place.
    4068             :         // Solves for air flow in gap between glass and shade/blind.
    4069             :         // Finds temperature of gap air and coefficient for convective heat transfer
    4070             :         // from glass to gap air and shade/blind to gap air.
    4071             : 
    4072             :         // METHODOLOGY EMPLOYED:
    4073             :         // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
    4074             :         // Detailed Calculations," 1/12/2000, Chapter 7, "Shading Devices."
    4075             : 
    4076             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4077             :         //   air flow or bottom for downward air flow (K)
    4078             : 
    4079             :         int ConstrNumSh;  // Shaded construction number
    4080             :         int MatNumSh;     // Material number of shade/blind layer
    4081             :         int nglassfaces;  // Number of glass faces in contruction
    4082             :         Real64 TGapInlet; // Temperature of air entering glass-shade/blind gap at bottom for upward
    4083             :         //   air flow or top for downward air flow (K)
    4084             :         Real64 TGlassFace; // Temperature of glass surface facing glass-shade/blind gap (K)
    4085             :         Real64 TShadeFace; // Temperature of shade surface facing glass-shade/blind gap (K)
    4086             :         Real64 hGapStill;  // Still-air glass-shade/blind gap conduction/convection coeff (W/m2-K)
    4087             :         Real64 TGapOld;    // Previous-iteration average air temp in glass-shade/blind gap (K)
    4088             :         Real64 GapHeight;  // Vertical length of glass-shade/blind gap (m)
    4089             :         Real64 GapDepth;   // Distance from shade to glass (m)
    4090             :         Real64 RhoAir;     // Density of glass-shade/blind gap air at a temperature of TGapOld (kg/m3)
    4091             :         Real64 RhoTRef;    // Density of glass-shade/blind air at reference temp = KelvinConv (kg/m3)
    4092             :         Real64 ViscAir;    // Viscosity of glass-shade/blind gap air at a temperature of TGapOld (kg/m3)
    4093             :         Real64 AGap;       // Cross sectional area of glass-shade/blind gap (m2); for vertical window, this
    4094             :         //   is in horizontal plane normal to window.
    4095             :         Real64 ATopGap; // Area of the top and bottom openings (m2)
    4096             :         Real64 ABotGap;
    4097             :         Real64 ALeftGap; // Area of the left and right openings (m2)
    4098             :         Real64 ARightGap;
    4099             :         Real64 AHolesGap; // Area of the holes in the shade (assumed homogeneously
    4100             :         //   distributed) (m2)
    4101             :         Real64 ATopLRH; // Intermediate variables
    4102             :         Real64 ABotLRH;
    4103             :         Real64 AEqInlet; // Equivalent inlet and outlet opening areas (m2)
    4104             :         Real64 AEqOutlet;
    4105             :         Real64 Zinlet; // Inlet and outlet pressure loss factors
    4106             :         Real64 Zoutlet;
    4107             :         Real64 AVGap;         // Coeff. of VGap**2 term in pressure balance equation
    4108             :         Real64 BVGap;         // Coeff. of VGap term in pressure balance equation
    4109             :         Real64 CVGap;         // VGap-independent term in pressure balance equation
    4110             :         Real64 GapHeightChar; // Characteristic height of the gap air temperature profile (m)
    4111             :         Real64 TAve;          // Average of TGlass and TShade (K)
    4112             :         // REAL(r64)            :: AirProps(8)         ! Air properties
    4113             :         int TotGaps;              // Glass/glass gaps + glass-shade/blind gap
    4114             :         Real64 con;               // Gap conductivity and derivative
    4115             :         Real64 gr;                // glass-shade/blind gap Grashof number
    4116             :         Real64 pr;                // glass-shade/blind gap Prandtl number
    4117             :         Real64 nu;                // glass-shade/blind gap Nusselt number
    4118             :         WinShadingType ShadeFlag; // Shading flag
    4119             :         int BlNum;                // Blind number
    4120             : 
    4121             :         // Air properties
    4122             :         //               Dens  dDens/dT  Con    dCon/dT   Vis    dVis/dT Prandtl dPrandtl/dT
    4123             :         // DATA AirProps / 1.29, -0.4d-2, 2.41d-2, 7.6d-5, 1.73d-5, 1.0d-7, 0.72,   1.8d-3  /
    4124             : 
    4125      338356 :         ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4126      338356 :         ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4127      338356 :         nglassfaces = 2 * state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers;
    4128      338356 :         TotGaps = state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers;
    4129             : 
    4130      338356 :         if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) { // Interior shade or blind
    4131      207157 :             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(nglassfaces);
    4132      207157 :             TGapInlet = state.dataWindowManager->tin;
    4133      207157 :             TGlassFace = state.dataWindowManager->thetas[nglassfaces - 1];
    4134      207157 :             TShadeFace = state.dataWindowManager->thetas[nglassfaces];
    4135             :         } else { // Exterior shade, screen or blind
    4136      131199 :             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1);
    4137      131199 :             TGapInlet = state.dataWindowManager->tout;
    4138      131199 :             TGlassFace = state.dataWindowManager->thetas[0];
    4139      131199 :             TShadeFace = state.dataWindowManager->thetas[nglassfaces + 1];
    4140             :         }
    4141      338356 :         TAve = 0.5 * (TGlassFace + TShadeFace);
    4142             : 
    4143      338356 :         if (iter == 0) {
    4144       54652 :             TGapOld = 0.5 * (TAve + TGapInlet);
    4145             :         } else {
    4146      283704 :             TGapOld = TGapNew;
    4147             :         }
    4148             : 
    4149             :         // Conductance of gap between glass and shade assuming gap is sealed
    4150      338356 :         WindowGasConductance(state, TGlassFace, TShadeFace, TotGaps, con, pr, gr);
    4151      338356 :         NusseltNumber(state, SurfNum, TGlassFace, TShadeFace, TotGaps, gr, pr, nu);
    4152      338356 :         hGapStill = con / state.dataWindowManager->gap[TotGaps - 1] * nu;
    4153             : 
    4154             :         // For near-horizontal windows (i.e., no more than 5 deg from horizontal) assume
    4155             :         // there is no air flow thru gap
    4156             : 
    4157      338356 :         if (std::abs(state.dataSurface->Surface(SurfNum).SinTilt) < 0.0872) {
    4158           0 :             VGap = 0.0;
    4159           0 :             hcv = 2.0 * hGapStill;
    4160           0 :             QConvGap = 0.0;
    4161           0 :             TGapNew = TAve;
    4162           0 :             TGapOutlet = TAve;
    4163           0 :             return;
    4164             :         }
    4165             : 
    4166      338356 :         GapHeight = state.dataSurface->Surface(SurfNum).Height;
    4167             : 
    4168      338356 :         if (ShadeFlag == WinShadingType::IntShade || ShadeFlag == WinShadingType::ExtShade || ShadeFlag == WinShadingType::ExtScreen) {
    4169             :             // Shade or Screen on
    4170      246591 :             GapDepth = state.dataMaterial->Material(MatNumSh).WinShadeToGlassDist;
    4171      246591 :             AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
    4172      246591 :             ATopGap = state.dataMaterial->Material(MatNumSh).WinShadeTopOpeningMult * AGap;
    4173      246591 :             ABotGap = state.dataMaterial->Material(MatNumSh).WinShadeBottomOpeningMult * AGap;
    4174      246591 :             ALeftGap = state.dataMaterial->Material(MatNumSh).WinShadeLeftOpeningMult * GapHeight * GapDepth;
    4175      246591 :             ARightGap = state.dataMaterial->Material(MatNumSh).WinShadeRightOpeningMult * GapHeight * GapDepth;
    4176      246591 :             AHolesGap = state.dataMaterial->Material(MatNumSh).WinShadeAirFlowPermeability * GapHeight * state.dataSurface->Surface(SurfNum).Width;
    4177             :         } else {
    4178             :             // Blind on
    4179       91765 :             BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
    4180       91765 :             GapDepth = state.dataHeatBal->Blind(BlNum).BlindToGlassDist;
    4181       91765 :             AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
    4182       91765 :             ATopGap = state.dataHeatBal->Blind(BlNum).BlindTopOpeningMult * AGap;
    4183       91765 :             ABotGap = state.dataHeatBal->Blind(BlNum).BlindBottomOpeningMult * AGap;
    4184       91765 :             ALeftGap = state.dataHeatBal->Blind(BlNum).BlindLeftOpeningMult * GapHeight * GapDepth;
    4185       91765 :             ARightGap = state.dataHeatBal->Blind(BlNum).BlindRightOpeningMult * GapHeight * GapDepth;
    4186       91765 :             AHolesGap = state.dataSurface->SurfWinBlindAirFlowPermeability(SurfNum) * GapHeight * state.dataSurface->Surface(SurfNum).Width;
    4187             :         }
    4188             : 
    4189      338356 :         RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapOld - state.dataWindowManager->TKelvin);
    4190      338356 :         ViscAir = state.dataWindowManager->AirProps[4] + state.dataWindowManager->AirProps[5] * (TGapOld - state.dataWindowManager->TKelvin);
    4191             :         // The factor 12 in the next line is based on the solution of steady laminar flow between fixed
    4192             :         // parallel plates given in Sec. 6.9.1 of Fundamentals of Fluid Mechanics, Munson/Young/Okishi, Third Edition
    4193             :         // Update, John Wiley & Sons, 1998; ISO 15099 has 8 for this factor, which is for flow through a tube.
    4194      338356 :         BVGap = 12.0 * ViscAir * GapHeight / pow_2(GapDepth);
    4195             :         // Adding 0.000001 and 0.000002 in the following gives ATopLRH = ABotLRH =
    4196             :         // 0.25*(ALeftGap + ARightGap + AHolesGap) when ABotGap = ATopGap = 0.0 (shade/blind sealed at
    4197             :         // bottom and top but possibly open at left side, right side and/or in-shade/blind)
    4198      338356 :         ATopLRH = 0.5 * ((ATopGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
    4199      338356 :         ABotLRH = 0.5 * ((ABotGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
    4200      338356 :         if (TGapOld > TGapInlet) {
    4201      210412 :             AEqInlet = ABotGap + ATopLRH;
    4202      210412 :             AEqOutlet = ATopGap + ABotLRH;
    4203             :         } else {
    4204      127944 :             AEqOutlet = ABotGap + ATopLRH;
    4205      127944 :             AEqInlet = ATopGap + ABotLRH;
    4206             :         }
    4207             :         // Adding 0.000001 in the following gives very large value of Zinlet for AEqInlet = 0 and
    4208             :         // very large value of Zoutlet for AEqInlet = 0; this gives VGap close to zero, as required
    4209             :         // when there is no inlet and/or outlet for air. This then reduces to the
    4210             :         // case of a completely sealed shade, in which hcv = 2*hGapStill and QConvGap = 0.
    4211      338356 :         Zinlet = pow_2(AGap / (0.6 * AEqInlet + 0.000001) - 1.0);
    4212      338356 :         Zoutlet = pow_2(AGap / (0.6 * AEqOutlet + 0.000001) - 1.0);
    4213      338356 :         AVGap = 0.5 * RhoAir * (1 + Zinlet + Zoutlet);
    4214      338356 :         RhoTRef = state.dataWindowManager->AirProps[0] * state.dataWindowManager->TKelvin;
    4215      338356 :         CVGap = RhoTRef * 9.81 * GapHeight * state.dataSurface->Surface(SurfNum).SinTilt * (TGapOld - TGapInlet) / (TGapOld * TGapInlet);
    4216             : 
    4217             :         // Solution of quadratic equation in VGap
    4218      338356 :         VGap = (std::sqrt(pow_2(BVGap) + std::abs(4.0 * AVGap * CVGap)) - BVGap) / (2.0 * AVGap);
    4219      338356 :         hcv = 2.0 * hGapStill + 4.0 * VGap;
    4220      338356 :         GapHeightChar = RhoAir * 1008.0 * GapDepth * VGap / (2.0 * hcv);
    4221             :         // The following avoids divide by zero and exponential underflow
    4222      338356 :         if (GapHeightChar == 0.0) {
    4223           0 :             TGapOutlet = TAve;
    4224      338356 :         } else if ((GapHeight / GapHeightChar) > 15.0) {
    4225       66501 :             TGapOutlet = TAve;
    4226             :         } else {
    4227      271855 :             TGapOutlet = TAve - (TAve - TGapInlet) * std::exp(-GapHeight / GapHeightChar);
    4228             :         }
    4229      338356 :         TGapNew = TAve - (GapHeightChar / GapHeight) * (TGapOutlet - TGapInlet);
    4230             : 
    4231             :         // Convective heat flow from gap to room air for interior shade or blind
    4232      338356 :         if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4233      207157 :             RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapNew - state.dataWindowManager->TKelvin);
    4234      207157 :             QConvGap = RhoAir * AGap * VGap * 1008.0 * (TGapOutlet - TGapInlet);
    4235             :             // Exclude convection to gap due to divider, if present; divider convection handled
    4236             :             // separately in CalcWinFrameAndDividerTemps
    4237      414314 :             QConvGap *= 0.5 * (1.0 + state.dataSurface->Surface(SurfNum).Area /
    4238      207157 :                                          (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum)));
    4239             :         }
    4240             :     }
    4241             : 
    4242             :     //****************************************************************************
    4243             : 
    4244       88448 :     void BetweenGlassShadeNaturalFlow(EnergyPlusData &state,
    4245             :                                       int const SurfNum,       // Surface number
    4246             :                                       int const iter,          // Iteration number for glass heat balance calculation
    4247             :                                       Real64 &VGap,            // Gas velocity in gaps (m/s)
    4248             :                                       Array1A<Real64> TGapNew, // Current-iteration average gas temp in gaps (K)
    4249             :                                       Array1A<Real64> hcv      // Convection coefficient from gap glass or shade to gap gas (W/m2-K)
    4250             :     )
    4251             :     {
    4252             : 
    4253             :         // SUBROUTINE INFORMATION:
    4254             :         //       AUTHOR         F. Winkelmann
    4255             :         //       DATE WRITTEN   December 2002
    4256             :         //       MODIFIED       na
    4257             :         //       RE-ENGINEERED  na
    4258             : 
    4259             :         // PURPOSE OF THIS SUBROUTINE:
    4260             :         // Called by SolveForWindowTemperatures for windows that have a
    4261             :         // between-glass shade or blind in place.
    4262             :         // Solves for gas flow in the two gaps on either side of shade/blind.
    4263             :         // Finds average temperature of gas in the two gaps, and the coefficient
    4264             :         // for convective heat transfer from glass to gap gas and shade/blind to gap gas
    4265             :         // for the two gaps. The two gaps are assumed to have the same depth so that the
    4266             :         // gas velocity due to natural convection is the same in the two gaps.
    4267             :         // The Between-glass shade/blind is between the two glass layers of double glazing
    4268             :         // or between the two inner glass layers of triple glazing. The quadruple glazing
    4269             :         // case is not considered.
    4270             : 
    4271             :         // METHODOLOGY EMPLOYED:
    4272             :         // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
    4273             :         // Detailed Calculations," 1/12/2000, Chapter 7, "Shading Devices."
    4274             : 
    4275             :         // Argument array dimensioning
    4276       88448 :         TGapNew.dim(2);
    4277       88448 :         hcv.dim(2);
    4278             : 
    4279             :         int ConstrNumSh; // Shaded construction number
    4280             :         int MatNumSh;    // Material number of shade/blind layer
    4281             :         int nglassfaces; // Number of glass faces in contruction
    4282             :         // In the following, "gaps" refer to the gaps on either side of the shade/blind
    4283      176896 :         Array1D<Real64> TGlassFace(2); // Temperature of glass surfaces facing gaps (K)
    4284      176896 :         Array1D<Real64> TShadeFace(2); // Temperature of shade surfaces facing gaps (K)
    4285      176896 :         Array1D<Real64> hGapStill(2);  // Still-air conduction/convection coeffs for the gaps (W/m2-K)
    4286      176896 :         Array1D<Real64> TGapOld(2);    // Previous-iteration average gas temp in gaps (K)
    4287             :         Real64 GapHeight;              // Vertical length of glass-shade/blind gap (m)
    4288             :         Real64 GapDepth;               // Distance from shade/blind to glass; assumed same for both gaps (m)
    4289      176896 :         Array1D<Real64> RhoGas(2);     // Density of gap gas at a temperature of TGapOld (kg/m3)
    4290             :         Real64 RhoTRef;                // Density of gap gas at reference temp = KelvinConvK (kg/m3)
    4291      176896 :         Array1D<Real64> ViscGas(2);    // Viscosity of gap gas at a temperature of TGapOld (kg/m3)
    4292             :         Real64 RhoGasZero;             // Gas density at KelvinConvK
    4293             :         Real64 ViscGasZero;            // Gas viscosity at KelvinConvK (not used)
    4294             :         Real64 AGap;                   // Cross sectional area of gaps (m2); for vertical window, this
    4295             :         //   is in horizontal plane normal to window.
    4296             :         Real64 ATopGap; // Area of the top and bottom openings of shade/blind (m2)
    4297             :         Real64 ABotGap;
    4298             :         Real64 ALeftGap; // Area of the left and right openings of shade/blind (m2)
    4299             :         Real64 ARightGap;
    4300             :         Real64 AHolesGap; // Area of the holes in the shade/blind (assumed homogeneously
    4301             :         //   distributed) (m2)
    4302             :         Real64 ATopLRH; // Intermediate variables
    4303             :         Real64 ABotLRH;
    4304             :         Real64 AEqInlet; // Equivalent inlet and outlet opening areas (m2)
    4305             :         Real64 AEqOutlet;
    4306             :         Real64 Zinlet; // Inlet and outlet pressure loss factors
    4307             :         Real64 Zoutlet;
    4308             :         Real64 AVGap;                     // Coeff. of VGap**2 term in pressure balance equation
    4309             :         Real64 BVGap;                     // Coeff. of VGap term in pressure balance equation
    4310             :         Real64 CVGap;                     // VGap-independent term in pressure balance equation
    4311      176896 :         Array1D<Real64> GapHeightChar(2); // Characteristic height of the gap gas temperature profile (m)
    4312      176896 :         Array1D<Real64> EpsChar(2);       // EXP(-GapHeight/GapHeightChar(IGap))
    4313      176896 :         Array1D<Real64> TAve(2);          // Average of TGlass and TShade for the gaps (K)
    4314             :         Real64 con;                       // Gap gas conductivity and derivative
    4315             :         Real64 gr;                        // Gap gas Grashof number
    4316             :         Real64 pr;                        // Gap gas Prandtl number
    4317             :         Real64 nu;                        // Gap gas Nusselt number
    4318             :         WinShadingType ShadeFlag;         // Shading flag
    4319             :         int BlNum;                        // Blind number
    4320             :         int IGap;                         // Gap counter; 1 = gap on outer side of shade/blind, 2 = gap on inner side.
    4321             :         int IGapInc;                      // Gap increment (0 or 1)
    4322             : 
    4323       88448 :         ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
    4324       88448 :         ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4325       88448 :         nglassfaces = 2 * state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers;
    4326             : 
    4327       88448 :         if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { // Double glazing
    4328       51045 :             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3);
    4329       51045 :             IGapInc = 0;
    4330      153135 :             for (IGap = 1; IGap <= 2; ++IGap) {
    4331      102090 :                 TGlassFace(IGap) = state.dataWindowManager->thetas[IGap];
    4332      102090 :                 TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 3];
    4333             :             }
    4334             :         } else { // Triple glazing
    4335       37403 :             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5);
    4336       37403 :             IGapInc = 1;
    4337      112209 :             for (IGap = 1; IGap <= 2; ++IGap) {
    4338       74806 :                 TGlassFace(IGap) = state.dataWindowManager->thetas[IGap + 2];
    4339       74806 :                 TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 5];
    4340             :             }
    4341             :         }
    4342             : 
    4343      265344 :         for (IGap = 1; IGap <= 2; ++IGap) {
    4344      176896 :             TAve(IGap) = 0.5 * (TGlassFace(IGap) + TShadeFace(IGap));
    4345      176896 :             if (iter == 0) {
    4346       17612 :                 TGapOld(IGap) = TAve(IGap);
    4347             :             } else {
    4348      159284 :                 TGapOld(IGap) = TGapNew(IGap);
    4349             :             }
    4350             :             // Conductance of gaps on either side of shade/blind assuming gaps are sealed
    4351      176896 :             WindowGasConductance(state, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, con, pr, gr);
    4352      176896 :             NusseltNumber(state, SurfNum, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, gr, pr, nu);
    4353      176896 :             hGapStill(IGap) = con / state.dataWindowManager->gap[IGap + IGapInc - 1] * nu;
    4354             :         }
    4355             : 
    4356             :         // For near-horizontal windows (i.e., no more than 5 deg from horizontal) assume
    4357             :         // there is no air flow thru gap
    4358             : 
    4359       88448 :         if (std::abs(state.dataSurface->Surface(SurfNum).SinTilt) < 0.0872) {
    4360           0 :             VGap = 0.0;
    4361           0 :             for (IGap = 1; IGap <= 2; ++IGap) {
    4362           0 :                 hcv(IGap) = 2.0 * hGapStill(IGap);
    4363           0 :                 TGapNew(IGap) = TAve(IGap);
    4364             :             }
    4365           0 :             return;
    4366             :         }
    4367             : 
    4368       88448 :         GapHeight = state.dataSurface->Surface(SurfNum).Height;
    4369       88448 :         GapDepth = state.dataWindowManager->gap[IGapInc];
    4370       88448 :         AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
    4371             : 
    4372       88448 :         if (ShadeFlag == WinShadingType::BGShade) {
    4373             :             // Shade on
    4374       46150 :             ATopGap = state.dataMaterial->Material(MatNumSh).WinShadeTopOpeningMult * AGap;
    4375       46150 :             ABotGap = state.dataMaterial->Material(MatNumSh).WinShadeBottomOpeningMult * AGap;
    4376       46150 :             ALeftGap = state.dataMaterial->Material(MatNumSh).WinShadeLeftOpeningMult * GapHeight * GapDepth;
    4377       46150 :             ARightGap = state.dataMaterial->Material(MatNumSh).WinShadeRightOpeningMult * GapHeight * GapDepth;
    4378       46150 :             AHolesGap = state.dataMaterial->Material(MatNumSh).WinShadeAirFlowPermeability * GapHeight * state.dataSurface->Surface(SurfNum).Width;
    4379             :         } else {
    4380             :             // Blind on
    4381       42298 :             BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
    4382       42298 :             ATopGap = state.dataHeatBal->Blind(BlNum).BlindTopOpeningMult * AGap;
    4383       42298 :             ABotGap = state.dataHeatBal->Blind(BlNum).BlindBottomOpeningMult * AGap;
    4384       42298 :             ALeftGap = state.dataHeatBal->Blind(BlNum).BlindLeftOpeningMult * GapHeight * GapDepth;
    4385       42298 :             ARightGap = state.dataHeatBal->Blind(BlNum).BlindRightOpeningMult * GapHeight * GapDepth;
    4386       42298 :             AHolesGap = state.dataSurface->SurfWinBlindAirFlowPermeability(SurfNum) * GapHeight * state.dataSurface->Surface(SurfNum).Width;
    4387             :         }
    4388             : 
    4389      265344 :         for (IGap = 1; IGap <= 2; ++IGap) {
    4390      176896 :             WindowGasPropertiesAtTemp(state, TGapOld(IGap), IGap + IGapInc, RhoGas(IGap), ViscGas(IGap));
    4391             :         }
    4392             : 
    4393       88448 :         BVGap = 12.0 * (ViscGas(1) + ViscGas(2)) * GapHeight / pow_2(GapDepth);
    4394             :         // Adding 0.000001 and 0.000002 in the following gives ATopLRH = ABotLRH =
    4395             :         // 0.25*(ALeftGap + ARightGap + AHolesGap) when ABotGap = ATopGap = 0.0 (shade/blind sealed at
    4396             :         // bottom and top but possibly open at left side, right side and/or in shade/blind)
    4397       88448 :         ATopLRH = 0.5 * ((ATopGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
    4398       88448 :         ABotLRH = 0.5 * ((ABotGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
    4399       88448 :         AEqInlet = ABotGap + ATopLRH;
    4400       88448 :         AEqOutlet = ATopGap + ABotLRH;
    4401             : 
    4402             :         // Adding 0.000001 in the following gives very large value of Zinlet for AEqInlet = 0 and
    4403             :         // very large value of Zoutlet for AEqInlet = 0; this gives VGap close to zero, as required
    4404             :         // when there is no inlet and/or outlet for air. This then reduces to the
    4405             :         // case of a completely sealed shade, in which hcv = 2*hGapStill and QConvGap = 0.
    4406       88448 :         Zinlet = pow_2(AGap / (0.6 * AEqInlet + 0.000001) - 1.0);
    4407       88448 :         Zoutlet = pow_2(AGap / (0.6 * AEqOutlet + 0.000001) - 1.0);
    4408       88448 :         AVGap = 0.5 * (RhoGas(1) + RhoGas(2)) * (1.0 + Zinlet + Zoutlet);
    4409       88448 :         WindowGasPropertiesAtTemp(state, state.dataWindowManager->TKelvin, 1 + IGapInc, RhoGasZero, ViscGasZero);
    4410       88448 :         RhoTRef = RhoGasZero * state.dataWindowManager->TKelvin;
    4411       88448 :         CVGap = RhoTRef * 9.81 * GapHeight * state.dataSurface->Surface(SurfNum).SinTilt * (TGapOld(1) - TGapOld(2)) / (TGapOld(1) * TGapOld(2));
    4412             : 
    4413             :         // Solution of quadratic equation in VGap
    4414             : 
    4415       88448 :         VGap = (std::sqrt(pow_2(BVGap) + std::abs(4 * AVGap * CVGap)) - BVGap) / (2 * AVGap);
    4416             : 
    4417      265344 :         for (IGap = 1; IGap <= 2; ++IGap) {
    4418      176896 :             hcv(IGap) = 2.0 * hGapStill(IGap) + 4.0 * VGap;
    4419      176896 :             GapHeightChar(IGap) = RhoGas(IGap) * 1008.0 * GapDepth * VGap / (2.0 * hcv(IGap));
    4420             :             // The following avoids divide by zero and exponential underflow
    4421      176896 :             if (GapHeightChar(IGap) == 0.0) {
    4422           0 :                 EpsChar(IGap) = 0.0;
    4423      176896 :             } else if ((GapHeight / GapHeightChar(IGap)) > 15.0) {
    4424        8936 :                 EpsChar(IGap) = 0.0;
    4425             :             } else {
    4426      167960 :                 EpsChar(IGap) = std::exp(-GapHeight / GapHeightChar(IGap));
    4427             :             }
    4428             :         }
    4429             : 
    4430       88448 :         TGapNew(1) =
    4431       88448 :             TAve(1) - (TAve(1) - TAve(2)) * (GapHeightChar(1) / GapHeight) * (1 - EpsChar(1)) * (1 - EpsChar(2)) / (1 - EpsChar(1) * EpsChar(2));
    4432             : 
    4433       88448 :         TGapNew(2) =
    4434       88448 :             TAve(2) - (TAve(2) - TAve(1)) * (GapHeightChar(2) / GapHeight) * (1 - EpsChar(1)) * (1 - EpsChar(2)) / (1 - EpsChar(1) * EpsChar(2));
    4435             :     }
    4436             : 
    4437             :     //****************************************************************************
    4438             : 
    4439       16422 :     void BetweenGlassForcedFlow(EnergyPlusData &state,
    4440             :                                 int const SurfNum,  // Surface number
    4441             :                                 int const iter,     // Iteration number for glass heat balance calculation
    4442             :                                 Real64 &VGap,       // Air velocity in airflow gap (m/s)
    4443             :                                 Real64 &TGapNew,    // Current-iteration average air temp in airflow gap (K)
    4444             :                                 Real64 &TGapOutlet, // Temperature of air leaving glass-shade/blind gap at top for upward
    4445             :                                 Real64 &hcv,        // Convection coefficient from gap glass faces to gap air (W/m2-K)
    4446             :                                 Real64 &QConvGap    // Convective heat gain from air flow gap (W)
    4447             :     )
    4448             :     {
    4449             : 
    4450             :         // SUBROUTINE INFORMATION:
    4451             :         //       AUTHOR         F. Winkelmann
    4452             :         //       DATE WRITTEN   February 2003
    4453             :         //       MODIFIED       na
    4454             :         //       RE-ENGINEERED  na
    4455             : 
    4456             :         // PURPOSE OF THIS SUBROUTINE:
    4457             :         // Called by SolveForWindowTemperatures for "airflow windows",i.e., windows
    4458             :         // with forced airflow in one of the gaps between layers of glass. Based on
    4459             :         // the velocity of airflow through gap, finds effective temperature of gap air,
    4460             :         // convective heat transfer coefficient from glass to gap air,
    4461             :         // the gap outlet temperature, and the outlet convective heat flow.
    4462             : 
    4463             :         // Called only for double and triple glazing. For triple glazing the airflow
    4464             :         // is assumed to be between the inner two layers of glass (glass layers 2 and 3).
    4465             : 
    4466             :         // METHODOLOGY EMPLOYED:
    4467             :         // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
    4468             :         // Detailed Calculations"
    4469             : 
    4470             :         // Using/Aliasing
    4471             :         using ScheduleManager::GetCurrentScheduleValue;
    4472             : 
    4473             :         // Locals
    4474             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4475             :         //   air flow or bottom for downward air flow (K)
    4476             : 
    4477             :         int ConstrNum;    // Construction number of surface
    4478             :         int NGlass;       // Number of glass layers in construction
    4479             :         int GapNum;       // Number of airflow gap
    4480             :         Real64 TGapInlet; // Temperature of air entering glass-shade/blind gap at bottom for upward
    4481             :         //   air flow or top for downward air flow (K)
    4482             :         Real64 TGlassFace1; // Temperature of left-hand glass surface facing airflow gap (K)
    4483             :         Real64 TGlassFace2; // Temperature of right-hand glass surface facing airflow gap (K)
    4484             :         Real64 hGapStill;   // Still-air gap conduction/convection coeff (W/m2-K)
    4485             :         Real64 TGapOld;     // Previous-iteration average air temp in airflow gap (K)
    4486             :         Real64 GapHeight;   // Vertical length of airflow gap (m)
    4487             :         Real64 GapDepth;    // Thickness of airflow gap (m)
    4488             :         Real64 RhoAir;      // Density of airflow gap air at a temperature of TGapOld (kg/m3)
    4489             :         Real64 AGap;        // Cross sectional area of airflow gap (m2); for vertical window, this
    4490             :         //   is in horizontal plane normal to window.
    4491             :         Real64 GapHeightChar; // Characteristic height of the airflow gap air temperature profile (m)
    4492             :         Real64 TAve;          // Average of TGlassFace1 and TGlassFace2 (K)
    4493             :         // REAL(r64)            :: AirProps(8)         ! Air properties
    4494             :         Real64 con; // Gap conductivity and derivative
    4495             :         Real64 gr;  // Gap air Grashof number
    4496             :         Real64 pr;  // Gap air Prandtl number
    4497             :         Real64 nu;  // Gap air Nusselt number
    4498             : 
    4499             :         // Air properties
    4500             :         //               Dens  dDens/dT  Con    dCon/dT   Vis    dVis/dT Prandtl dPrandtl/dT
    4501             :         // DATA AirProps / 1.29, -0.4d-2, 2.41d-2, 7.6d-5, 1.73d-5, 1.0d-7, 0.72,   1.8d-3  /
    4502             : 
    4503       16422 :         ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    4504       16422 :         NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    4505       16422 :         TGlassFace1 = state.dataWindowManager->thetas[2 * NGlass - 3];
    4506       16422 :         TGlassFace2 = state.dataWindowManager->thetas[2 * NGlass - 2];
    4507       16422 :         GapNum = NGlass - 1;
    4508       16422 :         TAve = 0.5 * (TGlassFace1 + TGlassFace2);
    4509             : 
    4510       16422 :         if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
    4511       16422 :             TGapInlet = state.dataWindowManager->tin; // Source is inside air
    4512             :         } else {
    4513           0 :             TGapInlet = state.dataWindowManager->tout; // Source is outside air
    4514             :         }
    4515             : 
    4516       16422 :         if (iter == 0) {
    4517        8064 :             TGapOld = 0.5 * (TAve + TGapInlet);
    4518             :         } else {
    4519        8358 :             TGapOld = TGapNew;
    4520             :         }
    4521             : 
    4522             :         // Conductance of gap assuming it is sealed
    4523       16422 :         WindowGasConductance(state, TGlassFace1, TGlassFace2, GapNum, con, pr, gr);
    4524       16422 :         NusseltNumber(state, SurfNum, TGlassFace1, TGlassFace2, GapNum, gr, pr, nu);
    4525       16422 :         hGapStill = con / state.dataWindowManager->gap[GapNum - 1] * nu;
    4526       16422 :         GapHeight = state.dataSurface->Surface(SurfNum).Height;
    4527       16422 :         GapDepth = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(2 * NGlass - 2)).Thickness;
    4528       16422 :         AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
    4529       16422 :         VGap = state.dataSurface->SurfWinAirflowThisTS(SurfNum) / GapDepth;
    4530       16422 :         hcv = 2.0 * hGapStill + 4.0 * VGap;
    4531       16422 :         RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapOld - state.dataWindowManager->TKelvin);
    4532       16422 :         GapHeightChar = RhoAir * 1008.0 * GapDepth * VGap / (2.0 * hcv);
    4533             :         // The following avoids divide by zero and exponential underflow
    4534       16422 :         if (GapHeightChar == 0.0) {
    4535           0 :             TGapOutlet = TAve;
    4536       16422 :         } else if ((GapHeight / GapHeightChar) > 15.0) {
    4537           0 :             TGapOutlet = TAve;
    4538             :         } else {
    4539       16422 :             TGapOutlet = TAve - (TAve - TGapInlet) * std::exp(-GapHeight / GapHeightChar);
    4540             :         }
    4541       16422 :         TGapNew = TAve - (GapHeightChar / GapHeight) * (TGapOutlet - TGapInlet);
    4542             :         // Convective heat flow from gap [W]
    4543       16422 :         RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapNew - state.dataWindowManager->TKelvin);
    4544       16422 :         QConvGap = RhoAir * AGap * VGap * 1008.0 * (TGapOutlet - TGapInlet);
    4545       16422 :     }
    4546             : 
    4547             :     //****************************************************************************
    4548             : 
    4549       20000 :     void BetweenGlassShadeForcedFlow(EnergyPlusData &state,
    4550             :                                      int const SurfNum,       // Surface number
    4551             :                                      int const iter,          // Iteration number for glass heat balance calculation
    4552             :                                      Real64 &VGap,            // Air velocity in each gap (m/s)
    4553             :                                      Array1A<Real64> TGapNew, // Current-iteration average gas temp in gaps (K)
    4554             :                                      Real64 &TGapOutletAve,   // Average of TGapOutlet(1) and TGapOutlet(2) (K)
    4555             :                                      Array1A<Real64> hcv,     // Convection coefficient from gap glass or shade to gap gas (W/m2-K)
    4556             :                                      Real64 &QConvTot         // Sum of convective heat flow from gaps (W)
    4557             :     )
    4558             :     {
    4559             : 
    4560             :         // SUBROUTINE INFORMATION:
    4561             :         //       AUTHOR         F. Winkelmann
    4562             :         //       DATE WRITTEN   February 2003
    4563             :         //       MODIFIED       na
    4564             :         //       RE-ENGINEERED  na
    4565             : 
    4566             :         // PURPOSE OF THIS SUBROUTINE:
    4567             :         // Called by SolveForWindowTemperatures for airflow windows with a
    4568             :         // between-glass shade or blind over which fan-forced air flows.
    4569             :         // Based on the air flow velocity (which is assumed to be the same in the
    4570             :         // gaps on either side of the shade/blind), finds, for each gap: the average
    4571             :         // air temperature, the shade/blind or glass surface to air convective heat
    4572             :         // transfer coefficient, the gap outlet temperature, and the outlet convective heat flow.
    4573             : 
    4574             :         // Called only for double and triple glazing. For triple glazing the airflow
    4575             :         // is assumed to be between the inner two layers of glass (glass layers 2 and 3),
    4576             :         // between which the shade/blind is located.
    4577             : 
    4578             :         // METHODOLOGY EMPLOYED:
    4579             :         // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
    4580             :         // Detailed Calculations," 1/12/2000, Chapter 7, "Shading Devices."
    4581             : 
    4582             :         // Argument array dimensioning
    4583       20000 :         TGapNew.dim(2);
    4584       20000 :         hcv.dim(2);
    4585             : 
    4586             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4587             :         int ConstrNumSh; // Shaded construction number
    4588             :         int MatNumSh;    // Material number of shade/blind layer
    4589             :         // In the following, "gaps" refer to the gaps on either side of the shade/blind
    4590       40000 :         Array1D<Real64> TGlassFace(2); // Temperature of glass surfaces facing gaps (K)
    4591       40000 :         Array1D<Real64> TShadeFace(2); // Temperature of shade surfaces facing gaps (K)
    4592       40000 :         Array1D<Real64> hGapStill(2);  // Still-air conduction/convection coeffs for the gaps (W/m2-K)
    4593       40000 :         Array1D<Real64> TGapOld(2);    // Previous-iteration average gas temp in gaps (K)
    4594             :         Real64 GapHeight;              // Vertical length of glass-shade/blind gap (m)
    4595             :         Real64 GapDepth;               // Distance from shade/blind to glass; assumed same for both gaps (m)
    4596       40000 :         Array1D<Real64> RhoAir(2);     // Density of gap air (kg/m3)
    4597             :         Real64 AGap;                   // Cross sectional area of each gap (m2); for vertical window, this
    4598             :         //   is in horizontal plane normal to window.
    4599             :         Real64 TGapInlet;                 // Gap inlet air temperature (K)
    4600       40000 :         Array1D<Real64> TGapOutlet(2);    // Gap outlet air temperature (K)
    4601       40000 :         Array1D<Real64> QConvGap(2);      // Convective heat flow from each gap (W)
    4602       40000 :         Array1D<Real64> GapHeightChar(2); // Characteristic height of the gap air temperature profile (m)
    4603       40000 :         Array1D<Real64> TAve(2);          // Average of TGlass and TShade for the gaps (K)
    4604             :         Real64 con;                       // Gap air conductivity and derivative
    4605             :         Real64 gr;                        // Gap air Grashof number
    4606             :         Real64 pr;                        // Gap air Prandtl number
    4607             :         Real64 nu;                        // Gap air Nusselt number
    4608             :         WinShadingType ShadeFlag;         // Shading flag
    4609             :         int IGap;                         // Gap counter; 1 = gap on outer side of shade/blind, 2 = gap on inner side.
    4610             :         int IGapInc;                      // Gap increment; =0, double glass, =1, triple glass
    4611             :         // REAL(r64)            :: AirProps(8)         ! Air properties
    4612             : 
    4613             :         // Air properties
    4614             :         //               Dens  dDens/dT  Con    dCon/dT   Vis    dVis/dT Prandtl dPrandtl/dT
    4615             :         // DATA AirProps / 1.29, -0.4d-2, 2.41d-2, 7.6d-5, 1.73d-5, 1.0d-7, 0.72,   1.8d-3  /
    4616             : 
    4617       20000 :         ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
    4618       20000 :         ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4619             : 
    4620       20000 :         if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { // Double glazing
    4621        9989 :             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3);
    4622        9989 :             IGapInc = 0;
    4623       29967 :             for (IGap = 1; IGap <= 2; ++IGap) {
    4624       19978 :                 TGlassFace(IGap) = state.dataWindowManager->thetas[IGap];
    4625       19978 :                 TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 3];
    4626             :             }
    4627             :         } else { // Triple glazing
    4628       10011 :             MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5);
    4629       10011 :             IGapInc = 1;
    4630       30033 :             for (IGap = 1; IGap <= 2; ++IGap) {
    4631       20022 :                 TGlassFace(IGap) = state.dataWindowManager->thetas[IGap + 2];
    4632       20022 :                 TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 5];
    4633             :             }
    4634             :         }
    4635             : 
    4636       20000 :         if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
    4637       20000 :             TGapInlet = state.dataWindowManager->tin;
    4638             :         } else {
    4639           0 :             TGapInlet = state.dataWindowManager->tout;
    4640             :         }
    4641             : 
    4642       20000 :         GapHeight = state.dataSurface->Surface(SurfNum).Height;
    4643       20000 :         GapDepth = state.dataWindowManager->gap[IGapInc];
    4644       20000 :         AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
    4645             :         // Factor of 2 below assumes gaps on either side of shade/blind have same depth
    4646       20000 :         VGap = state.dataSurface->SurfWinAirflowThisTS(SurfNum) / (2.0 * GapDepth);
    4647             : 
    4648       60000 :         for (IGap = 1; IGap <= 2; ++IGap) {
    4649       40000 :             TAve(IGap) = 0.5 * (TGlassFace(IGap) + TShadeFace(IGap));
    4650       40000 :             if (iter == 0) {
    4651       16128 :                 TGapOld(IGap) = TAve(IGap);
    4652             :             } else {
    4653       23872 :                 TGapOld(IGap) = TGapNew(IGap);
    4654             :             }
    4655             :             // Conductance of gaps on either side of shade/blind assuming gaps are sealed
    4656       40000 :             WindowGasConductance(state, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, con, pr, gr);
    4657       40000 :             NusseltNumber(state, SurfNum, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, gr, pr, nu);
    4658       40000 :             hGapStill(IGap) = con / state.dataWindowManager->gap[IGap + IGapInc - 1] * nu;
    4659             :             // Shade/blind or glass surface to air convection coefficient
    4660       40000 :             hcv(IGap) = 2.0 * hGapStill(IGap) + 4.0 * VGap;
    4661       40000 :             RhoAir(IGap) =
    4662       40000 :                 state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapOld(IGap) - state.dataWindowManager->TKelvin);
    4663       40000 :             hcv(IGap) = 2.0 * hGapStill(IGap) + 4.0 * VGap;
    4664       40000 :             GapHeightChar(IGap) = RhoAir(IGap) * 1008.0 * GapDepth * VGap / (2.0 * hcv(IGap));
    4665             :             // The following avoids divide by zero and exponential underflow
    4666       40000 :             if (GapHeightChar(IGap) == 0.0) {
    4667           0 :                 TGapOutlet(IGap) = TAve(IGap);
    4668       40000 :             } else if ((GapHeight / GapHeightChar(IGap)) > 15.0) {
    4669           0 :                 TGapOutlet(IGap) = TAve(IGap);
    4670             :             } else {
    4671       40000 :                 TGapOutlet(IGap) = TAve(IGap) - (TAve(IGap) - TGapInlet) * std::exp(-GapHeight / GapHeightChar(IGap));
    4672             :             }
    4673       40000 :             TGapNew(IGap) = TAve(IGap) - (GapHeightChar(IGap) / GapHeight) * (TGapOutlet(IGap) - TGapInlet);
    4674             :             // Convective heat flow from gap [W]
    4675       40000 :             RhoAir(IGap) =
    4676       40000 :                 state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapNew(IGap) - state.dataWindowManager->TKelvin);
    4677       40000 :             QConvGap(IGap) = RhoAir(IGap) * AGap * VGap * 1008.0 * (TGapOutlet(IGap) - TGapInlet);
    4678             :         }
    4679             : 
    4680       20000 :         QConvTot = QConvGap(1) + QConvGap(2);
    4681       20000 :         TGapOutletAve = 0.5 * (TGapOutlet(1) + TGapOutlet(2));
    4682       20000 :     }
    4683             : 
    4684             :     //****************************************************************************
    4685             : 
    4686    42053009 :     void LUdecomposition(EnergyPlusData &state,
    4687             :                          Array2<Real64> &ajac, // As input: matrix to be decomposed;
    4688             :                          int const n,          // Dimension of matrix
    4689             :                          Array1D_int &indx,    // Vector of row permutations
    4690             :                          Real64 &d             // +1 if even number of row interchange is even, -1
    4691             :     )
    4692             :     {
    4693             : 
    4694             :         // SUBROUTINE INFORMATION:
    4695             :         //       AUTHOR         F. Winkelmann, adapted from Numerical Recipes
    4696             :         //       DATE WRITTEN   February 2000
    4697             :         //       MODIFIED       na
    4698             :         //       RE-ENGINEERED  na
    4699             : 
    4700             :         // PURPOSE OF THIS SUBROUTINE:
    4701             :         // Performs LU decomposition of a matrix.
    4702             : 
    4703             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4704             :         //   as output: decomposed matrix
    4705             :         //   if odd
    4706             : 
    4707             :         int i; // Counters
    4708             :         int j;
    4709             :         int k;
    4710             :         int imax; // Temporary variable
    4711             :         //   as output: decomposed matrix
    4712    42053009 :         auto &vv = state.dataWindowManager->vv;
    4713             :         Real64 aamax; // Absolute value of largest element of matrix
    4714             :         Real64 dum;   // Temporary variable
    4715             :         Real64 sum;   // Sum of products of matrix elements
    4716             : 
    4717    42053009 :         assert(n <= 10); // vv sizing
    4718             : 
    4719    42053009 :         d = 1.0;
    4720   153808481 :         for (i = 1; i <= n; ++i) {
    4721   111755472 :             aamax = 0.0;
    4722   451959464 :             for (j = 1; j <= n; ++j) {
    4723   340203992 :                 if (std::abs(ajac(j, i)) > aamax) aamax = std::abs(ajac(j, i));
    4724             :             }
    4725   111755472 :             if (aamax == 0.0) ShowFatalError(state, "Singular matrix in LUdecomposition, window calculations");
    4726   111755472 :             vv[i - 1] = 1.0 / aamax;
    4727             :         }
    4728   153808481 :         for (j = 1; j <= n; ++j) {
    4729   225979732 :             for (i = 1; i <= j - 1; ++i) {
    4730   114224260 :                 sum = ajac(j, i);
    4731   179948760 :                 for (k = 1; k <= i - 1; ++k) {
    4732    65724500 :                     sum -= ajac(k, i) * ajac(j, k);
    4733             :                 }
    4734   114224260 :                 ajac(j, i) = sum;
    4735             :             }
    4736   111755472 :             aamax = 0.0;
    4737   337735204 :             for (i = j; i <= n; ++i) {
    4738   225979732 :                 sum = ajac(j, i);
    4739   405928492 :                 for (k = 1; k <= j - 1; ++k) {
    4740   179948760 :                     sum -= ajac(k, i) * ajac(j, k);
    4741             :                 }
    4742   225979732 :                 ajac(j, i) = sum;
    4743   225979732 :                 dum = vv[i - 1] * std::abs(sum);
    4744   225979732 :                 if (dum >= aamax) {
    4745   112176327 :                     imax = i;
    4746   112176327 :                     aamax = dum;
    4747             :                 }
    4748             :             }
    4749   111755472 :             if (j != imax) {
    4750     2450119 :                 for (k = 1; k <= n; ++k) {
    4751     2029264 :                     dum = ajac(k, imax);
    4752     2029264 :                     ajac(k, imax) = ajac(k, j);
    4753     2029264 :                     ajac(k, j) = dum;
    4754             :                 }
    4755      420855 :                 d = -d;
    4756      420855 :                 vv[imax - 1] = vv[j - 1];
    4757             :             }
    4758   111755472 :             indx(j) = imax;
    4759   111755472 :             if (ajac(j, j) == 0.0) ajac(j, j) = DataGlobalConstants::rTinyValue;
    4760   111755472 :             if (j != n) {
    4761    69702463 :                 dum = 1.0 / ajac(j, j);
    4762   183926723 :                 for (i = j + 1; i <= n; ++i) {
    4763   114224260 :                     ajac(j, i) *= dum;
    4764             :                 }
    4765             :             }
    4766             :         }
    4767    42053009 :     }
    4768             : 
    4769             :     //**************************************************************************
    4770             : 
    4771    42053009 :     void LUsolution(Array2<Real64> const &a, // Matrix and vector in a.x = b;
    4772             :                     int const n,             // Dimension of a and b
    4773             :                     Array1D_int const &indx, // Vector of row permutations
    4774             :                     Array1D<Real64> &b       // Matrix and vector in a.x = b;
    4775             :     )
    4776             :     {
    4777             : 
    4778             :         // SUBROUTINE INFORMATION:
    4779             :         //       AUTHOR         F. Winkelmann, adapted from Numerical Recipes
    4780             :         //       DATE WRITTEN   February 2000
    4781             :         //       MODIFIED       na
    4782             :         //       RE-ENGINEERED  na
    4783             : 
    4784             :         // PURPOSE OF THIS SUBROUTINE:
    4785             :         // Solves set of linear equations a.x = b
    4786             : 
    4787             :         // Locals
    4788             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4789             :         //   b is also output as the solution, x
    4790             :         //   b is also output as the solution, x
    4791             : 
    4792             :         int i; // Counters
    4793             :         int j;
    4794             :         int ii; // Intermediate variables
    4795             :         int ll;
    4796             :         Real64 sum; // Summation variable
    4797             : 
    4798    42053009 :         ii = 0;
    4799   153808481 :         for (i = 1; i <= n; ++i) {
    4800   111755472 :             ll = indx(i);
    4801   111755472 :             sum = b(ll);
    4802   111755472 :             b(ll) = b(i);
    4803   111755472 :             if (ii != 0) {
    4804   183926723 :                 for (j = ii; j <= i - 1; ++j) {
    4805   114224260 :                     sum -= a(j, i) * b(j);
    4806             :                 }
    4807    42053009 :             } else if (sum != 0.0) {
    4808    42053009 :                 ii = i;
    4809             :             }
    4810   111755472 :             b(i) = sum;
    4811             :         }
    4812   153808481 :         for (i = n; i >= 1; --i) {
    4813   111755472 :             sum = b(i);
    4814   225979732 :             for (j = i + 1; j <= n; ++j) {
    4815   114224260 :                 sum -= a(j, i) * b(j);
    4816             :             }
    4817   111755472 :             b(i) = sum / a(i, i);
    4818             :         }
    4819    42053009 :     }
    4820             : 
    4821             :     //******************************************************************************
    4822             : 
    4823    13949597 :     void WindowGasConductance(EnergyPlusData &state,
    4824             :                               Real64 const tleft,  // Temperature of gap surface closest to outside (K)
    4825             :                               Real64 const tright, // Temperature of gap surface closest to zone (K)
    4826             :                               int const IGap,      // Gap number
    4827             :                               Real64 &con,         // Gap gas conductance (W/m2-K)
    4828             :                               Real64 &pr,          // Gap gas Prandtl number
    4829             :                               Real64 &gr           // Gap gas Grashof number
    4830             :     )
    4831             :     {
    4832             : 
    4833             :         // SUBROUTINE INFORMATION:
    4834             :         //       AUTHOR         Adapted by Fred Winkelmann from Window5 subroutine gasses
    4835             :         //       DATE WRITTEN   September 2001
    4836             :         //       MODIFIED       na
    4837             :         //       RE-ENGINEERED  na
    4838             : 
    4839             :         // PURPOSE OF THIS SUBROUTINE:
    4840             :         // Find the coefficient of convective/conductive heat transfer in the gas-filled gap
    4841             :         // between isothermal solid layers. The gap may be filled with a single gas or a gas mixture.
    4842             : 
    4843             :         // METHODOLOGY EMPLOYED:
    4844             :         // Based on methodology in Chapter 5 of the July 18, 2001 draft of ISO 15099,
    4845             :         // "Thermal Performance of Windows, Doors and Shading Devices--Detailed Calculations."
    4846             :         // The equation numbers below correspond to those in the standard.
    4847             : 
    4848             :         // REFERENCES:
    4849             :         // Window5 source code; ISO 15099
    4850             : 
    4851    13949597 :         constexpr Real64 pres(1.0e5);     // Gap gas pressure (Pa)
    4852    13949597 :         constexpr Real64 gaslaw(8314.51); // Molar gas constant (J/kMol-K)
    4853    13949597 :         Real64 const two_sqrt_2(2.0 * std::sqrt(2.0));
    4854             : 
    4855             :         int IMix; // Counters of gases in a mixture
    4856             :         int i;
    4857             :         int j;
    4858             :         int NMix;      // Number of gases in a mixture
    4859             :         Real64 molmix; // Molecular weight of mixture
    4860             : 
    4861    13949597 :         auto &kprime = state.dataWindowManager->kprime;
    4862    13949597 :         auto &kdblprm = state.dataWindowManager->kdblprm;
    4863    13949597 :         auto &mukpdwn = state.dataWindowManager->mukpdwn;
    4864    13949597 :         auto &kpdown = state.dataWindowManager->kpdown;
    4865    13949597 :         auto &kdpdown = state.dataWindowManager->kdpdown;
    4866    13949597 :         auto &frct = state.dataWindowManager->frct;
    4867    13949597 :         auto &fvis = state.dataWindowManager->fvis;
    4868    13949597 :         auto &fcon = state.dataWindowManager->fcon;
    4869    13949597 :         auto &fdens = state.dataWindowManager->fdens;
    4870    13949597 :         auto &fcp = state.dataWindowManager->fcp;
    4871             : 
    4872             :         Real64 kpmix; // Monotonic thermal conductivity of mixture
    4873             :         Real64 kdpmix;
    4874             :         Real64 kmix;      // For accumulating conductance of gas mixture
    4875             :         Real64 mumix;     // For accumulating viscosity of gas mixture
    4876    13949597 :         Real64 visc(0.0); // Dynamic viscosity of mixture at tmean (g/m-s)
    4877    13949597 :         Real64 cp(0.0);   // Specific heat of mixture at tmean (J/m3-K)
    4878    13949597 :         Real64 dens(0.0); // Density of mixture at tmean (kg/m3)
    4879             :         Real64 cpmixm;    // Gives cp when divided by molmix
    4880             :         Real64 phimup;    // Numerator factor
    4881             :         Real64 downer;    // Denominator factor
    4882             :         Real64 psiup;     // Numerator factor
    4883             :         Real64 psiterm;   // Factor
    4884             :         Real64 phikup;    // Numerator factor
    4885             :         Real64 rhomix;    // Density of gas mixture (kg/m3)
    4886             : 
    4887             :         // Autodesk:Logic Either assert NMix>0 or handle NMix<=0 in logic so that con and locals guar. initialized before use
    4888    13949597 :         NMix = state.dataWindowManager->gnmix[IGap - 1];
    4889             : 
    4890    28026599 :         for (IMix = 1; IMix <= NMix; ++IMix) {
    4891    14077002 :             frct[IMix - 1] = state.dataWindowManager->gfract[IMix - 1][IGap - 1];
    4892             :         }
    4893             : 
    4894    13949597 :         Real64 const tmean(0.5 * (tleft + tright)); // Average gap gas temperature (K)
    4895    13949597 :         Real64 const tmean_2(pow_2(tmean));
    4896             : 
    4897    27899194 :         fcon[0] = state.dataWindowManager->gcon[0][0][IGap - 1] + state.dataWindowManager->gcon[1][0][IGap - 1] * tmean +
    4898    13949597 :                   state.dataWindowManager->gcon[2][0][IGap - 1] * tmean_2;
    4899    27899194 :         fvis[0] = state.dataWindowManager->gvis[0][0][IGap - 1] + state.dataWindowManager->gvis[1][0][IGap - 1] * tmean +
    4900    13949597 :                   state.dataWindowManager->gvis[2][0][IGap - 1] * tmean_2;
    4901    27899194 :         fcp[0] = state.dataWindowManager->gcp[0][0][IGap - 1] + state.dataWindowManager->gcp[1][0][IGap - 1] * tmean +
    4902    13949597 :                  state.dataWindowManager->gcp[2][0][IGap - 1] * tmean_2;
    4903    13949597 :         fdens[0] = pres * state.dataWindowManager->gwght[0][IGap - 1] / (gaslaw * tmean); // Density using ideal gas law:
    4904             :         //  rho=(presure*molecweight)/(gasconst*tmean)
    4905             : 
    4906    13949597 :         if (NMix == 1) { // Single gas
    4907    13822192 :             con = fcon[0];
    4908    13822192 :             visc = fvis[0];
    4909    13822192 :             cp = fcp[0];
    4910    13822192 :             dens = fdens[0];
    4911      127405 :         } else if (NMix > 1) {                                                                   // Multiple gases; calculate mixture properties
    4912      127405 :             molmix = frct[0] * state.dataWindowManager->gwght[0][IGap - 1];                      // initialize eq. 56
    4913      127405 :             cpmixm = molmix * fcp[0];                                                            // initialize eq. 58
    4914      127405 :             kprime[0] = 3.75 * (gaslaw / state.dataWindowManager->gwght[0][IGap - 1]) * fvis[0]; // eq. 67
    4915      127405 :             kdblprm[0] = fcon[0] - kprime[0];                                                    // eq. 67
    4916             : 
    4917             :             // Initialize summations for eqns 60-66
    4918      127405 :             mumix = 0.0;
    4919      127405 :             kpmix = 0.0;
    4920      127405 :             kdpmix = 0.0;
    4921      127405 :             mukpdwn[0] = 1.0;
    4922      127405 :             kpdown[0] = 1.0;
    4923      127405 :             kdpdown[0] = 1.0;
    4924             : 
    4925             :             // Calculate properties of mixture constituents
    4926      254810 :             for (i = 2; i <= NMix; ++i) {
    4927      254810 :                 fcon[i - 1] = state.dataWindowManager->gcon[0][i - 1][IGap - 1] + state.dataWindowManager->gcon[1][i - 1][IGap - 1] * tmean +
    4928      127405 :                               state.dataWindowManager->gcon[2][i - 1][IGap - 1] * tmean_2;
    4929      254810 :                 fvis[i - 1] = state.dataWindowManager->gvis[0][i - 1][IGap - 1] + state.dataWindowManager->gvis[1][i - 1][IGap - 1] * tmean +
    4930      127405 :                               state.dataWindowManager->gvis[2][i - 1][IGap - 1] * tmean_2;
    4931      254810 :                 fcp[i - 1] = state.dataWindowManager->gcp[0][i - 1][IGap - 1] + state.dataWindowManager->gcp[1][i - 1][IGap - 1] * tmean +
    4932      127405 :                              state.dataWindowManager->gcp[2][i - 1][IGap - 1] * tmean_2;
    4933      127405 :                 fdens[i - 1] = pres * state.dataWindowManager->gwght[i - 1][IGap - 1] / (gaslaw * tmean);
    4934      127405 :                 molmix += frct[i - 1] * state.dataWindowManager->gwght[i - 1][IGap - 1];                       // eq. 56
    4935      127405 :                 cpmixm += frct[i - 1] * fcp[i - 1] * state.dataWindowManager->gwght[i - 1][IGap - 1];          // eq. 58-59
    4936      127405 :                 kprime[i - 1] = 3.75 * gaslaw / state.dataWindowManager->gwght[i - 1][IGap - 1] * fvis[i - 1]; // eq. 67
    4937      127405 :                 kdblprm[i - 1] = fcon[i - 1] - kprime[i - 1];                                                  // eq. 68
    4938      127405 :                 mukpdwn[i - 1] = 1.0;                                                                          // initialize denomonator of eq. 60
    4939      127405 :                 kpdown[i - 1] = 1.0;                                                                           // initialize denomonator of eq. 63
    4940      127405 :                 kdpdown[i - 1] = 1.0;                                                                          // initialize denomonator of eq. 65
    4941             :             }
    4942             : 
    4943      382215 :             for (i = 1; i <= NMix; ++i) {
    4944      764430 :                 for (j = 1; j <= NMix; ++j) {
    4945             :                     // numerator of equation 61
    4946     1019240 :                     phimup = pow_2(1.0 + std::sqrt(fvis[i - 1] / fvis[j - 1]) * root_4(state.dataWindowManager->gwght[j - 1][IGap - 1] /
    4947      509620 :                                                                                        state.dataWindowManager->gwght[i - 1][IGap - 1]));
    4948             :                     // denomonator of eq. 61, 64 and 66
    4949      509620 :                     downer = two_sqrt_2 *
    4950      509620 :                              std::sqrt(1 + (state.dataWindowManager->gwght[i - 1][IGap - 1] / state.dataWindowManager->gwght[j - 1][IGap - 1]));
    4951             :                     // calculate the denominator of eq. 60
    4952      509620 :                     if (i != j) mukpdwn[i - 1] += phimup / downer * frct[j - 1] / frct[i - 1];
    4953             :                     // numerator of eq. 64; psiterm is the multiplied term in backets
    4954     1019240 :                     psiup = pow_2(1.0 + std::sqrt(kprime[i - 1] / kprime[j - 1]) * root_4(state.dataWindowManager->gwght[i - 1][IGap - 1] /
    4955      509620 :                                                                                           state.dataWindowManager->gwght[j - 1][IGap - 1]));
    4956     1528860 :                     psiterm = 1.0 + 2.41 * (state.dataWindowManager->gwght[i - 1][IGap - 1] - state.dataWindowManager->gwght[j - 1][IGap - 1]) *
    4957     1019240 :                                         (state.dataWindowManager->gwght[i - 1][IGap - 1] - 0.142 * state.dataWindowManager->gwght[j - 1][IGap - 1]) /
    4958      509620 :                                         pow_2(state.dataWindowManager->gwght[i - 1][IGap - 1] + state.dataWindowManager->gwght[j - 1][IGap - 1]);
    4959             :                     // using the common denominator, downer, calculate the denominator for eq. 63
    4960      509620 :                     if (i != j) kpdown[i - 1] += psiup * (psiterm / downer) * (frct[j - 1] / frct[i - 1]);
    4961             :                     // calculate the numerator of eq. 66
    4962     1019240 :                     phikup = pow_2(1.0 + std::sqrt(kprime[i - 1] / kprime[j - 1]) * root_4(state.dataWindowManager->gwght[i - 1][IGap - 1] /
    4963      509620 :                                                                                            state.dataWindowManager->gwght[j - 1][IGap - 1]));
    4964             :                     // using the common denominator, downer, calculate the denomonator for eq. 65
    4965      509620 :                     if (i != j) kdpdown[i - 1] += (phikup / downer) * (frct[j - 1] / frct[i - 1]);
    4966             :                 }
    4967      254810 :                 mumix += fvis[i - 1] / mukpdwn[i - 1];     // eq. 60
    4968      254810 :                 kpmix += kprime[i - 1] / kpdown[i - 1];    // eq. 63
    4969      254810 :                 kdpmix += kdblprm[i - 1] / kdpdown[i - 1]; // eq. 65
    4970             :             }
    4971             : 
    4972             :             // Calculate the density of the mixture assuming an ideal gas
    4973      127405 :             rhomix = pres * molmix / (gaslaw * tmean); // eq. 57
    4974      127405 :             kmix = kpmix + kdpmix;                     // eq. 68-a
    4975             : 
    4976             :             // Final mixture properties
    4977      127405 :             visc = mumix;
    4978      127405 :             con = kmix;
    4979      127405 :             dens = rhomix;
    4980      127405 :             cp = cpmixm / molmix;
    4981             : 
    4982             :         } else {
    4983           0 :             assert(false);
    4984             :         } // End of check if single or multiple gases in gap
    4985             : 
    4986    13949597 :         pr = cp * visc / con;
    4987    13949597 :         gr = 9.807 * pow_3(state.dataWindowManager->gap[IGap - 1]) * std::abs(tleft - tright) * pow_2(dens) / (tmean * pow_2(visc));
    4988    13949597 :     }
    4989             : 
    4990             :     //******************************************************************************
    4991             : 
    4992      265344 :     void WindowGasPropertiesAtTemp(EnergyPlusData &state,
    4993             :                                    Real64 const tmean, // Temperature of gas in gap (K)
    4994             :                                    int const IGap,     // Gap number
    4995             :                                    Real64 &dens,       // Gap gas density at tmean (kg/m3)
    4996             :                                    Real64 &visc        // Gap gas dynamic viscosity at tmean (g/m-s)
    4997             :     )
    4998             :     {
    4999             : 
    5000             :         // SUBROUTINE INFORMATION:
    5001             :         //       AUTHOR         F. Winkelmann
    5002             :         //       DATE WRITTEN   December 2002
    5003             :         //       MODIFIED       na
    5004             :         //       RE-ENGINEERED  na
    5005             : 
    5006             :         // PURPOSE OF THIS SUBROUTINE:
    5007             :         // Finds the density and viscosity of the gas in a gap at a particular temperature.
    5008             :         // The gap may be filled with a single gas or a gas mixture.
    5009             :         // Based on Subroutine WindowGasConductance.
    5010             : 
    5011             :         // METHODOLOGY EMPLOYED:
    5012             :         // See Subr. WindowGasConductance
    5013             : 
    5014             :         // REFERENCES:
    5015             :         // See Subr. WindowGasConductance
    5016             : 
    5017      265344 :         Real64 constexpr pres(1.0e5);     // Gap gas pressure (Pa)
    5018      265344 :         Real64 constexpr gaslaw(8314.51); // Molar gas constant (J/kMol-K)
    5019      265344 :         Real64 const two_sqrt_2(2.0 * std::sqrt(2.0));
    5020             : 
    5021             :         int IMix; // Counters of gases in a mixture
    5022             :         int i;
    5023             :         int j;
    5024             :         int NMix;                    // Number of gases in a mixture
    5025             :         Real64 molmix;               // Molecular weight of mixture
    5026      530688 :         Array1D<Real64> mukpdwn(10); // Denominator term
    5027             :         Real64 mumix;                // For accumulating viscosity of gas mixture
    5028             :         Real64 phimup;               // Numerator factor
    5029             :         Real64 downer;               // Denominator factor
    5030             :         Real64 rhomix;               // Density of gas mixture (kg/m3)
    5031      530688 :         Array1D<Real64> frct(10);    // Fraction of each gas in a mixture
    5032      530688 :         Array1D<Real64> fvis(10);    // Viscosity of each gas in a mixture (g/m-s)
    5033      530688 :         Array1D<Real64> fdens(10);   // Density of each gas in a mixture (kg/m3)
    5034             : 
    5035      265344 :         NMix = state.dataWindowManager->gnmix[IGap - 1];
    5036             : 
    5037      530688 :         for (IMix = 1; IMix <= NMix; ++IMix) {
    5038      265344 :             frct(IMix) = state.dataWindowManager->gfract[IMix - 1][IGap - 1];
    5039             :         }
    5040             : 
    5041      265344 :         Real64 const tmean_2(pow_2(tmean));
    5042      530688 :         fvis(1) = state.dataWindowManager->gvis[0][0][IGap - 1] + state.dataWindowManager->gvis[1][0][IGap - 1] * tmean +
    5043      265344 :                   state.dataWindowManager->gvis[2][0][IGap - 1] * tmean_2;
    5044      265344 :         fdens(1) = pres * state.dataWindowManager->gwght[0][IGap - 1] / (gaslaw * tmean); // Density using ideal gas law:
    5045             :         //  rho=(presure*molecweight)/(gasconst*tmean)
    5046      265344 :         if (NMix == 1) { // Single gas
    5047      265344 :             visc = fvis(1);
    5048      265344 :             dens = fdens(1);
    5049             :         } else {                                                            // Multiple gases; calculate mixture properties
    5050           0 :             molmix = frct(1) * state.dataWindowManager->gwght[0][IGap - 1]; // initialize eq. 56
    5051             : 
    5052             :             // Initialize summations for eqns 60-66
    5053           0 :             mumix = 0.0;
    5054           0 :             mukpdwn(1) = 1.0;
    5055             : 
    5056             :             // Calculate properties of mixture constituents
    5057           0 :             for (i = 2; i <= NMix; ++i) {
    5058           0 :                 fvis(i) = state.dataWindowManager->gvis[0][i - 1][IGap - 1] + state.dataWindowManager->gvis[1][i - 1][IGap - 1] * tmean +
    5059           0 :                           state.dataWindowManager->gvis[2][i - 1][IGap - 1] * tmean_2;
    5060           0 :                 fdens(i) = pres * state.dataWindowManager->gwght[i - 1][IGap - 1] / (gaslaw * tmean);
    5061           0 :                 molmix += frct(i) * state.dataWindowManager->gwght[i - 1][IGap - 1]; // eq. 56
    5062           0 :                 mukpdwn(i) = 1.0;                                                    // initialize denomonator of eq. 60
    5063             :             }
    5064             : 
    5065           0 :             for (i = 1; i <= NMix; ++i) {
    5066           0 :                 for (j = 1; j <= NMix; ++j) {
    5067             :                     // numerator of equation 61
    5068           0 :                     phimup = pow_2(1.0 + std::sqrt(fvis(i) / fvis(j)) * root_4(state.dataWindowManager->gwght[j - 1][IGap - 1] /
    5069           0 :                                                                                state.dataWindowManager->gwght[i - 1][IGap - 1]));
    5070             :                     // denomonator of eq. 61, 64 and 66
    5071           0 :                     downer = two_sqrt_2 *
    5072           0 :                              std::sqrt(1 + (state.dataWindowManager->gwght[i - 1][IGap - 1] / state.dataWindowManager->gwght[j - 1][IGap - 1]));
    5073             :                     // calculate the denominator of eq. 60
    5074           0 :                     if (i != j) mukpdwn(i) += phimup / downer * frct(j) / frct(i);
    5075             :                 }
    5076           0 :                 mumix += fvis(i) / mukpdwn(i); // eq. 60
    5077             :             }
    5078             : 
    5079             :             // Calculate the density of the mixture assuming an ideal gas
    5080           0 :             rhomix = pres * molmix / (gaslaw * tmean); // eq. 57
    5081             : 
    5082             :             // Final mixture properties
    5083           0 :             visc = mumix;
    5084           0 :             dens = rhomix;
    5085             : 
    5086             :         } // End of check if single or multiple gases in gap
    5087      265344 :     }
    5088             : 
    5089             :     //********************************************************************************
    5090             : 
    5091    22607285 :     void StartingWindowTemps(EnergyPlusData &state,
    5092             :                              int const SurfNum,          // Surface number
    5093             :                              Array1A<Real64> AbsRadShade // Short-wave radiation absorbed by shade/blind faces
    5094             :     )
    5095             :     {
    5096             : 
    5097             :         // SUBROUTINE INFORMATION:
    5098             :         //       AUTHOR         F. Winkelmann
    5099             :         //       DATE WRITTEN   January 2000
    5100             :         //       MODIFIED       March 2003, FW: add rough calc of increase above ambient of
    5101             :         //                        initial shade/blind temperature when shade/blind deployed
    5102             :         //                        after having been off.
    5103             :         //                      Jan 2004, FW: take into account whether storm window was added
    5104             :         //                        or removed in the current time step.
    5105             :         //       RE-ENGINEERED  na
    5106             : 
    5107             :         // PURPOSE OF THIS SUBROUTINE:
    5108             :         // Initializes face temperature distribution prior to iteration
    5109             : 
    5110             :         // Argument array dimensioning
    5111    22607285 :         AbsRadShade.dim(2);
    5112             : 
    5113    22607285 :         constexpr Real64 hrad(5.3);    // Typical radiative conductance (W/m2-K)
    5114    22607285 :         constexpr Real64 resgap(0.21); // Typical gap resistance (m2-K/W)
    5115             : 
    5116             :         int i;                      // Face counter
    5117             :         WinShadingType ShadeFlag;   // Shading flag
    5118    45214570 :         Array1D<Real64> rguess(11); // Combined radiative/convective resistance (m2-K/W) of
    5119             :         // inside or outside air film, or gap
    5120             :         Real64 restot; // Total window resistance including outside
    5121             :         //   and inside air films (m2-K/W)
    5122             :         Real64 temdiff;          // Inside/outside air temperature difference (K)
    5123             :         Real64 ressum;           // Resistance sum (m2-K/W)
    5124             :         int StormWinFlagPrevDay; // Previous time step value (day) of storm window flag
    5125             :         int StormWinFlagThisDay; // Current time step value (day) of storm window flag
    5126             :         int nglfacePrevDay;      // Previous time step value (dya) of number of glass faces (may differ
    5127             :         //   current time step value, nglface, if storm window was
    5128             :         //   added or removed during the current time step).
    5129             : 
    5130    22607285 :         StormWinFlagPrevDay = state.dataSurface->SurfWinStormWinFlagPrevDay(SurfNum);
    5131    22607285 :         StormWinFlagThisDay = state.dataSurface->SurfWinStormWinFlag(SurfNum);
    5132             : 
    5133    22607285 :         if (state.dataGlobal->BeginEnvrnFlag || (StormWinFlagThisDay != StormWinFlagPrevDay)) {
    5134             : 
    5135             :             // Guess values of glass face temperatures based on a simple resistance-network solution
    5136             :             // that (1) ignores short- and long-wave radiation (from lights and zone equipment) absorbed
    5137             :             // by the glass faces, and (2) assumes zero glass resistance. Absorbed solar is also ignored
    5138             :             // since the tests on BeginEnvrnFlag and storm window transition can be true only at midnight.
    5139             :             // Interaction with shade or blind, if one of these is present, is ignored. See below for
    5140             :             // separate calculation of shade/blind temperature.
    5141             : 
    5142       25016 :             rguess(1) = 1.0 / (state.dataWindowManager->hcout + hrad);
    5143       25016 :             rguess(state.dataWindowManager->nglface + 1) = 1.0 / (state.dataWindowManager->hcin + hrad);
    5144             : 
    5145       58099 :             for (i = 2; i <= state.dataWindowManager->nglface; i += 2) {
    5146       33083 :                 rguess(i) = 1.0 / state.dataWindowManager->scon[i / 2 - 1];
    5147       33083 :                 if (i < state.dataWindowManager->nglface) rguess(i + 1) = resgap;
    5148             :             }
    5149             : 
    5150       25016 :             restot = 0.0;
    5151      116198 :             for (i = 1; i <= state.dataWindowManager->nglface + 1; ++i) {
    5152       91182 :                 restot += rguess(i);
    5153             :             }
    5154             : 
    5155       25016 :             temdiff = state.dataWindowManager->tin - state.dataWindowManager->tout;
    5156       25016 :             if (std::abs(temdiff) < 0.5) temdiff = 2.0;
    5157             : 
    5158       25016 :             ressum = 0.0;
    5159       91182 :             for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
    5160       66166 :                 ressum += rguess(i);
    5161       66166 :                 state.dataWindowManager->thetas[i - 1] = (ressum / restot) * temdiff + state.dataWindowManager->tout;
    5162             :             }
    5163             : 
    5164             :         } else {
    5165             :             // Use previous time step values
    5166    80938327 :             for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
    5167    58356058 :                 state.dataWindowManager->thetas[i - 1] = state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(i);
    5168             :             }
    5169             :         }
    5170             : 
    5171             :         // Initialize face temperatures of shade or blind, if present
    5172             : 
    5173    22607285 :         ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    5174    67780919 :         if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum)) ||
    5175    45125468 :             state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) == WinShadingType::ExtShade ||
    5176    67724417 :             state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) == WinShadingType::ExtBlind ||
    5177    22558013 :             ANY_BETWEENGLASS_SHADE_BLIND(state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum))) {
    5178             :             // Shade or blind is on during the previous TS; use previous-TS values of shade/blind face temps.
    5179             :             // Note that if shade or blind is NOT on in the current TS the following two
    5180             :             // temperature values, although calculated here, are not used. The shade/blind face numbers
    5181             :             // during the previous time step depend on whether a storm window glass layer was added to
    5182             :             // or removed from the window during the current time step.
    5183       66126 :             nglfacePrevDay = state.dataWindowManager->nglface;
    5184       66126 :             if (StormWinFlagPrevDay == 0 && StormWinFlagThisDay == 1) nglfacePrevDay = state.dataWindowManager->nglface - 2;
    5185       66126 :             if (StormWinFlagPrevDay == 1 && StormWinFlagThisDay == 0) nglfacePrevDay = state.dataWindowManager->nglface + 2;
    5186       66126 :             state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
    5187       66126 :                 state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(nglfacePrevDay + 1);
    5188       66126 :             state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
    5189       66126 :                 state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(nglfacePrevDay + 2);
    5190             :         } else {
    5191             :             // No shade or blind previous time step; guess starting values of shade/blind
    5192             :             // taking into account short- and long-wave radiation (from solar, lights and zone equipment)
    5193             :             // absorbed by shade/blind faces. Face temps are assumed to be the same and
    5194             :             // equal to shade/blind temp. For interior shade/blind, air temp on either side is
    5195             :             // assumed to be the same and equal to tin; for exterior blind it is assumed to be
    5196             :             // equal to tout. For between-glass shade/blind it is assumed to be equal to the
    5197             :             // average temperature of the adjacent glass faces.
    5198             : 
    5199    22541159 :             if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    5200        4475 :                 state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
    5201        4475 :                     state.dataWindowManager->tin + (AbsRadShade(1) + AbsRadShade(2)) / (2 * (state.dataWindowManager->hcin + hrad));
    5202        4475 :                 state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
    5203        4475 :                     state.dataWindowManager->thetas[state.dataWindowManager->nglface];
    5204    22536684 :             } else if (ShadeFlag == WinShadingType::ExtShade || ShadeFlag == WinShadingType::ExtBlind) {
    5205         180 :                 state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
    5206         180 :                     state.dataWindowManager->tout + (AbsRadShade(1) + AbsRadShade(2)) / (2 * (state.dataWindowManager->hcout + hrad));
    5207         180 :                 state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
    5208         180 :                     state.dataWindowManager->thetas[state.dataWindowManager->nglface];
    5209    22536504 :             } else if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    5210             :                 // Between-glass shade/blind allowed only for double and triple glazing.
    5211             :                 // The factor 16.0 below is based on a combined convective/radiative heat transfer
    5212             :                 // coefficient on either side of the shade/blind of 8.0 W/m2-K -- about 1.4 Btu/h-ft2-F.
    5213          30 :                 if (state.dataWindowManager->nglface == 4) { // double glazing
    5214          22 :                     state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
    5215          22 :                         0.5 * (state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]) + (AbsRadShade(1) + AbsRadShade(2)) / 16.0;
    5216          22 :                     state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
    5217          22 :                         state.dataWindowManager->thetas[state.dataWindowManager->nglface];
    5218             :                 } else { // triple glazing
    5219           8 :                     state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
    5220           8 :                         0.5 * (state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]) + (AbsRadShade(1) + AbsRadShade(2)) / 16.0;
    5221           8 :                     state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
    5222           8 :                         state.dataWindowManager->thetas[state.dataWindowManager->nglface];
    5223             :                 }
    5224             :             }
    5225             :         }
    5226    22607285 :     }
    5227             : 
    5228             :     //****************************************************************************
    5229             : 
    5230    13949597 :     void NusseltNumber(EnergyPlusData &state,
    5231             :                        int const SurfNum, // Surface number
    5232             :                        Real64 const tso,  // Temperature of gap surface closest to outside (K)
    5233             :                        Real64 const tsi,  // Temperature of gap surface closest to zone (K)
    5234             :                        int const IGap,    // Gap number
    5235             :                        Real64 const gr,   // Gap gas Grashof number
    5236             :                        Real64 const pr,   // Gap gas Prandtl number
    5237             :                        Real64 &gnu        // Gap gas Nusselt number
    5238             :     )
    5239             :     {
    5240             : 
    5241             :         // SUBROUTINE INFORMATION:
    5242             :         //       AUTHOR         Adapted by Fred Winkelmann from Window5 subroutine nusselt
    5243             :         //       DATE WRITTEN   September 2001
    5244             :         //       MODIFIED       na
    5245             :         //       RE-ENGINEERED  na
    5246             : 
    5247             :         // PURPOSE OF THIS SUBROUTINE:
    5248             :         // Finds the Nusselt number for gas-filled gaps between isothermal solid layers.
    5249             :         // The gap may be filled with a single gas or a gas mixture.
    5250             : 
    5251             :         // METHODOLOGY EMPLOYED:
    5252             :         // Based on methodology in Chapter 5 of the July 18, 2001 draft of ISO 15099,
    5253             :         // "Thermal Performance of Windows, Doors and Shading Devices--Detailed Calculations."
    5254             :         // The equation numbers below correspond to those in the standard.
    5255             : 
    5256             :         // REFERENCES:
    5257             :         // Window5 source code; ISO 15099
    5258             : 
    5259             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5260             :         Real64 asp;    // Aspect ratio: window height to gap width
    5261             :         Real64 ra;     // Rayleigh number
    5262             :         Real64 gnu901; // Nusselt number temporary variables for
    5263             :         Real64 gnu902;
    5264             :         Real64 gnu90;
    5265             :         Real64 gnu601;
    5266             :         Real64 gnu602; // different tilt and Ra ranges
    5267             :         Real64 gnu60;
    5268             :         Real64 gnu601a;
    5269             :         Real64 gnua;
    5270             :         Real64 gnub;
    5271             :         Real64 cra; // Temporary variables
    5272             :         Real64 a;
    5273             :         Real64 b;
    5274             :         Real64 g;
    5275             :         Real64 ang;
    5276             : 
    5277    13949597 :         if (SurfNum > 0) {
    5278    13941373 :             asp = state.dataSurface->Surface(SurfNum).Height / state.dataWindowManager->gap[IGap - 1];
    5279             :         } else { // SurfNum = 0 when NusseltNumber is called from CalcNominalWindowCond, which applies to a
    5280             :             // particular construction. So window height is not known and we assume 5 ft (1.524 m)
    5281        8224 :             asp = 1.524 / state.dataWindowManager->gap[IGap - 1];
    5282             :         }
    5283             : 
    5284    13949597 :         state.dataWindowManager->tiltr = state.dataWindowManager->tilt * DataGlobalConstants::DegToRadians;
    5285    13949597 :         ra = gr * pr;
    5286             :         //! fw if (ra > 2.0e6): error that outside range of Rayleigh number?
    5287             : 
    5288    13949597 :         if (ra <= 1.0e4) gnu901 = 1.0 + 1.7596678e-10 * std::pow(ra, 2.2984755); // eq. 51
    5289    13949597 :         if (ra > 1.0e4 && ra <= 5.0e4) gnu901 = 0.028154 * std::pow(ra, 0.4134); // eq. 50
    5290    13949597 :         if (ra > 5.0e4) gnu901 = 0.0673838 * std::pow(ra, 1.0 / 3.0);            // eq. 49
    5291             : 
    5292    13949597 :         gnu902 = 0.242 * std::pow(ra / asp, 0.272); // eq. 52
    5293    13949597 :         gnu90 = max(gnu901, gnu902);
    5294             : 
    5295    13949597 :         if (tso > tsi) {                                                          // window heated from above
    5296     4635528 :             gnu = 1.0 + (gnu90 - 1.0) * std::sin(state.dataWindowManager->tiltr); // eq. 53
    5297             :         } else {                                                                  // window heated from below
    5298     9314069 :             if (state.dataWindowManager->tilt >= 60.0) {
    5299     8183659 :                 if (ra >= 0.001) {
    5300     8160963 :                     g = 0.5 * std::pow(1.0 + std::pow(ra / 3160.0, 20.6), -0.1); // eq. 47
    5301             :                 } else {
    5302       22696 :                     g = 0.5;
    5303             :                 }
    5304     8183659 :                 gnu601a = 1.0 + pow_7(0.0936 * std::pow(ra, 0.314) / (1.0 + g)); // eq. 45
    5305     8183659 :                 gnu601 = std::pow(gnu601a, 0.142857);
    5306             : 
    5307             :                 // For any aspect ratio
    5308     8183659 :                 gnu602 = (0.104 + 0.175 / asp) * std::pow(ra, 0.283); // eq. 46
    5309     8183659 :                 gnu60 = max(gnu601, gnu602);
    5310             : 
    5311             :                 // linear interpolation for layers inclined at angles between 60 and 90 deg
    5312     8183659 :                 gnu = ((90.0 - state.dataWindowManager->tilt) * gnu60 + (state.dataWindowManager->tilt - 60.0) * gnu90) / 30.0;
    5313             :             }
    5314     9314069 :             if (state.dataWindowManager->tilt < 60.0) { // eq. 42
    5315     1130410 :                 cra = ra * std::cos(state.dataWindowManager->tiltr);
    5316     1130410 :                 a = 1.0 - 1708.0 / cra;
    5317     1130410 :                 b = std::pow(cra / 5830.0, 0.33333) - 1.0;
    5318     1130410 :                 gnua = (std::abs(a) + a) / 2.0;
    5319     1130410 :                 gnub = (std::abs(b) + b) / 2.0;
    5320     1130410 :                 ang = 1708.0 * std::pow(std::sin(1.8 * state.dataWindowManager->tiltr), 1.6);
    5321     1130410 :                 gnu = 1.0 + 1.44 * gnua * (1.0 - ang / cra) + gnub;
    5322             :             }
    5323             :         }
    5324    13949597 :     }
    5325             : 
    5326             :     //*******************************************************************************************************
    5327             : 
    5328      912020 :     void TransAndReflAtPhi(Real64 const cs,                // Cosine of incidence angle
    5329             :                            Real64 const tf0,               // Transmittance at zero incidence angle
    5330             :                            Real64 const rf0,               // Front reflectance at zero incidence angle
    5331             :                            Real64 const rb0,               // Back reflectance at zero incidence angle
    5332             :                            Real64 &tfp,                    // Transmittance at cs
    5333             :                            Real64 &rfp,                    // Front reflectance at cs
    5334             :                            Real64 &rbp,                    // Back reflectance at cs
    5335             :                            bool const SimpleGlazingSystem, // .TRUE. if simple block model being used
    5336             :                            Real64 const SimpleGlazingSHGC, // SHGC value to use in alternate model for simple glazing system
    5337             :                            Real64 const SimpleGlazingU     // U-factor value to use in alternate model for simple glazing system
    5338             :     )
    5339             :     {
    5340             : 
    5341             :         // SUBROUTINE INFORMATION:
    5342             :         //       AUTHOR         F. Winkelmann
    5343             :         //       DATE WRITTEN   January 2000
    5344             :         //       MODIFIED       5 June 2003, FCW: modify to correspond to WINDOW 4 and WINDOW 5.
    5345             :         //                      Original routine was based on the method in E.U. Finlayson et al,
    5346             :         //                      "WINDOW 4.0: Documentation of Calculation Procedures," LBL-33943,
    5347             :         //                      July 1993, which is not used in either WINDOW 4 or WINDOW 5.
    5348             :         //                      The current routine is based on ASHRAE Handbook of Fundamentals,
    5349             :         //                      2001, pp. 30.20-23, "Optical Properties of Single Glazing Layers."
    5350             :         //                      Original routine underpredicted transmittance at angles of
    5351             :         //                      incidence > 60 degrees.
    5352             :         //                      June 2009.  Brent Griffith.  add simple window correlation
    5353             :         //                                   newer model from LBNL windows group 5/15/2009
    5354             :         //       RE-ENGINEERED  na
    5355             : 
    5356             :         // PURPOSE OF THIS SUBROUTINE:
    5357             :         // For a single glazing layer, calculate transmittance and reflectance at an arbitrary
    5358             :         // angle of incidence given transmittance and reflectance at zero incidence angle.
    5359             : 
    5360             :         // REFERENCES:
    5361             :         // ASHRAE Handbook of Fundamentals, 2001, pp. 30.20-23,
    5362             :         // "Optical Properties of Single Glazing Layers."
    5363             : 
    5364             :         Real64 tfp1; // Transmittance at cs for each polarization
    5365             :         Real64 tfp2;
    5366             :         Real64 rfp1; // Front reflectance at cs for each polarization
    5367             :         Real64 rfp2;
    5368             :         Real64 rbp1; // Back reflectance at cs for each polarization
    5369             :         Real64 rbp2;
    5370             :         Real64 betaf; // Intermediate variables
    5371             :         Real64 betab;
    5372             :         Real64 r0f;
    5373             :         Real64 r0b;
    5374             :         Real64 abf;
    5375             :         Real64 abb;
    5376             :         Real64 ngf; // Front and back index of refraction
    5377             :         Real64 ngb;
    5378             :         Real64 cgf; // Intermediate variables
    5379             :         Real64 cgb;
    5380             :         Real64 rpf1; // Front and back air/glass interface reflectivity
    5381             :         Real64 rpb1;
    5382             :         Real64 tpf1;
    5383             :         Real64 tpb1;
    5384             :         //  and transmittivity for first polarization
    5385             :         Real64 rpf2; // Front and back air/glass interface reflectivity
    5386             :         Real64 rpb2;
    5387             :         Real64 tpf2;
    5388             :         Real64 tpb2;
    5389             :         //  and transmittivity for second polarization
    5390             :         Real64 tcl; // Transmittance and reflectance for clear glass
    5391             :         Real64 rcl;
    5392             :         Real64 tbnz; // Transmittance and reflectance for bronze glass
    5393             :         Real64 rbnz;
    5394             :         Real64 expmabfdivcgf;
    5395             :         Real64 expm2abfdivcgf;
    5396             :         Real64 expmabbdivcgb;
    5397             : 
    5398             :         Real64 testval; // temporary value for calculations
    5399             :         Real64 tmp1;    // temporary value for calculations
    5400             :         Real64 tmp2;    // temporary value for calculations
    5401             :         Real64 tmp3;    // temporary value for calculations
    5402             :         Real64 tmp4;    // temporary value for calculations
    5403             :         Real64 tmp5;    // temporary value for calculations
    5404             :         Real64 tmp6;    // temporary value for calculations
    5405             :         Real64 tmp7;    // temporary value for calculations
    5406             :         Real64 tmp8;    // temporary value for calculations
    5407             :         Real64 tmp9;    // temporary value for calculations
    5408             : 
    5409      912020 :         if (SimpleGlazingSystem) { // use alternate angular dependence model for block model of simple glazing input
    5410             : 
    5411        4880 :             Real64 const cs_2(pow_2(cs));
    5412        4880 :             Real64 const cs_3(pow_3(cs));
    5413        4880 :             Real64 const cs_4(pow_4(cs));
    5414        4880 :             Real64 TransCurveA = 0.00 + 3.36 * cs - 3.85 * cs_2 + 1.49 * cs_3 + 0.01 * cs_4;
    5415        4880 :             Real64 TransCurveB = 0.00 + 2.83 * cs - 2.42 * cs_2 + 0.04 * cs_3 + 0.55 * cs_4;
    5416        4880 :             Real64 TransCurveC = 0.00 + 2.45 * cs - 1.58 * cs_2 - 0.64 * cs_3 + 0.77 * cs_4;
    5417        4880 :             Real64 TransCurveD = 0.00 + 2.85 * cs - 2.58 * cs_2 + 0.40 * cs_3 + 0.35 * cs_4;
    5418        4880 :             Real64 TransCurveE = 0.00 + 1.51 * cs + 2.49 * cs_2 - 5.87 * cs_3 + 2.88 * cs_4;
    5419        4880 :             Real64 TransCurveF = 0.00 + 1.21 * cs + 3.14 * cs_2 - 6.37 * cs_3 + 3.03 * cs_4;
    5420        4880 :             Real64 TransCurveG = 0.00 + 1.09 * cs + 3.54 * cs_2 - 6.84 * cs_3 + 3.23 * cs_4;
    5421        4880 :             Real64 TransCurveH = 0.00 + 0.98 * cs + 3.83 * cs_2 - 7.13 * cs_3 + 3.33 * cs_4;
    5422        4880 :             Real64 TransCurveI = 0.00 + 0.79 * cs + 3.93 * cs_2 - 6.86 * cs_3 + 3.15 * cs_4;
    5423        4880 :             Real64 TransCurveJ = 0.00 + 0.08 * cs + 6.02 * cs_2 - 8.84 * cs_3 + 3.74 * cs_4;
    5424        4880 :             Real64 TransCurveFGHI = (TransCurveF + TransCurveG + TransCurveH + TransCurveI) / 4.0;
    5425        4880 :             Real64 TransCurveFH = (TransCurveF + TransCurveH) / 2.0;
    5426        4880 :             Real64 TransCurveBDCD = (TransCurveB + TransCurveD + TransCurveC + TransCurveD) / 4.0;
    5427             : 
    5428        4880 :             Real64 ReflectCurveA = 1.00 - 0.70 * cs + 2.57 * cs_2 - 3.20 * cs_3 + 1.33 * cs_4 - TransCurveA;
    5429        4880 :             Real64 ReflectCurveB = 1.00 - 1.87 * cs + 6.50 * cs_2 - 7.86 * cs_3 + 3.23 * cs_4 - TransCurveB;
    5430        4880 :             Real64 ReflectCurveC = 1.00 - 2.52 * cs + 8.40 * cs_2 - 9.86 * cs_3 + 3.99 * cs_4 - TransCurveC;
    5431        4880 :             Real64 ReflectCurveD = 1.00 - 1.85 * cs + 6.40 * cs_2 - 7.64 * cs_3 + 3.11 * cs_4 - TransCurveD;
    5432        4880 :             Real64 ReflectCurveE = 1.00 - 1.57 * cs + 5.60 * cs_2 - 6.82 * cs_3 + 2.80 * cs_4 - TransCurveE;
    5433        4880 :             Real64 ReflectCurveF = 1.00 - 3.15 * cs + 10.98 * cs_2 - 13.14 * cs_3 + 5.32 * cs_4 - TransCurveF;
    5434        4880 :             Real64 ReflectCurveG = 1.00 - 3.25 * cs + 11.32 * cs_2 - 13.54 * cs_3 + 5.49 * cs_4 - TransCurveG;
    5435        4880 :             Real64 ReflectCurveH = 1.00 - 3.39 * cs + 11.70 * cs_2 - 13.94 * cs_3 + 5.64 * cs_4 - TransCurveH;
    5436        4880 :             Real64 ReflectCurveI = 1.00 - 4.06 * cs + 13.55 * cs_2 - 15.74 * cs_3 + 6.27 * cs_4 - TransCurveI;
    5437        4880 :             Real64 ReflectCurveJ = 1.00 - 4.35 * cs + 14.27 * cs_2 - 16.32 * cs_3 + 6.39 * cs_4 - TransCurveJ;
    5438             : 
    5439        4880 :             Real64 ReflectCurveFGHI = (ReflectCurveF + ReflectCurveG + ReflectCurveH + ReflectCurveI) / 4.0;
    5440        4880 :             Real64 ReflectCurveFH = (ReflectCurveF + ReflectCurveH) / 2.0;
    5441        4880 :             Real64 ReflectCurveBDCD = (ReflectCurveB + ReflectCurveD + ReflectCurveC + ReflectCurveD) / 4.0;
    5442             : 
    5443        4880 :             Real64 TransTmp(0.0);
    5444        4880 :             Real64 ReflectTmp(0.0);
    5445             : 
    5446        4880 :             if (SimpleGlazingU < 1.4195) { // cell 1, 2, or 3
    5447          80 :                 if (SimpleGlazingSHGC > 0.45) {
    5448             :                     // cell # 1
    5449             :                     // Curve E
    5450          80 :                     TransTmp = TransCurveE;
    5451          80 :                     ReflectTmp = ReflectCurveE;
    5452             : 
    5453           0 :                 } else if ((0.35 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
    5454             :                     // cell # 2
    5455             :                     // 2 way interpolation between Curve E and Curve J
    5456           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.35, 0.45, TransCurveJ, TransCurveE);
    5457           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.35, 0.45, ReflectCurveJ, ReflectCurveE);
    5458             : 
    5459           0 :                 } else if (SimpleGlazingSHGC < 0.35) {
    5460             :                     // cell # 3
    5461             :                     // Curve J
    5462           0 :                     TransTmp = TransCurveJ;
    5463           0 :                     ReflectTmp = ReflectCurveJ;
    5464             :                 }
    5465             : 
    5466        4800 :             } else if ((1.4195 <= SimpleGlazingU) && (SimpleGlazingU <= 1.7034)) { // cell 4, 5 , 6, 7, 8, 9, or 10
    5467           0 :                 if (SimpleGlazingSHGC > 0.55) {
    5468             :                     // cell # 4
    5469             :                     // Curve E
    5470           0 :                     TransTmp = TransCurveE;
    5471           0 :                     ReflectTmp = ReflectCurveE;
    5472             : 
    5473           0 :                 } else if ((0.5 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.55)) {
    5474             :                     // cell # 5
    5475             :                     // 4 way interpolation between Curve E , Curve E, Curve E and Curve FGHI
    5476             : 
    5477           0 :                     TransTmp = InterpolateBetweenFourValues(
    5478             :                         SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.50, 0.55, TransCurveE, TransCurveE, TransCurveFGHI, TransCurveE);
    5479           0 :                     ReflectTmp = InterpolateBetweenFourValues(
    5480             :                         SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.50, 0.55, ReflectCurveE, ReflectCurveE, ReflectCurveFGHI, ReflectCurveE);
    5481             : 
    5482           0 :                 } else if ((0.45 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.5)) {
    5483             :                     // cell # 6
    5484             :                     // 2 way interpolation between Curve E and Curve FGHI
    5485           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, TransCurveE, TransCurveFGHI);
    5486           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, ReflectCurveE, ReflectCurveFGHI);
    5487             : 
    5488           0 :                 } else if ((0.35 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
    5489             :                     // cell # 7
    5490             :                     // 4 way interpolation between Curve E , Curve FGHI, Curve J and Curve FGHI
    5491           0 :                     TransTmp = InterpolateBetweenFourValues(
    5492             :                         SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.35, 0.45, TransCurveJ, TransCurveE, TransCurveFGHI, TransCurveFGHI);
    5493           0 :                     ReflectTmp = InterpolateBetweenFourValues(SimpleGlazingU,
    5494             :                                                               SimpleGlazingSHGC,
    5495             :                                                               1.4195,
    5496             :                                                               1.7034,
    5497             :                                                               0.35,
    5498             :                                                               0.45,
    5499             :                                                               ReflectCurveJ,
    5500             :                                                               ReflectCurveE,
    5501             :                                                               ReflectCurveFGHI,
    5502             :                                                               ReflectCurveFGHI);
    5503             : 
    5504           0 :                 } else if ((0.3 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.35)) {
    5505             :                     // cell # 8
    5506             :                     // 2 way interpolation between Curve J and Curve FGHI
    5507           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, TransCurveJ, TransCurveFGHI);
    5508           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, ReflectCurveJ, ReflectCurveFGHI);
    5509             : 
    5510           0 :                 } else if ((0.25 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.3)) {
    5511             :                     // cell # 9
    5512             :                     // 4 way interpolation between Curve J, Curve FGHI, Curve J and Curve FH
    5513           0 :                     TransTmp = InterpolateBetweenFourValues(
    5514             :                         SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.25, 0.3, TransCurveJ, TransCurveJ, TransCurveFH, TransCurveFGHI);
    5515           0 :                     ReflectTmp = InterpolateBetweenFourValues(
    5516             :                         SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.25, 0.3, ReflectCurveJ, ReflectCurveJ, ReflectCurveFH, ReflectCurveFGHI);
    5517             : 
    5518           0 :                 } else if (SimpleGlazingSHGC <= 0.25) {
    5519             :                     // cell # 10
    5520             :                     // 2 way interpolation between Curve J and Curve FH
    5521           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, TransCurveJ, TransCurveFH);
    5522           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, ReflectCurveJ, ReflectCurveFH);
    5523             :                 }
    5524        4800 :             } else if ((1.7034 < SimpleGlazingU) && (SimpleGlazingU < 3.4068)) { // cell 11, 12, 13, 14, or 15
    5525        9280 :                 if (SimpleGlazingSHGC > 0.55) {
    5526             :                     // cell # 11
    5527             :                     // Curve E
    5528         400 :                     TransTmp = TransCurveE;
    5529         400 :                     ReflectTmp = ReflectCurveE;
    5530             : 
    5531        4240 :                 } else if ((0.5 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.55)) {
    5532             :                     // cell # 12
    5533             :                     // 2 way interpolation between Curve E and Curve FGHI
    5534           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.5, 0.55, TransCurveFGHI, TransCurveE);
    5535           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.5, 0.55, ReflectCurveFGHI, ReflectCurveE);
    5536             : 
    5537        4240 :                 } else if ((0.3 < SimpleGlazingSHGC) && (SimpleGlazingSHGC < 0.5)) {
    5538             :                     // cell # 13
    5539             :                     // Curve FGHI
    5540        4240 :                     TransTmp = TransCurveFGHI;
    5541        4240 :                     ReflectTmp = ReflectCurveFGHI;
    5542             : 
    5543           0 :                 } else if ((0.25 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.3)) {
    5544             :                     // cell # 14
    5545             :                     // 2 way interpolation between Curve FGHI and Curve FH
    5546           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.25, 0.30, TransCurveFH, TransCurveFGHI);
    5547           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.25, 0.30, ReflectCurveFH, ReflectCurveFGHI);
    5548             : 
    5549           0 :                 } else if (SimpleGlazingSHGC < 0.25) {
    5550             :                     // cell # 15
    5551             :                     // Curve FH
    5552           0 :                     TransTmp = TransCurveFH;
    5553           0 :                     ReflectTmp = ReflectCurveFH;
    5554             :                 }
    5555             : 
    5556         160 :             } else if ((3.4068 <= SimpleGlazingU) && (SimpleGlazingU <= 4.5424)) { // cell 16, 17, 18, 19, 20, 21, 22, or 23
    5557         160 :                 if (SimpleGlazingSHGC > 0.65) {
    5558             :                     // cell # 16
    5559             :                     // 2 way interpolation between Curve E and Curve A
    5560           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveE, TransCurveA);
    5561           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveE, ReflectCurveA);
    5562             : 
    5563          80 :                 } else if ((0.6 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.65)) {
    5564             :                     // cell # 17
    5565             :                     // 4 way interpolation between Curve E , Curve E, Curve A, and Curve BDCD
    5566           0 :                     TransTmp = InterpolateBetweenFourValues(
    5567             :                         SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.6, 0.65, TransCurveE, TransCurveE, TransCurveBDCD, TransCurveA);
    5568           0 :                     ReflectTmp = InterpolateBetweenFourValues(
    5569             :                         SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.6, 0.65, ReflectCurveE, ReflectCurveE, ReflectCurveBDCD, ReflectCurveA);
    5570             : 
    5571          80 :                 } else if ((0.55 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.6)) {
    5572             :                     // cell # 18
    5573             :                     // 2 way interpolation between Curve E and Curve BDCD
    5574           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveE, TransCurveBDCD);
    5575           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveE, ReflectCurveBDCD);
    5576             : 
    5577          80 :                 } else if ((0.5 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.55)) {
    5578             :                     // cell # 19
    5579             :                     // 4 way interpolation between Curve E , Curve FGHI, Curve BDCD and Curve BDCD
    5580          40 :                     TransTmp = InterpolateBetweenFourValues(
    5581             :                         SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.5, 0.55, TransCurveFGHI, TransCurveE, TransCurveBDCD, TransCurveBDCD);
    5582          40 :                     ReflectTmp = InterpolateBetweenFourValues(SimpleGlazingU,
    5583             :                                                               SimpleGlazingSHGC,
    5584             :                                                               3.4068,
    5585             :                                                               4.5424,
    5586             :                                                               0.5,
    5587             :                                                               0.55,
    5588             :                                                               ReflectCurveFGHI,
    5589             :                                                               ReflectCurveE,
    5590             :                                                               ReflectCurveBDCD,
    5591             :                                                               ReflectCurveBDCD);
    5592             : 
    5593          40 :                 } else if ((0.45 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.5)) {
    5594             :                     // cell # 20
    5595             :                     // 2 way interpolation between Curve FGHI and Curve BDCD
    5596           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveFGHI, TransCurveBDCD);
    5597           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveFGHI, ReflectCurveBDCD);
    5598             : 
    5599          40 :                 } else if ((0.3 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
    5600             :                     // cell # 21
    5601             :                     // 4 way interpolation between Curve FGHI, Curve FGHI, Curve BDCD, and Curve D
    5602          40 :                     TransTmp = InterpolateBetweenFourValues(
    5603             :                         SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.3, 0.45, TransCurveFGHI, TransCurveFGHI, TransCurveD, TransCurveBDCD);
    5604          40 :                     ReflectTmp = InterpolateBetweenFourValues(SimpleGlazingU,
    5605             :                                                               SimpleGlazingSHGC,
    5606             :                                                               3.4068,
    5607             :                                                               4.5424,
    5608             :                                                               0.3,
    5609             :                                                               0.45,
    5610             :                                                               ReflectCurveFGHI,
    5611             :                                                               ReflectCurveFGHI,
    5612             :                                                               ReflectCurveD,
    5613             :                                                               ReflectCurveBDCD);
    5614             : 
    5615           0 :                 } else if ((0.25 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.3)) {
    5616             :                     // cell # 22
    5617             :                     // 4 way interpolation between Curve FGHI, Curve FH, Curve D, and Curve D
    5618           0 :                     TransTmp = InterpolateBetweenFourValues(
    5619             :                         SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.25, 0.3, TransCurveFH, TransCurveFGHI, TransCurveD, TransCurveD);
    5620           0 :                     ReflectTmp = InterpolateBetweenFourValues(
    5621             :                         SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.25, 0.3, ReflectCurveFH, ReflectCurveFGHI, ReflectCurveD, ReflectCurveD);
    5622             : 
    5623           0 :                 } else if (SimpleGlazingSHGC <= 0.25) {
    5624             :                     // cell # 23
    5625             :                     // 2 way interpolation between Curve FH and Curve D
    5626           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveFH, TransCurveD);
    5627           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveFH, ReflectCurveD);
    5628             :                 }
    5629          80 :             } else if (SimpleGlazingU > 4.5424) { // cell 24, 25, 26, 27, or 28
    5630          80 :                 if (SimpleGlazingSHGC > 0.65) {
    5631             :                     // cell # 24
    5632             :                     // Curve A
    5633          80 :                     TransTmp = TransCurveA;
    5634          80 :                     ReflectTmp = ReflectCurveA;
    5635           0 :                 } else if ((0.6 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.65)) {
    5636             :                     // cell # 25
    5637             :                     // 2 way interpolation between Curve A and Curve BDCD
    5638           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.6, 0.65, TransCurveBDCD, TransCurveA);
    5639           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.6, 0.65, ReflectCurveBDCD, ReflectCurveA);
    5640             : 
    5641           0 :                 } else if ((0.45 < SimpleGlazingSHGC) && (SimpleGlazingSHGC < 0.6)) {
    5642             :                     // cell # 26
    5643             :                     // Curve BDCD
    5644           0 :                     TransTmp = TransCurveBDCD;
    5645           0 :                     ReflectTmp = ReflectCurveBDCD;
    5646             : 
    5647           0 :                 } else if ((0.3 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
    5648             :                     // cell # 27
    5649             :                     // 2 way interpolation between Curve BDCD and Curve D
    5650           0 :                     TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.3, 0.45, TransCurveD, TransCurveBDCD);
    5651           0 :                     ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.3, 0.45, ReflectCurveD, ReflectCurveBDCD);
    5652             : 
    5653           0 :                 } else if (SimpleGlazingSHGC < 0.3) {
    5654             :                     // cell # 28
    5655             :                     // Curve D
    5656           0 :                     TransTmp = TransCurveD;
    5657           0 :                     ReflectTmp = ReflectCurveD;
    5658             : 
    5659             :                 } else {
    5660           0 :                     assert(false);
    5661             :                 }
    5662             :             } else {
    5663           0 :                 assert(false);
    5664             :             }
    5665             : 
    5666        4880 :             if (cs == 1.0) { // at 0 deg incident, TransTmp and ReflectTmp should be 1.0
    5667         488 :                 TransTmp = 1.0;
    5668         488 :                 ReflectTmp = 0.0;
    5669             :             }
    5670             : 
    5671             :             // now apply normalization factors to zero incidence angle properties
    5672        4880 :             tfp = tf0 * TransTmp;
    5673        4880 :             tfp = max(min(1.0, tfp), 0.0);
    5674             : 
    5675        4880 :             rfp = rf0 * (1. - ReflectTmp) + ReflectTmp;
    5676        4880 :             rfp = max(min(0.9999 - tfp, rfp), 0.0);
    5677             : 
    5678        4880 :             rbp = rfp;
    5679             : 
    5680      907140 :         } else if (tf0 <= 0.0) {
    5681             :             // This is an opaque window.  For all angles, set transmittance to 0; set reflectance to that at zero incidence angle.
    5682           0 :             tfp = 0.0;
    5683           0 :             rfp = rf0;
    5684           0 :             rbp = rb0;
    5685             :         } else {
    5686             : 
    5687      907140 :             betaf = pow_2(tf0) - pow_2(rf0) + 2.0 * rf0 + 1.0;
    5688      907140 :             betab = pow_2(tf0) - pow_2(rb0) + 2.0 * rb0 + 1.0;
    5689      907140 :             r0f = (betaf - std::sqrt(pow_2(betaf) - 4.0 * (2.0 - rf0) * rf0)) / (2.0 * (2.0 - rf0));
    5690      907140 :             r0b = (betab - std::sqrt(pow_2(betab) - 4.0 * (2.0 - rb0) * rb0)) / (2.0 * (2.0 - rb0));
    5691             : 
    5692      907140 :             tmp1 = std::abs(r0f - r0b);
    5693      907140 :             if (tmp1 != 0.0) {
    5694      264420 :                 testval = std::abs(r0f - r0b) / (r0f + r0b);
    5695             :             } else {
    5696      642720 :                 testval = 0.0;
    5697             :             }
    5698             : 
    5699      907140 :             if (testval < 0.001) { // CR8830, CR8942, implications of relaxation of glazing properties CR8413
    5700             :                 // UNCOATED GLASS
    5701      653220 :                 tmp1 = r0f * tf0;
    5702      653220 :                 if (tmp1 != 0.0) {
    5703      653220 :                     abf = std::log(tmp1 / (rf0 - r0f));
    5704             :                 } else {
    5705           0 :                     abf = 0.0;
    5706             :                 }
    5707      653220 :                 tmp2 = r0b * tf0;
    5708      653220 :                 if (tmp2 != 0.0) {
    5709      653220 :                     abb = std::log(tmp2 / (rb0 - r0b));
    5710             :                 } else {
    5711           0 :                     abb = 0.0;
    5712             :                 }
    5713      653220 :                 ngf = (1.0 + std::sqrt(r0f)) / (1.0 - std::sqrt(r0f));
    5714      653220 :                 ngb = (1.0 + std::sqrt(r0b)) / (1.0 - std::sqrt(r0b));
    5715      653220 :                 cgf = std::sqrt(1.0 - (1.0 - cs * cs) / pow_2(ngf));
    5716      653220 :                 cgb = std::sqrt(1.0 - (1.0 - cs * cs) / pow_2(ngb));
    5717      653220 :                 tmp3 = ngf * cs - cgf;
    5718      653220 :                 if (tmp3 != 0.0) {
    5719      653220 :                     rpf1 = pow_2(tmp3 / (ngf * cs + cgf));
    5720             :                 } else {
    5721           0 :                     rpf1 = 0.0;
    5722             :                 }
    5723      653220 :                 tmp4 = ngf * cgf - cs;
    5724      653220 :                 if (tmp4 != 0.0) {
    5725      653220 :                     rpf2 = pow_2(tmp4 / (ngf * cgf + cs));
    5726             :                 } else {
    5727           0 :                     rpf2 = 0.0;
    5728             :                 }
    5729      653220 :                 tpf1 = 1 - rpf1;
    5730      653220 :                 tpf2 = 1 - rpf2;
    5731      653220 :                 tmp5 = ngb * cs - cgb;
    5732      653220 :                 if (tmp5 != 0.0) {
    5733      653220 :                     rpb1 = pow_2(tmp5 / (ngb * cs + cgb));
    5734             :                 } else {
    5735           0 :                     rpb1 = 0.0;
    5736             :                 }
    5737      653220 :                 tmp6 = ngb * cgb - cs;
    5738      653220 :                 if (tmp6 != 0.0) {
    5739      653220 :                     rpb2 = pow_2(tmp6 / (ngb * cgb + cs));
    5740             :                 } else {
    5741           0 :                     rpb2 = 0.0;
    5742             :                 }
    5743      653220 :                 tpb1 = 1 - rpf1;
    5744      653220 :                 tpb2 = 1 - rpf2;
    5745      653220 :                 tmp7 = -abf;
    5746      653220 :                 if (cgf != 0.0) {
    5747      653220 :                     expmabfdivcgf = std::exp(tmp7 / cgf);
    5748             :                 } else {
    5749           0 :                     expmabfdivcgf = 0.0;
    5750             :                 }
    5751      653220 :                 tmp8 = -2.0 * abf;
    5752      653220 :                 if (cgf != 0.0) {
    5753      653220 :                     expm2abfdivcgf = std::exp(tmp8 / cgf);
    5754             :                 } else {
    5755           0 :                     expm2abfdivcgf = 0.0;
    5756             :                 }
    5757      653220 :                 if (tpf1 != 0.0) {
    5758      587898 :                     tfp1 = pow_2(tpf1) * expmabfdivcgf / (1.0 - pow_2(rpf1) * expm2abfdivcgf);
    5759             :                 } else {
    5760       65322 :                     tfp1 = 0.0;
    5761             :                 }
    5762      653220 :                 rfp1 = rpf1 * (1.0 + tfp1 * expmabfdivcgf);
    5763      653220 :                 if (tpf2 != 0.0) {
    5764      587898 :                     tfp2 = pow_2(tpf2) * expmabfdivcgf / (1.0 - pow_2(rpf2) * expm2abfdivcgf);
    5765             :                 } else {
    5766       65322 :                     tfp2 = 0.0;
    5767             :                 }
    5768      653220 :                 rfp2 = rpf2 * (1.0 + tfp2 * expmabfdivcgf);
    5769      653220 :                 tfp = 0.5 * (tfp1 + tfp2);
    5770      653220 :                 rfp = 0.5 * (rfp1 + rfp2);
    5771      653220 :                 tmp9 = -abb;
    5772      653220 :                 if (tmp9 != 0.0) {
    5773      653220 :                     expmabbdivcgb = std::exp(tmp9 / cgb);
    5774             :                 } else {
    5775           0 :                     expmabbdivcgb = 0.0;
    5776             :                 }
    5777      653220 :                 rbp1 = rpb1 * (1.0 + tfp1 * expmabbdivcgb);
    5778      653220 :                 rbp2 = rpb2 * (1.0 + tfp2 * expmabbdivcgb);
    5779      653220 :                 rbp = 0.5 * (rbp1 + rbp2);
    5780             :             } else {
    5781             :                 // COATED GLASS
    5782      253920 :                 if (tf0 > 0.645) {
    5783             :                     // Use clear glass angular distribution.
    5784             :                     // Normalized clear glass transmittance and reflectance distribution
    5785      144900 :                     if (cs > 0.999) { // Angle of incidence = 0 deg
    5786       14490 :                         tcl = 1.0;
    5787       14490 :                         rcl = 0.0;
    5788      130410 :                     } else if (cs < 0.001) { // Angle of incidence = 90 deg
    5789       14490 :                         tcl = 0.0;
    5790       14490 :                         rcl = 1.0;
    5791             :                     } else {
    5792      115920 :                         tcl = -0.0015 + (3.355 + (-3.840 + (1.460 + 0.0288 * cs) * cs) * cs) * cs;
    5793      115920 :                         rcl = 0.999 + (-0.563 + (2.043 + (-2.532 + 1.054 * cs) * cs) * cs) * cs - tcl;
    5794             :                     }
    5795      144900 :                     tfp = tf0 * tcl;
    5796      144900 :                     rfp = rf0 * (1.0 - rcl) + rcl;
    5797      144900 :                     rbp = rb0 * (1.0 - rcl) + rcl;
    5798             :                 } else {
    5799             :                     // Use bronze glass angular distribution.
    5800             :                     // Normalized bronze tinted glass transmittance and reflectance distribution
    5801      109020 :                     if (cs > 0.999) { // Angle of incidence = 0 deg
    5802       10902 :                         tbnz = 1.0;
    5803       10902 :                         rbnz = 0.0;
    5804       98118 :                     } else if (cs < 0.001) { // Angle of incidence = 90 deg
    5805       10902 :                         tbnz = 0.0;
    5806       10902 :                         rbnz = 1.0;
    5807             :                     } else {
    5808       87216 :                         tbnz = -0.002 + (2.813 + (-2.341 + (-0.05725 + 0.599 * cs) * cs) * cs) * cs;
    5809       87216 :                         rbnz = 0.997 + (-1.868 + (6.513 + (-7.862 + 3.225 * cs) * cs) * cs) * cs - tbnz;
    5810             :                     }
    5811      109020 :                     tfp = tf0 * tbnz;
    5812      109020 :                     rfp = rf0 * (1.0 - rbnz) + rbnz;
    5813      109020 :                     rbp = rb0 * (1.0 - rbnz) + rbnz;
    5814             :                 }
    5815             :             }
    5816             :         }
    5817             : 
    5818             :         // total absorptance cannot be negative
    5819      912020 :         assert(1.0 - rfp - tfp >= -1e6);
    5820      912020 :         assert(1.0 - rbp - tfp >= -1e6);
    5821      912020 :     }
    5822             : 
    5823           0 :     Real64 InterpolateBetweenTwoValues(Real64 const X, Real64 const X0, Real64 const X1, Real64 const F0, Real64 const F1)
    5824             :     {
    5825             : 
    5826             :         // FUNCTION INFORMATION:
    5827             :         //       AUTHOR         Brent Griffith
    5828             :         //       DATE WRITTEN   June 2009
    5829             :         //       MODIFIED       na
    5830             :         //       RE-ENGINEERED  na
    5831             : 
    5832             :         // PURPOSE OF THIS FUNCTION:
    5833             :         // Interpolate between two results
    5834             : 
    5835             :         // METHODOLOGY EMPLOYED:
    5836             :         // linear interpolation
    5837             : 
    5838             :         Real64 InterpResult;
    5839             : 
    5840           0 :         InterpResult = F0 + ((X - X0) / (X1 - X0)) * (F1 - F0);
    5841           0 :         return InterpResult;
    5842             :     }
    5843             : 
    5844         160 :     Real64 InterpolateBetweenFourValues(Real64 const X,
    5845             :                                         Real64 const Y,
    5846             :                                         Real64 const X1,
    5847             :                                         Real64 const X2,
    5848             :                                         Real64 const Y1,
    5849             :                                         Real64 const Y2,
    5850             :                                         Real64 const Fx1y1,
    5851             :                                         Real64 const Fx1y2,
    5852             :                                         Real64 const Fx2y1,
    5853             :                                         Real64 const Fx2y2)
    5854             :     {
    5855             : 
    5856             :         // FUNCTION INFORMATION:
    5857             :         //       AUTHOR         Brent Griffith
    5858             :         //       DATE WRITTEN   June 2009
    5859             :         //       MODIFIED       na
    5860             :         //       RE-ENGINEERED  na
    5861             : 
    5862             :         // PURPOSE OF THIS FUNCTION:
    5863             :         // Interpolate between four results.
    5864             : 
    5865             :         // METHODOLOGY EMPLOYED:
    5866             :         // bilinear interpolation (approximate)
    5867             : 
    5868             :         // REFERENCES:
    5869             :         // http://en.wikipedia.org/wiki/Bilinear_interpolation
    5870             : 
    5871             :         // Return value
    5872             :         Real64 InterpResult;
    5873             : 
    5874         480 :         InterpResult = (Fx1y1 / ((X2 - X1) * (Y2 - Y1))) * (X2 - X) * (Y2 - Y) + (Fx2y1 / ((X2 - X1) * (Y2 - Y1))) * (X - X1) * (Y2 - Y) +
    5875         320 :                        (Fx1y2 / ((X2 - X1) * (Y2 - Y1))) * (X2 - X) * (Y - Y1) + (Fx2y2 / ((X2 - X1) * (Y2 - Y1))) * (X - X1) * (Y - Y1);
    5876         160 :         return InterpResult;
    5877             :     }
    5878             : 
    5879             :     //**************************************************************************
    5880             : 
    5881       22832 :     void W5LsqFit(Array1S<Real64> const IndepVar, // Independent variables
    5882             :                   Array1S<Real64> const DepVar,   // Dependent variables
    5883             :                   int const N,                    // Order of polynomial
    5884             :                   int const N1,                   // First and last data points used
    5885             :                   int const N2,
    5886             :                   Array1S<Real64> CoeffsCurve // Polynomial coeffients from fit
    5887             :     )
    5888             :     {
    5889             : 
    5890             :         // SUBROUTINE INFORMATION:
    5891             :         //       AUTHOR         George Walton
    5892             :         //       DATE WRITTEN   April 1976
    5893             :         //       MODIFIED       November 1999 F.Winkelmann
    5894             :         //       RE-ENGINEERED  na
    5895             : 
    5896             :         // PURPOSE OF THIS SUBROUTINE:
    5897             :         // Does least squares fit for coefficients of a polynomial
    5898             :         // that gives a window property, such as transmittance, as a function of
    5899             :         // the cosine of the angle of incidence. The polynomial is of the
    5900             :         // form C1*X + C2*X**2 + C3*X**3 + ... +CN*X**N, where N <= 6.
    5901             :         // Adapted from BLAST subroutine LSQFIT.
    5902             : 
    5903       45664 :         Array2D<Real64> A(6, 6);  // Least squares derivative matrix
    5904       45664 :         Array1D<Real64> B(6);     // Least squares derivative vector
    5905       45664 :         Array2D<Real64> D(6, 16); // Powers of independent variable
    5906             :         Real64 ACON;              // Intermediate variables
    5907             :         Real64 SUM;
    5908             :         int i; // Loop parameters
    5909             :         int j;
    5910             :         int K;
    5911             :         int L;
    5912             :         int M;
    5913             :         int KP1;
    5914             :         int LP1;
    5915             :         int NM1;
    5916             : 
    5917             :         // Set up least squares matrix
    5918      251152 :         for (M = N1; M <= N2; ++M) {
    5919      228320 :             D(1, M) = IndepVar(M);
    5920             :         }
    5921             : 
    5922      136992 :         for (i = 2; i <= N; ++i) {
    5923     1255760 :             for (M = N1; M <= N2; ++M) {
    5924     1141600 :                 D(i, M) = D(i - 1, M) * IndepVar(M);
    5925             :             }
    5926             :         }
    5927             : 
    5928      159824 :         for (i = 1; i <= N; ++i) {
    5929      136992 :             SUM = 0.0;
    5930     1506912 :             for (M = N1; M <= N2; ++M) {
    5931     1369920 :                 SUM += DepVar(M) * D(i, M);
    5932             :             }
    5933      136992 :             B(i) = SUM;
    5934      958944 :             for (j = 1; j <= N; ++j) {
    5935      821952 :                 SUM = 0.0;
    5936     9041472 :                 for (M = N1; M <= N2; ++M) {
    5937     8219520 :                     SUM += D(i, M) * D(j, M);
    5938             :                 }
    5939      821952 :                 A(j, i) = SUM;
    5940      821952 :                 A(i, j) = SUM;
    5941             :             }
    5942             :         }
    5943             : 
    5944             :         // Solve the simultaneous equations using Gauss elimination
    5945       22832 :         NM1 = N - 1;
    5946      136992 :         for (K = 1; K <= NM1; ++K) {
    5947      114160 :             KP1 = K + 1;
    5948      456640 :             for (i = KP1; i <= N; ++i) {
    5949      342480 :                 ACON = A(K, i) / A(K, K);
    5950      342480 :                 B(i) -= B(K) * ACON;
    5951     1940720 :                 for (j = K; j <= N; ++j) {
    5952     1598240 :                     A(j, i) -= A(j, K) * ACON;
    5953             :                 }
    5954             :             }
    5955             :         }
    5956             : 
    5957             :         // Perform back substituion
    5958       22832 :         CoeffsCurve(N) = B(N) / A(N, N);
    5959       22832 :         LP1 = N;
    5960       22832 :         L = N - 1;
    5961             : 
    5962      251152 :         while (L > 0) {
    5963      114160 :             SUM = 0.0;
    5964      456640 :             for (j = LP1; j <= N; ++j) {
    5965      342480 :                 SUM += A(j, L) * CoeffsCurve(j);
    5966             :             }
    5967      114160 :             CoeffsCurve(L) = (B(L) - SUM) / A(L, L);
    5968      114160 :             LP1 = L;
    5969      114160 :             --L;
    5970             :         }
    5971       22832 :     }
    5972             : 
    5973             :     //********************************************************************************
    5974             : 
    5975           0 :     void W5LsqFit2(Array1A<Real64> const IndepVar, // Independent variables
    5976             :                    Array1A<Real64> const DepVar,   // Dependent variables
    5977             :                    int const N,                    // Order of polynomial
    5978             :                    int const N1,                   // First and last data points used
    5979             :                    int const N2,
    5980             :                    Array1A<Real64> CoeffsCurve // Polynomial coefficients from fit
    5981             :     )
    5982             :     {
    5983             : 
    5984             :         // SUBROUTINE INFORMATION:
    5985             :         //       AUTHOR         George Walton
    5986             :         //       DATE WRITTEN   April 1976
    5987             :         //       MODIFIED       November 1999 F.Winkelmann
    5988             :         //                      May 2001 F. Winkelmann, to do 19 indep. variables
    5989             :         //       RE-ENGINEERED  na
    5990             : 
    5991             :         // PURPOSE OF THIS SUBROUTINE:
    5992             :         // Does least squares fit for coefficients of a polynomial
    5993             :         // that gives a window property, such as transmittance, as a function of
    5994             :         // the cosine of the angle of incidence. The polynomial is of the
    5995             :         // form C1*X + C2*X**2 + C3*X**3 + ... +CN*X**N, where N <= 6.
    5996             :         // Adapted from BLAST subroutine LSQFIT.
    5997             : 
    5998             :         // Argument array dimensioning
    5999           0 :         IndepVar.dim(19);
    6000           0 :         DepVar.dim(19);
    6001           0 :         CoeffsCurve.dim(6);
    6002             : 
    6003           0 :         Array2D<Real64> A(6, 6);  // Least squares derivative matrix
    6004           0 :         Array1D<Real64> B(6);     // Least squares derivative vector
    6005           0 :         Array2D<Real64> D(6, 16); // Powers of independent variable
    6006             :         Real64 ACON;              // Intermediate variables
    6007             :         Real64 SUM;
    6008             :         int i; // Loop parameters
    6009             :         int j;
    6010             :         int K;
    6011             :         int L;
    6012             :         int M;
    6013             :         int KP1;
    6014             :         int LP1;
    6015             :         int NM1;
    6016             : 
    6017             :         // Set up least squares matrix
    6018           0 :         for (M = N1; M <= N2; ++M) {
    6019           0 :             D(1, M) = IndepVar(M);
    6020             :         }
    6021             : 
    6022           0 :         for (i = 2; i <= N; ++i) {
    6023           0 :             for (M = N1; M <= N2; ++M) {
    6024           0 :                 D(i, M) = D(i - 1, M) * IndepVar(M);
    6025             :             }
    6026             :         }
    6027             : 
    6028           0 :         for (i = 1; i <= N; ++i) {
    6029           0 :             SUM = 0.0;
    6030           0 :             for (M = N1; M <= N2; ++M) {
    6031           0 :                 SUM += DepVar(M) * D(i, M);
    6032             :             }
    6033           0 :             B(i) = SUM;
    6034           0 :             for (j = 1; j <= N; ++j) {
    6035           0 :                 SUM = 0.0;
    6036           0 :                 for (M = N1; M <= N2; ++M) {
    6037           0 :                     SUM += D(i, M) * D(j, M);
    6038             :                 }
    6039           0 :                 A(j, i) = SUM;
    6040           0 :                 A(i, j) = SUM;
    6041             :             }
    6042             :         }
    6043             : 
    6044             :         // Solve the simultaneous equations using Gauss elimination
    6045           0 :         NM1 = N - 1;
    6046           0 :         for (K = 1; K <= NM1; ++K) {
    6047           0 :             KP1 = K + 1;
    6048           0 :             for (i = KP1; i <= N; ++i) {
    6049           0 :                 ACON = A(K, i) / A(K, K);
    6050           0 :                 B(i) -= B(K) * ACON;
    6051           0 :                 for (j = K; j <= N; ++j) {
    6052           0 :                     A(j, i) -= A(j, K) * ACON;
    6053             :                 }
    6054             :             }
    6055             :         }
    6056             : 
    6057             :         // Perform back substituion
    6058           0 :         CoeffsCurve(N) = B(N) / A(N, N);
    6059           0 :         LP1 = N;
    6060           0 :         L = N - 1;
    6061             : 
    6062           0 :         while (L > 0) {
    6063           0 :             SUM = 0.0;
    6064           0 :             for (j = LP1; j <= N; ++j) {
    6065           0 :                 SUM += A(j, L) * CoeffsCurve(j);
    6066             :             }
    6067           0 :             CoeffsCurve(L) = (B(L) - SUM) / A(L, L);
    6068           0 :             LP1 = L;
    6069           0 :             --L;
    6070             :         }
    6071           0 :     }
    6072             : 
    6073             :     //***********************************************************************
    6074             : 
    6075       22384 :     Real64 DiffuseAverage(Array1S<Real64> const PropertyValue) // Property value at angles of incidence
    6076             :     {
    6077             : 
    6078             :         // FUNCTION INFORMATION:
    6079             :         //       AUTHOR         Fred Winkelmann
    6080             :         //       DATE WRITTEN   November 1999
    6081             :         //       MODIFIED       na
    6082             :         //       RE-ENGINEERED  na
    6083             : 
    6084             :         // PURPOSE OF THIS FUNCTION:
    6085             :         // Calculate value of property, such as transmittance, for hemispherical
    6086             :         // diffuse radiation from property values at angles of incidence from
    6087             :         // 0 to 90 degrees in 10 degree increments.
    6088             : 
    6089             :         // METHODOLOGY EMPLOYED:
    6090             :         // By Simpson's rule, evaluates the integral from 0 to 90 deg of
    6091             :         // 2*PropertyValue(phi)*cos(phi)*sin(phi)*dphi (which is same as
    6092             :         // PropertyValue(phi)*sin(2*phi)*dphi)
    6093             : 
    6094             :         // Return value
    6095             :         Real64 DiffuseAverage;
    6096             : 
    6097             :         // Locals
    6098             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    6099             :         // 0,10,20,...,80,90 degress
    6100             : 
    6101       22384 :         Real64 const DPhiR(10.0 * DataGlobalConstants::DegToRadians); // Half of 10-deg incidence angle increment (radians)
    6102             :         int IPhi;                                                     // Incidence angle counter
    6103             : 
    6104       22384 :         DiffuseAverage = 0.0;
    6105      223840 :         for (IPhi = 1; IPhi <= 9; ++IPhi) {
    6106      201456 :             DiffuseAverage +=
    6107      201456 :                 0.5 * DPhiR * (PropertyValue(IPhi) * std::sin(2.0 * (IPhi - 1) * DPhiR) + PropertyValue(IPhi + 1) * std::sin(2.0 * IPhi * DPhiR));
    6108             :         }
    6109       22384 :         if (DiffuseAverage < 0.0) DiffuseAverage = 0.0;
    6110             : 
    6111       22384 :         return DiffuseAverage;
    6112             :     }
    6113             : 
    6114             :     //*************************************************************************************
    6115             : 
    6116         296 :     Real64 DiffuseAverageProfAngGnd(Array1S<Real64> const Property) // Property value vs. profile angle
    6117             :     {
    6118             : 
    6119             :         // FUNCTION INFORMATION:
    6120             :         //       AUTHOR         Fred Winkelmann
    6121             :         //       DATE WRITTEN   January 2004
    6122             :         //       MODIFIED       na
    6123             :         //       RE-ENGINEERED  na
    6124             : 
    6125             :         // PURPOSE OF THIS FUNCTION:
    6126             :         // Calculates diffuse average of Property, such as blind transmittance, over profile angles
    6127             :         // corresponding to (upgoing) radiation from the ground.
    6128             : 
    6129             :         // METHODOLOGY EMPLOYED:
    6130             :         // Integration by Simpson's rule assuming uniform radiance distribution.
    6131             : 
    6132             :         // Using/Aliasing
    6133             :         using General::InterpProfAng;
    6134             : 
    6135             :         // Return value
    6136             :         Real64 DiffuseAverageProfAngGnd;
    6137             : 
    6138             :         Real64 Phi;  // Profile angle (radians)
    6139             :         Real64 DPhi; // Phi increment
    6140             :         int IPhi;    // Phi index
    6141             :         Real64 Sum;  // Sums
    6142             :         Real64 SumDenom;
    6143             : 
    6144         296 :         Sum = 0.0;
    6145         296 :         SumDenom = 0.0;
    6146         296 :         DPhi = 5.0 * DataGlobalConstants::DegToRadians;
    6147             : 
    6148             :         // Integrate from -90 to 0 deg
    6149        5624 :         for (IPhi = 1; IPhi <= 18; ++IPhi) {
    6150        5328 :             Phi = -DataGlobalConstants::PiOvr2 + (IPhi - 0.5) * DPhi;
    6151        5328 :             Sum += std::cos(Phi) * DPhi * InterpProfAng(Phi, Property);
    6152        5328 :             SumDenom += std::cos(Phi) * DPhi;
    6153             :         }
    6154             : 
    6155         296 :         DiffuseAverageProfAngGnd = Sum / SumDenom;
    6156         296 :         if (DiffuseAverageProfAngGnd < 0.0) DiffuseAverageProfAngGnd = 0.0;
    6157             : 
    6158         296 :         return DiffuseAverageProfAngGnd;
    6159             :     }
    6160             : 
    6161             :     //*************************************************************************************
    6162             : 
    6163         296 :     Real64 DiffuseAverageProfAngSky(Array1S<Real64> const Property) // Property value vs. profile angle
    6164             :     {
    6165             : 
    6166             :         // FUNCTION INFORMATION:
    6167             :         //       AUTHOR         Fred Winkelmann
    6168             :         //       DATE WRITTEN   January 2004
    6169             :         //       MODIFIED       na
    6170             :         //       RE-ENGINEERED  na
    6171             : 
    6172             :         // PURPOSE OF THIS FUNCTION:
    6173             :         // Calculates diffuse average of Property, such as blind transmittance, over profile angles
    6174             :         // corresponding to (downgoing) radiation from the sky.
    6175             : 
    6176             :         // METHODOLOGY EMPLOYED:
    6177             :         // Integration by Simpson's rule assuming uniform radiance distribution.
    6178             : 
    6179             :         // Using/Aliasing
    6180             :         using General::InterpProfAng;
    6181             : 
    6182             :         // Return value
    6183             :         Real64 DiffuseAverageProfAngSky;
    6184             : 
    6185             :         Real64 Phi;  // Profile angle (radians)
    6186             :         Real64 DPhi; // Phi increment
    6187             :         int IPhi;    // Phi index
    6188             :         Real64 Sum;  // Sums
    6189             :         Real64 SumDenom;
    6190             : 
    6191         296 :         Sum = 0.0;
    6192         296 :         SumDenom = 0.0;
    6193         296 :         DPhi = 5.0 * DataGlobalConstants::DegToRadians;
    6194             : 
    6195             :         // Integrate from 0 to 90 deg
    6196        5624 :         for (IPhi = 19; IPhi <= 36; ++IPhi) {
    6197        5328 :             Phi = -DataGlobalConstants::PiOvr2 + (IPhi - 0.5) * DPhi;
    6198        5328 :             Sum += std::cos(Phi) * DPhi * InterpProfAng(Phi, Property);
    6199        5328 :             SumDenom += std::cos(Phi) * DPhi;
    6200             :         }
    6201             : 
    6202         296 :         DiffuseAverageProfAngSky = Sum / SumDenom;
    6203         296 :         if (DiffuseAverageProfAngSky < 0.0) DiffuseAverageProfAngSky = 0.0;
    6204             : 
    6205         296 :         return DiffuseAverageProfAngSky;
    6206             :     }
    6207             : 
    6208             :     //*************************************************************************************
    6209             : 
    6210      589776 :     void CalcWinFrameAndDividerTemps(EnergyPlusData &state,
    6211             :                                      int const SurfNum,     // Surface number
    6212             :                                      Real64 const tout,     // Outside air temperature (K)
    6213             :                                      Real64 const tin,      // Inside air temperature (K)
    6214             :                                      Real64 const HOutConv, // Outside convective air film conductance (W/m2-K)
    6215             :                                      Real64 const HInConv,  // Inside convective air film conductance (W/m2-K)
    6216             :                                      Real64 const Outir,    // Exterior IR irradiance from sky and ground
    6217             :                                      int const ConstrNum    // Construction number of window
    6218             :     )
    6219             :     {
    6220             : 
    6221             :         // SUBROUTINE INFORMATION:
    6222             :         //       AUTHOR         F. Winkelmann
    6223             :         //       DATE WRITTEN   May 2000
    6224             :         //       MODIFIED       Aug 2000, FCW: Add effect of frame and divider projections
    6225             :         //                      Jun 2001, FCW: Add frame/divider contribution to WinHeatGain
    6226             :         //                      Aug 2003, FCW: Fix calculation of divider outside temp: frame
    6227             :         //                       inside temp was being used instead of divider inside temp
    6228             :         //       RE-ENGINEERED  na
    6229             : 
    6230             :         // PURPOSE OF THIS SUBROUTINE:
    6231             :         // Calculates window frame divider face temperatures from a linearized
    6232             :         // heat balance on the inside and outside faces
    6233             : 
    6234             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6235             :         Real64 HInRad;            // Inside radiative conductance (W/m2-K)
    6236             :         Real64 HOutRad;           // Outside radiative conductance (W/m2-K)
    6237             :         int FrDivNum;             // Frame/divider number
    6238             :         Real64 TInRad;            // Inside radiative temperature (K)
    6239             :         Real64 TInRadFr;          // Effective inside radiative temperature for frame (K)
    6240             :         Real64 TInRadDiv;         // Effective inside radiative temperature for divider (K)
    6241             :         Real64 TOutRad;           // Outside radiative temperature (K)
    6242             :         Real64 TOutRadFr;         // Effective outside radiative temperature for frame (K)
    6243             :         Real64 TOutRadDiv;        // Effective outside radiative temperature for divider (K)
    6244             :         WinShadingType ShadeFlag; // Window shading flag
    6245             :         Real64 FrameCon;          // Frame conductance (W/m2-K)
    6246             : 
    6247             :         Real64 Afac; // Intermediate calculation variables
    6248             :         Real64 Bfac;
    6249             :         Real64 Dfac;
    6250             :         Real64 Efac;
    6251             :         DataSurfaces::FrameDividerType DivType; // Divider type
    6252             :         Real64 DivCon;                          // Divider conductance (W/m2-K)
    6253             :         Real64 DivEmisIn;                       // Inside divider emissivity
    6254             :         Real64 DivEmisOut;                      // Outside divider emissivity
    6255             : 
    6256             :         Real64 ProjCorrFrOut; // Outside correction factor for absorbed radiation
    6257             :         //   for frame with outside projection
    6258             :         Real64 ProjCorrFrIn; // Inside correction factor for absorbed radiation
    6259             :         //   for frame with inside projection
    6260             :         Real64 HOutConvFr; // Effective outside convective coeff for frame
    6261             :         //   with outside projection (W/m2-K)
    6262             :         Real64 HOutConvDiv; // Effective outside convective coeff for divider
    6263             :         //   with outside projection (W/m2-K)
    6264             :         Real64 HInConvFr; // Effective inside convective coeff for frame
    6265             :         //   with inside projection (W/m2-K)
    6266             :         Real64 HInConvDiv; // Effective inside convective coeff for divider
    6267             :         //   with inside projection (W/m2-K)
    6268             :         Real64 EmisGlassOut; // Outside surface emissivity of window glazing
    6269             :         Real64 EmisGlassIn;  // Inside surface emissivity of window glazing
    6270             :         int TotGlassLayers;  // Total number of glass layers
    6271             :         int TotLayers;       // Total number of layers in unshaded construction
    6272             :         // Real64 DivTempOut;          // Outside surface divider temperature (K)
    6273             :         Real64 FrameHeatGain; // Heat gain to zone from frame (W)
    6274             :         // Real64 FrameHeatTransfer;   // Heat tansfer through frame (W)
    6275             :         // Real64 ProjCorrWinHeatGain; // Inside projection correction to IR from divider to zone
    6276             :         //   for window heat gain calculation
    6277             :         Real64 DividerHeatGain; // Heat gain to zone from divider (W)
    6278             :         // Real64 DividerHeatTransfer; // Heat transfer through divider (W)
    6279             : 
    6280      589776 :         TInRad = root_4(state.dataSurface->SurfWinIRfromParentZone(SurfNum) / state.dataWindowManager->sigma);
    6281      589776 :         TOutRad = root_4(Outir / state.dataWindowManager->sigma);
    6282      589776 :         ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    6283      589776 :         FrDivNum = state.dataSurface->Surface(SurfNum).FrameDivider;
    6284      589776 :         TotLayers = state.dataConstruction->Construct(ConstrNum).TotLayers;
    6285      589776 :         TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
    6286      589776 :         EmisGlassOut = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermalFront;
    6287      589776 :         EmisGlassIn = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLayers)).AbsorpThermalBack;
    6288      589776 :         FrameHeatGain = 0.0;
    6289      589776 :         DividerHeatGain = 0.0;
    6290      589776 :         state.dataSurface->SurfWinFrameHeatGain(SurfNum) = 0.0;
    6291      589776 :         state.dataSurface->SurfWinFrameHeatLoss(SurfNum) = 0.0;
    6292      589776 :         state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
    6293      589776 :         state.dataSurface->SurfWinDividerHeatLoss(SurfNum) = 0.0;
    6294             : 
    6295      589776 :         if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    6296             :             // Window has a frame. Note that if a shade, screen or blind is present it covers only the glazed part of the
    6297             :             // window and is assumed not to shadow long- or short-wave radiation incident on the frame elements.
    6298      589776 :             ProjCorrFrOut = state.dataSurface->SurfWinProjCorrFrOut(SurfNum);
    6299      589776 :             ProjCorrFrIn = state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
    6300      589776 :             TOutRadFr = TOutRad * root_4((1.0 + 0.5 * ProjCorrFrOut) / (1.0 + ProjCorrFrOut));
    6301      589776 :             TInRadFr = TInRad * root_4((1.0 + 0.5 * ProjCorrFrIn) / (1.0 + ProjCorrFrIn));
    6302      589776 :             FrameCon = state.dataSurface->SurfWinFrameConductance(SurfNum);
    6303     1179552 :             HInRad = 0.5 * state.dataSurface->SurfWinFrameEmis(SurfNum) * state.dataWindowManager->sigma *
    6304      589776 :                      pow_3(TInRadFr + state.dataSurface->SurfWinFrameTempIn(SurfNum) + state.dataWindowManager->TKelvin);
    6305      589776 :             HInConvFr = HInConv;
    6306     1179552 :             HOutRad = 0.5 * state.dataSurface->SurfWinFrameEmis(SurfNum) * state.dataWindowManager->sigma *
    6307      589776 :                       pow_3(TOutRadFr + state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) + state.dataWindowManager->TKelvin);
    6308      589776 :             HOutConvFr = HOutConv;
    6309      589776 :             if (state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut > 0.0) {
    6310      522576 :                 HOutRad *= (1.0 + ProjCorrFrOut);
    6311      522576 :                 HOutConvFr = HOutConv * (1.0 + ProjCorrFrOut);
    6312             :                 // Add long-wave from outside window surface absorbed by frame outside projection
    6313      522576 :                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) +=
    6314      522576 :                     0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).FrameEmis * EmisGlassOut *
    6315     1045152 :                     state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(1));
    6316             :             }
    6317      589776 :             if (state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn > 0.0) {
    6318      522576 :                 HInRad *= (1.0 + ProjCorrFrIn);
    6319      522576 :                 HInConvFr = HInConv * (1.0 + ProjCorrFrIn);
    6320             :                 // Add long-wave from inside window surface absorbed by frame inside projection
    6321      522576 :                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
    6322      522576 :                     0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).FrameEmis * EmisGlassIn *
    6323     1045152 :                     state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(2 * TotGlassLayers));
    6324             :             }
    6325      589776 :             Afac = (HOutRad * TOutRadFr + HOutConvFr * tout + state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum)) / (HOutRad + FrameCon + HOutConvFr);
    6326      589776 :             Bfac = FrameCon / (HOutRad + FrameCon + HOutConvFr);
    6327      589776 :             Dfac = (HInRad * TInRadFr + HInConvFr * tin + state.dataSurface->SurfWinFrameQRadInAbs(SurfNum)) / (HInRad + FrameCon + HInConvFr);
    6328      589776 :             Efac = FrameCon / (HInRad + FrameCon + HInConvFr);
    6329      589776 :             state.dataSurface->SurfWinFrameTempIn(SurfNum) = (Dfac + Efac * Afac) / (1.0 - Efac * Bfac) - state.dataWindowManager->TKelvin;
    6330      589776 :             state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) =
    6331      589776 :                 Afac + Bfac * (state.dataSurface->SurfWinFrameTempIn(SurfNum) + state.dataWindowManager->TKelvin) - state.dataWindowManager->TKelvin;
    6332             :             // Heat gain to zone from frame
    6333             : 
    6334             :             // FrameHeatTransfer = state.dataSurface->SurfWinFrameArea(SurfNum) * FrameCon *
    6335             :             //                     (state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) - state.dataSurface->SurfWinFrameTempIn(SurfNum));
    6336     1179552 :             FrameHeatGain = state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
    6337     1179552 :                             (HInConvFr * (state.dataSurface->SurfWinFrameTempIn(SurfNum) + state.dataWindowManager->TKelvin - tin));
    6338             : 
    6339      589776 :             if (FrameHeatGain > 0.0) {
    6340      124385 :                 state.dataSurface->SurfWinFrameHeatGain(SurfNum) = FrameHeatGain;
    6341             :             } else {
    6342      465391 :                 state.dataSurface->SurfWinFrameHeatLoss(SurfNum) = std::abs(FrameHeatGain);
    6343             :             }
    6344             : 
    6345      589776 :             state.dataSurface->SurfWinHeatGain(SurfNum) += FrameHeatGain;
    6346      589776 :             state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = FrameHeatGain;
    6347             :         } // End of check if window has a frame
    6348             : 
    6349      589776 :         if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && state.dataSurface->SurfWinStormWinFlag(SurfNum) < 1) {
    6350             :             // Window has divider. Note that if the window has a storm window layer in place (StormWinFlag = 1)
    6351             :             // the divider heat transfer calculation is not done.
    6352             : 
    6353      261168 :             DivType = state.dataSurface->SurfWinDividerType(SurfNum);
    6354      261168 :             DivCon = state.dataSurface->SurfWinDividerConductance(SurfNum);
    6355             : 
    6356      261168 :             if (DivType == DataSurfaces::FrameDividerType::DividedLite) { // Divided lite
    6357      231696 :                 DivEmisIn = state.dataSurface->SurfWinDividerEmis(SurfNum);
    6358      231696 :                 DivEmisOut = DivEmisIn;
    6359             :             } else { // Suspended (between-glass) divider
    6360       29472 :                 DivEmisOut = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermalFront;
    6361       29472 :                 DivEmisIn =
    6362             :                     state.dataMaterial
    6363       29472 :                         ->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataConstruction->Construct(ConstrNum).TotLayers))
    6364             :                         .AbsorpThermalBack;
    6365             :             }
    6366             : 
    6367      522336 :             TOutRadDiv = TOutRad * root_4((1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)) /
    6368      261168 :                                           (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivOut(SurfNum)));
    6369      522336 :             TInRadDiv = TInRad * root_4((1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) /
    6370      261168 :                                         (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)));
    6371      522336 :             HInRad = 0.5 * DivEmisIn * state.dataWindowManager->sigma *
    6372      261168 :                      pow_3(TInRadDiv + state.dataSurface->SurfWinDividerTempIn(SurfNum) + state.dataWindowManager->TKelvin);
    6373      522336 :             HOutRad = 0.5 * DivEmisOut * state.dataWindowManager->sigma *
    6374      261168 :                       pow_3(TOutRadDiv + state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) + state.dataWindowManager->TKelvin);
    6375      261168 :             HOutConvDiv = HOutConv;
    6376             : 
    6377      261168 :             if (state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut > 0.0) {
    6378      223632 :                 HOutRad *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    6379      223632 :                 if (state.dataSurface->SurfWinShadingFlag(SurfNum) == WinShadingType::ExtShade)
    6380           0 :                     HOutConvDiv = state.dataSurface->SurfWinConvCoeffWithShade(SurfNum);
    6381      223632 :                 HOutConvDiv *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    6382             :                 // Add long-wave from outside window surface absorbed by divider outside projection
    6383      223632 :                 state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) +=
    6384      223632 :                     state.dataSurface->SurfWinProjCorrDivOut(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).DividerEmis * EmisGlassOut *
    6385      447264 :                     state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(1));
    6386             :             }
    6387             : 
    6388      261168 :             HInConvDiv = HInConv;
    6389             : 
    6390      261168 :             if (state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn > 0.0) {
    6391      223632 :                 HInRad *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
    6392      223632 :                 if (state.dataSurface->SurfWinShadingFlag(SurfNum) == WinShadingType::IntShade)
    6393           0 :                     HInConvDiv = state.dataSurface->SurfWinConvCoeffWithShade(SurfNum);
    6394      223632 :                 HInConvDiv *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
    6395             :                 // Add long-wave from inside window surface absorbed by divider inside projection
    6396      223632 :                 state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
    6397      223632 :                     state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).DividerEmis * EmisGlassIn *
    6398      447264 :                     state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(2 * TotGlassLayers));
    6399             :             }
    6400      261168 :             Afac =
    6401      261168 :                 (HOutRad * TOutRadDiv + HOutConvDiv * tout + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum)) / (HOutRad + DivCon + HOutConvDiv);
    6402      261168 :             Bfac = DivCon / (HOutRad + DivCon + HOutConvDiv);
    6403      261168 :             Dfac = (HInRad * TInRadDiv + HInConvDiv * tin + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum)) / (HInRad + DivCon + HInConvDiv);
    6404      261168 :             Efac = DivCon / (HInRad + DivCon + HInConvDiv);
    6405      261168 :             state.dataSurface->SurfWinDividerTempIn(SurfNum) = (Dfac + Efac * Afac) / (1 - Efac * Bfac) - state.dataWindowManager->TKelvin;
    6406      261168 :             state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) =
    6407      522336 :                 Afac + Bfac * (state.dataSurface->SurfWinDividerTempIn(SurfNum) + state.dataWindowManager->TKelvin) -
    6408      261168 :                 state.dataWindowManager->TKelvin;
    6409             :             // Contribution of divider to window heat gain
    6410             :             // ProjCorrWinHeatGain = 1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
    6411             : 
    6412      522336 :             DividerHeatGain = state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    6413      522336 :                               (HInConvDiv * (state.dataSurface->SurfWinDividerTempIn(SurfNum) + state.dataWindowManager->TKelvin - tin));
    6414             :             // DividerHeatTransfer = state.dataSurface->SurfWinDividerArea(SurfNum) * DivCon *
    6415             :             //                      (state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) - state.dataSurface->SurfWinDividerTempIn(SurfNum));
    6416             : 
    6417      261168 :             if (DividerHeatGain > 0.0) {
    6418       57853 :                 state.dataSurface->SurfWinDividerHeatGain(SurfNum) = DividerHeatGain;
    6419             :             } else {
    6420      203315 :                 state.dataSurface->SurfWinDividerHeatLoss(SurfNum) = std::abs(DividerHeatGain);
    6421             :             }
    6422      261168 :             state.dataSurface->SurfWinHeatGain(SurfNum) += DividerHeatGain;
    6423      261168 :             state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) += DividerHeatGain;
    6424             :             // If interior shade is present it is assumed that both the convective and IR radiative gain
    6425             :             // from the inside surface of the divider goes directly into the zone air -- i.e., the IR radiative
    6426             :             // interaction between divider and shade is ignored due to the difficulty of calculating this interaction
    6427             :             // at the same time that the interaction between glass and shade is calculated.
    6428      261168 :             if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum)))
    6429         742 :                 state.dataSurface->SurfWinDividerHeatGain(SurfNum) = DividerHeatGain;
    6430             :             // DivTempOut = state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) + state.dataWindowManager->TKelvin;
    6431             :         } // End of check if window has dividers
    6432      589776 :     }
    6433             : 
    6434             :     //************************************************************************************
    6435             : 
    6436        2602 :     void CalcNominalWindowCond(EnergyPlusData &state,
    6437             :                                int const ConstrNum,        // Construction number
    6438             :                                int const WinterSummerFlag, // 1=winter, 2=summer
    6439             :                                Real64 &NominalConductance, // Nominal center-of-glass conductance, including air films
    6440             :                                Real64 &SHGC,               // Nominal center-of-glass solar heat gain coefficient for
    6441             :                                Real64 &TSolNorm,           // Overall beam solar transmittance at normal incidence
    6442             :                                Real64 &TVisNorm,           // Overall beam visible transmittance at normal incidence
    6443             :                                int &errFlag                // Error flag
    6444             :     )
    6445             :     {
    6446             : 
    6447             :         // SUBROUTINE INFORMATION:
    6448             :         //       AUTHOR         F. Winkelmann
    6449             :         //       DATE WRITTEN   September 2000
    6450             :         //       MODIFIED       Oct 2000, FW: add solar heat gain coefficient
    6451             :         //                      June 2001, FW: account for blinds; change summer outside air
    6452             :         //                       temp from 35.0C to 31.7C to correspond to ASHRAE value
    6453             :         //                      Feb 2003, FW: add comments that this routine is not called for
    6454             :         //                       between-glass shade/blind constructions.
    6455             :         //                      May 2006, RR: account for screens
    6456             :         //                      Oct 2007, LKL: change temps to match Window 5 values
    6457             :         //                      Feb 2009, BG: Changes for CR7682 (SHGC)
    6458             :         //       RE-ENGINEERED  na
    6459             : 
    6460             :         // PURPOSE OF THIS SUBROUTINE:
    6461             :         // Calculates nominal center-of-glass U-value and solar heat gain coefficient
    6462             :         // (SHGC) of a window construction for ASHRAE winter and summer conditions.
    6463             :         // Winter:
    6464             :         // Inside air temperature = 21.C (69.80F)
    6465             :         // Outside air temperature = -18C (-.4F)
    6466             :         // Windspeed = 5.5 m/s (12.3 mph)
    6467             :         // No solar radiation
    6468             :         // Replaced Winter:
    6469             :         // Inside air temperature = 21.1C (70F)
    6470             :         // Outside air temperature = -17.8C (0F)
    6471             :         // Windspeed = 6.71 m/s (15 mph)
    6472             :         // No solar radiation
    6473             :         // Summer:
    6474             :         // Inside air temperature = 24C (75.2F)
    6475             :         // Outside air temperature = 32C (89.6F)
    6476             :         // Windspeed = 2.8 m/s (6.2 mph)
    6477             :         // 783 W/m2 (248 Btu/h-ft2) incident beam solar radiation normal to glazing
    6478             :         // Replaced Summer:
    6479             :         // Inside air temperature = 24C (75.2F) ! BG changed again Feb. 2009 by 0.1 (per Window5 team)
    6480             :         // Outside air temperature = 31.7C (89F)
    6481             :         // Windspeed = 3.35 m/s (7.5 mph)
    6482             :         // 783 W/m2 (248 Btu/h-ft2) incident beam solar radiation normal to glazing
    6483             :         // The window's inside surround is assumed to be a black body at the inside air temp.
    6484             :         // The window's outside surround is assumed t be a black body at the outside air temp.
    6485             :         // Note that in this routine we use a value of 26 W/m2 for the outside convective
    6486             :         // air film conductance for 5.5 m/s (12.3 mph) wind speed.
    6487             :         // This is the value used in Window 5 and is also the value for which the center-of-glass
    6488             :         // conductances in the EnergyPlus window construction reference data set were calculated.
    6489             :         // However, in the time step loop we will have different values of outside film
    6490             :         // conductance depending on that time step's wind speed, wind direction, surface-to-air temp difference,
    6491             :         // etc.(see subroutine InitExteriorConvectionCoeff).
    6492             :         // This routine will return an error and exit for window constructions with between-glass shade or blind
    6493             :         // until a method is worked out to determine the nominal conductance and SHGC in this case.
    6494             :         // If an interior or exterior shade or blind is present in the construction,
    6495             :         // the conductance calculation does not include the effect of the shade or blind.
    6496             :         // This is because in this case the conductance depends on the natural convective
    6497             :         // air flow in the shade/glass, screen/glass or blind/glass channel, which in turn is highly dependent
    6498             :         // on window height and other parameters that are not part of the construction definition.
    6499             :         // Therefore, the reported conductance value will be too high for windows with a tightly fitting
    6500             :         // shade, screen or blind with a relatively high thermal resistance.
    6501             :         // For SHGC calculation, all solar absorbed by interior blind or shade is assumed
    6502             :         // to go into zone air. (This is not true in general; the fraction of this absorbed solar that
    6503             :         // is conducted back out is accounted for in the time-step glazing calculation.)
    6504             :         // For CR 7682, the SHGC calculations were changed to model the absorbed solar arriving at the middle of the layer
    6505             :         // rather than at the outer face of the layer.  The resistances changed by one half the glazing layer, or 0.5/scon(n).
    6506             :         // (CR 7682 also changed WindowTempsForNominalCond to include absorbed solar, a bigger change)
    6507             : 
    6508             :         // Using/Aliasing
    6509             :         using General::BlindBeamBeamTrans;
    6510             :         using General::InterpProfSlatAng;
    6511             :         using General::InterpSlatAng;
    6512             :         using General::POLYF;
    6513             : 
    6514             :         // Locals
    6515             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    6516             :         //   normal incidence beam solar radiation
    6517             : 
    6518             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6519             :         int TotLay; // Total number of layers in a construction
    6520             :         //   (sum of solid layers and gap layers)
    6521             :         int TotGlassLay; // Total number of glass layers in a construction
    6522             :         int Lay;         // Layer number
    6523             :         int LayPtr;      // Material number for a layer
    6524             :         int IGlass;      // glass layer number (1,2,3,...)
    6525             :         int IGap;        // Gap layer number (1,2,...)
    6526             :         int IMix;        // Gas component loop index for gap gas mixture
    6527             :         int ICoeff;      // Gas property coefficient index
    6528             : 
    6529             :         Real64 BeamSolarInc; // Incident beam radiation at zero angle of incidence (W/m2)
    6530             :                              //        Real64 hOutRad;      // Radiative conductance of outside and inside airfilm [W/m2-K]
    6531             :                              //        Real64 hInRad;
    6532             :                              //        Real64 rOut; // Combined radiative and conductive outside and inside film
    6533             :                              //        Real64 rIn;
    6534             :         //   resistance [m2-K/W]
    6535        5199 :         Array1D<Real64> hgap(5);        // Conductive gap conductance [W/m2-K]
    6536             :                                         //        Array1D<Real64> hGapTot(5);     // Combined radiative and conductive gap conductance [W/m2-K]
    6537             :                                         //        Real64 Rbare;                   // Nominal center-of-glass resistance without air films [m2-K/W]
    6538             :         WinShadingType ShadeFlag;       // Shading flag
    6539             :         Real64 ShadeRes;                // Thermal resistance of shade
    6540             :         int MatOutside;                 // Material number of outside layer of construction
    6541             :         int MatInside;                  // Material number of inside layer of construction
    6542             :         int MatShade;                   // Material number of shade layer
    6543        5199 :         Array1D<Real64> AbsBeamNorm(5); // Beam absorptance at normal incidence for each glass layer
    6544             :         Real64 AbsBeamShadeNorm;        // Shade solar absorptance at normal incidence
    6545             :         int ConstrNum1;                 // Construction counter
    6546             :         int ConstrNumBare;              // Construction without shading device
    6547             :         int BlNum;                      // Blind number
    6548             :         int ScNum;                      // Screen number
    6549             :         bool VarSlats;                  // True if slats in blind are variable angle
    6550             :         Real64 SlatAng;                 // Slat angle (rad)
    6551             :         int LayPtrSh;                   // Layer pointer of blind
    6552             :         Real64 TBmBm;                   // Bare glass normal incidence beam-beam transmittance
    6553             :         Real64 TBmBmVis;
    6554             :         Real64 TBlBmBm; // Normal incidence blind beam-beam transmittance
    6555             :         Real64 TScBmBm; // Screen incident beam-beam transmittance
    6556             :         Real64 TScBmBmVis;
    6557             :         Real64 TBmBmBl; // TBmBm * TBlBmBm, TBmBmVis * TBlBmBm
    6558             :         Real64 TBmBmBlVis;
    6559             :         Real64 RGlDiffBack; // Bare glass back sol/vis reflectance
    6560             :         Real64 RGlDiffBackVis;
    6561             :         Real64 RGlDiffFront; // Bare glass front sol/vis reflectance
    6562             :         Real64 RGlDiffFrontVis;
    6563             :         Real64 RhoBlFront; // Blind normal front beam-diffuse sol/vis reflectance
    6564             :         Real64 RhoBlFrontVis;
    6565             :         Real64 RhoBlBack; // Blind normal back beam-diffuse sol/vis reflectance
    6566             :         Real64 RhoBlBackVis;
    6567             :         Real64 RScBack; // Screen back beam-diffuse sol/vis reflectance (same as front)
    6568             :         Real64 RScBackVis;
    6569             :         Real64 AbsBlFront;     // Blind normal front beam solar absorptance
    6570             :         Real64 AbsBlBack;      // Blind normal back beam solar absorptance
    6571             :         Real64 RhoBlDiffFront; // Blind front diffuse-diffuse sol/vis reflectance
    6572             :         Real64 RhoBlDiffFrontVis;
    6573             :         Real64 AbsBlDiffFront; // Blind front diffuse solar absorptance
    6574             :         Real64 AbsBlDiffBack;  // Blind back diffuse solar absorptance
    6575             :         Real64 RGlFront;       // Bare glass normal front beam sol/vis reflectance
    6576             :         Real64 RGlFrontVis;
    6577             :         Real64 RhoBlDiffBack; // Blind back diffuse-diffuse sol/vis reflectance
    6578             :         Real64 RhoBlDiffBackVis;
    6579             :         Real64 RScDifBack; // Screen back diffuse-diffuse sol/vis reflectance (doesn't change with sun angle)
    6580             :         Real64 RScDifBackVis;
    6581             :         Real64 TBlBmDif; // Blind front normal beam-diffuse sol/vis transmittance
    6582             :         Real64 TBlBmDifVis;
    6583             :         Real64 TBlDifDif; // Blind front diffuse-diffuse sol/vis transmittance
    6584             :         Real64 TBlDifDifVis;
    6585             :         Real64 TScBmDif; // Screen front beam-diffuse sol/vis transmittance
    6586             :         Real64 TScBmDifVis;
    6587             :         Real64 TDif; // Bare glass diffuse sol/vis transmittance
    6588             :         Real64 TDifVis;
    6589             :         Real64 AGlDiffBack; // Back diffuse solar absorptance of a glass layer
    6590             : 
    6591             :         // Autodesk:Uninit Initialize variables used uninitialized
    6592             :         //        Rbare = 0.0; // Autodesk:Uninit Force default initialization
    6593        2602 :         NominalConductance = 0.0;
    6594        2602 :         errFlag = 0;
    6595        2602 :         TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers;
    6596        2602 :         TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    6597        2602 :         state.dataWindowManager->ngllayer = TotGlassLay; // Autodesk:Uninit This routine needs to check/enforce 1<=ngllayer<=4
    6598             :         // EPTeam - believe that is done on input.
    6599        2602 :         state.dataWindowManager->nglface = 2 * state.dataWindowManager->ngllayer;
    6600        2602 :         state.dataWindowManager->tilt = 90.0; // Assume vertical window
    6601             : 
    6602        2602 :         if (WinterSummerFlag == 1) { // Winter
    6603             :             // LKL Oct 2007:  According to Window5, Winter environmental conditions are:
    6604        1313 :             state.dataWindowManager->tin = 294.15;  // Inside air temperature (69.8F, 21.C)
    6605        1313 :             state.dataWindowManager->tout = 255.15; // Outside air temperature (-.4F, -18C)
    6606        1313 :             state.dataWindowManager->hcout = 26.0;  // Outside convective film conductance for 5.5 m/s (12.3 mph) wind speed
    6607             :             // (the value used in Window 5)
    6608             :             //  tin = 294.26   ! Inside air temperature (70F, 21.1C)
    6609             :             //  tout = 255.35  ! Outside air temperature (0F, -17.8C)
    6610             :             //  hcout = 25.47  ! Outside convective film conductance for 6.71 m/s (15 mph) wind speed
    6611             :             //                 ! (the value used in Window 4)
    6612        1313 :             BeamSolarInc = 0.0;
    6613             :         } else { // Summer
    6614             :             // LKL Oct 2007: According to Window5, Summer environmental conditions are:
    6615             :             // tin = 297.05d0   ! Inside air temperature (75.2F, 24C)
    6616             :             // BG Feb. 2009: According to Window5 Expert Christian Kohler, it is exactly 24C or 297.15
    6617        1289 :             state.dataWindowManager->tin = 297.15;
    6618        1289 :             state.dataWindowManager->tout = 305.15; // Outside air temperature (89.6F, 32C)
    6619        1289 :             state.dataWindowManager->hcout = 15.0;  // Outside convective film conductance for 2.8 m/s (6.2 mph) wind speed
    6620             :             // (the value used in Window 5)
    6621             :             //  tin = 297.05   ! Inside air temperature (75F, 23.9C)
    6622             :             //  !tout = 308.15  ! Outside air temperature (95F, 35.0C)
    6623             :             //  ! Changed 6/20/01 by FCW to make consistent with Window 4 and 5.
    6624             :             //  tout = 304.82  ! Outside air temperature (89F, 31.7C)
    6625             :             //  hcout = 18.86  ! Outside convective film conductance for 3.35 m/s (7.5 mph) wind speed
    6626             :             //                 ! (average of Window 4 0 m/s and 6.71 m/s values)
    6627        1289 :             BeamSolarInc = 783.0;
    6628             :         }
    6629             : 
    6630             :         // IR incident on inside of glazing (inside surround assumed to be
    6631             :         // a black body at inside air temperature)
    6632        2602 :         state.dataWindowManager->Rmir = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tin);
    6633             : 
    6634             :         // IR incident on outside of glazing
    6635             :         // (outside surround is assumed to be a black body at outside air temperature)
    6636        2602 :         state.dataWindowManager->Outir = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tout);
    6637             : 
    6638             :         // Determine whether construction has an exterior or interior shade or blind
    6639        2602 :         ShadeFlag = WinShadingType::NoShade;
    6640        2602 :         ShadeRes = 0.0;
    6641        2602 :         MatOutside = state.dataConstruction->Construct(ConstrNum).LayerPoint(1);
    6642        2602 :         MatInside = state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay);
    6643        2602 :         if (state.dataMaterial->Material(MatOutside).Group == DataHeatBalance::MaterialGroup::Shade) { // Exterior shade present
    6644           5 :             MatShade = MatOutside;
    6645           5 :             ShadeFlag = WinShadingType::ExtShade;
    6646             :             // Set glazing outside convection coefficient to Window 4 still-air value
    6647           5 :             state.dataWindowManager->hcout = 12.25;
    6648        2597 :         } else if (state.dataMaterial->Material(MatOutside).Group == DataHeatBalance::MaterialGroup::Screen) { // Exterior screen present
    6649           4 :             MatShade = MatOutside;
    6650           4 :             ScNum = state.dataMaterial->Material(MatShade).ScreenDataPtr;
    6651             :             // Orphaned constructs with exterior screen are ignored
    6652           4 :             if (ScNum > 0) ShadeFlag = WinShadingType::ExtScreen;
    6653           4 :             state.dataWindowManager->hcout = 12.25;
    6654        2593 :         } else if (state.dataMaterial->Material(MatOutside).Group == DataHeatBalance::MaterialGroup::WindowBlind) { // Exterior blind present
    6655           4 :             MatShade = MatOutside;
    6656           4 :             ShadeFlag = WinShadingType::ExtBlind;
    6657           4 :             BlNum = state.dataMaterial->Material(MatShade).BlindDataPtr;
    6658           4 :             state.dataWindowManager->hcout = 12.25;
    6659        2589 :         } else if (state.dataMaterial->Material(MatInside).Group == DataHeatBalance::MaterialGroup::Shade) { // Interior shade present
    6660          40 :             MatShade = MatInside;
    6661          40 :             ShadeFlag = WinShadingType::IntShade;
    6662        2549 :         } else if (state.dataMaterial->Material(MatInside).Group == DataHeatBalance::MaterialGroup::WindowBlind) { // Interior blind present
    6663          21 :             MatShade = MatInside;
    6664          21 :             BlNum = state.dataMaterial->Material(MatShade).BlindDataPtr;
    6665          21 :             ShadeFlag = WinShadingType::IntBlind;
    6666        2528 :         } else if (TotGlassLay == 2) {
    6667         962 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
    6668             :                 DataHeatBalance::MaterialGroup::Shade)
    6669           1 :                 ShadeFlag = WinShadingType::BGShade;
    6670         962 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
    6671             :                 DataHeatBalance::MaterialGroup::WindowBlind)
    6672           2 :                 ShadeFlag = WinShadingType::BGBlind;
    6673        1566 :         } else if (TotGlassLay == 3) {
    6674         132 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
    6675             :                 DataHeatBalance::MaterialGroup::Shade)
    6676           1 :                 ShadeFlag = WinShadingType::BGShade;
    6677         132 :             if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
    6678             :                 DataHeatBalance::MaterialGroup::WindowBlind)
    6679           1 :                 ShadeFlag = WinShadingType::BGBlind;
    6680             :         }
    6681             : 
    6682        2602 :         if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    6683           5 :             errFlag = 2;
    6684           5 :             return;
    6685             :         }
    6686             : 
    6687        2597 :         TSolNorm = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
    6688        2597 :         TVisNorm = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
    6689        2597 :         AbsBeamShadeNorm = 0.0;
    6690        2597 :         if (ShadeFlag == WinShadingType::IntShade || ShadeFlag == WinShadingType::ExtShade) { // Exterior or interior shade on
    6691          45 :             AbsBeamShadeNorm = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef);
    6692             :             // Exterior blind or screen or interior blind on
    6693        2552 :         } else if (ShadeFlag == WinShadingType::IntBlind || ShadeFlag == WinShadingType::ExtBlind || ShadeFlag == WinShadingType::ExtScreen) {
    6694             :             // Find unshaded construction that goes with this construction w/blind or screen
    6695          29 :             ConstrNumBare = 0;
    6696         173 :             for (ConstrNum1 = 1; ConstrNum1 <= state.dataHeatBal->TotConstructs; ++ConstrNum1) {
    6697         379 :                 if (ConstrNum1 != ConstrNum && state.dataConstruction->Construct(ConstrNum1).TypeIsWindow &&
    6698         239 :                     state.dataConstruction->Construct(ConstrNum1).TotGlassLayers == state.dataConstruction->Construct(ConstrNum1).TotSolidLayers &&
    6699          33 :                     state.dataConstruction->Construct(ConstrNum1).TotGlassLayers == state.dataConstruction->Construct(ConstrNum).TotGlassLayers) {
    6700             :                     // We have an unshaded window construction with the same number of glass layers as ConstrNum;
    6701             :                     // see if the glass and gas layers match
    6702          31 :                     ConstrNumBare = ConstrNum1;
    6703          66 :                     for (Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNum1).TotLayers; ++Lay) {
    6704          35 :                         LayPtr = state.dataConstruction->Construct(ConstrNum1).LayerPoint(Lay);
    6705          35 :                         if (ShadeFlag == WinShadingType::IntBlind) { // The shaded construction has an interior blind
    6706          21 :                             LayPtrSh = state.dataConstruction->Construct(ConstrNum).LayerPoint(Lay);
    6707             :                         } else { // The shaded construction has an exterior blind or screen
    6708          14 :                             LayPtrSh = state.dataConstruction->Construct(ConstrNum).LayerPoint(Lay + 1);
    6709             :                         }
    6710          35 :                         if (LayPtrSh != LayPtr) ConstrNumBare = 0;
    6711             :                     }
    6712          31 :                     if (ConstrNumBare != 0) break;
    6713             :                 }
    6714             :             }
    6715          29 :             if (ConstrNumBare == 0) {
    6716             :                 // No matching bare construction found for this construction with blind or screen
    6717           0 :                 errFlag = 1;
    6718           0 :                 return;
    6719             :             }
    6720             : 
    6721          29 :             TBmBm = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).TransSolBeamCoef);
    6722          29 :             TBmBmVis = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).TransVisBeamCoef);
    6723          29 :             if (ShadeFlag == WinShadingType::ExtScreen) {
    6724             :                 //   Don't need to call subroutine, use normal incident properties (SUBROUTINE CalcNominalWindowCond)
    6725             :                 //   Last call to CalcScreenTransmittance(ISurf) was done at direct normal angle (0,0) in CalcWindowScreenProperties
    6726           4 :                 TScBmBm = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTrans;
    6727           4 :                 TScBmBmVis = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTransVis;
    6728           4 :                 TScBmDif = state.dataHeatBal->SurfaceScreens(ScNum).BmDifTrans;
    6729           4 :                 TScBmDifVis = state.dataHeatBal->SurfaceScreens(ScNum).BmDifTransVis;
    6730           4 :                 TDif = state.dataConstruction->Construct(ConstrNumBare).TransDiff;
    6731           4 :                 TDifVis = state.dataConstruction->Construct(ConstrNumBare).TransDiffVis;
    6732           4 :                 RScBack = state.dataHeatBal->SurfaceScreens(ScNum).ReflectScreen;
    6733           4 :                 RScBackVis = state.dataHeatBal->SurfaceScreens(ScNum).ReflectScreenVis;
    6734           4 :                 RScDifBack = state.dataHeatBal->SurfaceScreens(ScNum).DifReflect;
    6735           4 :                 RScDifBackVis = state.dataHeatBal->SurfaceScreens(ScNum).DifReflectVis;
    6736           4 :                 RGlFront = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
    6737           4 :                 RGlFrontVis = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
    6738           4 :                 RGlDiffFront = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffFront;
    6739           4 :                 RGlDiffFrontVis = state.dataConstruction->Construct(ConstrNumBare).ReflectVisDiffFront;
    6740           8 :                 TSolNorm = TScBmBm * (TBmBm + TDif * RGlFront * RScBack / (1 - RGlDiffFront * RScDifBack)) +
    6741           4 :                            TScBmDif * TDif / (1 - RGlDiffFront * RScDifBack);
    6742           8 :                 TVisNorm = TScBmBmVis * (TBmBmVis + TDifVis * RGlFrontVis * RScBackVis / (1 - RGlDiffFrontVis * RScDifBackVis)) +
    6743           4 :                            TScBmDifVis * TDifVis / (1 - RGlDiffFrontVis * RScDifBackVis);
    6744             :             } else {
    6745          25 :                 VarSlats = false;
    6746          25 :                 if (state.dataHeatBal->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Variable) VarSlats = true;
    6747          25 :                 SlatAng = state.dataHeatBal->Blind(BlNum).SlatAngle * DataGlobalConstants::DegToRadians;
    6748          75 :                 TBlBmBm = BlindBeamBeamTrans(0.0,
    6749             :                                              SlatAng,
    6750          25 :                                              state.dataHeatBal->Blind(BlNum).SlatWidth,
    6751          25 :                                              state.dataHeatBal->Blind(BlNum).SlatSeparation,
    6752          25 :                                              state.dataHeatBal->Blind(BlNum).SlatThickness);
    6753          25 :                 TBmBmBl = TBmBm * TBlBmBm;
    6754          25 :                 TBmBmBlVis = TBmBmVis * TBlBmBm;
    6755          25 :                 TBlBmDif = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans);
    6756          25 :                 TBlBmDifVis = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontBeamDiffTrans);
    6757          25 :                 TDif = state.dataConstruction->Construct(ConstrNumBare).TransDiff;
    6758          25 :                 TDifVis = state.dataConstruction->Construct(ConstrNumBare).TransDiffVis;
    6759          25 :                 if (ShadeFlag == WinShadingType::IntBlind) {
    6760          21 :                     RGlDiffBack = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffBack;
    6761          21 :                     RGlDiffBackVis = state.dataConstruction->Construct(ConstrNumBare).ReflectVisDiffBack;
    6762          21 :                     RhoBlFront = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl);
    6763          21 :                     RhoBlFrontVis = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontBeamDiffRefl);
    6764          21 :                     AbsBlFront = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs);
    6765          21 :                     RhoBlDiffFront = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl);
    6766          21 :                     RhoBlDiffFrontVis = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffRefl);
    6767          21 :                     AbsBlDiffFront = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs);
    6768          21 :                     AbsBeamShadeNorm = TBmBm * (AbsBlFront + RhoBlFront * RGlDiffBack * AbsBlDiffFront / (1.0 - RhoBlDiffFront * RGlDiffBack));
    6769          21 :                     TBlDifDif = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans);
    6770          21 :                     TBlDifDifVis = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffTrans);
    6771          21 :                     TSolNorm = TBmBm * (TBlBmBm + TBlBmDif + TBlDifDif * RhoBlFront * RGlDiffBack / (1.0 - RhoBlDiffFront * RGlDiffBack));
    6772             :                     //     use of TBlBmBm here is correct, visible and IR transmittance are the same (reference deleted CR6925 on 3/20/2006)
    6773          21 :                     TVisNorm = TBmBmVis *
    6774          21 :                                (TBlBmBm + TBlBmDifVis + TBlDifDifVis * RhoBlFrontVis * RGlDiffBackVis / (1.0 - RhoBlDiffFrontVis * RGlDiffBackVis));
    6775             :                 } // (IntBlind)
    6776          25 :                 if (ShadeFlag == WinShadingType::ExtBlind) {
    6777          12 :                     TBlBmBm = BlindBeamBeamTrans(0.0,
    6778             :                                                  SlatAng,
    6779           4 :                                                  state.dataHeatBal->Blind(BlNum).SlatWidth,
    6780           4 :                                                  state.dataHeatBal->Blind(BlNum).SlatSeparation,
    6781           4 :                                                  state.dataHeatBal->Blind(BlNum).SlatThickness);
    6782           4 :                     RGlFront = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
    6783           4 :                     RGlFrontVis = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
    6784           4 :                     AbsBlFront = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs);
    6785           4 :                     AbsBlBack = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackBeamAbs);
    6786           4 :                     AbsBlDiffBack = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackDiffAbs);
    6787           4 :                     RGlDiffFront = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffFront;
    6788           4 :                     RGlDiffFrontVis = state.dataConstruction->Construct(ConstrNumBare).ReflectVisDiffFront;
    6789           4 :                     RhoBlDiffBack = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl);
    6790           4 :                     RhoBlDiffBackVis = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl);
    6791           4 :                     RhoBlBack = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl);
    6792           4 :                     RhoBlBackVis = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl);
    6793           4 :                     AbsBeamShadeNorm =
    6794           4 :                         AbsBlFront + AbsBlBack * RGlFront * TBlBmBm +
    6795           4 :                         (AbsBlDiffBack * RGlDiffFront / (1.0 - RhoBlDiffBack * RGlDiffFront)) * (RGlFront * TBlBmBm * RhoBlBack + TBlBmDif);
    6796           4 :                     RGlDiffFront = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffFront;
    6797           8 :                     TSolNorm = TBlBmBm * (TBmBm + TDif * RGlFront * RhoBlBack / (1 - RGlDiffFront * RhoBlDiffBack)) +
    6798           4 :                                TBlBmDif * TDif / (1.0 - RGlDiffFront * RhoBlDiffBack);
    6799           8 :                     TVisNorm = TBlBmBm * (TBmBmVis + TDifVis * RGlFrontVis * RhoBlBackVis / (1 - RGlDiffFrontVis * RhoBlDiffBackVis)) +
    6800           4 :                                TBlBmDifVis * TDifVis / (1.0 - RGlDiffFrontVis * RhoBlDiffBackVis);
    6801             :                 } // (ExtBlind)
    6802             :             }     // (Screen or Blind)
    6803             :         }         // (Shade, Blind, or Screen)
    6804             : 
    6805             :         // Fill the layer properties needed for the thermal calculation.
    6806             : 
    6807             :         // The layer and face numbering are as follows (for the triple glazing case):
    6808             :         // Glass layers are 1,2 and 3, where 1 is the outside (outside environment facing)
    6809             :         //   layer and 3 is the inside (room-facing) layer;
    6810             :         // Faces (also called surfaces) are 1,2,3,4,5 and 6, where face 1 is the
    6811             :         //   outside (front) face of glass layer 1, face 2 is the inside (back)
    6812             :         //   face of glass layer 1, face 3 is the outer face of glass layer 2, face 4 is the
    6813             :         //   inner face of glass layer 2, etc.
    6814             :         // Gap layers are 1 and 2, where gap layer 1 is between glass layers 1 and 2
    6815             :         //   and gap layer 2 is between glass layers 2 and 3.
    6816             : 
    6817        2597 :         IGlass = 0;
    6818        2597 :         IGap = 0;
    6819             : 
    6820        7872 :         for (Lay = 1; Lay <= TotLay; ++Lay) {
    6821        5275 :             LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(Lay);
    6822        6903 :             if ((state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGlass) ||
    6823        1628 :                 (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowSimpleGlazing)) {
    6824        3885 :                 ++IGlass;
    6825        3885 :                 state.dataWindowManager->thick[IGlass - 1] = state.dataMaterial->Material(LayPtr).Thickness;
    6826        3885 :                 state.dataWindowManager->scon[IGlass - 1] =
    6827        3885 :                     state.dataMaterial->Material(LayPtr).Conductivity / state.dataMaterial->Material(LayPtr).Thickness;
    6828        3885 :                 state.dataWindowManager->emis[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).AbsorpThermalFront;
    6829        3885 :                 state.dataWindowManager->emis[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).AbsorpThermalBack;
    6830        3885 :                 state.dataWindowManager->tir[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).TransThermal;
    6831        3885 :                 state.dataWindowManager->tir[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).TransThermal;
    6832        3885 :                 AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(IGlass));
    6833        3885 :                 if (ShadeFlag == WinShadingType::IntBlind) { // Interior blind on
    6834          21 :                     AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).AbsBeamCoef(IGlass));
    6835          21 :                     AGlDiffBack = state.dataConstruction->Construct(ConstrNumBare).AbsDiffBack(IGlass);
    6836          21 :                     AbsBeamNorm(IGlass) += TBmBm * AGlDiffBack * RhoBlFront / (1.0 - RhoBlFront * RGlDiffBack);
    6837        3864 :                 } else if (ShadeFlag == WinShadingType::ExtBlind) { // Exterior blind on
    6838           4 :                     AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).AbsBeamCoef(IGlass));
    6839          12 :                     AbsBeamNorm(IGlass) = TBlBmBm * AbsBeamNorm(IGlass) + (TBlBmBm * RGlFront * RhoBlBack + TBlBmDif) *
    6840           8 :                                                                               state.dataConstruction->Construct(ConstrNumBare).AbsDiff(IGlass) /
    6841           4 :                                                                               (1.0 - RGlDiffFront * RhoBlDiffBack);
    6842        3860 :                 } else if (ShadeFlag == WinShadingType::ExtScreen) { // Exterior screen on
    6843           6 :                     AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).AbsBeamCoef(IGlass));
    6844          18 :                     AbsBeamNorm(IGlass) = TScBmBm * AbsBeamNorm(IGlass) + (TScBmBm * RGlFront * RScBack + TScBmDif) *
    6845          12 :                                                                               state.dataConstruction->Construct(ConstrNumBare).AbsDiff(IGlass) /
    6846           6 :                                                                               (1.0 - RGlDiffFront * RScDifBack);
    6847             :                 }
    6848        3885 :                 state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 2] = 0.5 * BeamSolarInc * AbsBeamNorm(IGlass);
    6849        3885 :                 state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 1] = 0.5 * BeamSolarInc * AbsBeamNorm(IGlass);
    6850             :             }
    6851       14588 :             if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGas ||
    6852        9277 :                 state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGasMixture ||
    6853        4002 :                 state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::ComplexWindowGap) { // Gap layer
    6854        1302 :                 ++IGap;
    6855             :                 // Simon: Need to re-reference gas data in casee of complex fenestration gap
    6856        1302 :                 if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::ComplexWindowGap) {
    6857          29 :                     LayPtr = state.dataMaterial->Material(LayPtr).GasPointer;
    6858             :                 }
    6859        1302 :                 state.dataWindowManager->gap[IGap - 1] = state.dataMaterial->Material(LayPtr).Thickness;
    6860        1302 :                 state.dataWindowManager->gnmix[IGap - 1] = state.dataMaterial->Material(LayPtr).NumberOfGasesInMixture;
    6861        2640 :                 for (IMix = 1; IMix <= state.dataWindowManager->gnmix[IGap - 1]; ++IMix) {
    6862        1338 :                     state.dataWindowManager->gwght[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasWght(IMix);
    6863        1338 :                     state.dataWindowManager->gfract[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasFract(IMix);
    6864        5352 :                     for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
    6865        4014 :                         state.dataWindowManager->gcon[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCon(ICoeff, IMix);
    6866        4014 :                         state.dataWindowManager->gvis[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasVis(ICoeff, IMix);
    6867        4014 :                         state.dataWindowManager->gcp[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCp(ICoeff, IMix);
    6868             :                     }
    6869             :                 }
    6870             :             }
    6871             :         }
    6872             : 
    6873             :         // Factors used in glass temperature solution
    6874        2597 :         if (state.dataWindowManager->ngllayer >= 2) {
    6875        1132 :             state.dataWindowManager->A23P =
    6876        1132 :                 -state.dataWindowManager->emis[2] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
    6877        1132 :             state.dataWindowManager->A32P =
    6878        1132 :                 state.dataWindowManager->emis[1] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
    6879        1132 :             state.dataWindowManager->A23 = state.dataWindowManager->emis[1] * state.dataWindowManager->sigma * state.dataWindowManager->A23P;
    6880             :         }
    6881             : 
    6882        2597 :         if (state.dataWindowManager->ngllayer >= 3) {
    6883         144 :             state.dataWindowManager->A45P =
    6884         144 :                 -state.dataWindowManager->emis[4] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
    6885         144 :             state.dataWindowManager->A54P =
    6886         144 :                 state.dataWindowManager->emis[3] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
    6887         144 :             state.dataWindowManager->A45 = state.dataWindowManager->emis[3] * state.dataWindowManager->sigma * state.dataWindowManager->A45P;
    6888             :         }
    6889             : 
    6890        2597 :         if (state.dataWindowManager->ngllayer == 4) {
    6891          12 :             state.dataWindowManager->A67P =
    6892          12 :                 -state.dataWindowManager->emis[6] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
    6893          12 :             state.dataWindowManager->A76P =
    6894          12 :                 state.dataWindowManager->emis[5] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
    6895          12 :             state.dataWindowManager->A67 = state.dataWindowManager->emis[5] * state.dataWindowManager->sigma * state.dataWindowManager->A67P;
    6896             :         }
    6897             : 
    6898        2597 :         state.dataWindowManager->thetas = {0.0};
    6899             : 
    6900        2597 :         WindowTempsForNominalCond(state, ConstrNum, hgap, 1.0);
    6901             : 
    6902        2597 :         if (!ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) AbsBeamShadeNorm = 0.0;
    6903             : 
    6904             :         // Get center-of-glass conductance and solar heat gain coefficient
    6905             :         // including inside and outside air films
    6906        2597 :         Real64 inputU = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).SimpleWindowUfactor;
    6907             : 
    6908             :         // Calculate the NominalConductance glazing only (before adjusted)
    6909        2597 :         EvalNominalWindowCond(state, AbsBeamShadeNorm, AbsBeamNorm, hgap, NominalConductance, SHGC, TSolNorm);
    6910             : 
    6911        2597 :         if (WinterSummerFlag == 1) {
    6912        1308 :             state.dataHeatBal->NominalUBeforeAdjusted(ConstrNum) = NominalConductance;
    6913        1308 :             if (inputU > 0) {                  // only compute adjustment ratio when there is valid user input U
    6914         122 :                 Real64 wettedAreaAdjRatio = 1; // Adjustment ratio for the wetted area
    6915         122 :                 Real64 hcoutRated = state.dataWindowManager->hcout;
    6916             :                 // Adjustment ratio applies to convective film coefficients when input U value is above the limit of the simple glazing nominal U
    6917             :                 // Representing the nominal highly conductive frame effects. Solved iteratively.
    6918         122 :                 Real64 adjLower = 1.0;
    6919         122 :                 Real64 adjUpper = 2.0;
    6920         122 :                 int MaxIter = 100;
    6921         154 :                 while (std::abs(inputU - NominalConductance) > 0.01 && MaxIter > 0) {
    6922          16 :                     wettedAreaAdjRatio = (adjLower + adjUpper) / 2;
    6923          16 :                     WindowTempsForNominalCond(
    6924             :                         state, ConstrNum, hgap, wettedAreaAdjRatio); // reeval hcout at each iteration, hcin is not linear to wetted area
    6925          16 :                     state.dataWindowManager->hcout = hcoutRated * wettedAreaAdjRatio; // reeval hcout
    6926          16 :                     EvalNominalWindowCond(state, AbsBeamShadeNorm, AbsBeamNorm, hgap, NominalConductance, SHGC, TSolNorm);
    6927          16 :                     if (NominalConductance < inputU) {
    6928           5 :                         adjLower = wettedAreaAdjRatio;
    6929             :                     } else {
    6930          11 :                         adjUpper = wettedAreaAdjRatio;
    6931             :                     }
    6932          16 :                     MaxIter -= 1;
    6933             :                 }
    6934         122 :                 state.dataHeatBal->CoeffAdjRatio(ConstrNum) = wettedAreaAdjRatio;
    6935             :             }
    6936             :         }
    6937             : 
    6938             :         // EPTeam - again -- believe that is enforced in input //Autodesk But this routine is not self-protecting: Add as an assert
    6939             : 
    6940             :         // init the surface convective and radiative adjustment ratio
    6941       33215 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6942       61252 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6943       30634 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    6944       30634 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    6945       30634 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    6946       99303 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    6947       68669 :                     if (state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) {
    6948       68637 :                         int ConstrNum2 = state.dataSurface->Surface(SurfNum).Construction;
    6949       68637 :                         state.dataHeatBalSurf->SurfWinCoeffAdjRatio(SurfNum) = state.dataHeatBal->CoeffAdjRatio(ConstrNum2);
    6950             :                     }
    6951             :                 }
    6952             :             }
    6953             :         }
    6954             : 
    6955             :         // Need to add variables writing here since this routine will override previously calcualted values from WinCalc-Engine
    6956        2597 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    6957           3 :             TSolNorm = GetSolarTransDirectHemispherical(state, ConstrNum);
    6958           3 :             TVisNorm = GetVisibleTransDirectHemispherical(state, ConstrNum);
    6959             :         }
    6960             :     }
    6961             : 
    6962        2613 :     void EvalNominalWindowCond(EnergyPlusData &state,
    6963             :                                Real64 const AbsBeamShadeNorm,     // Shade solar absorptance at normal incidence
    6964             :                                Array1D<Real64> const AbsBeamNorm, // Beam absorptance at normal incidence for each glass layer
    6965             :                                Array1D<Real64> const hgap,        // Conductive gap conductance [W/m2-K]
    6966             :                                Real64 &NominalConductance,        // Nominal center-of-glass conductance, including air films
    6967             :                                Real64 &SHGC,                      // Nominal center-of-glass solar heat gain coefficient for
    6968             :                                Real64 &TSolNorm                   // Overall beam solar transmittance at normal incidence
    6969             :     )
    6970             :     {
    6971        5226 :         Array1D<Real64> hGapTot(5); // Combined radiative and conductive gap conductance [W/m2-K]
    6972             : 
    6973        2613 :         Real64 hOutRad = state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * 0.5 *
    6974        2613 :                          pow_3(state.dataWindowManager->tout + state.dataWindowManager->thetas[0]);
    6975        2613 :         Real64 rOut = 1.0 / (hOutRad + state.dataWindowManager->hcout);
    6976        2613 :         Real64 hInRad = state.dataWindowManager->emis[state.dataWindowManager->nglface - 1] * state.dataWindowManager->sigma * 0.5 *
    6977        2613 :                         pow_3(state.dataWindowManager->tin + state.dataWindowManager->thetas[state.dataWindowManager->nglface - 1]);
    6978        2613 :         Real64 rIn = 1.0 / (hInRad + state.dataWindowManager->hcin);
    6979        2613 :         Real64 Rbare = 0;
    6980             : 
    6981        2613 :         switch (state.dataWindowManager->ngllayer) {
    6982             :         // the switch cases here are just the integer number of layers, not exactly "magic" numbers 1, 2, 3. and 4.
    6983        1481 :         case 1:
    6984        1481 :             Rbare = 1.0 / state.dataWindowManager->scon[0];
    6985        1481 :             state.dataWindowManager->Rtot = rOut + Rbare + rIn;
    6986        2962 :             SHGC = AbsBeamNorm(1) * (rOut + (0.5 / state.dataWindowManager->scon[0])) /
    6987        1481 :                    state.dataWindowManager->Rtot; // BG changed for CR7682 (solar absorbed in middle of layer)
    6988        1481 :             SHGC += AbsBeamShadeNorm;
    6989        1481 :             SHGC += TSolNorm;
    6990        1481 :             break;
    6991             : 
    6992         988 :         case 2:
    6993        1976 :             hGapTot(1) = hgap(1) + std::abs(state.dataWindowManager->A23) * 0.5 *
    6994         988 :                                        pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
    6995         988 :             Rbare = 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1];
    6996         988 :             state.dataWindowManager->Rtot = rOut + Rbare + rIn;
    6997        1976 :             SHGC = AbsBeamNorm(1) * (rOut + 0.5 / state.dataWindowManager->scon[0]) / state.dataWindowManager->Rtot +
    6998        1976 :                    AbsBeamNorm(2) * (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 0.5 / state.dataWindowManager->scon[1]) /
    6999         988 :                        state.dataWindowManager->Rtot; // CR7682
    7000         988 :             SHGC += AbsBeamShadeNorm;
    7001         988 :             SHGC += TSolNorm;
    7002         988 :             break;
    7003             : 
    7004         132 :         case 3:
    7005         264 :             hGapTot(1) = hgap(1) + std::abs(state.dataWindowManager->A23) * 0.5 *
    7006         132 :                                        pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
    7007         264 :             hGapTot(2) = hgap(2) + std::abs(state.dataWindowManager->A45) * 0.5 *
    7008         132 :                                        pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
    7009         264 :             Rbare = 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
    7010         132 :                     1.0 / state.dataWindowManager->scon[2];
    7011         132 :             state.dataWindowManager->Rtot = rOut + Rbare + rIn;
    7012         396 :             SHGC = AbsBeamNorm(1) * (rOut + 0.5 / state.dataWindowManager->scon[0]) / state.dataWindowManager->Rtot +
    7013         264 :                    AbsBeamNorm(2) * (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 0.5 / state.dataWindowManager->scon[1]) /
    7014         264 :                        state.dataWindowManager->Rtot +
    7015         264 :                    AbsBeamNorm(3) *
    7016         264 :                        (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
    7017         264 :                         0.5 / state.dataWindowManager->scon[2]) /
    7018         132 :                        state.dataWindowManager->Rtot;
    7019         132 :             SHGC += AbsBeamShadeNorm;
    7020         132 :             SHGC += TSolNorm;
    7021         132 :             break;
    7022             : 
    7023          12 :         case 4:
    7024          24 :             hGapTot(1) = hgap(1) + std::abs(state.dataWindowManager->A23) * 0.5 *
    7025          12 :                                        pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
    7026          24 :             hGapTot(2) = hgap(2) + std::abs(state.dataWindowManager->A45) * 0.5 *
    7027          12 :                                        pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
    7028          24 :             hGapTot(3) = hgap(3) + std::abs(state.dataWindowManager->A67) * 0.5 *
    7029          12 :                                        pow_3(state.dataWindowManager->thetas[5] + state.dataWindowManager->thetas[6]);
    7030          36 :             Rbare = 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
    7031          24 :                     1.0 / state.dataWindowManager->scon[2] + 1.0 / hGapTot(3) + 1.0 / state.dataWindowManager->scon[3];
    7032          12 :             state.dataWindowManager->Rtot = rOut + Rbare + rIn;
    7033          36 :             SHGC = AbsBeamNorm(1) * (rOut + 0.5 / state.dataWindowManager->scon[0]) / state.dataWindowManager->Rtot +
    7034          24 :                    AbsBeamNorm(2) * (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 0.5 / state.dataWindowManager->scon[1]) /
    7035          24 :                        state.dataWindowManager->Rtot +
    7036          24 :                    AbsBeamNorm(3) *
    7037          24 :                        (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
    7038          24 :                         0.5 / state.dataWindowManager->scon[2]) /
    7039          24 :                        state.dataWindowManager->Rtot +
    7040          24 :                    AbsBeamNorm(4) *
    7041          24 :                        (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
    7042          36 :                         1.0 / state.dataWindowManager->scon[2] + 1.0 / hGapTot(3) + 0.5 / state.dataWindowManager->scon[3]) /
    7043          12 :                        state.dataWindowManager->Rtot; // CR7682
    7044          12 :             SHGC += AbsBeamShadeNorm;
    7045          12 :             SHGC += TSolNorm;
    7046          12 :             break;
    7047           0 :         default:
    7048           0 :             break;
    7049             :         }
    7050        2613 :         NominalConductance = 1.0 / (rOut + Rbare + rIn);
    7051        2613 :     }
    7052             :     //****************************************************************************
    7053             : 
    7054        2613 :     void WindowTempsForNominalCond(EnergyPlusData &state,
    7055             :                                    int const ConstrNum,  // Construction number
    7056             :                                    Array1A<Real64> hgap, // Gap gas conductive conductance (W/m2-K)
    7057             :                                    Real64 const adjRatio // adjusment Ratio to hcin
    7058             :     )
    7059             :     {
    7060             : 
    7061             :         // SUBROUTINE INFORMATION:
    7062             :         //       AUTHOR         F. Winkelmann
    7063             :         //       DATE WRITTEN   September 2000
    7064             :         //       MODIFIED       Nov 2002, FW: increase MaxIterations from 15 to 100, add face
    7065             :         //                       temperature relaxation, and increase convergence tolerance by
    7066             :         //                       a factor of 10 if no convergence after MaxIterations,
    7067             :         //                       all for consistency with SolveForWindowTemperatures.
    7068             :         //                      Mar 2003, FW: increase convergence tolerance from 0.01 to 0.02;
    7069             :         //                       remove redundant relaxation on radiative conductances (both of
    7070             :         //                       these were also done in SolveForWindowTemperatures).
    7071             :         //                      Jan 2009, BG: changed interior convection coefficient correlation to match
    7072             :         //                       ISO 15099.
    7073             :         //                      Feb 2009, BG: extended coefficient to include absorbed radiation
    7074             :         //                       to cover summer conditions for SHGC determination.
    7075             :         //       RE-ENGINEERED  na
    7076             : 
    7077             :         // PURPOSE OF THIS SUBROUTINE:
    7078             :         // This is a shortened form of SolveForWindowTemperatures tailored
    7079             :         // for calculation of the nominal center-of-glass U-value for a window
    7080             :         // construction at ASHRAE winter conditions and for determining conditions at
    7081             :         // summer conditions for calculationg SHGC.
    7082             :         // Evaluates the coefficients Aface and Bface in the system of linear
    7083             :         // algebraic equations
    7084             :         //     Sum    [Aface(i,j)*thetas(j)] = Bface(i), i = 1,nglface
    7085             :         //  j=1,nglface
    7086             :         // where
    7087             :         // nglface = number of glass faces (= 2 * number of layers) and
    7088             :         // thetas(j) = temperature of face j
    7089             : 
    7090             :         // METHODOLOGY EMPLOYED:
    7091             :         // The Aface and Bface coefficients are determined by the equations for
    7092             :         // heat balance at the glass faces. The system of linear equations is solved
    7093             :         // by LU decomposition.
    7094             : 
    7095             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
    7096             : 
    7097             :         // Argument array dimensioning
    7098        2613 :         hgap.dim(5);
    7099             : 
    7100        2613 :         int constexpr MaxIterations(100);  // Maximum allowed number of iterations
    7101        2613 :         Real64 constexpr errtemptol(0.02); // Tolerance on errtemp for convergence
    7102             :         static constexpr std::string_view RoutineName("WindowTempsForNominalCond");
    7103             : 
    7104             :         int i;                  // Counter
    7105        5226 :         Array1D<Real64> hr(10); // Radiative conductance (W/m2-K)
    7106             :         Real64 hcinprev;        // Value of hcin from previous iteration
    7107             :         Real64 d;               // +1 if number of row interchanges is even,
    7108             :         // -1 if odd (in LU decomposition)
    7109        5226 :         Array1D_int indx(10);          // Vector of row permutations in LU decomposition
    7110        5226 :         Array2D<Real64> Aface(10, 10); // Coefficient in equation Aface*thetas = Bface
    7111        5226 :         Array1D<Real64> Bface(10);     // Coefficient in equation Aface*thetas = Bface
    7112             :         int iter;                      // Iteration number
    7113             :         Real64 errtemp;                // Absolute value of sum of face temperature differences
    7114             :         //   between iterations, divided by number of faces
    7115             :         Real64 TmeanFilm;       // mean film temperature
    7116             :         Real64 TmeanFilmKelvin; // mean film temperature for property evaluation
    7117             :         Real64 rho;             // density of (apparently dry) air [kg/m3]
    7118             :         Real64 g;               // acceleration due to gravity [m/s2]
    7119             :         Real64 Height;          // window cavity height [m]
    7120             :         Real64 Cp;              // specific heat of air [J/kg-K]
    7121             :         Real64 lambda;          // thermal conductivity of air [W/m-K]
    7122             :         Real64 mu;              // dynamic viscosity of air [kg/m-s]
    7123             :         Real64 RaH;             // Rayleigh number for cavity height [ Non dim]
    7124             :         Real64 TiltDeg;         // glazing tilt in degrees
    7125             :         Real64 sineTilt;        // sine of glazing tilt
    7126             :         Real64 Nuint;           // Nusselt number for interior surface convection
    7127             : 
    7128        2613 :         iter = 0;
    7129             : 
    7130             :         // Initialize face temperatures
    7131        2613 :         StartingWinTempsForNominalCond(state);
    7132             : 
    7133             :         // Calculate radiative conductance
    7134        2613 :         errtemp = errtemptol * 2.0;
    7135             : 
    7136        2613 :         TiltDeg = 90.0;
    7137             : 
    7138        2613 :         sineTilt = std::sin(TiltDeg * DataGlobalConstants::DegToRadians); // degrees as arg
    7139             : 
    7140       32517 :         while (iter < MaxIterations && errtemp > errtemptol) {
    7141       61304 :             for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
    7142       46352 :                 hr(i) = state.dataWindowManager->emis[i - 1] * state.dataWindowManager->sigma * pow_3(state.dataWindowManager->thetas[i - 1]);
    7143             :                 //! fw 3/4/03 if ( iter >= 1 ) hr(i) = 0.5*(hrprev(i)+hr(i))
    7144             :             }
    7145             : 
    7146       14952 :             Aface = 0.0;
    7147       14952 :             Bface = 0.0;
    7148             : 
    7149             :             // Inside convective film conductance for vertical window
    7150       14952 :             if (iter >= 1) {
    7151       12339 :                 hcinprev = state.dataWindowManager->hcin;
    7152             :             }
    7153             :             // CR7670 BG this next correlation was used for hcin but is not "standard" for windows
    7154             :             //  hcin = 1.31d0*((ABS(thetas(nglface)-tin))**0.3333d0)
    7155             :             // Begin calculating for ISO 15099 method.
    7156             :             // mean film temperature
    7157       29904 :             TmeanFilmKelvin = state.dataWindowManager->tin + 0.25 * (state.dataWindowManager->thetas[state.dataWindowManager->nglface - 1] -
    7158       14952 :                                                                      state.dataWindowManager->tin); // eq. 133 in ISO 15099
    7159       14952 :             TmeanFilm = TmeanFilmKelvin - 273.15;
    7160             :             // the following properties are constants or linear relations for "standard" type reporting
    7161       14952 :             rho = PsyRhoAirFnPbTdbW(state, 101325.0, TmeanFilm, 0.0, RoutineName); // dry air assumption
    7162       14952 :             g = 9.81;
    7163       14952 :             Height = 1.0; // standard window rating practice is to use 1 meter (rather than actual)
    7164             : 
    7165       14952 :             lambda = 2.873E-3 + 7.76E-5 * TmeanFilmKelvin; // Table B.1 in ISO 15099
    7166       14952 :             mu = 3.723E-6 + 4.94E-8 * TmeanFilmKelvin;     // Table B.2 in ISO 15099
    7167       14952 :             Cp = 1002.737 + 1.2324E-2 * TmeanFilmKelvin;   // Table B.3 in ISO 15099
    7168             : 
    7169       44856 :             RaH = (pow_2(rho) * pow_3(Height) * g * Cp *
    7170       14952 :                    (std::abs(state.dataWindowManager->thetas[state.dataWindowManager->nglface - 1] - state.dataWindowManager->tin))) /
    7171       14952 :                   (TmeanFilmKelvin * mu * lambda); // eq 132 in ISO 15099
    7172             : 
    7173       14952 :             Nuint = 0.56 * root_4(RaH * sineTilt); // eq. 135 in ISO 15099 (only need this one because tilt is 90 deg
    7174             : 
    7175       14952 :             state.dataWindowManager->hcin = Nuint * lambda / Height;
    7176             : 
    7177             :             // End calculations for ISO 15099 method.
    7178             : 
    7179       14952 :             if (iter >= 1) state.dataWindowManager->hcin = 0.5 * (hcinprev + state.dataWindowManager->hcin);
    7180             : 
    7181       14952 :             state.dataWindowManager->hcin *= adjRatio;
    7182             : 
    7183       14952 :             ++iter;
    7184             : 
    7185       14952 :             GetHeatBalanceEqCoefMatrixSimple(state, state.dataWindowManager->ngllayer, hr, hgap, Aface, Bface);
    7186             : 
    7187       14952 :             LUdecomposition(state, Aface, state.dataWindowManager->nglface, indx,
    7188             :                             d); // Note that these routines change Aface;
    7189       14952 :             LUsolution(Aface, state.dataWindowManager->nglface, indx,
    7190             :                        Bface); // face temperatures are returned in Bface
    7191             : 
    7192       14952 :             errtemp = 0.0;
    7193       61304 :             for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
    7194       46352 :                 errtemp += std::abs(state.dataWindowManager->thetas[i - 1] - Bface(i)) / state.dataWindowManager->nglface;
    7195             :             }
    7196             : 
    7197       61304 :             for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
    7198       46352 :                 state.dataWindowManager->thetas[i - 1] = 0.5 * (state.dataWindowManager->thetas[i - 1] + Bface(i));
    7199             :             }
    7200             :         }
    7201             : 
    7202             :         // No convergence after MaxIterations; and/or error tolerance
    7203        2613 :         if (errtemp >= 10 * errtemptol) {
    7204             :             // Fatal error: didn't converge
    7205           0 :             ShowFatalError(state,
    7206           0 :                            "Convergence error in WindowTempsForNominalCond for construction " + state.dataConstruction->Construct(ConstrNum).Name);
    7207             :         }
    7208        2613 :     }
    7209             : 
    7210             :     //****************************************************************************
    7211             : 
    7212        2613 :     void StartingWinTempsForNominalCond(EnergyPlusData &state)
    7213             :     {
    7214             : 
    7215             :         // SUBROUTINE INFORMATION:
    7216             :         //       AUTHOR         F. Winkelmann
    7217             :         //       DATE WRITTEN   September 2000
    7218             :         //       MODIFIED       na
    7219             :         //       RE-ENGINEERED  na
    7220             : 
    7221             :         // PURPOSE OF THIS SUBROUTINE:
    7222             :         // Initializes face temperature distribution prior to iteration.
    7223             :         // This is a shortened form of StartingWindowTemps for use in calculating
    7224             :         // the nominal center-of-glass U-value.
    7225             : 
    7226        2613 :         Real64 constexpr hrad(5.3);           // Typical radiative conductance (W/m2-K)
    7227        2613 :         Real64 constexpr hcinStartValue(3.2); // Starting value for inside air film convective
    7228             :         //   conductance (estimated for typical double glazing
    7229             :         //   using 1.31(dT**0.333), where dT =
    7230             :         //   room air temp - inside surface temp = 14.2K)
    7231        2613 :         Real64 constexpr resgap(0.21); // Typical gap resistance (m2-K/W)
    7232             : 
    7233             :         int i;                      // Face counter
    7234        5226 :         Array1D<Real64> rguess(11); // Combined radiative/convective resistance (m2-K/W) of
    7235             :         // inside or outside air film, or gap
    7236             :         Real64 restot; // Total window resistance including outside
    7237             :         //   and inside air films (m2-K/W)
    7238             :         Real64 temdiff; // Inside/outside air temperature difference (K)
    7239             :         Real64 ressum;  // Resistance sum (m2-K/W)
    7240             : 
    7241        2613 :         rguess(1) = 1.0 / (state.dataWindowManager->hcout + hrad);
    7242        2613 :         rguess(state.dataWindowManager->nglface + 1) = 1.0 / (hcinStartValue + hrad);
    7243             : 
    7244        6514 :         for (i = 2; i <= state.dataWindowManager->nglface; i += 2) {
    7245        3901 :             rguess(i) = 1.0 / state.dataWindowManager->scon[i / 2 - 1];
    7246        3901 :             if (i < state.dataWindowManager->nglface) rguess(i + 1) = resgap;
    7247             :         }
    7248        2613 :         restot = 0.0;
    7249             : 
    7250       13028 :         for (i = 1; i <= state.dataWindowManager->nglface + 1; ++i) {
    7251       10415 :             restot += rguess(i);
    7252             :         }
    7253             : 
    7254        2613 :         temdiff = state.dataWindowManager->tin - state.dataWindowManager->tout;
    7255        2613 :         if (std::abs(temdiff) < 0.5) temdiff = 2.0;
    7256        2613 :         ressum = 0.0;
    7257             : 
    7258       10415 :         for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
    7259        7802 :             ressum += rguess(i);
    7260        7802 :             state.dataWindowManager->thetas[i - 1] = (ressum / restot) * temdiff + state.dataWindowManager->tout;
    7261             :         }
    7262        2613 :     }
    7263             : 
    7264             :     //****************************************************************************
    7265             : 
    7266         768 :     void ReportGlass(EnergyPlusData &state)
    7267             :     {
    7268             : 
    7269             :         // SUBROUTINE INFORMATION:
    7270             :         //       AUTHOR         Linda K. Lawrie
    7271             :         //       DATE WRITTEN   March 2000
    7272             :         //       MODIFIED       na
    7273             :         //       RE-ENGINEERED  na
    7274             : 
    7275             :         // PURPOSE OF THIS SUBROUTINE:
    7276             :         // This routine gives a detailed report to the user about
    7277             :         // the calculation parameters for windows and their associated
    7278             :         // materials.
    7279             : 
    7280             :         using General::POLYF;
    7281             : 
    7282             :         using General::ScanForReports;
    7283             :         using WindowComplexManager::CalcComplexWindowThermal;
    7284             :         using WindowComplexManager::UpdateComplexWindows;
    7285             : 
    7286         768 :         static Array1D_string const Roughness({0, 5}, {"VeryRough", "Rough", "MediumRough", "MediumSmooth", "Smooth", "VerySmooth"});
    7287         768 :         static Array1D_string const GasTypeName({0, 4}, {"Custom", "Air", "Argon", "Krypton", "Xenon"});
    7288             : 
    7289         768 :         Real64 TempVar(0.0); // just temporary usage for complex fenestration
    7290             : 
    7291             :         int ThisNum;
    7292             :         int Layer;
    7293             :         int BlNum; // Blind number
    7294             :         int i;
    7295             :         Real64 NominalConductanceWinter; // Nominal center-of-glass conductance of a window construction
    7296             :         // for ASHRAE winter conditions (W/m2-K):
    7297             :         // Inside air temperature = 21.1C (70F)
    7298             :         // Outside air temperature = -17.8C (0F)
    7299             :         // Windspeed = 6.71 m/s (15 mph)
    7300             :         // No solar radiation
    7301             :         Real64 NominalConductanceSummer; // Nominal center-of-glass conductance of a window construction
    7302             :         // for ASHRAE summer conditions (W/m2-K):
    7303             :         // Inside air temperature = 23.9C (75F)
    7304             :         // Outside air temperature = 35.0C (95F)
    7305             :         // Windspeed = 3.35 m/s (7.5 mph)
    7306             :         // 783 W/m2 (248 Btu/h-ft2) incident beam solar radiation normal to glazing
    7307         768 :         Real64 SHGCWinter(0.0); // Center-of-glass solar heat gain coefficient for ASHRAE
    7308         768 :         Real64 SHGCSummer(0.0);
    7309             :         // winter and summer conditions
    7310             :         Real64 TransSolNorm;        // Window construction solar transmittance at normal incidence
    7311             :         Real64 TransVisNorm;        // Window construction visible transmittance at normal incidence
    7312             :         int errFlag;                // Error flag
    7313        1536 :         std::string SolarDiffusing; // 'Yes' if glass is solar diffusing; otherwise 'No' (clear glass)
    7314        1536 :         std::string SpectralDataName;
    7315        1536 :         std::string OpticalDataType;
    7316        1536 :         std::string SlateOrientation;
    7317        1536 :         std::string GapVentType;
    7318             : 
    7319         768 :         ScanForReports(state, "Constructions", state.dataWindowManager->DoReport, "Constructions");
    7320             : 
    7321         768 :         if (std::any_of(state.dataConstruction->Construct.begin(),
    7322         768 :                         state.dataConstruction->Construct.end(),
    7323        4383 :                         [](Construction::ConstructionProps const &e) { return e.TypeIsWindow; }))
    7324         675 :             state.dataWindowManager->HasWindows = true;
    7325         768 :         if (std::any_of(state.dataConstruction->Construct.begin(),
    7326         768 :                         state.dataConstruction->Construct.end(),
    7327        5844 :                         [](Construction::ConstructionProps const &e) { return e.WindowTypeBSDF; }))
    7328           9 :             state.dataWindowManager->HasComplexWindows = true; // Yes, this is a bit different than actually using them.
    7329         768 :         if (std::any_of(state.dataConstruction->Construct.begin(),
    7330         768 :                         state.dataConstruction->Construct.end(),
    7331        5846 :                         [](Construction::ConstructionProps const &e) { return e.WindowTypeEQL; }))
    7332           1 :             state.dataWindowManager->HasEQLWindows = true; // for reporting purpose only
    7333        1327 :         if (state.dataWindowManager->DoReport &&
    7334         335 :             (state.dataWindowManager->HasWindows || state.dataWindowManager->HasComplexWindows || state.dataWindowManager->HasEQLWindows)) {
    7335             :             //                                      Write Descriptions
    7336         261 :             print(state.files.eio,
    7337             :                   "{}\n",
    7338             :                   "! <WindowConstruction>,Construction Name,Index,#Layers,Roughness,Conductance {W/m2-K},Conductance (Before Adjusted) {W/m2-K},"
    7339             :                   "Convection Coefficient Adjustment Ratio,SHGC,"
    7340         261 :                   "Solar Transmittance at Normal Incidence,Visible Transmittance at Normal Incidence");
    7341         261 :             if ((state.dataHeatBal->TotSimpleWindow > 0) || (state.dataHeatBal->W5GlsMat > 0) || (state.dataHeatBal->W5GlsMatAlt > 0))
    7342         255 :                 print(state.files.eio,
    7343             :                       "{}\n",
    7344             :                       "! <WindowMaterial:Glazing>, Material Name, Optical Data Type, Spectral Data Set Name, "
    7345             :                       "Thickness {m}, Solar Transmittance,Front Solar Reflectance, Back Solar Reflectance, Visible "
    7346             :                       "Transmittance, Front Visible Reflectance,Back Visible Reflectance,Infrared Transmittance, "
    7347             :                       "Front Thermal Emissivity, Back Thermal Emissivity,Conductivity {W/m-K},Dirt Factor,Solar "
    7348         255 :                       "Diffusing");
    7349         261 :             if ((state.dataHeatBal->W5GasMat > 0) || (state.dataHeatBal->W5GasMatMixture > 0))
    7350          87 :                 print(state.files.eio, "{}\n", "! <WindowMaterial:Gas>,Material Name,GasType,Thickness {m}");
    7351         261 :             if (state.dataHeatBal->TotShades > 0)
    7352           7 :                 print(state.files.eio,
    7353             :                       "{}\n",
    7354             :                       "! <WindowMaterial:Shade>,Material Name,Thickness {m},Conductivity {W/m-K},Thermal "
    7355           7 :                       "Absorptance,Transmittance,Visible Transmittance,Shade Reflectance");
    7356         261 :             if (state.dataHeatBal->TotScreens > 0)
    7357           2 :                 print(state.files.eio,
    7358             :                       "{}\n",
    7359             :                       "! <WindowMaterial:Screen>,Material Name,Thickness {m},Conductivity {W/m-K},Thermal "
    7360             :                       "Absorptance,Transmittance,Reflectance,Visible Reflectance,Diffuse Reflectance,Diffuse Visible "
    7361           2 :                       "Reflectance,Screen Material Diameter To Spacing Ratio,Screen To GlassDistance {m}");
    7362         261 :             if (state.dataHeatBal->TotBlinds > 0)
    7363          15 :                 print(state.files.eio,
    7364             :                       "{}\n",
    7365             :                       "! <WindowMaterial:Blind>,Material Name,Slat Width {m},Slat Separation {m},Slat Thickness "
    7366             :                       "{m},Slat Angle {deg},Slat Beam Solar Transmittance,Slat Beam Solar Front Reflectance,Blind To "
    7367          15 :                       "Glass Distance {m}");
    7368             : 
    7369         261 :             if (state.dataWindowManager->HasComplexWindows)
    7370           8 :                 print(state.files.eio,
    7371             :                       "{}\n",
    7372             :                       "! <WindowConstruction:Complex>,Construction Name,Index,#Layers,U-factor {W/m2-K},SHGC"
    7373           8 :                       "NFRC Product Type,Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
    7374             : 
    7375         261 :             if (state.dataWindowManager->HasEQLWindows)
    7376           1 :                 print(state.files.eio,
    7377             :                       "{}\n",
    7378             :                       "! <Construction:WindowEquivalentLayer>,Construction Name,Index,#Layers,U-factor {W/m2-K},SHGC, "
    7379           1 :                       "Solar Transmittance at Normal Incidence");
    7380         261 :             if (state.dataHeatBal->W5GlsMatEQL > 0)
    7381           1 :                 print(state.files.eio,
    7382             :                       "{}\n",
    7383             :                       "! <WindowMaterial:Glazing:EquivalentLayer>, Material Name, Optical Data Type, Spectral Data "
    7384             :                       "Set Name, Front Side Beam-Beam Solar Transmittance, Back Side Beam-Beam Solar Transmittance, "
    7385             :                       "Front Side Beam-Beam Solar Reflectance, Back Side Beam-Beam Solar Reflectance, Front Side "
    7386             :                       "Beam-Diffuse Solar Transmittance, Back Side Beam-Diffuse Solar Transmittance, , Front Side "
    7387             :                       "Beam-Diffuse Solar Reflectance, Back Side Beam-Diffuse Solar Reflectance, Diffuse-Diffuse "
    7388             :                       "Solar Transmittance, Front Side Diffuse-Diffuse Solar Reflectance, Back Side Diffuse-Diffuse "
    7389             :                       "Solar Reflectance, Infrared Transmittance, Front Side Infrared Emissivity, Back Side Infrared "
    7390           1 :                       "Emissivity");
    7391         261 :             if (state.dataHeatBal->TotShadesEQL > 0)
    7392           1 :                 print(state.files.eio,
    7393             :                       "{}\n",
    7394             :                       "! <WindowMaterial:Shade:EquivalentLayer>, Material Name, Front Side Beam-Beam Solar "
    7395             :                       "Transmittance, Back Side Beam-Beam Solar Transmittance, Front Side Beam-Diffuse Solar "
    7396             :                       "Transmittance, Back Side Beam-Diffuse Solar Transmittance, , Front Side Beam-Diffuse Solar "
    7397             :                       "Reflectance, Back Side Beam-Diffuse Solar Reflectance, Infrared Transmittance, Front Side "
    7398           1 :                       "Infrared Emissivity, Back Side Infrared Emissivity");
    7399             : 
    7400         261 :             if (state.dataHeatBal->TotDrapesEQL > 0)
    7401           0 :                 print(state.files.eio,
    7402             :                       "{}\n",
    7403             :                       "! <WindowMaterial:Drape:EquivalentLayer>, Material Name, Front Side Beam-Beam Solar "
    7404             :                       "Transmittance, Back Side Beam-Beam Solar Transmittance, Front Side Beam-Diffuse Solar "
    7405             :                       "Transmittance, Back Side Beam-Diffuse Solar Transmittance, , Front Side Beam-Diffuse Solar "
    7406             :                       "Reflectance, Back Side Beam-Diffuse Solar Reflectance, Infrared Transmittance, Front Side "
    7407             :                       "Infrared Emissivity, Back Side Infrared Emissivity, Width of Pleated Fabric, Length of Pleated "
    7408           0 :                       "Fabric");
    7409             : 
    7410         261 :             if (state.dataHeatBal->TotBlindsEQL > 0)
    7411           0 :                 print(state.files.eio,
    7412             :                       "{}\n",
    7413             :                       "! <WindowMaterial:Blind:EquivalentLayer>, Material Name, Slat Orientation, Slat Width, Slat "
    7414             :                       "Separation, Slat Crown, Slat Angle, Front Side Slate Beam-Diffuse Solar Transmittance, Back "
    7415             :                       "Side Slate Beam-Diffuse Solar Transmittance, Front Side Slate Beam-Diffuse Solar Reflectance, "
    7416             :                       "Back Side Slate Beam-Diffuse Solar Reflectance, Slat Diffuse-Diffuse Solar Transmittance, "
    7417             :                       "Front Side Slat Diffuse-Diffuse Solar Reflectance, Back Side Slat Diffuse-Diffuse Solar "
    7418             :                       "Reflectance, Infrared Transmittance, Front Side Infrared Emissivity, Back Side Infrared "
    7419           0 :                       "Emissivity, Slat Angle Control");
    7420         261 :             if (state.dataHeatBal->TotScreensEQL > 0)
    7421           1 :                 print(state.files.eio,
    7422             :                       "{}\n",
    7423             :                       "! <WindowMaterial:Screen:EquivalentLayer>, Material Name, Screen Beam-Beam Solar "
    7424             :                       "Transmittance, Screen Beam-Diffuse Solar Transmittance, Screen Beam-Diffuse Solar Reflectance, "
    7425             :                       "Screen Infrared Transmittance, Screen Infrared Emissivity, Screen Wire Spacing, Screen Wire "
    7426           1 :                       "Diameter");
    7427         261 :             if (state.dataHeatBal->W5GapMatEQL > 0)
    7428           1 :                 print(state.files.eio, "{}\n", "! <WindowMaterial:Gap:EquivalentLayer>, Material Name, GasType, Gap Thickness {m}, Gap Vent Type");
    7429             : 
    7430        3017 :             for (ThisNum = 1; ThisNum <= state.dataHeatBal->TotConstructs; ++ThisNum) {
    7431             : 
    7432        2756 :                 if (state.dataConstruction->Construct(ThisNum).WindowTypeBSDF) {
    7433             : 
    7434          11 :                     i = ThisNum;
    7435          11 :                     CalcComplexWindowThermal(state, 0, i, TempVar, TempVar, TempVar, TempVar, DataBSDFWindow::Condition::Winter);
    7436          11 :                     CalcComplexWindowThermal(state, 0, i, TempVar, TempVar, TempVar, TempVar, DataBSDFWindow::Condition::Summer);
    7437             : 
    7438             :                     static constexpr std::string_view Format_800(" WindowConstruction:Complex,{},{},{},{:.3R},{:.3R}\n");
    7439          44 :                     print(state.files.eio,
    7440             :                           Format_800,
    7441          11 :                           state.dataConstruction->Construct(ThisNum).Name,
    7442             :                           ThisNum,
    7443          11 :                           state.dataConstruction->Construct(ThisNum).TotSolidLayers,
    7444          11 :                           state.dataHeatBal->NominalU(ThisNum),
    7445          11 :                           state.dataConstruction->Construct(ThisNum).SummerSHGC);
    7446             : 
    7447        2745 :                 } else if (state.dataConstruction->Construct(ThisNum).TypeIsWindow) {
    7448             :                     // Calculate for ASHRAE winter and summer conditions:
    7449             :                     // (1) nominal center-of-glass conductance, including inside and outside air films,
    7450             :                     // (2) solar heat gain coefficient (SHGC),
    7451             :                     // (3) solar transmittance at normal incidence, and (4) visible transmittance at normal incidence.
    7452             : 
    7453         663 :                     if (state.dataConstruction->Construct(ThisNum).WindowTypeEQL) {
    7454             :                         // for equivalent layer Window already calculated
    7455             :                         // NominalU(ThisNum)=NominalConductanceWinter
    7456             :                         // Save the SHGC for later use in tabular report IVRS
    7457             :                         // Construct(ThisNum)%SummerSHGC = SHGCSummer
    7458           3 :                         state.dataConstruction->Construct(ThisNum).VisTransNorm = 0.0; // TODO list
    7459             : 
    7460             :                         static constexpr std::string_view Format_799(" Construction:WindowEquivalentLayer,{},{},{},{:.3R},{:.3R},{:.3R}\n");
    7461          15 :                         print(state.files.eio,
    7462             :                               Format_799,
    7463           3 :                               state.dataConstruction->Construct(ThisNum).Name,
    7464             :                               ThisNum,
    7465           3 :                               state.dataConstruction->Construct(ThisNum).TotSolidLayers,
    7466           3 :                               state.dataHeatBal->NominalU(ThisNum),
    7467           3 :                               state.dataConstruction->Construct(ThisNum).SummerSHGC,
    7468           3 :                               state.dataConstruction->Construct(ThisNum).SolTransNorm);
    7469             : 
    7470             :                     } else {
    7471             : 
    7472         660 :                         CalcNominalWindowCond(state, ThisNum, 1, NominalConductanceWinter, SHGCWinter, TransSolNorm, TransVisNorm, errFlag);
    7473             : 
    7474         660 :                         if (errFlag == 1) {
    7475           0 :                             ShowWarningError(state,
    7476           0 :                                              "Window construction " + state.dataConstruction->Construct(ThisNum).Name +
    7477             :                                                  " has an interior or exterior blind");
    7478           0 :                             ShowContinueError(state, "but the corresponding construction without the blind cannot be found.");
    7479           0 :                             ShowContinueError(state, "The ReportGlass entry for this construction will not be printed in eplusout.eio.");
    7480           0 :                             continue;
    7481             :                         }
    7482             : 
    7483             :                         // Skip constructions with between-glass shade/blind until method is worked out to determine
    7484             :                         // nominal conductance and SHGC.
    7485             : 
    7486         665 :                         if (errFlag == 2) {
    7487          15 :                             ShowWarningError(state,
    7488          10 :                                              "Window construction " + state.dataConstruction->Construct(ThisNum).Name +
    7489             :                                                  " has a between-glass shade or blind");
    7490           5 :                             ShowContinueError(state, "The ReportGlass entry for this construction will not be printed in eplusout.eio.");
    7491           5 :                             continue;
    7492             :                         }
    7493             : 
    7494         655 :                         state.dataHeatBal->NominalU(ThisNum) = NominalConductanceWinter;
    7495         655 :                         if (!state.dataConstruction->Construct(ThisNum).WindowTypeEQL) {
    7496         655 :                             CalcNominalWindowCond(state, ThisNum, 2, NominalConductanceSummer, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
    7497             :                         }
    7498             :                         // Save the SHGC for later use in tabular report IVRS
    7499         655 :                         state.dataConstruction->Construct(ThisNum).SummerSHGC = SHGCSummer;
    7500         655 :                         state.dataConstruction->Construct(ThisNum).VisTransNorm = TransVisNorm;
    7501         655 :                         state.dataConstruction->Construct(ThisNum).SolTransNorm = TransSolNorm;
    7502             : 
    7503             :                         static constexpr std::string_view Format_700(" WindowConstruction,{},{},{},{},{:.3R},{:.3R},{:.3R},{:.3R}\n");
    7504        3275 :                         print(state.files.eio,
    7505             :                               Format_700,
    7506         655 :                               state.dataConstruction->Construct(ThisNum).Name,
    7507             :                               ThisNum,
    7508         655 :                               state.dataConstruction->Construct(ThisNum).TotLayers,
    7509         655 :                               Roughness(static_cast<int>(state.dataConstruction->Construct(ThisNum).OutsideRoughness)),
    7510             :                               NominalConductanceWinter,
    7511         655 :                               state.dataHeatBal->NominalUBeforeAdjusted(ThisNum),
    7512         655 :                               state.dataHeatBal->CoeffAdjRatio(ThisNum),
    7513             :                               SHGCSummer,
    7514             :                               TransSolNorm,
    7515             :                               TransVisNorm);
    7516             :                     }
    7517             :                     //    Write(OutputFileConstrainParams, 705)  TRIM(Construct(ThisNum)%Name), SHGCSummer ,TransVisNorm
    7518             : 
    7519        2074 :                     for (i = 1; i <= state.dataConstruction->Construct(ThisNum).TotLayers; ++i) {
    7520        1416 :                         Layer = state.dataConstruction->Construct(ThisNum).LayerPoint(i);
    7521        1416 :                         switch (state.dataMaterial->Material(Layer).Group) {
    7522         347 :                         case DataHeatBalance::MaterialGroup::WindowGas: {
    7523             :                             static constexpr std::string_view Format_702(" WindowMaterial:Gas,{},{},{:.3R}\n");
    7524        1041 :                             print(state.files.eio,
    7525             :                                   Format_702,
    7526         347 :                                   state.dataMaterial->Material(Layer).Name,
    7527         347 :                                   GasTypeName(state.dataMaterial->Material(Layer).GasType(1)),
    7528         347 :                                   state.dataMaterial->Material(Layer).Thickness);
    7529             :                             //! fw CASE(WindowGasMixture)
    7530         347 :                         } break;
    7531          18 :                         case DataHeatBalance::MaterialGroup::Shade: {
    7532             :                             static constexpr std::string_view Format_703(" WindowMaterial:Shade,,{},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
    7533         126 :                             print(state.files.eio,
    7534             :                                   Format_703,
    7535          18 :                                   state.dataMaterial->Material(Layer).Name,
    7536          18 :                                   state.dataMaterial->Material(Layer).Thickness,
    7537          18 :                                   state.dataMaterial->Material(Layer).Conductivity,
    7538          18 :                                   state.dataMaterial->Material(Layer).AbsorpThermal,
    7539          18 :                                   state.dataMaterial->Material(Layer).Trans,
    7540          18 :                                   state.dataMaterial->Material(Layer).TransVis,
    7541          18 :                                   state.dataMaterial->Material(Layer).ReflectShade);
    7542          18 :                         } break;
    7543          12 :                         case DataHeatBalance::MaterialGroup::WindowBlind: {
    7544          12 :                             BlNum = state.dataMaterial->Material(Layer).BlindDataPtr;
    7545             :                             static constexpr std::string_view Format_704(
    7546             :                                 " WindowMaterial:Blind,{},{:.4R},{:.4R},{:.4R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
    7547          96 :                             print(state.files.eio,
    7548             :                                   Format_704,
    7549          12 :                                   state.dataMaterial->Material(Layer).Name,
    7550          12 :                                   state.dataHeatBal->Blind(BlNum).SlatWidth,
    7551          12 :                                   state.dataHeatBal->Blind(BlNum).SlatSeparation,
    7552          12 :                                   state.dataHeatBal->Blind(BlNum).SlatThickness,
    7553          12 :                                   state.dataHeatBal->Blind(BlNum).SlatAngle,
    7554          12 :                                   state.dataHeatBal->Blind(BlNum).SlatTransSolBeamDiff,
    7555          12 :                                   state.dataHeatBal->Blind(BlNum).SlatFrontReflSolBeamDiff,
    7556          12 :                                   state.dataHeatBal->Blind(BlNum).BlindToGlassDist);
    7557          12 :                         } break;
    7558           2 :                         case DataHeatBalance::MaterialGroup::Screen: {
    7559           2 :                             if (state.dataMaterial->Material(Layer).ScreenDataPtr > 0) {
    7560             :                                 static constexpr std::string_view Format_706(
    7561             :                                     " WindowMaterial:Screen,{},{:.5R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
    7562          22 :                                 print(
    7563             :                                     state.files.eio,
    7564             :                                     Format_706,
    7565           2 :                                     state.dataMaterial->Material(Layer).Name,
    7566           2 :                                     state.dataMaterial->Material(Layer).Thickness,
    7567           2 :                                     state.dataMaterial->Material(Layer).Conductivity,
    7568           2 :                                     state.dataMaterial->Material(Layer).AbsorpThermal,
    7569           2 :                                     state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).BmBmTrans,
    7570           2 :                                     state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).ReflectSolBeamFront,
    7571           2 :                                     state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).ReflectVisBeamFront,
    7572           2 :                                     state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).DifReflect,
    7573           2 :                                     state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).DifReflectVis,
    7574           2 :                                     state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).ScreenDiameterToSpacingRatio,
    7575           2 :                                     state.dataMaterial->Material(Layer).WinShadeToGlassDist);
    7576             :                             }
    7577           2 :                         } break;
    7578        1010 :                         case DataHeatBalance::MaterialGroup::WindowGlass:
    7579             :                         case DataHeatBalance::MaterialGroup::WindowSimpleGlazing: {
    7580        1010 :                             SolarDiffusing = "No";
    7581        1010 :                             if (state.dataMaterial->Material(Layer).SolarDiffusing) SolarDiffusing = "Yes";
    7582        1010 :                             OpticalDataType = "SpectralAverage";
    7583        1010 :                             SpectralDataName = "";
    7584        1010 :                             if (state.dataMaterial->Material(Layer).GlassSpectralDataPtr > 0) {
    7585         181 :                                 OpticalDataType = "Spectral";
    7586         181 :                                 SpectralDataName = state.dataHeatBal->SpectralData(state.dataMaterial->Material(Layer).GlassSpectralDataPtr).Name;
    7587             :                             }
    7588        1010 :                             if (state.dataMaterial->Material(Layer).GlassSpectralAndAngle) {
    7589           0 :                                 OpticalDataType = "SpectralAndAngle";
    7590           0 :                                 SpectralDataName =
    7591           0 :                                     state.dataCurveManager->PerfCurve(state.dataMaterial->Material(Layer).GlassSpecAngTransDataPtr).Name + ", " +
    7592           0 :                                     state.dataCurveManager->PerfCurve(state.dataMaterial->Material(Layer).GlassSpecAngFRefleDataPtr).Name + ", " +
    7593           0 :                                     state.dataCurveManager->PerfCurve(state.dataMaterial->Material(Layer).GlassSpecAngBRefleDataPtr).Name;
    7594             :                             }
    7595             :                             static constexpr std::string_view Format_707(
    7596             :                                 " WindowMaterial:Glazing,{},{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{"
    7597             :                                 ":.5R},{:.5R},{:.5R},{:.5R},{:.5R},{}\n");
    7598       13130 :                             print(state.files.eio,
    7599             :                                   Format_707,
    7600        1010 :                                   state.dataMaterial->Material(Layer).Name,
    7601             :                                   OpticalDataType,
    7602             :                                   SpectralDataName,
    7603        1010 :                                   state.dataMaterial->Material(Layer).Thickness,
    7604        1010 :                                   state.dataMaterial->Material(Layer).Trans,
    7605        1010 :                                   state.dataMaterial->Material(Layer).ReflectSolBeamFront,
    7606        1010 :                                   state.dataMaterial->Material(Layer).ReflectSolBeamBack,
    7607        1010 :                                   state.dataMaterial->Material(Layer).TransVis,
    7608        1010 :                                   state.dataMaterial->Material(Layer).ReflectVisBeamFront,
    7609        1010 :                                   state.dataMaterial->Material(Layer).ReflectVisBeamBack,
    7610        1010 :                                   state.dataMaterial->Material(Layer).TransThermal,
    7611        1010 :                                   state.dataMaterial->Material(Layer).AbsorpThermalFront,
    7612        1010 :                                   state.dataMaterial->Material(Layer).AbsorpThermalBack,
    7613        1010 :                                   state.dataMaterial->Material(Layer).Conductivity,
    7614        1010 :                                   state.dataMaterial->Material(Layer).GlassTransDirtFactor,
    7615             :                                   SolarDiffusing);
    7616        1010 :                         } break;
    7617           8 :                         case DataHeatBalance::MaterialGroup::GlassEquivalentLayer: {
    7618           8 :                             OpticalDataType = "SpectralAverage";
    7619           8 :                             SpectralDataName = "";
    7620             :                             static constexpr std::string_view Format_708(
    7621             :                                 " WindowMaterial:Glazing:EquivalentLayer,{},{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}"
    7622             :                                 ",{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}\n");
    7623         120 :                             print(state.files.eio,
    7624             :                                   Format_708,
    7625           8 :                                   state.dataMaterial->Material(Layer).Name,
    7626             :                                   OpticalDataType,
    7627             :                                   SpectralDataName,
    7628           8 :                                   state.dataMaterial->Material(Layer).TausFrontBeamBeam,
    7629           8 :                                   state.dataMaterial->Material(Layer).TausBackBeamBeam,
    7630           8 :                                   state.dataMaterial->Material(Layer).ReflFrontBeamBeam,
    7631           8 :                                   state.dataMaterial->Material(Layer).ReflBackBeamBeam,
    7632           8 :                                   state.dataMaterial->Material(Layer).TausFrontBeamDiff,
    7633           8 :                                   state.dataMaterial->Material(Layer).TausBackBeamDiff,
    7634           8 :                                   state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
    7635           8 :                                   state.dataMaterial->Material(Layer).ReflBackBeamDiff,
    7636           8 :                                   state.dataMaterial->Material(Layer).TausDiffDiff,
    7637           8 :                                   state.dataMaterial->Material(Layer).ReflFrontDiffDiff,
    7638           8 :                                   state.dataMaterial->Material(Layer).ReflBackDiffDiff,
    7639           8 :                                   state.dataMaterial->Material(Layer).TausThermal,
    7640           8 :                                   state.dataMaterial->Material(Layer).EmissThermalFront,
    7641           8 :                                   state.dataMaterial->Material(Layer).EmissThermalBack);
    7642           8 :                         } break;
    7643           2 :                         case DataHeatBalance::MaterialGroup::ShadeEquivalentLayer: {
    7644             :                             static constexpr std::string_view Format_709(
    7645             :                                 " WindowMaterial:Shade:EquivalentLayer,{},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R}\n");
    7646          20 :                             print(state.files.eio,
    7647             :                                   Format_709,
    7648           2 :                                   state.dataMaterial->Material(Layer).Name,
    7649           2 :                                   state.dataMaterial->Material(Layer).TausFrontBeamBeam,
    7650           2 :                                   state.dataMaterial->Material(Layer).TausBackBeamBeam,
    7651           2 :                                   state.dataMaterial->Material(Layer).TausFrontBeamDiff,
    7652           2 :                                   state.dataMaterial->Material(Layer).TausBackBeamDiff,
    7653           2 :                                   state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
    7654           2 :                                   state.dataMaterial->Material(Layer).ReflBackBeamDiff,
    7655           2 :                                   state.dataMaterial->Material(Layer).TausThermal,
    7656           2 :                                   state.dataMaterial->Material(Layer).EmissThermalFront,
    7657           2 :                                   state.dataMaterial->Material(Layer).EmissThermalBack);
    7658           2 :                         } break;
    7659           0 :                         case DataHeatBalance::MaterialGroup::DrapeEquivalentLayer: {
    7660             :                             static constexpr std::string_view Format_710(
    7661             :                                 " WindowMaterial:Drape:EquivalentLayer,{},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},"
    7662             :                                 "{:.4R},{:.4R},{:.5R},{:.5R}\n");
    7663           0 :                             print(state.files.eio,
    7664             :                                   Format_710,
    7665           0 :                                   state.dataMaterial->Material(Layer).Name,
    7666           0 :                                   state.dataMaterial->Material(Layer).TausFrontBeamBeam,
    7667           0 :                                   state.dataMaterial->Material(Layer).TausFrontBeamDiff,
    7668           0 :                                   state.dataMaterial->Material(Layer).TausBackBeamDiff,
    7669           0 :                                   state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
    7670           0 :                                   state.dataMaterial->Material(Layer).ReflBackBeamDiff,
    7671           0 :                                   state.dataMaterial->Material(Layer).TausThermal,
    7672           0 :                                   state.dataMaterial->Material(Layer).EmissThermalFront,
    7673           0 :                                   state.dataMaterial->Material(Layer).EmissThermalBack,
    7674           0 :                                   state.dataMaterial->Material(Layer).PleatedDrapeWidth,
    7675           0 :                                   state.dataMaterial->Material(Layer).PleatedDrapeLength);
    7676           0 :                         } break;
    7677           1 :                         case DataHeatBalance::MaterialGroup::ScreenEquivalentLayer: {
    7678             :                             static constexpr std::string_view Format_711(
    7679             :                                 " WindowMaterial:Screen:EquivalentLayer,{},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R}"
    7680             :                                 ",{:.4R},{:.4R},{:.5R},{:.5R}\n");
    7681          11 :                             print(state.files.eio,
    7682             :                                   Format_711,
    7683           1 :                                   state.dataMaterial->Material(Layer).Name,
    7684           1 :                                   state.dataMaterial->Material(Layer).TausFrontBeamBeam,
    7685           1 :                                   state.dataMaterial->Material(Layer).TausFrontBeamDiff,
    7686           1 :                                   state.dataMaterial->Material(Layer).TausBackBeamDiff,
    7687           1 :                                   state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
    7688           1 :                                   state.dataMaterial->Material(Layer).ReflBackBeamDiff,
    7689           1 :                                   state.dataMaterial->Material(Layer).TausThermal,
    7690           1 :                                   state.dataMaterial->Material(Layer).EmissThermalFront,
    7691           1 :                                   state.dataMaterial->Material(Layer).EmissThermalBack,
    7692           1 :                                   state.dataMaterial->Material(Layer).ScreenWireSpacing,
    7693           1 :                                   state.dataMaterial->Material(Layer).ScreenWireDiameter);
    7694           1 :                         } break;
    7695           0 :                         case DataHeatBalance::MaterialGroup::BlindEquivalentLayer: {
    7696           0 :                             SlateOrientation = "Horizontal";
    7697           0 :                             if (state.dataMaterial->Material(Layer).SlatOrientation == DataWindowEquivalentLayer::Orientation::Vertical) {
    7698           0 :                                 SlateOrientation = "Vertical";
    7699             :                             }
    7700             :                             // Formats
    7701             :                             static constexpr std::string_view Format_712(
    7702             :                                 " WindowMaterial:Blind:EquivalentLayer,{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:."
    7703             :                                 "5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}");
    7704           0 :                             print(state.files.eio,
    7705             :                                   Format_712,
    7706           0 :                                   state.dataMaterial->Material(Layer).Name,
    7707             :                                   SlateOrientation,
    7708           0 :                                   state.dataMaterial->Material(Layer).SlatWidth,
    7709           0 :                                   state.dataMaterial->Material(Layer).SlatSeparation,
    7710           0 :                                   state.dataMaterial->Material(Layer).SlatCrown,
    7711           0 :                                   state.dataMaterial->Material(Layer).SlatAngle,
    7712           0 :                                   state.dataMaterial->Material(Layer).TausFrontBeamDiff,
    7713           0 :                                   state.dataMaterial->Material(Layer).TausBackBeamDiff,
    7714           0 :                                   state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
    7715           0 :                                   state.dataMaterial->Material(Layer).ReflBackBeamDiff,
    7716           0 :                                   state.dataMaterial->Material(Layer).TausDiffDiff,
    7717           0 :                                   state.dataMaterial->Material(Layer).ReflFrontDiffDiff,
    7718           0 :                                   state.dataMaterial->Material(Layer).ReflBackDiffDiff,
    7719           0 :                                   state.dataMaterial->Material(Layer).TausThermal,
    7720           0 :                                   state.dataMaterial->Material(Layer).EmissThermalFront,
    7721           0 :                                   state.dataMaterial->Material(Layer).EmissThermalBack);
    7722           0 :                         } break;
    7723           8 :                         case DataHeatBalance::MaterialGroup::GapEquivalentLayer: {
    7724           8 :                             GapVentType = "Sealed";
    7725           8 :                             if (state.dataMaterial->Material(Layer).GapVentType == 2) {
    7726           0 :                                 GapVentType = "VentedIndoor";
    7727           8 :                             } else if (state.dataMaterial->Material(Layer).GapVentType == 3) {
    7728           0 :                                 GapVentType = "VentedOutdoor";
    7729             :                             }
    7730             :                             static constexpr std::string_view Format_713(" WindowMaterial:Gap:EquivalentLayer,{},{},{:.3R},{}\n");
    7731          24 :                             print(state.files.eio,
    7732             :                                   Format_713,
    7733           8 :                                   state.dataMaterial->Material(Layer).Name,
    7734           8 :                                   GasTypeName(state.dataMaterial->Material(Layer).GasType(1)),
    7735           8 :                                   state.dataMaterial->Material(Layer).Thickness,
    7736             :                                   GapVentType);
    7737           8 :                         } break;
    7738           8 :                         default:
    7739           8 :                             break;
    7740             :                         }
    7741             :                     }
    7742             :                 }
    7743             :             }
    7744             : 
    7745         507 :         } else if (state.dataWindowManager->HasWindows) {
    7746             : 
    7747        3293 :             for (ThisNum = 1; ThisNum <= state.dataHeatBal->TotConstructs; ++ThisNum) {
    7748             : 
    7749        2879 :                 if (!state.dataConstruction->Construct(ThisNum).TypeIsWindow) continue;
    7750         653 :                 if (state.dataConstruction->Construct(ThisNum).WindowTypeEQL) continue; // skip if equivalent layer window
    7751             : 
    7752             :                 // Calculate for ASHRAE winter and summer conditions: (1)nominal center-of-glass conductance,
    7753             :                 // (2) solar heat gain coefficient (SHGC), including inside and outside air films,
    7754             :                 // (3) solar transmittance at normal incidence, and (4) visible transmittance at normal incidence.
    7755             : 
    7756         653 :                 CalcNominalWindowCond(state, ThisNum, 1, NominalConductanceWinter, SHGCWinter, TransSolNorm, TransVisNorm, errFlag);
    7757         653 :                 if (errFlag == 1 || errFlag == 2) continue;
    7758         653 :                 state.dataHeatBal->NominalU(ThisNum) = NominalConductanceWinter;
    7759             :                 // Need to have this because of window assembly reports (Simon)
    7760         653 :                 state.dataConstruction->Construct(ThisNum).SummerSHGC = SHGCSummer;
    7761         653 :                 state.dataConstruction->Construct(ThisNum).VisTransNorm = TransVisNorm;
    7762             :             }
    7763             :         }
    7764         768 :     }
    7765             : 
    7766             :     //*************************************************************************************
    7767             : 
    7768          17 :     void CalcWindowBlindProperties(EnergyPlusData &state)
    7769             :     {
    7770             : 
    7771             :         // SUBROUTINE INFORMATION:
    7772             :         //       AUTHOR         Hans Simmler
    7773             :         //       DATE WRITTEN   July-Aug 1995
    7774             :         //       MODIFIED       Aug 2001 (FCW): adapt to EnergyPlus
    7775             :         //                      Dec 2001 (FCW): add variable slat angle
    7776             :         //       RE-ENGINEERED  na
    7777             : 
    7778             :         // PURPOSE OF THIS SUBROUTINE:
    7779             :         // Calculates solar-optical properties of a window blind
    7780             :         // from slat properties and solar profile angle. Assumes flat slats.
    7781             : 
    7782             :         // METHODOLOGY EMPLOYED:
    7783             :         // The solar profile angle is varied from -90 to +90 deg and slat angle is varied from 0 to 180deg,
    7784             :         // covering the full range of possible profile angles and slat angles.
    7785             :         // (The profile angle is defined as the angle of incidence when the radiation
    7786             :         // source is located in a plane that (1)is perpendicular to the  plane of the blinds [which is
    7787             :         // the same as the window plane] and (2) contains the slat normal vector.)
    7788             : 
    7789             :         // In the time-step calculation,the blind properties vs. profile angle and slat angle
    7790             :         // that are calculated here will be applicable to windows and slats
    7791             :         // of arbitrary orientation, and to arbitrary sun positions, as long as the appropiate
    7792             :         // profile angle is used. The slat angle for a particular window with blinds is determined
    7793             :         // each time step in subroutine WindowShadingManager on the basis of user-specified
    7794             :         // slat control options.
    7795             : 
    7796             :         // REFERENCES:
    7797             :         // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
    7798             :         // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
    7799             : 
    7800             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7801             : 
    7802          34 :         Array1D<Real64> bld_pr(15);     // Slat properties
    7803          34 :         Array1D<Real64> st_lay(16);     // Solar-optical blind/glazing system properties
    7804             :         Real64 sun_el;                  // Solar profile angle (radians)
    7805          34 :         Array1D<Real64> sun_el_deg(37); // Solar profile angle (deg) corresponding to sun_el values
    7806             :         Real64 bld_el;                  // Slat angle (elevation of slat normal vector in plane
    7807             :         //  perpendicular to window and containing the slat normal vector) (radians)
    7808             :         int ISolVis;  // 1 = do solar and IR calculation; 2 = do visible calculation
    7809             :         int IProfAng; // Profile angle index
    7810             :         int BlindNum; // Blind number
    7811             :         int ISlatAng; // Slat angle index
    7812             : 
    7813          37 :         for (BlindNum = 1; BlindNum <= state.dataHeatBal->TotBlinds; ++BlindNum) {
    7814             : 
    7815          20 :             bld_pr(2) = state.dataHeatBal->Blind(BlindNum).SlatWidth;
    7816          20 :             bld_pr(3) = state.dataHeatBal->Blind(BlindNum).SlatSeparation;
    7817             : 
    7818          60 :             for (ISolVis = 1; ISolVis <= 2; ++ISolVis) {
    7819          40 :                 if (ISolVis == 1) { // For solar calculation
    7820          20 :                     bld_pr(4) = 0.0;
    7821          20 :                     bld_pr(5) = 0.0;
    7822          20 :                     bld_pr(6) = 0.0;
    7823          20 :                     bld_pr(7) = state.dataHeatBal->Blind(BlindNum).SlatTransSolBeamDiff;
    7824          20 :                     bld_pr(8) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflSolBeamDiff;
    7825          20 :                     bld_pr(9) = state.dataHeatBal->Blind(BlindNum).SlatBackReflSolBeamDiff;
    7826          20 :                     bld_pr(10) = state.dataHeatBal->Blind(BlindNum).SlatTransSolDiffDiff;
    7827          20 :                     bld_pr(11) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflSolDiffDiff;
    7828          20 :                     bld_pr(12) = state.dataHeatBal->Blind(BlindNum).SlatBackReflSolDiffDiff;
    7829             :                 } else { // For visible calculation
    7830          20 :                     bld_pr(4) = 0.0;
    7831          20 :                     bld_pr(5) = 0.0;
    7832          20 :                     bld_pr(6) = 0.0;
    7833          20 :                     bld_pr(7) = state.dataHeatBal->Blind(BlindNum).SlatTransVisBeamDiff;
    7834          20 :                     bld_pr(8) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflVisBeamDiff;
    7835          20 :                     bld_pr(9) = state.dataHeatBal->Blind(BlindNum).SlatBackReflVisBeamDiff;
    7836          20 :                     bld_pr(10) = state.dataHeatBal->Blind(BlindNum).SlatTransVisDiffDiff;
    7837          20 :                     bld_pr(11) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflVisDiffDiff;
    7838          20 :                     bld_pr(12) = state.dataHeatBal->Blind(BlindNum).SlatBackReflVisDiffDiff;
    7839             :                 }
    7840             :                 // For IR calculation
    7841          40 :                 bld_pr(13) = state.dataHeatBal->Blind(BlindNum).SlatTransIR;
    7842          40 :                 bld_pr(14) = state.dataHeatBal->Blind(BlindNum).SlatFrontEmissIR;
    7843          40 :                 bld_pr(15) = state.dataHeatBal->Blind(BlindNum).SlatBackEmissIR;
    7844             : 
    7845             :                 // Calculate diffuse properties of blind. If blind has variable slat angle, &
    7846             :                 // vary slat angle from 0 to 180 deg in 10-deg steps (for MaxSlatAngs = 19).
    7847             :                 // If blind has fixed slat angle, calculate properties at that angle only.
    7848             : 
    7849         154 :                 for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
    7850             : 
    7851         148 :                     st_lay = 0.0;
    7852         148 :                     if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) {
    7853          34 :                         bld_el = state.dataHeatBal->Blind(BlindNum).SlatAngle * DataGlobalConstants::DegToRadians;
    7854             :                     } else {                                                                     // Variable slat angle
    7855         114 :                         bld_el = (DataGlobalConstants::Pi / (MaxSlatAngs - 1)) * (ISlatAng - 1); // 0 <= bld_el <= 180 deg
    7856             :                     }
    7857         148 :                     BlindOpticsDiffuse(state, BlindNum, ISolVis, bld_pr, bld_el, st_lay);
    7858             : 
    7859         148 :                     if (ISolVis == 1) { // Fill blind diffuse solar and IR properties
    7860          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffTrans(ISlatAng) = st_lay(9);
    7861          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffRefl(ISlatAng) = st_lay(10);
    7862          74 :                         state.dataHeatBal->Blind(BlindNum).SolBackDiffDiffTrans(ISlatAng) = st_lay(11);
    7863          74 :                         state.dataHeatBal->Blind(BlindNum).SolBackDiffDiffRefl(ISlatAng) = st_lay(12);
    7864          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffAbs(ISlatAng) = max(0.0, 1.0 - st_lay(9) - st_lay(10));
    7865          74 :                         state.dataHeatBal->Blind(BlindNum).SolBackDiffAbs(ISlatAng) = max(0.0, 1.0 - st_lay(11) - st_lay(12));
    7866          74 :                         state.dataHeatBal->Blind(BlindNum).IRFrontTrans(ISlatAng) = st_lay(13);
    7867          74 :                         state.dataHeatBal->Blind(BlindNum).IRFrontEmiss(ISlatAng) = st_lay(14);
    7868          74 :                         state.dataHeatBal->Blind(BlindNum).IRBackTrans(ISlatAng) = st_lay(13);
    7869          74 :                         state.dataHeatBal->Blind(BlindNum).IRBackEmiss(ISlatAng) = st_lay(15);
    7870             :                     } else { // Fill blind diffuse visible properties
    7871          74 :                         state.dataHeatBal->Blind(BlindNum).VisFrontDiffDiffTrans(ISlatAng) = st_lay(9);
    7872          74 :                         state.dataHeatBal->Blind(BlindNum).VisFrontDiffDiffRefl(ISlatAng) = st_lay(10);
    7873          74 :                         state.dataHeatBal->Blind(BlindNum).VisBackDiffDiffTrans(ISlatAng) = st_lay(11);
    7874          74 :                         state.dataHeatBal->Blind(BlindNum).VisBackDiffDiffRefl(ISlatAng) = st_lay(12);
    7875             :                     }
    7876             : 
    7877         148 :                     if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
    7878             :                 } // End of slat angle loop
    7879             : 
    7880             :                 // Calculate beam properties of blind. Vary profile angle from -90 to +90 deg in 5-deg steps.
    7881             :                 // If blind has variable slat angle, vary slat angle from 0 to 180 deg in 10-deg steps
    7882             :                 // (for MaxSlatAngs = 19). If blind has fixed slat angle, calculate properties at that angle only.
    7883             : 
    7884        1520 :                 for (IProfAng = 1; IProfAng <= 37; ++IProfAng) {
    7885        1480 :                     sun_el = -DataGlobalConstants::Pi / 2.0 + (DataGlobalConstants::Pi / 36.0) * (IProfAng - 1);
    7886        1480 :                     sun_el_deg(IProfAng) = 57.2958 * sun_el;
    7887             : 
    7888        5698 :                     for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
    7889        5476 :                         st_lay = 0.0;
    7890        5476 :                         if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) {
    7891        1258 :                             bld_el = state.dataHeatBal->Blind(BlindNum).SlatAngle * DataGlobalConstants::DegToRadians;
    7892             :                         } else {                                                                     // Variable slat angle
    7893        4218 :                             bld_el = (DataGlobalConstants::Pi / (MaxSlatAngs - 1)) * (ISlatAng - 1); // 0 <= bld_el <= 180 deg
    7894             :                         }
    7895             : 
    7896             :                         // Beam solar-optical properties of blind for given profile angle and slat angle
    7897             : 
    7898        5476 :                         BlindOpticsBeam(state, BlindNum, bld_pr, bld_el, sun_el, st_lay);
    7899             : 
    7900        5476 :                         if (ISolVis == 1) { // Fill blind beam solar properties
    7901        2738 :                             state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamTrans(ISlatAng, IProfAng) = st_lay(1);
    7902        2738 :                             state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamRefl(ISlatAng, IProfAng) = st_lay(2);
    7903        2738 :                             state.dataHeatBal->Blind(BlindNum).SolBackBeamBeamTrans(ISlatAng, IProfAng) = st_lay(3);
    7904        2738 :                             state.dataHeatBal->Blind(BlindNum).SolBackBeamBeamRefl(ISlatAng, IProfAng) = st_lay(4);
    7905        2738 :                             state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffTrans(ISlatAng, IProfAng) = st_lay(5);
    7906        2738 :                             state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffRefl(ISlatAng, IProfAng) = st_lay(6);
    7907        2738 :                             state.dataHeatBal->Blind(BlindNum).SolBackBeamDiffTrans(ISlatAng, IProfAng) = st_lay(7);
    7908        2738 :                             state.dataHeatBal->Blind(BlindNum).SolBackBeamDiffRefl(ISlatAng, IProfAng) = st_lay(8);
    7909        2738 :                             state.dataHeatBal->Blind(BlindNum).SolFrontBeamAbs(ISlatAng, IProfAng) =
    7910        2738 :                                 max(0.0, 1.0 - st_lay(6) - st_lay(1) - st_lay(5));
    7911        2738 :                             state.dataHeatBal->Blind(BlindNum).SolBackBeamAbs(ISlatAng, IProfAng) = max(0.0, 1.0 - st_lay(7) - st_lay(3) - st_lay(8));
    7912             : 
    7913             :                         } else { // Fill blind beam visible properties
    7914        2738 :                             state.dataHeatBal->Blind(BlindNum).VisFrontBeamBeamTrans(ISlatAng, IProfAng) = st_lay(1);
    7915        2738 :                             state.dataHeatBal->Blind(BlindNum).VisFrontBeamBeamRefl(ISlatAng, IProfAng) = st_lay(2);
    7916        2738 :                             state.dataHeatBal->Blind(BlindNum).VisBackBeamBeamTrans(ISlatAng, IProfAng) = st_lay(3);
    7917        2738 :                             state.dataHeatBal->Blind(BlindNum).VisBackBeamBeamRefl(ISlatAng, IProfAng) = st_lay(4);
    7918        2738 :                             state.dataHeatBal->Blind(BlindNum).VisFrontBeamDiffTrans(ISlatAng, IProfAng) = st_lay(5);
    7919        2738 :                             state.dataHeatBal->Blind(BlindNum).VisFrontBeamDiffRefl(ISlatAng, IProfAng) = st_lay(6);
    7920        2738 :                             state.dataHeatBal->Blind(BlindNum).VisBackBeamDiffTrans(ISlatAng, IProfAng) = st_lay(7);
    7921        2738 :                             state.dataHeatBal->Blind(BlindNum).VisBackBeamDiffRefl(ISlatAng, IProfAng) = st_lay(8);
    7922             :                         }
    7923             : 
    7924        5476 :                         if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
    7925             :                     } // End of loop over slat angles
    7926             :                 }     // End of loop over profile angles
    7927             : 
    7928          40 :                 if (ISolVis == 1) {
    7929          77 :                     for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
    7930          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffTransGnd(ISlatAng) =
    7931         222 :                             DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamTrans(ISlatAng, {1, 37})) +
    7932         148 :                             DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffTrans(ISlatAng, {1, 37}));
    7933          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffTransSky(ISlatAng) =
    7934         222 :                             DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamTrans(ISlatAng, {1, 37})) +
    7935         148 :                             DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffTrans(ISlatAng, {1, 37}));
    7936          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffAbsGnd(ISlatAng) =
    7937         148 :                             DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamAbs(ISlatAng, {1, 37}));
    7938          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffAbsSky(ISlatAng) =
    7939         148 :                             DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamAbs(ISlatAng, {1, 37}));
    7940          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffReflGnd(ISlatAng) =
    7941         148 :                             DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffRefl(ISlatAng, {1, 37}));
    7942          74 :                         state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffReflSky(ISlatAng) =
    7943         148 :                             DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffRefl(ISlatAng, {1, 37}));
    7944             : 
    7945             :                         // TH 2/17/2010. Added. Loop only for movable slat blinds
    7946          74 :                         if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
    7947             :                     }
    7948             :                 }
    7949             : 
    7950             :             } // End of loop over solar vs. visible properties
    7951             : 
    7952             :         } // End of loop over blinds
    7953          17 :     }
    7954             : 
    7955             :     //*************************************************************************************
    7956             : 
    7957           2 :     void CalcWindowScreenProperties(EnergyPlusData &state)
    7958             :     {
    7959             : 
    7960             :         // SUBROUTINE INFORMATION:
    7961             :         //       AUTHOR         Richard Raustad
    7962             :         //       DATE WRITTEN   April 2006
    7963             :         //       MODIFIED       na
    7964             :         //       RE-ENGINEERED  na
    7965             : 
    7966             :         // PURPOSE OF THIS SUBROUTINE:
    7967             :         // Initialize static properties of window screens.
    7968             : 
    7969             :         // METHODOLOGY EMPLOYED:
    7970             :         // Loop through all surfaces to determine which window has an exterior screen. Static
    7971             :         // variables are defined here, dynamic variables are calculated in CalcScreenTransmittance.
    7972             : 
    7973             :         // Locals
    7974             :         // SUBROUTINE PARAMETER DEFINITIONS:
    7975           2 :         int constexpr M(18);
    7976           2 :         int constexpr N(18);
    7977             : 
    7978             :         int SurfNum;     // Index to surface number
    7979             :         int ScreenNum;   // Index to each screen used on exterior of window
    7980             :         int ConstrNumSh; // Index to shaded construction
    7981             :         int MatNum;      // Index to material number
    7982             :         int i;           // Integration loop counters
    7983             :         int j;
    7984             :         Real64 SumTrans;      // Integration variable for transmittance
    7985             :         Real64 SumTransVis;   // Integration variable for visible transmittance
    7986             :         Real64 SumReflect;    // Integration variable for reflectance
    7987             :         Real64 SumReflectVis; // Integration variable for visible reflectance
    7988             :         Real64 SumArea;       // Integration variable for area of quarter hemisphere
    7989             :         bool FoundMaterial;   // Flag to avoid printing screen transmittance data multiple times when Material:WindowScreen
    7990             :         // is used on multiple surfaces
    7991             :         bool PrintTransMap; // Flag used to print transmittance map
    7992             : 
    7993           2 :         constexpr std::array<std::string_view, static_cast<int>(ScreenBeamReflectanceModel::Num)> ScreenBeamReflectanceModelNamesUC{
    7994             :             "DONOTMODEL", "MODELASDIRECTBEAM", "MODELASDIFFUSE"};
    7995             : 
    7996           2 :         state.dataHeatBal->SurfaceScreens.allocate(state.dataHeatBal->NumSurfaceScreens);
    7997           2 :         state.dataHeatBal->ScreenTrans.allocate(state.dataHeatBal->NumSurfaceScreens);
    7998           2 :         ScreenNum = 0;
    7999             : 
    8000             :         // Pre-calculate these constants
    8001           4 :         std::vector<Real64> sunAzimuth;
    8002           4 :         std::vector<Real64> sin_sunAzimuth;
    8003           4 :         std::vector<Real64> cos_sunAzimuth;
    8004           4 :         std::vector<Real64> sunAltitude;
    8005           4 :         std::vector<Real64> sin_sunAltitude;
    8006           4 :         std::vector<Real64> cos_sunAltitude;
    8007           4 :         std::vector<Real64> skyArea;      // Area of integration
    8008           4 :         Array2D<Real64> relativeAzimuth;  // Relative azimuth angle of sun with respect to surface outward normal
    8009           4 :         Array2D<Real64> relativeAltitude; // Relative altitude angle of sun with respect to surface outward normal
    8010             : 
    8011           2 :         relativeAzimuth.allocate(N, M);
    8012           2 :         relativeAltitude.allocate(N, M);
    8013             : 
    8014          38 :         for (j = 0; j <= N - 1; ++j) {
    8015          36 :             Real64 currAzimuth = (90.0 / N) * j * DataGlobalConstants::DegToRadians;
    8016          36 :             sunAzimuth.push_back(currAzimuth); // Azimuth angle of sun during integration
    8017          36 :             sin_sunAzimuth.push_back(std::sin(currAzimuth));
    8018          36 :             cos_sunAzimuth.push_back(std::cos(currAzimuth));
    8019             :         }
    8020             : 
    8021          38 :         for (i = 0; i <= M - 1; ++i) {
    8022          36 :             Real64 currAltitude = (90.0 / M) * i * DataGlobalConstants::DegToRadians;
    8023          36 :             sunAltitude.push_back(currAltitude); // Altitude angle of sun during integration
    8024          36 :             sin_sunAltitude.push_back(std::sin(currAltitude));
    8025          36 :             cos_sunAltitude.push_back(std::cos(currAltitude));
    8026          36 :             skyArea.push_back(sin_sunAltitude[i] * cos_sunAltitude[i]);
    8027             :         }
    8028             : 
    8029          38 :         for (j = 1; j <= N; ++j) {
    8030         684 :             for (i = 1; i <= M; ++i) {
    8031             :                 // Integrate transmittance using coordinate transform
    8032         648 :                 relativeAzimuth(i, j) = std::asin(sin_sunAltitude[i - 1] * cos_sunAzimuth[j - 1]);        // phi prime
    8033         648 :                 relativeAltitude(i, j) = std::atan(std::tan(sunAltitude[i - 1]) * sin_sunAzimuth[j - 1]); // alpha
    8034             :             }
    8035             :         }
    8036             : 
    8037           2 :         PrintTransMap = false;
    8038         192 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    8039             : 
    8040         190 :             if (state.dataSurface->Surface(SurfNum).HasShadeControl) {
    8041          28 :                 ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
    8042          28 :                 MatNum = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1);
    8043             :                 WinShadingType ShadingType =
    8044          28 :                     state.dataSurface->WindowShadingControl(state.dataSurface->Surface(SurfNum).activeWindowShadingControl).ShadingType;
    8045          28 :                 if (ShadingType == WinShadingType::ExtScreen) {
    8046             : 
    8047           8 :                     if (state.dataMaterial->Material(MatNum).ScreenMapResolution > 0) PrintTransMap = true;
    8048           8 :                     ++ScreenNum;
    8049           8 :                     state.dataSurface->SurfWinScreenNumber(SurfNum) = ScreenNum;
    8050             :                     //     If a screen material is used more than once, the Material structure's screen data pointer holds the screen number
    8051             :                     //     of the last window surface. Use this method to access the screen parameter's only for static variables such as
    8052             :                     //     diffuse properties (InitGlassOpticalCalculations). For all cases where the screen properties are a function of
    8053             :                     //     sun azimuth and altitude angles, use the SurfaceScreens structure.
    8054           8 :                     state.dataMaterial->Material(MatNum).ScreenDataPtr = ScreenNum;
    8055           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber = MatNum;
    8056             :                     //     Invert calculation done in GetMaterialInput to find Diameter to Spacing ratio (Props(7)/Props(6))
    8057             :                     //     dataMaterial.Material(MaterNum)%Trans = (1 - MaterialProps(7)/MaterialProps(6))**2.0
    8058           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).ScreenDiameterToSpacingRatio =
    8059           8 :                         1.0 - std::sqrt(state.dataMaterial->Material(MatNum).Trans);
    8060             : 
    8061           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).screenBeamReflectanceModel = static_cast<DataSurfaces::ScreenBeamReflectanceModel>(
    8062          24 :                         getEnumerationValue(ScreenBeamReflectanceModelNamesUC,
    8063          24 :                                             UtilityRoutines::MakeUPPERCase(state.dataMaterial->Material(MatNum).ReflectanceModeling)));
    8064             : 
    8065             :                     // Reflectance of screen material only
    8066           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinder =
    8067           8 :                         state.dataMaterial->Material(MatNum).ReflectShade / (1 - state.dataMaterial->Material(MatNum).Trans);
    8068           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinderVis =
    8069           8 :                         state.dataMaterial->Material(MatNum).ReflectShadeVis / (1 - state.dataMaterial->Material(MatNum).Trans);
    8070             : 
    8071             :                     //     Integrate the transmittance over a quarter hemisphere for use in diffuse calculations
    8072           8 :                     SumTrans = 0.0;
    8073           8 :                     SumTransVis = 0.0;
    8074           8 :                     SumReflect = 0.0;
    8075           8 :                     SumReflectVis = 0.0;
    8076           8 :                     SumArea = 0.0;
    8077             :                     //     Integration over quarter hemisphere in polar coordinates and converting to rectangular to call screen model.
    8078             :                     //     Proceed in reverse order such that the last calculation yields zero sun angle to window screen normal (angles=0,0).
    8079             :                     //     The properties calculated at zero sun angle are then used elsewhere prior to the start of the actual simulation.
    8080             : 
    8081         152 :                     for (j = N; j >= 1; --j) {
    8082        2736 :                         for (i = M; i >= 1; --i) {
    8083             :                             // Integrate transmittance using coordinate transform
    8084        2592 :                             CalcScreenTransmittance(state, 0, relativeAltitude(i, j), relativeAzimuth(i, j), ScreenNum);
    8085        2592 :                             SumTrans +=
    8086        5184 :                                 (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTrans + state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTrans) *
    8087        2592 :                                 skyArea[i - 1];
    8088        7776 :                             SumTransVis += (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTransVis +
    8089        5184 :                                             state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTransVis) *
    8090        2592 :                                            skyArea[i - 1];
    8091        2592 :                             SumReflect += state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectSolBeamFront * skyArea[i - 1];
    8092        2592 :                             SumReflectVis += state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectVisBeamFront * skyArea[i - 1];
    8093        2592 :                             SumArea += skyArea[i - 1];
    8094             :                         }
    8095             :                     }
    8096             : 
    8097             :                     // Reflectance of overall screen including openings and scattered transmittance
    8098           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectScreen =
    8099          16 :                         state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinder *
    8100           8 :                         (1.0 - (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTrans + state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTrans));
    8101           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectScreenVis =
    8102          16 :                         state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinderVis *
    8103           8 :                         (1.0 -
    8104           8 :                          (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTransVis + state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTransVis));
    8105             : 
    8106           8 :                     if (SumArea != 0) {
    8107           8 :                         state.dataHeatBal->SurfaceScreens(ScreenNum).DifDifTrans = SumTrans / SumArea;
    8108           8 :                         state.dataHeatBal->SurfaceScreens(ScreenNum).DifDifTransVis = SumTransVis / SumArea;
    8109           8 :                         state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect = SumReflect / SumArea;
    8110           8 :                         state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflectVis = SumReflectVis / SumArea;
    8111             :                     }
    8112           8 :                     state.dataHeatBal->SurfaceScreens(ScreenNum).DifScreenAbsorp = max(
    8113             :                         0.0,
    8114           8 :                         (1.0 - state.dataHeatBal->SurfaceScreens(ScreenNum).DifDifTrans - state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect));
    8115             : 
    8116           8 :                     state.dataMaterial->Material(MatNum).AbsorpThermalBack = state.dataHeatBal->SurfaceScreens(ScreenNum).DifScreenAbsorp;
    8117           8 :                     state.dataMaterial->Material(MatNum).AbsorpThermalFront = state.dataHeatBal->SurfaceScreens(ScreenNum).DifScreenAbsorp;
    8118           8 :                     state.dataMaterial->Material(MatNum).ReflectSolBeamFront = state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect;
    8119           8 :                     state.dataMaterial->Material(MatNum).ReflectSolBeamBack = state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect;
    8120             : 
    8121             :                 } // (ShadingType == 'EXTERIORSCREEN')
    8122             :             }
    8123             :         } // End of screen surface initialization
    8124             : 
    8125             :         // Write transmittance versus direct normal angle to csv file
    8126             : 
    8127           2 :         if (PrintTransMap) {
    8128             :             // Fortran version did not have error handling in case of file open failure. This one does.
    8129             :             // Which is correct?
    8130           4 :             auto screenCsvFile = state.files.screenCsv.open(state, "CalcWindowScreenComponents", state.files.outputControl.screen);
    8131             : 
    8132             :             //  WRITE(ScreenTransUnitNo,*)' '
    8133          10 :             for (ScreenNum = 1; ScreenNum <= state.dataHeatBal->NumSurfaceScreens; ++ScreenNum) {
    8134           8 :                 MatNum = state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber;
    8135             :                 //   Do not print transmittance map if angle increment is equal to 0
    8136           8 :                 if (state.dataMaterial->Material(MatNum).ScreenMapResolution == 0) continue;
    8137           8 :                 FoundMaterial = false;
    8138          20 :                 for (i = ScreenNum + 1; i <= state.dataHeatBal->NumSurfaceScreens; ++i) {
    8139             :                     //     Write out transmittance data once for each Material:WindowScreen object
    8140          12 :                     if (MatNum == state.dataHeatBal->SurfaceScreens(i).MaterialNumber) FoundMaterial = true;
    8141             :                 }
    8142           8 :                 if (FoundMaterial) continue;
    8143             :                 //   Store transmittance at direct normal angle
    8144           2 :                 if (state.dataMaterial->Material(MatNum).ScreenMapResolution != 0) {
    8145           6 :                     state.dataHeatBal->ScreenTrans(ScreenNum).Trans.allocate(90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1,
    8146           6 :                                                                              90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1);
    8147           6 :                     state.dataHeatBal->ScreenTrans(ScreenNum).Scatt.allocate(90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1,
    8148           6 :                                                                              90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1);
    8149           2 :                     state.dataHeatBal->ScreenTrans(ScreenNum).Trans = 0.0;
    8150           2 :                     state.dataHeatBal->ScreenTrans(ScreenNum).Scatt = 0.0;
    8151          40 :                     for (j = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; j >= 1; --j) {
    8152         760 :                         for (i = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; i >= 1; --i) {
    8153             :                             Real64 SunAzimuth =
    8154         722 :                                 state.dataMaterial->Material(MatNum).ScreenMapResolution * (j - 1) * DataGlobalConstants::DegToRadians;
    8155             :                             Real64 SunAltitude =
    8156         722 :                                 state.dataMaterial->Material(MatNum).ScreenMapResolution * (i - 1) * DataGlobalConstants::DegToRadians;
    8157         722 :                             CalcScreenTransmittance(state, 0, SunAltitude, SunAzimuth, ScreenNum);
    8158         722 :                             state.dataHeatBal->ScreenTrans(ScreenNum).Trans(i, j) = state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTrans;
    8159         722 :                             state.dataHeatBal->ScreenTrans(ScreenNum).Scatt(i, j) = state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTrans;
    8160             :                         }
    8161             :                     }
    8162             : 
    8163           4 :                     print(screenCsvFile,
    8164             :                           "MATERIAL:WINDOWSCREEN:{}\n",
    8165           4 :                           state.dataMaterial->Material(state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber).Name);
    8166           2 :                     print(screenCsvFile,
    8167             :                           "Tabular data for beam solar transmittance at varying \"relative\" azimuth (row) and "
    8168           2 :                           "altitude (column) angles (deg) [relative to surface normal].\n");
    8169           2 :                     print(screenCsvFile, ",90");
    8170          36 :                     for (i = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution; i >= 2; --i) {
    8171          34 :                         print(screenCsvFile, ",{}", (i - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
    8172             :                     }
    8173           2 :                     print(screenCsvFile, ",0\n");
    8174             : 
    8175          40 :                     for (j = 1; j <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; ++j) {
    8176          38 :                         print(screenCsvFile, "{}", (j - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
    8177         722 :                         for (i = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; i >= 2; --i) {
    8178         684 :                             print(screenCsvFile, ",{:.6R}", state.dataHeatBal->ScreenTrans(ScreenNum).Trans(i, j));
    8179             :                         }
    8180          38 :                         print(screenCsvFile, ",{:.6R}\n", state.dataHeatBal->ScreenTrans(ScreenNum).Trans(i, j));
    8181             :                     }
    8182           2 :                     print(screenCsvFile, "\n\n");
    8183             : 
    8184           4 :                     print(screenCsvFile,
    8185             :                           "MATERIAL:WINDOWSCREEN:{}\n",
    8186           4 :                           state.dataMaterial->Material(state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber).Name);
    8187           2 :                     print(screenCsvFile,
    8188             :                           "Tabular data for scattered solar transmittance at varying \"relative\" azimuth (row) and "
    8189           2 :                           "altitude (column) angles (deg) [relative to surface normal].\n");
    8190             : 
    8191          38 :                     for (i = 1; i <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution; ++i) {
    8192          36 :                         print(screenCsvFile, ",{}", (i - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
    8193             :                     }
    8194           2 :                     print(screenCsvFile, ",{}\n", (i - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
    8195             : 
    8196          40 :                     for (j = 1; j <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; ++j) {
    8197          38 :                         print(screenCsvFile, "{}", (j - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
    8198         722 :                         for (i = 1; i <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution; ++i) {
    8199         684 :                             print(screenCsvFile, ",{:.6R}", state.dataHeatBal->ScreenTrans(ScreenNum).Scatt(i, j));
    8200             :                         }
    8201          38 :                         print(screenCsvFile, ",{:.6R}\n", state.dataHeatBal->ScreenTrans(ScreenNum).Scatt(i, j));
    8202             :                     }
    8203           2 :                     print(screenCsvFile, "\n\n");
    8204             :                 }
    8205             :             }
    8206             :         }
    8207           2 :         state.dataHeatBal->ScreenTrans.deallocate();
    8208           2 :     }
    8209             : 
    8210         148 :     void BlindOpticsDiffuse(EnergyPlusData &state,
    8211             :                             int const BlindNum,      // Blind number
    8212             :                             int const ISolVis,       // 1 = solar and IR calculation; 2 = visible calculation
    8213             :                             Array1A<Real64> const c, // Slat properties
    8214             :                             Real64 const b_el,       // Slat elevation (radians)
    8215             :                             Array1A<Real64> p        // Blind properties
    8216             :     )
    8217             :     {
    8218             : 
    8219             :         // SUBROUTINE INFORMATION:
    8220             :         //       AUTHOR         Hans Simmler
    8221             :         //       DATE WRITTEN   July-Aug 1995
    8222             :         //       MODIFIED       Aug 2001 (FCW): adapt to EnergyPlus
    8223             :         //                      Aug 2002 (FCW): make corrections so that calculations are consistent with
    8224             :         //                       G(i) = Sum over j of J(j)*F(j,i). Previously, i,j was
    8225             :         //                      interchanged in F, so that
    8226             :         //                       G(i) = Sum over j of J(j)*F(i,j), which is wrong.
    8227             :         //                      This change was made to resolve discrepancies between EnergyPlus results
    8228             :         //                      and blind transmittance measurements made at Oklahoma State Univ.
    8229             :         //                      Feb 2004 (FCW): modify slat edge correction calc to avoid possible divide by zero
    8230             :         //       RE-ENGINEERED  na
    8231             : 
    8232             :         // PURPOSE OF THIS SUBROUTINE:
    8233             :         // From the slat properties, calculates the diffuse solar, diffuse visible and IR
    8234             :         // transmission and reflection properties of a window blind.
    8235             : 
    8236             :         // METHODOLOGY EMPLOYED:
    8237             :         // na
    8238             : 
    8239             :         // REFERENCES:
    8240             :         // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
    8241             :         // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
    8242             : 
    8243             :         // Argument array dimensioning
    8244         148 :         c.dim(15);
    8245         148 :         p.dim(16);
    8246             : 
    8247             :         Real64 ri; // Front and back IR slat reflectance
    8248             :         Real64 rib;
    8249             :         Real64 phib;                     // Elevation of slat normal vector (radians)
    8250             :         Real64 phis;                     // Source elevation (radians)
    8251             :         Real64 delphis;                  // Angle increment for integration over source distribution (radians)
    8252         296 :         Array1D<Real64> fEdgeSource(10); // Slat edge correction factor vs source elevation
    8253         296 :         Array1D<Real64> fEdgeA(2);       // Average slat edge correction factor for upper and lower quadrants
    8254             :         //  seen by window blind
    8255             :         Real64 gamma; // phib - phis
    8256             :         int Iphis;    // Source elevation counter
    8257             :         int IUpDown;  // =1 for source in upper quadrant, =2 for source in lower quadrant
    8258             :         Real64 fEdge; // Slat edge correction factor
    8259             :         Real64 fEdge1;
    8260         296 :         Array1D<Real64> j(6);       // Slat section radiosity vector
    8261         296 :         Array1D<Real64> G(6);       // Slat section irradiance vector
    8262         296 :         Array1D<Real64> Q(6);       // Slat section radiance vector
    8263         296 :         Array2D<Real64> F(6, 6);    // View factor array
    8264         296 :         Array2D<Real64> X(4, 4);    // Exchange matrix
    8265         296 :         Array2D<Real64> Xinv(4, 4); // Inverse of exchange matrix
    8266             :         int k;                      // Array indices
    8267             :         int m;
    8268         296 :         Array1D_int indx(4);     // LU decomposition indices
    8269             :         Real64 BlindIRreflFront; // Blind front IR reflectance
    8270             :         Real64 BlindIRreflBack;  // Blind back IR reflectance
    8271             : 
    8272             :         // The slat input properties are:
    8273             :         // c(1)    0. (unused)
    8274             :         // c(2)    Slat width (m)
    8275             :         // c(3)    Slat separation (m)
    8276             :         // c(4)    0. (unused)
    8277             :         // c(5)    0. (unused)
    8278             :         // c(6)    0. (unused)
    8279             :         //      The following are solar or visible properties
    8280             :         // c(7)    trans beam-diff
    8281             :         // c(8)    refl front beam-diff
    8282             :         // c(9)    refl back beam-diff
    8283             :         // c(10)   trans diff-diff
    8284             :         // c(11)   refl front diff-diff
    8285             :         // c(12)   refl back diff-diff
    8286             :         //      The following are hemispherical thermal IR properties
    8287             :         // c(13)   trans diff-diff
    8288             :         // c(14)   emiss front diff
    8289             :         // c(15)   emiss back diff
    8290             : 
    8291             :         // The calculated blind properties are:
    8292             :         //      The following are solar or visible properties
    8293             :         // p(1)    trans front beam-beam
    8294             :         // p(2)    refl front beam-beam
    8295             :         // p(3)    trans back beam-beam
    8296             :         // p(4)    refl back beam-beam
    8297             :         // p(5)    trans front beam-diff
    8298             :         // p(6)    refl front beam-diff
    8299             :         // p(7)    trans back beam-diff
    8300             :         // p(8)    refl back beam-diff
    8301             :         // p(9)    trans front diff-diff
    8302             :         // p(10)   refl front diff-diff
    8303             :         // p(11)   trans back diff-diff
    8304             :         // p(12)   refl back diff-diff
    8305             :         //      The following are IR properties
    8306             :         // p(13)   IR trans front (same as IR trans back)
    8307             :         // p(14)   IR emissivity front
    8308             :         // p(15)   IR emissivity back
    8309             :         // p(16)   0.0 (unused)
    8310             : 
    8311             :         //     Calculate view factors between slat sections (slat is divided longitudinally into two equal parts)
    8312             : 
    8313         148 :         ViewFac(c(2), c(3), b_el, DataGlobalConstants::PiOvr2, F);
    8314             : 
    8315             :         //     Set up exchange matrix X for diffuse properties
    8316             : 
    8317         444 :         for (k = 3; k <= 5; k += 2) {
    8318        1480 :             for (m = 3; m <= 6; ++m) {
    8319        1184 :                 X(m - 2, k - 2) = -c(12) * F(k, m) - c(10) * F(k + 1, m);
    8320        1184 :                 X(m - 2, k - 1) = -c(10) * F(k, m) - c(11) * F(k + 1, m);
    8321             :             }
    8322             :         }
    8323             : 
    8324         740 :         for (k = 1; k <= 4; ++k) {
    8325         592 :             ++X(k, k);
    8326             :         }
    8327             : 
    8328         148 :         indx = 0;
    8329         148 :         InvertMatrix(state, X, Xinv, indx, 4, 4); // Autodesk:Note X modified by this call
    8330             : 
    8331             :         //---------Calculate diffuse short-wave properties for the front side of the blind
    8332             : 
    8333             :         //     Sources
    8334             : 
    8335         148 :         Q(3) = c(12) * F(3, 1) + c(10) * F(4, 1);
    8336         148 :         Q(4) = c(10) * F(3, 1) + c(11) * F(4, 1);
    8337         148 :         Q(5) = c(12) * F(5, 1) + c(10) * F(6, 1);
    8338         148 :         Q(6) = c(10) * F(5, 1) + c(11) * F(6, 1);
    8339             : 
    8340             :         //     Radiosities
    8341             : 
    8342         148 :         j(1) = 1.0;
    8343         148 :         j(2) = 0.0;
    8344         740 :         for (k = 3; k <= 6; ++k) {
    8345         592 :             j(k) = 0.0;
    8346        2960 :             for (m = 3; m <= 6; ++m) {
    8347        2368 :                 j(k) += Xinv(m - 2, k - 2) * Q(m);
    8348             :             }
    8349             :         }
    8350             : 
    8351             :         //     Irradiances
    8352             : 
    8353        1036 :         for (k = 1; k <= 6; ++k) {
    8354         888 :             G(k) = 0.0;
    8355        6216 :             for (m = 1; m <= 6; ++m) {
    8356             :                 // G(k)=G(k)+F(k,m)*J(m)
    8357        5328 :                 G(k) += j(m) * F(k, m);
    8358             :             }
    8359             :         }
    8360             : 
    8361             :         //     Slat edge correction factor
    8362         148 :         phib = b_el;
    8363         148 :         delphis = DataGlobalConstants::PiOvr2 / 10.0;
    8364         444 :         for (IUpDown = 1; IUpDown <= 2; ++IUpDown) {
    8365        3256 :             for (Iphis = 1; Iphis <= 10; ++Iphis) {
    8366        2960 :                 phis = -(Iphis - 0.5) * delphis;
    8367        2960 :                 if (IUpDown == 2) phis = (Iphis - 0.5) * delphis;
    8368        2960 :                 fEdgeSource(Iphis) = 0.0;
    8369        2960 :                 fEdge1 = 0.0;
    8370        2960 :                 gamma = phib - phis;
    8371        2960 :                 if (std::abs(std::sin(gamma)) > 0.01) {
    8372        2936 :                     if ((phib > 0.0 && phib <= DataGlobalConstants::PiOvr2 && phis <= phib) ||
    8373        1108 :                         (phib > DataGlobalConstants::PiOvr2 && phib <= DataGlobalConstants::Pi && phis > -(DataGlobalConstants::Pi - phib))) {
    8374        4236 :                         fEdge1 = state.dataHeatBal->Blind(BlindNum).SlatThickness * std::abs(std::sin(gamma)) /
    8375        4236 :                                  ((state.dataHeatBal->Blind(BlindNum).SlatSeparation +
    8376        4236 :                                    state.dataHeatBal->Blind(BlindNum).SlatThickness / std::abs(std::sin(phib))) *
    8377        2118 :                                   std::cos(phis));
    8378             :                     }
    8379        2936 :                     fEdgeSource(Iphis) = min(1.0, std::abs(fEdge1));
    8380             :                 }
    8381             :             }
    8382         296 :             fEdgeA(IUpDown) = DiffuseAverage(fEdgeSource);
    8383             :         }
    8384         148 :         fEdge = 0.5 * (fEdgeA(1) + fEdgeA(2));
    8385             : 
    8386             :         //     Front diffuse-diffuse transmittance (transmittance of slat edge assumed zero)
    8387         148 :         p(9) = G(2) * (1.0 - fEdge);
    8388             : 
    8389             :         //     Front diffuse-diffuse reflectance (edge of slat is assumed to have same diffuse
    8390             :         //     reflectance as front side of slat, c(11))
    8391         148 :         p(10) = G(1) * (1.0 - fEdge) + fEdge * c(11);
    8392             : 
    8393             :         //-----------Calculate diffuse short-wave properties for the back side of the blind
    8394             : 
    8395             :         //     Sources
    8396             : 
    8397         148 :         Q(3) = c(12) * F(3, 2) + c(10) * F(4, 2);
    8398         148 :         Q(4) = c(10) * F(3, 2) + c(11) * F(4, 2);
    8399         148 :         Q(5) = c(12) * F(5, 2) + c(10) * F(6, 2);
    8400         148 :         Q(6) = c(10) * F(5, 2) + c(11) * F(6, 2);
    8401             : 
    8402             :         //     Radiosities
    8403             : 
    8404         148 :         j(1) = 0.0;
    8405         148 :         j(2) = 1.0;
    8406         740 :         for (k = 3; k <= 6; ++k) {
    8407         592 :             j(k) = 0.0;
    8408        2960 :             for (m = 3; m <= 6; ++m) {
    8409        2368 :                 j(k) += Xinv(m - 2, k - 2) * Q(m);
    8410             :             }
    8411             :         }
    8412             : 
    8413             :         //     Irradiances
    8414             : 
    8415        1036 :         for (k = 1; k <= 6; ++k) {
    8416         888 :             G(k) = 0.0;
    8417        6216 :             for (m = 1; m <= 6; ++m) {
    8418             :                 // G(k)=G(k)+F(k,m)*J(m)
    8419        5328 :                 G(k) += j(m) * F(k, m);
    8420             :             }
    8421             :         }
    8422             : 
    8423             :         //     Back diffuse-diffuse transmittance
    8424         148 :         p(11) = G(1) * (1.0 - fEdge);
    8425             : 
    8426             :         //     Back hemi-hemi reflectance
    8427         148 :         p(12) = G(2) * (1.0 - fEdge) + fEdge * c(11);
    8428             : 
    8429         148 :         if (ISolVis == 1) {
    8430             : 
    8431             :             //-----------Calculate IR properties of the blind
    8432             :             //           (use same set of view factors as for diffuse short-wave properties)
    8433             : 
    8434             :             //     Front and back slat IR reflectances
    8435          74 :             ri = 1 - c(13) - c(14);
    8436          74 :             rib = 1 - c(13) - c(15);
    8437             : 
    8438             :             //     Set up exchange matrix X for diffuse properties
    8439             : 
    8440         222 :             for (k = 3; k <= 5; k += 2) {
    8441         740 :                 for (m = 3; m <= 6; ++m) {
    8442         592 :                     X(m - 2, k - 2) = -rib * F(k, m) - c(13) * F(k + 1, m);
    8443         592 :                     X(m - 2, k - 1) = -c(13) * F(k, m) - ri * F(k + 1, m);
    8444             :                 }
    8445             :             }
    8446             : 
    8447         370 :             for (k = 1; k <= 4; ++k) {
    8448         296 :                 ++X(k, k);
    8449             :             }
    8450             : 
    8451          74 :             indx = 0;
    8452          74 :             InvertMatrix(state, X, Xinv, indx, 4, 4); // Autodesk:Note X modified by this call
    8453             : 
    8454             :             //---------Calculate diffuse IR properties for the FRONT side of the blind
    8455             : 
    8456             :             //     Sources
    8457             : 
    8458          74 :             Q(3) = rib * F(3, 1) + c(13) * F(4, 1);
    8459          74 :             Q(4) = c(13) * F(3, 1) + ri * F(4, 1);
    8460          74 :             Q(5) = rib * F(5, 1) + c(13) * F(6, 1);
    8461          74 :             Q(6) = c(13) * F(5, 1) + ri * F(6, 1);
    8462             : 
    8463             :             //     Radiosities
    8464             : 
    8465          74 :             j(1) = 1.0;
    8466          74 :             j(2) = 0.0;
    8467         370 :             for (k = 3; k <= 6; ++k) {
    8468         296 :                 j(k) = 0.0;
    8469        1480 :                 for (m = 3; m <= 6; ++m) {
    8470        1184 :                     j(k) += Xinv(m - 2, k - 2) * Q(m);
    8471             :                 }
    8472             :             }
    8473             : 
    8474             :             //     Irradiances
    8475         518 :             for (k = 1; k <= 6; ++k) {
    8476         444 :                 G(k) = 0.0;
    8477        3108 :                 for (m = 1; m <= 6; ++m) {
    8478             :                     // G(k)=G(k)+F(k,m)*J(m)
    8479        2664 :                     G(k) += j(m) * F(k, m);
    8480             :                 }
    8481             :             }
    8482             : 
    8483             :             //     Front diffuse-diffuse IR transmittance (transmittance of slat edge assumed zero)
    8484          74 :             p(13) = G(2) * (1.0 - fEdge);
    8485             : 
    8486             :             //     Front diffuse-diffuse IR reflectance (edge of slat is assumed to have same IR
    8487             :             //     reflectance as front side of slat, ri)
    8488          74 :             BlindIRreflFront = G(1) * (1.0 - fEdge) + fEdge * ri;
    8489             : 
    8490             :             //     Front IR emissivity
    8491          74 :             p(14) = max(0.0001, 1.0 - p(13) - BlindIRreflFront);
    8492             : 
    8493             :             //-----------Calculate diffuse IR properties for the BACK side of the blind
    8494             : 
    8495             :             //     Sources
    8496             : 
    8497          74 :             Q(3) = rib * F(3, 2) + c(13) * F(4, 2);
    8498          74 :             Q(4) = c(13) * F(3, 2) + ri * F(4, 2);
    8499          74 :             Q(5) = rib * F(5, 2) + c(13) * F(6, 2);
    8500          74 :             Q(6) = c(13) * F(5, 2) + ri * F(6, 2);
    8501             : 
    8502             :             //     Radiosities
    8503             : 
    8504          74 :             j(1) = 0.0;
    8505          74 :             j(2) = 1.0;
    8506         370 :             for (k = 3; k <= 6; ++k) {
    8507         296 :                 j(k) = 0.0;
    8508        1480 :                 for (m = 3; m <= 6; ++m) {
    8509        1184 :                     j(k) += Xinv(m - 2, k - 2) * Q(m);
    8510             :                 }
    8511             :             }
    8512             : 
    8513             :             //     Irradiances
    8514             : 
    8515         518 :             for (k = 1; k <= 6; ++k) {
    8516         444 :                 G(k) = 0.0;
    8517        3108 :                 for (m = 1; m <= 6; ++m) {
    8518             :                     // G(k)=G(k)+F(k,m)*J(m)
    8519        2664 :                     G(k) += j(m) * F(k, m);
    8520             :                 }
    8521             :             }
    8522             : 
    8523             :             //     Back diffuse-diffuse IR reflectance
    8524          74 :             BlindIRreflBack = G(2) * (1.0 - fEdge) + fEdge * ri;
    8525             : 
    8526             :             //     Back IR emissivity
    8527          74 :             p(15) = max(0.0001, 1.0 - p(13) - BlindIRreflBack);
    8528             : 
    8529             :         } // End of IR properties calculation
    8530         148 :     }
    8531             : 
    8532             :     //**********************************************************************************************
    8533             : 
    8534        5476 :     void BlindOpticsBeam(EnergyPlusData &state,
    8535             :                          int const BlindNum,      // Blind number
    8536             :                          Array1A<Real64> const c, // Slat properties (equivalent to BLD_PR)
    8537             :                          Real64 const b_el,       // Slat elevation (radians)
    8538             :                          Real64 const s_el,       // Solar profile angle (radians)
    8539             :                          Array1A<Real64> p        // Blind properties (equivalent to ST_LAY)
    8540             :     )
    8541             :     {
    8542             : 
    8543             :         // SUBROUTINE INFORMATION:
    8544             :         //       AUTHOR         Hans Simmler
    8545             :         //       DATE WRITTEN   July-Aug 1995
    8546             :         //       MODIFIED       Aug 2001 (FCW): adapt to EnergyPlus
    8547             :         //                      Aug 2002 (FCW): make corrections so that calculations are consistent with
    8548             :         //                       G(i) = Sum over j of J(j)*F(j,i). Previously, i,j was
    8549             :         //                      interchanged in F, so that
    8550             :         //                       G(i) = Sum over j of J(j)*F(i,j), which is wrong.
    8551             :         //                      This change was made to resolve discrepancies between EnergyPlus results
    8552             :         //                      and blind transmittance measurements made at Oklahoma State Univ.
    8553             :         //       RE-ENGINEERED  na
    8554             : 
    8555             :         // PURPOSE OF THIS SUBROUTINE:
    8556             :         //     Calculates the beam radiation properties of a
    8557             :         //     window blind consisting of flat slats with known material properties.
    8558             :         //     The calculation for the reverse direction is done with the radiation source
    8559             :         //     reflected at the window plane.
    8560             : 
    8561             :         // REFERENCES:
    8562             :         // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
    8563             :         // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
    8564             : 
    8565             :         using General::BlindBeamBeamTrans; // Blind beam-to-beam transmittance function
    8566             : 
    8567             :         // Argument array dimensioning
    8568        5476 :         c.dim(15);
    8569        5476 :         p.dim(16);
    8570             : 
    8571             :         // The slat input properties are:
    8572             :         // c(1)    0. (unused)
    8573             :         // c(2)    Slat width (m)
    8574             :         // c(3)    Slat separation (m)
    8575             :         // c(4)    0. (unused)
    8576             :         // c(5)    0. (unused)
    8577             :         // c(6)    0. (unused)
    8578             :         //      The following are solar or visible properties
    8579             :         // c(7)    trans beam-diff
    8580             :         // c(8)    refl front beam-diff
    8581             :         // c(9)    refl back beam-diff
    8582             :         // c(10)   trans diff-diff
    8583             :         // c(11)   refl front diff-diff
    8584             :         // c(12)   refl back diff-diff
    8585             :         //      The following are hemispherical thermal IR properties
    8586             :         // c(13)   trans diff-diff
    8587             :         // c(14)   emiss front diff
    8588             :         // c(15)   emiss back diff
    8589             : 
    8590             :         // The calculated blind properties are:
    8591             :         //      The following are solar or visible properties
    8592             :         // p(1)    trans front beam-beam
    8593             :         // p(2)    refl front beam-beam
    8594             :         // p(3)    trans back beam-beam
    8595             :         // p(4)    refl back beam-beam
    8596             :         // p(5)    trans front beam-diff
    8597             :         // p(6)    refl front beam-diff
    8598             :         // p(7)    trans back beam-diff
    8599             :         // p(8)    refl back beam-diff
    8600             :         // p(9)    trans front diff-diff
    8601             :         // p(10)   refl front diff-diff
    8602             :         // p(11)   trans back diff-diff
    8603             :         // p(12)   refl back diff-diff
    8604             :         //      The following are IR properties
    8605             :         // p(13)   IR trans front (same as IR trans back)
    8606             :         // p(14)   IR emissivity front
    8607             :         // p(15)   IR emissivity back
    8608             :         // p(16)   0.0 (unused)
    8609             : 
    8610             :         Real64 phib;                // Elevation angle of normal vector to front of slat (0 to pi radians)
    8611             :         Real64 phis;                // Elevation angle of source vector; same as "profile angle" (-pi/2 to pi/2 radians)
    8612             :         Real64 gamma;               // phib - phis (radians)
    8613       10952 :         Array1D<Real64> j(6);       // Slat surface section radiosity vector
    8614       10952 :         Array1D<Real64> G(6);       // Slat surface section irradiance vector
    8615       10952 :         Array1D<Real64> Q(6);       // Slat surface section source vector
    8616       10952 :         Array2D<Real64> F(6, 6);    // View factor array
    8617       10952 :         Array2D<Real64> X(4, 4);    // X*J = Q
    8618       10952 :         Array2D<Real64> Xinv(4, 4); // J = Xinv*Q
    8619             :         Real64 fEdge;               // Slat edge correction factor
    8620             :         Real64 fEdge1;
    8621             :         int i; // Array indices
    8622             :         int k;
    8623             :         int m;
    8624       10952 :         Array1D_int indx(4); // Indices for LU decomposition
    8625             : 
    8626        5476 :         p = 0.0;
    8627             : 
    8628             :         //     Elevation of radiation source; source is assumed to be in a plane that
    8629             :         //     (1) contains the slat outward normal and (2) is perpendicular to plane of the blinds.
    8630        5476 :         phis = s_el;
    8631             : 
    8632             :         //     Elevation of slat outward normal
    8633        5476 :         phib = b_el;
    8634             : 
    8635             :         //     Loop twice for front and back side properties of blind
    8636       16428 :         for (i = 0; i <= 2; i += 2) {
    8637             : 
    8638             :             //       For back-side properties, reflect the source position so that it is the mirror
    8639             :             //       image of the original source position, where the "mirror" is in the plane of the
    8640             :             //       blinds. This is equivalent to keeping the original source position but rotating
    8641             :             //       the slats so that the original slat angle (e.g., 45 deg) becomes 180 - original slat
    8642             :             //       angle (135 deg).
    8643             : 
    8644       10952 :             if (i == 2) {
    8645        5476 :                 phib = DataGlobalConstants::Pi - phib;
    8646             :             }
    8647             : 
    8648             :             //       Correction factor that accounts for finite thickness of slats. It is used to modify the
    8649             :             //       blind transmittance and reflectance to account for reflection and absorption by the
    8650             :             //       edge of the slat. fEdge is ratio of area subtended by edge of slat
    8651             :             //       to area between tops of adjacent slats.
    8652             : 
    8653       10952 :             fEdge = 0.0;
    8654       10952 :             fEdge1 = 0.0;
    8655       10952 :             gamma = phib - phis;
    8656       10952 :             if (std::abs(std::sin(gamma)) > 0.01) {
    8657       10644 :                 if ((phib > 0.0 && phib <= DataGlobalConstants::PiOvr2 && phis <= phib) ||
    8658        5112 :                     (phib > DataGlobalConstants::PiOvr2 && phib <= DataGlobalConstants::Pi && phis > -(DataGlobalConstants::Pi - phib))) {
    8659       15312 :                     fEdge1 = state.dataHeatBal->Blind(BlindNum).SlatThickness * std::abs(std::sin(gamma)) /
    8660       15312 :                              ((state.dataHeatBal->Blind(BlindNum).SlatSeparation +
    8661       15312 :                                state.dataHeatBal->Blind(BlindNum).SlatThickness / std::abs(std::sin(phib))) *
    8662        7656 :                               std::cos(phis));
    8663             :                 }
    8664       10644 :                 fEdge = min(1.0, std::abs(fEdge1));
    8665             :             }
    8666             : 
    8667             :             //       Direct-to-direct transmittance (portion of beam that passes between slats without
    8668             :             //       without touching them
    8669             : 
    8670       32856 :             p(1 + i) = BlindBeamBeamTrans(phis,
    8671             :                                           phib,
    8672       10952 :                                           state.dataHeatBal->Blind(BlindNum).SlatWidth,
    8673       10952 :                                           state.dataHeatBal->Blind(BlindNum).SlatSeparation,
    8674       10952 :                                           state.dataHeatBal->Blind(BlindNum).SlatThickness);
    8675             :             //       Direct-to-direct reflectance; this is zero for now since all reflection is assumed to be diffuse.
    8676       10952 :             p(2 + i) = 0.0;
    8677             : 
    8678             :             //       View factors between slat sections for calculating direct-to-diffuse transmittance and reflectance
    8679       10952 :             ViewFac(c(2), c(3), phib, phis, F);
    8680             : 
    8681             :             //       Set up exchange matrix X for calculating direct-to-diffuse properties
    8682             : 
    8683       32856 :             for (k = 3; k <= 5; k += 2) {
    8684      109520 :                 for (m = 3; m <= 6; ++m) {
    8685       87616 :                     X(m - 2, k - 2) = -c(12) * F(k, m) - c(10) * F(k + 1, m);
    8686       87616 :                     X(m - 2, k - 1) = -c(10) * F(k, m) - c(11) * F(k + 1, m);
    8687             :                 }
    8688             :             }
    8689             : 
    8690       54760 :             for (k = 1; k <= 4; ++k) {
    8691       43808 :                 ++X(k, k);
    8692             :             }
    8693             : 
    8694       10952 :             indx = 0;
    8695             :             // In the following, note that InvertMatrix changes X
    8696       10952 :             InvertMatrix(state, X, Xinv, indx, 4, 4);
    8697             : 
    8698             :             //       Set up sources for direct-diffuse slat properties
    8699       10952 :             if (std::abs(phis - phib) <= DataGlobalConstants::PiOvr2) { // Beam hits front of slat
    8700        5600 :                 Q(3) = c(4) + c(7);                                     // beam-beam trans of slat + beam-diff trans of slat
    8701        5600 :                 Q(4) = c(5) + c(8);                                     // front beam-beam refl of slat + front beam-diff refl of slat
    8702             :             } else {                                                    // Beam hits back of slat
    8703        5352 :                 Q(3) = c(6) + c(9);                                     // back beam-beam refl of slat  + back beam-diff refl of slat
    8704        5352 :                 Q(4) = c(4) + c(7);                                     // beam-beam trans of slat + beam-diff trans of slat
    8705             :             }
    8706             : 
    8707             :             //       Correct for fraction of beam that is not directly transmitted; 1 - this fraction is
    8708             :             //       the fraction of the incoming beam that is incident on the front or back surfaces of the slats.
    8709       10952 :             Q(3) *= (1.0 - p(1 + i));
    8710       10952 :             Q(4) *= (1.0 - p(1 + i));
    8711             : 
    8712             :             //       Radiosities (radiance of slat sections)
    8713       10952 :             j(1) = 0.0;
    8714       10952 :             j(2) = 0.0;
    8715       54760 :             for (k = 3; k <= 6; ++k) {
    8716       43808 :                 j(k) = 0.0;
    8717      131424 :                 for (m = 3; m <= 4; ++m) {
    8718       87616 :                     j(k) += Xinv(m - 2, k - 2) * Q(m);
    8719             :                 }
    8720             :             }
    8721             : 
    8722             :             //       Irradiance on slat sections
    8723       76664 :             for (k = 1; k <= 6; ++k) {
    8724       65712 :                 G(k) = 0.0;
    8725      328560 :                 for (m = 3; m <= 6; ++m) {
    8726      262848 :                     G(k) += j(m) * F(k, m);
    8727             :                 }
    8728             :             }
    8729             : 
    8730             :             //       Direct-to-diffuse transmittance
    8731       10952 :             p(5 + i) = G(2) * (1.0 - fEdge);
    8732             : 
    8733             :             //       Direct-to-diffuse reflectance (assuming the edge reflectance is the same as the
    8734             :             //       reflectance of the front side of the slat, C(8))
    8735       10952 :             p(6 + i) = G(1) * (1.0 - fEdge) + fEdge * c(8);
    8736             : 
    8737             :         } // End of loop over front and back side properties of blind
    8738        5476 :     }
    8739             : 
    8740             :     //********************************************************************************************
    8741             : 
    8742       11100 :     void ViewFac(Real64 const s,    // Slat width (m)
    8743             :                  Real64 const h,    // Distance between faces of adjacent slats (m)
    8744             :                  Real64 const phib, // Elevation angle of normal to slat (radians)
    8745             :                  Real64 const phis, // Profile angle of radiation source (radians)
    8746             :                  Array2A<Real64> F  // View factor array
    8747             :     )
    8748             :     {
    8749             : 
    8750             :         // SUBROUTINE INFORMATION:
    8751             :         //       AUTHOR         Hans Simmler
    8752             :         //       DATE WRITTEN   July-Aug 1995
    8753             :         //       MODIFIED       Aug 2001 (FCW): adapt to EnergyPlus
    8754             :         //                      Apr 2002 (FCW): prevent sqrt of small negative argument
    8755             :         //       RE-ENGINEERED  na
    8756             : 
    8757             :         // PURPOSE OF THIS SUBROUTINE:
    8758             :         //     Calculates the view factors between sections of adjacent slats,
    8759             :         //     where each slat is divided longitudinally into two equal sections whose
    8760             :         //     dimensions depend on source profile angle and slat geometry. The view
    8761             :         //     factors are used in BlindOpticsBeam and BlindOpticsDiffuse to determine blind
    8762             :         //     transmittance and reflectance for short-wave and long-wave radiation.
    8763             : 
    8764             :         // METHODOLOGY EMPLOYED:
    8765             :         //     Uses expressions for view factor between flat strips with a common edge
    8766             :         //     and flat strips displaced from one another. See engineering documentation.
    8767             : 
    8768             :         // REFERENCES:
    8769             :         // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
    8770             :         // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
    8771             : 
    8772             :         // Argument array dimensioning
    8773       11100 :         F.dim(6, 6);
    8774             : 
    8775       22200 :         Array1D<Real64> L(6); // Length of slat sections: L1 = L2 = h; L3, L5 = length
    8776             :         Real64 L3;
    8777             :         Real64 L5;
    8778             :         //  of upper slat sections; L4, L6 = length of lower slat
    8779             :         //  slat sections (m)
    8780             :         Real64 d1; // Slat geometry variables (m)
    8781             :         Real64 d2;
    8782             :         Real64 d3;
    8783             :         Real64 d4;
    8784             :         Real64 d5;
    8785             :         Real64 d6;
    8786             :         Real64 h2; // h**2
    8787             :         Real64 ht; // 2*h
    8788             :         Real64 w;  // Slat geometry variable (m)
    8789             :         Real64 a;  // Intermediate variable (m)
    8790             :         Real64 co; // Cosine of source profile angle
    8791             :         int i;     // View factor array indices
    8792             :         int j;
    8793             : 
    8794       11100 :         h2 = pow_2(h);
    8795       11100 :         ht = 2.0 * h;
    8796       11100 :         co = std::cos(phis);
    8797       11100 :         if (std::abs(co) < 0.001) co = 0.0;
    8798       11100 :         w = ht;
    8799       11100 :         if (co != 0.0) w = s * std::cos(phib - phis) / co;
    8800       11100 :         L3 = s * h / std::abs(w);
    8801       11100 :         if (L3 > s) L3 = s;
    8802       11100 :         L5 = s - L3;
    8803       11100 :         a = ht * std::cos(phib);
    8804             :         // MAX(0.,...) in the following prevents small negative argument for sqrt
    8805       11100 :         d1 = std::sqrt(max(0.0, s * s + h2 + a * s));
    8806       11100 :         d2 = std::sqrt(max(0.0, s * s + h2 - a * s));
    8807       11100 :         d3 = std::sqrt(max(0.0, L3 * L3 + h2 + a * L3));
    8808       11100 :         d4 = std::sqrt(max(0.0, L3 * L3 + h2 - a * L3));
    8809       11100 :         d5 = std::sqrt(max(0.0, L5 * L5 + h2 - a * L5));
    8810       11100 :         d6 = std::sqrt(max(0.0, L5 * L5 + h2 + a * L5));
    8811       77700 :         for (i = 1; i <= 6; ++i) {
    8812       66600 :             F(i, i) = 0.0;
    8813             :         }
    8814       11100 :         F(1, 1) = 0.0;
    8815       11100 :         F(2, 1) = (d1 + d2 - 2.0 * s) / ht;
    8816       11100 :         F(3, 1) = (h + L3 - d3) / ht;
    8817       11100 :         F(4, 1) = (h + L3 - d4) / ht;
    8818       11100 :         F(5, 1) = (L5 + d3 - d1) / ht;
    8819       11100 :         F(6, 1) = (L5 + d4 - d2) / ht;
    8820       11100 :         F(3, 2) = (L3 + d5 - d2) / ht;
    8821       11100 :         F(4, 2) = (L3 + d6 - d1) / ht;
    8822       11100 :         F(5, 2) = (h + L5 - d5) / ht;
    8823       11100 :         F(6, 2) = (h + L5 - d6) / ht;
    8824       11100 :         F(4, 3) = (d3 + d4 - ht) / (2.0 * L3);
    8825       11100 :         F(5, 3) = 0.0;
    8826       11100 :         F(6, 3) = (d2 + h - d4 - d5) / (2.0 * L3);
    8827       11100 :         F(5, 4) = (d1 + h - d3 - d6) / (2.0 * L3);
    8828       11100 :         F(6, 4) = 0.0;
    8829       11100 :         F(6, 5) = 0.0;
    8830       11100 :         if (L5 > 0.0) F(6, 5) = (d5 + d6 - ht) / (2.0 * L5);
    8831       11100 :         L(1) = h;
    8832       11100 :         L(2) = h;
    8833       11100 :         L(3) = L3;
    8834       11100 :         L(4) = L3;
    8835       11100 :         L(5) = L5;
    8836       11100 :         L(6) = L5;
    8837       66600 :         for (i = 2; i <= 6; ++i) {
    8838      222000 :             for (j = 1; j <= i - 1; ++j) {
    8839      166500 :                 F(j, i) = 0.0;
    8840      166500 :                 if (L(i) > 0.0) F(j, i) = F(i, j) * L(j) / L(i);
    8841             :             }
    8842             :         }
    8843       11100 :     }
    8844             : 
    8845             :     //*****************************************************************************************
    8846             : 
    8847       11174 :     void InvertMatrix(EnergyPlusData &state,
    8848             :                       Array2A<Real64> a, // Matrix to be inverted
    8849             :                       Array2A<Real64> y, // Inverse of matrix a
    8850             :                       Array1A_int indx,  // Index vector for LU decomposition
    8851             :                       int const np,      // Dimension of matrix
    8852             :                       int const n)
    8853             :     {
    8854             : 
    8855             :         // SUBROUTINE INFORMATION:
    8856             :         //       AUTHOR         Hans Simmler
    8857             :         //       DATE WRITTEN   July-Aug 1995
    8858             :         //       MODIFIED       Aug 2001 (FCW): adapt to EnergyPlus
    8859             :         //       RE-ENGINEERED  na
    8860             : 
    8861             :         // PURPOSE OF THIS SUBROUTINE:
    8862             :         //     Inverts a matrix.
    8863             : 
    8864             :         // METHODOLOGY EMPLOYED:
    8865             :         //     Uses LU decomposition.
    8866             : 
    8867             :         // Argument array dimensioning
    8868       11174 :         a.dim(np, np);
    8869       11174 :         y.dim(np, np);
    8870       11174 :         indx.dim(np);
    8871             : 
    8872             :         int i; // Array indices
    8873             :         int j;
    8874             :         int d;
    8875             : 
    8876       11174 :         y = 0.0;
    8877       55870 :         for (i = 1; i <= n; ++i) {
    8878       44696 :             y(i, i) = 1.0;
    8879             :         }
    8880       11174 :         indx = 0;
    8881             : 
    8882       11174 :         LUDCMP(state, a, n, np, indx, d);
    8883             : 
    8884       55870 :         for (j = 1; j <= n; ++j) {
    8885       44696 :             LUBKSB(a, n, np, indx, y(j, 1));
    8886             :         }
    8887       11174 :     }
    8888             : 
    8889             :     //*****************************************************************************************
    8890             : 
    8891       11174 :     void LUDCMP(EnergyPlusData &state,
    8892             :                 Array2A<Real64> A, // matrix
    8893             :                 int const N,
    8894             :                 int const NP,
    8895             :                 Array1A_int INDX,
    8896             :                 int &D)
    8897             :     {
    8898             : 
    8899             :         // SUBROUTINE INFORMATION:
    8900             :         //       AUTHOR         Fred Winkelmann?
    8901             :         //       DATE WRITTEN   <date_written>
    8902             :         //       MODIFIED       na
    8903             :         //       RE-ENGINEERED  na
    8904             : 
    8905             :         // PURPOSE OF THIS SUBROUTINE:
    8906             :         // This subroutine performs a LU decompostion of given matrix.
    8907             : 
    8908             :         // Argument array dimensioning
    8909       11174 :         A.dim(NP, NP);
    8910       11174 :         INDX.dim(N);
    8911             : 
    8912       22348 :         Array1D<Real64> VV(100);
    8913             :         Real64 sum;
    8914             :         Real64 aamax;
    8915             :         Real64 dum;
    8916             :         int i;
    8917             :         int j;
    8918             :         int K;
    8919             :         int imax;
    8920             : 
    8921       11174 :         D = 1;
    8922       55870 :         for (i = 1; i <= N; ++i) {
    8923       44696 :             aamax = 0.0;
    8924      223480 :             for (j = 1; j <= N; ++j) {
    8925      178784 :                 if (std::abs(A(j, i)) > aamax) aamax = std::abs(A(j, i));
    8926             :             }
    8927             : 
    8928       44696 :             if (aamax == 0.0) {
    8929           0 :                 ShowFatalError(state, "Singular matrix in LUDCMP, window calculations");
    8930             :             }
    8931       44696 :             VV(i) = 1.0 / aamax; // Was commented out prior to 10/5/01, which caused overflows
    8932             :             // in this routine in rare cases
    8933             :         }
    8934             : 
    8935       55870 :         for (j = 1; j <= N; ++j) {
    8936       44696 :             if (j > 1) {
    8937      100566 :                 for (i = 1; i <= j - 1; ++i) {
    8938       67044 :                     sum = A(j, i);
    8939       67044 :                     if (i > 1) {
    8940       78218 :                         for (K = 1; K <= i - 1; ++K) {
    8941       44696 :                             sum -= A(K, i) * A(j, K);
    8942             :                         }
    8943             : 
    8944       33522 :                         A(j, i) = sum;
    8945             :                     }
    8946             :                 }
    8947             :             }
    8948       44696 :             aamax = 0.0;
    8949      156436 :             for (i = j; i <= N; ++i) {
    8950      111740 :                 sum = A(j, i);
    8951      111740 :                 if (j > 1) {
    8952      178784 :                     for (K = 1; K <= j - 1; ++K) {
    8953      111740 :                         sum -= A(K, i) * A(j, K);
    8954             :                     }
    8955       67044 :                     A(j, i) = sum;
    8956             :                 }
    8957             : 
    8958      111740 :                 dum = VV(i) * std::abs(sum);
    8959      111740 :                 if (dum >= aamax) {
    8960       44696 :                     imax = i;
    8961       44696 :                     aamax = dum;
    8962             :                 }
    8963             :             }
    8964             : 
    8965       44696 :             if (j != imax) {
    8966           0 :                 for (K = 1; K <= N; ++K) {
    8967           0 :                     dum = A(K, imax);
    8968           0 :                     A(K, imax) = A(K, j);
    8969           0 :                     A(K, j) = dum;
    8970             :                 }
    8971             : 
    8972           0 :                 D = -D;
    8973           0 :                 VV(imax) = VV(j);
    8974             :             }
    8975             : 
    8976       44696 :             INDX(j) = imax;
    8977       44696 :             if (j != N) {
    8978       33522 :                 if (A(j, j) == 0.0) A(j, j) = DataGlobalConstants::rTinyValue;
    8979             : 
    8980       33522 :                 dum = 1.0 / A(j, j);
    8981      100566 :                 for (i = j + 1; i <= N; ++i) {
    8982       67044 :                     A(j, i) *= dum;
    8983             :                 }
    8984             :             }
    8985             :         }
    8986             : 
    8987       11174 :         if (A(N, N) == 0.0) A(N, N) = DataGlobalConstants::rTinyValue;
    8988       11174 :     }
    8989             : 
    8990             :     //*****************************************************************************************
    8991             : 
    8992       44696 :     void LUBKSB(Array2A<Real64> A, int const N, int const NP, Array1A_int INDX, Array1A<Real64> B)
    8993             :     {
    8994             : 
    8995             :         // SUBROUTINE INFORMATION:
    8996             :         //       AUTHOR         <author>
    8997             :         //       DATE WRITTEN   <date_written>
    8998             :         //       MODIFIED       na
    8999             :         //       RE-ENGINEERED  na
    9000             : 
    9001             :         // PURPOSE OF THIS SUBROUTINE:
    9002             :         // This subroutine performs back substitution of a LU matrix.
    9003             : 
    9004             :         // Argument array dimensioning
    9005       44696 :         A.dim(NP, NP);
    9006       44696 :         INDX.dim(N);
    9007       44696 :         B.dim(N);
    9008             : 
    9009             :         int j;
    9010             :         int i;
    9011             :         int ii;
    9012             :         int LL;
    9013             :         Real64 sum;
    9014             : 
    9015       44696 :         ii = 0;
    9016             : 
    9017      223480 :         for (i = 1; i <= N; ++i) {
    9018      178784 :             LL = INDX(i);
    9019      178784 :             sum = B(LL);
    9020      178784 :             B(LL) = B(i);
    9021      178784 :             if (ii != 0) {
    9022      178784 :                 for (j = ii; j <= i - 1; ++j) {
    9023      111740 :                     sum -= A(j, i) * B(j);
    9024             :                 }
    9025      111740 :             } else if (sum != 0.0) {
    9026       44696 :                 ii = i;
    9027             :             }
    9028             : 
    9029      178784 :             B(i) = sum;
    9030             :         }
    9031             : 
    9032      223480 :         for (i = N; i >= 1; --i) {
    9033      178784 :             sum = B(i);
    9034      178784 :             if (i < N) {
    9035      402264 :                 for (j = i + 1; j <= N; ++j) {
    9036      268176 :                     sum -= A(j, i) * B(j);
    9037             :                 }
    9038             :             }
    9039             : 
    9040      178784 :             B(i) = sum / A(i, i);
    9041             :         }
    9042       44696 :     }
    9043             : 
    9044             :     // added for custom solar or visible spectrum
    9045             : 
    9046         771 :     void CheckAndReadCustomSprectrumData(EnergyPlusData &state)
    9047             :     {
    9048             : 
    9049             :         // SUBROUTINE INFORMATION:
    9050             :         //       AUTHOR         T. Hong
    9051             :         //       DATE WRITTEN   August 2013
    9052             :         //       MODIFIED
    9053             :         //       RE-ENGINEERED  na
    9054             : 
    9055             :         // PURPOSE OF THIS SUBROUTINE:
    9056             :         // Check, read, and assign the custom solar or visible spectrum to:
    9057             :         //  solar: nume, wle(nume), e(nume). nume = 107
    9058             :         //  visible: numt3, wlt3(numt3), y30(numt3). numt3 = 81
    9059             :         // Three related IDD objects:
    9060             :         //  EnergyManagementSystem:ConstructionIndexVariable
    9061             :         //  Site:SolarAndVisibleSpectrum, Site:SpectrumData
    9062             : 
    9063             :         // METHODOLOGY EMPLOYED:
    9064             :         // Overwriting the default values
    9065             : 
    9066             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9067         771 :         bool ErrorsFound(false); // If errors detected in input
    9068             :         int NumAlphas;           // Number of Alphas for each GetobjectItem call
    9069             :         int NumNumbers;          // Number of Numbers for each GetobjectItem call
    9070             :         int NumArgs;
    9071             :         int IOStatus;
    9072         772 :         Array1D_string cAlphaArgs;    // Alpha input items for object
    9073         772 :         Array1D<Real64> rNumericArgs; // Numeric input items for object
    9074             : 
    9075         772 :         std::string cCurrentModuleObject;
    9076         772 :         std::string cSolarSpectrum;
    9077         772 :         std::string cVisibleSpectrum;
    9078         771 :         int iSolarSpectrum(0);
    9079         771 :         int iVisibleSpectrum(0);
    9080         771 :         int NumSiteSpectrum(0);
    9081             :         int Loop;
    9082             :         int iTmp;
    9083             : 
    9084         771 :         if (state.dataWindowManager->RunMeOnceFlag) return;
    9085             : 
    9086             :         // Step 1 - check whether there is custom solar or visible spectrum
    9087         771 :         cCurrentModuleObject = "Site:SolarAndVisibleSpectrum";
    9088         771 :         NumSiteSpectrum = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    9089             : 
    9090             :         // no custom spectrum data, done!
    9091         771 :         if (NumSiteSpectrum == 0) {
    9092         770 :             state.dataWindowManager->RunMeOnceFlag = true;
    9093         770 :             return;
    9094             :         }
    9095             : 
    9096             :         // read custom spectrum data from Site:SolarAndVisibleSpectrum
    9097           1 :         if (NumSiteSpectrum > 1) { // throw error
    9098           0 :             ShowSevereError(state, "Only one " + cCurrentModuleObject + " object is allowed");
    9099           0 :             ErrorsFound = true;
    9100             :         }
    9101             : 
    9102           1 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
    9103           1 :         cAlphaArgs.allocate(NumAlphas);
    9104           1 :         rNumericArgs.dimension(NumNumbers, 0.0);
    9105             : 
    9106           1 :         if (NumSiteSpectrum == 1) {
    9107           3 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    9108             :                                                                      cCurrentModuleObject,
    9109             :                                                                      1,
    9110           1 :                                                                      state.dataIPShortCut->cAlphaArgs,
    9111             :                                                                      NumAlphas,
    9112           1 :                                                                      state.dataIPShortCut->rNumericArgs,
    9113             :                                                                      NumNumbers,
    9114             :                                                                      IOStatus);
    9115             : 
    9116             :             // use default spectrum data, done!
    9117           1 :             if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(2), "Default")) {
    9118           0 :                 state.dataWindowManager->RunMeOnceFlag = true;
    9119           0 :                 return;
    9120             :             }
    9121             : 
    9122             :             // now read custom solar and visible spectrum data
    9123           1 :             cSolarSpectrum = state.dataIPShortCut->cAlphaArgs(3);
    9124           1 :             cVisibleSpectrum = state.dataIPShortCut->cAlphaArgs(4);
    9125             : 
    9126           1 :             cCurrentModuleObject = "Site:SpectrumData";
    9127           1 :             NumSiteSpectrum = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    9128           1 :             if (NumSiteSpectrum == 0) { // throw error
    9129           0 :                 ShowSevereError(state, "No " + cCurrentModuleObject + " object is found");
    9130           0 :                 ErrorsFound = true;
    9131             :             }
    9132             : 
    9133           1 :             cAlphaArgs.deallocate();
    9134           1 :             rNumericArgs.deallocate();
    9135             : 
    9136           1 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
    9137           1 :             cAlphaArgs.allocate(NumAlphas);
    9138           1 :             rNumericArgs.dimension(NumNumbers, 0.0);
    9139             : 
    9140           1 :             iSolarSpectrum = 0;
    9141           1 :             iVisibleSpectrum = 0;
    9142           2 :             for (Loop = 1; Loop <= NumSiteSpectrum; ++Loop) {
    9143             :                 // Step 2 - read user-defined spectrum data
    9144           6 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    9145             :                                                                          cCurrentModuleObject,
    9146             :                                                                          Loop,
    9147           2 :                                                                          state.dataIPShortCut->cAlphaArgs,
    9148             :                                                                          NumAlphas,
    9149           2 :                                                                          state.dataIPShortCut->rNumericArgs,
    9150             :                                                                          NumNumbers,
    9151             :                                                                          IOStatus);
    9152           2 :                 if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(1), cSolarSpectrum)) {
    9153           1 :                     iSolarSpectrum = Loop;
    9154             :                     // overwrite the default solar spectrum
    9155           1 :                     if (NumNumbers > 2 * state.dataWindowManager->nume) {
    9156           0 :                         ShowSevereError(state,
    9157           0 :                                         "Solar spectrum data pair is more than 107 - " + cCurrentModuleObject + " - " +
    9158           0 :                                             state.dataIPShortCut->cAlphaArgs(1));
    9159           0 :                         ErrorsFound = true;
    9160             :                     } else {
    9161             :                         // Step 3 - overwrite default solar spectrum data
    9162         108 :                         for (iTmp = 1; iTmp <= state.dataWindowManager->nume; ++iTmp) {
    9163         107 :                             if (iTmp <= NumNumbers / 2) {
    9164         107 :                                 state.dataWindowManager->wle[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp - 1);
    9165         107 :                                 state.dataWindowManager->e[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp);
    9166             :                             } else {
    9167           0 :                                 state.dataWindowManager->wle[iTmp - 1] = 0.0;
    9168           0 :                                 state.dataWindowManager->e[iTmp - 1] = 0.0;
    9169             :                             }
    9170             :                         }
    9171             :                     }
    9172             :                 }
    9173           2 :                 if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(1), cVisibleSpectrum)) {
    9174           1 :                     iVisibleSpectrum = Loop;
    9175             :                     // overwrite the default solar spectrum
    9176           1 :                     if (NumNumbers > 2 * state.dataWindowManager->numt3) {
    9177           0 :                         ShowSevereError(state,
    9178           0 :                                         "Visible spectrum data pair is more than 81 - " + cCurrentModuleObject + " - " +
    9179           0 :                                             state.dataIPShortCut->cAlphaArgs(1));
    9180           0 :                         ErrorsFound = true;
    9181             :                     } else {
    9182             :                         // Step 3 - overwrite default visible spectrum data
    9183          82 :                         for (iTmp = 1; iTmp <= state.dataWindowManager->numt3; ++iTmp) {
    9184          81 :                             if (iTmp <= NumNumbers / 2) {
    9185          81 :                                 state.dataWindowManager->wlt3[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp - 1);
    9186          81 :                                 state.dataWindowManager->y30[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp);
    9187             :                             } else {
    9188           0 :                                 state.dataWindowManager->wlt3[iTmp - 1] = 0.0;
    9189           0 :                                 state.dataWindowManager->y30[iTmp - 1] = 0.0;
    9190             :                             }
    9191             :                         }
    9192             :                     }
    9193             :                 }
    9194           2 :                 if ((iSolarSpectrum > 0) && (iVisibleSpectrum > 0)) break;
    9195             :             }
    9196             :         }
    9197             : 
    9198           1 :         cAlphaArgs.deallocate();
    9199           1 :         rNumericArgs.deallocate();
    9200             : 
    9201           1 :         if (ErrorsFound) {
    9202           0 :             ShowFatalError(state, "Errors found in processing input for user-defined solar/visible spectrum");
    9203             :         }
    9204             : 
    9205           1 :         state.dataWindowManager->RunMeOnceFlag = true;
    9206             :     }
    9207             : 
    9208             :     //*****************************************************************************************
    9209             : 
    9210         771 :     void initWindowModel(EnergyPlusData &state)
    9211             :     {
    9212        1542 :         const std::string objectName = "WindowsCalculationEngine";
    9213         771 :         state.dataWindowManager->inExtWindowModel = CWindowModel::WindowModelFactory(state, objectName);
    9214         771 :         state.dataWindowManager->winOpticalModel = CWindowOpticalModel::WindowOpticalModelFactory(state);
    9215         771 :     }
    9216             : 
    9217             :     //*****************************************************************************************
    9218             : 
    9219             : } // namespace WindowManager
    9220             : 
    9221        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13