LCOV - code coverage report
Current view: top level - EnergyPlus - Material.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1099 1814 60.6 %
Date: 2024-08-23 23:50:59 Functions: 5 6 83.3 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // ObjexxFCL Headers
      49             : #include <ObjexxFCL/Array.functions.hh>
      50             : 
      51             : // EnergyPlus Headers
      52             : #include <EnergyPlus/CurveManager.hh>
      53             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      54             : #include <EnergyPlus/DataEnvironment.hh>
      55             : #include <EnergyPlus/DataHeatBalance.hh>
      56             : #include <EnergyPlus/DataIPShortCuts.hh>
      57             : #include <EnergyPlus/EMSManager.hh>
      58             : #include <EnergyPlus/General.hh>
      59             : #include <EnergyPlus/GlobalNames.hh>
      60             : #include <EnergyPlus/HeatBalanceManager.hh>
      61             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      62             : #include <EnergyPlus/Material.hh>
      63             : #include <EnergyPlus/ScheduleManager.hh>
      64             : #include <EnergyPlus/UtilityRoutines.hh>
      65             : 
      66             : namespace EnergyPlus::Material {
      67             : 
      68             : constexpr std::array<std::string_view, (int)GapVentType::Num> gapVentTypeNames = {"Sealed", "VentedIndoor", "VentedOutdoor"};
      69             : constexpr std::array<std::string_view, (int)GasType::Num> gasTypeNames = {"Custom", "Air", "Argon", "Krypton", "Xenon"};
      70             : constexpr std::array<std::string_view, (int)GasType::Num> gasTypeNamesUC = {"CUSTOM", "AIR", "ARGON", "KRYPTON", "XENON"};
      71             : constexpr std::array<std::string_view, (int)SurfaceRoughness::Num> surfaceRoughnessNames = {
      72             :     "VeryRough", "Rough", "MediumRough", "MediumSmooth", "Smooth", "VerySmooth"};
      73             : 
      74             : constexpr std::array<Material::Gas, 10> gases = {
      75             :     Gas(),                                                                                                        // Empty
      76             :     {GasType::Air, {2.873e-3, 7.760e-5, 0.0}, {3.723e-6, 4.940e-8, 0.0}, {1002.737, 1.2324e-2, 0.0}, 28.97, 1.4}, // Air
      77             :     {GasType::Argon, {2.285e-3, 5.149e-5, 0.0}, {3.379e-6, 6.451e-8, 0.0}, {521.929, 0.0, 0.0}, 39.948, 1.67},    // Argon
      78             :     {GasType::Krypton, {9.443e-4, 2.826e-5, 0.0}, {2.213e-6, 7.777e-8, 0.0}, {248.091, 0.0, 0.0}, 83.8, 1.68},    // Krypton
      79             :     {GasType::Xenon, {4.538e-4, 1.723e-5, 0.0}, {1.069e-6, 7.414e-8, 0.0}, {158.340, 0.0, 0.0}, 131.3, 1.66},     // Xenon
      80             :     Gas(),                                                                                                        // Empty
      81             :     Gas(),                                                                                                        // Empty
      82             :     Gas(),                                                                                                        // Empty
      83             :     Gas(),                                                                                                        // Empty
      84             :     Gas()                                                                                                         // Empty
      85             : };
      86             : 
      87         796 : void GetMaterialData(EnergyPlusData &state, bool &ErrorsFound) // set to true if errors found in input
      88             : {
      89             : 
      90             :     // SUBROUTINE INFORMATION:
      91             :     //       AUTHOR         Richard Liesen
      92             :     //       DATE WRITTEN   September 1997
      93             :     //       MODIFIED       April 1999; L.Lawrie
      94             :     //                      Sept 1999, FCW, Window5 modifications
      95             :     //                      Mar 2001, FCW, WindowShade mods
      96             :     //                      Sep 2001, FCW, add Material:WindowGasMixture
      97             :     //                      Oct 2001, FCW, add Material:WindowBlind
      98             :     //                      Dec 2003, FCW, add glass solar/visible transmittance dirt factor
      99             :     //                      Feb 2009, TH, added WindowMaterial:GlazingGroup:Thermochromic
     100             : 
     101             :     //       RE-ENGINEERED  na
     102             : 
     103             :     // PURPOSE OF THIS SUBROUTINE:
     104             :     // The purpose of this subroutine is to serve as a transfer agent
     105             :     // between the input file and the material derived type.  The new input
     106             :     // file is working, and this file reads the material data directly
     107             :     // from the input file and transfer that information to the new data
     108             :     // structure.  Data read in this routine is stored in a
     109             :     // derived type (Material) defined in the DataHeatBalance module.
     110             : 
     111             :     // In April 1999, a new set of material definitions replaced the one "all-purpose"
     112             :     // material definition.  There are now 10 flavors of materials.  Definitions from
     113             :     // the IDD appear below before their counterpart "gets".
     114             : 
     115             :     using Curve::GetCurveIndex;
     116             :     using Curve::GetCurveMinMaxValues;
     117             : 
     118             :     using General::ScanForReports;
     119             : 
     120             :     // if this has a size, then input has already been gotten
     121         796 :     if (state.dataHeatBalMgr->UniqueMaterialNames.size()) {
     122           0 :         return;
     123             :     }
     124             : 
     125             :     int IOStat;                        // IO Status when calling get input subroutine
     126         796 :     Array1D_string MaterialNames(7);   // Number of Material Alpha names defined
     127             :     int MaterNum;                      // Counter to keep track of the material number
     128             :     int MaterialNumAlpha;              // Number of material alpha names being passed
     129             :     int MaterialNumProp;               // Number of material properties being passed
     130         796 :     Array1D<Real64> MaterialProps(27); // Temporary array to transfer material properties
     131             :     int RegMat;                        // Regular Materials -- full property definition
     132             :     int RegRMat;                       // Regular Materials -- R only property definition
     133             :     int AirMat;                        // Air space materials in opaque constructions
     134             :     int IRTMat;                        // Infrared Transmitting Materials -- R only property definition
     135             : 
     136             :     int EcoRoofMat;                     // Materials for ecoRoof
     137             :     int NumGas;                         // Index for loop over gap gases in a mixture
     138             :     int NumGases;                       // Number of gasses in a mixture
     139         796 :     GasType gasType = GasType::Invalid; // Gas type index: 1=air, 2=argon, 3=krypton, 4=xenon
     140             :     int Loop;
     141             :     int ICoeff;            // Gas property coefficient index
     142             :     Real64 MinSlatAngGeom; // Minimum and maximum slat angle allowed by slat geometry (deg)
     143             :     Real64 MaxSlatAngGeom;
     144             :     Real64 ReflectivitySol;   // Glass reflectivity, solar
     145             :     Real64 ReflectivityVis;   // Glass reflectivity, visible
     146             :     Real64 TransmittivitySol; // Glass transmittivity, solar
     147             :     Real64 TransmittivityVis; // Glass transmittivity, visible
     148             :     Real64 DenomRGas;         // Denominator for WindowGas calculations of NominalR
     149             :     Real64 Openness;          // insect screen openness fraction = (1-d/s)^2
     150             :     Real64 minAngValue;       // minimum value of angle
     151             :     Real64 maxAngValue;       // maximum value of angle
     152             :     Real64 minLamValue;       // minimum value of wavelength
     153             :     Real64 maxLamValue;       // maximum value of wavelength
     154             : 
     155             :     // Added TH 1/9/2009 to read the thermochromic glazings
     156         796 :     int iTC(0);
     157         796 :     int iMat(0);
     158             : 
     159             :     // Added TH 7/27/2009 for constructions defined with F or C factor method
     160             :     int TotFfactorConstructs; // Number of slabs-on-grade or underground floor constructions defined with F factors
     161             :     int TotCfactorConstructs; // Number of underground wall constructions defined with C factors
     162             : 
     163             :     static constexpr std::string_view RoutineName("GetMaterialData: ");
     164             : 
     165         796 :     auto &ip = state.dataInputProcessing->inputProcessor;
     166         796 :     auto &ipsc = state.dataIPShortCut;
     167             : 
     168         796 :     RegMat = ip->getNumObjectsFound(state, "Material");
     169         796 :     RegRMat = ip->getNumObjectsFound(state, "Material:NoMass");
     170         796 :     IRTMat = ip->getNumObjectsFound(state, "Material:InfraredTransparent");
     171         796 :     AirMat = ip->getNumObjectsFound(state, "Material:AirGap");
     172         796 :     state.dataHeatBal->W5GlsMat = ip->getNumObjectsFound(state, "WindowMaterial:Glazing");
     173         796 :     state.dataHeatBal->W5GlsMatAlt = ip->getNumObjectsFound(state, "WindowMaterial:Glazing:RefractionExtinctionMethod");
     174         796 :     state.dataHeatBal->W5GasMat = ip->getNumObjectsFound(state, "WindowMaterial:Gas");
     175         796 :     state.dataHeatBal->W5GasMatMixture = ip->getNumObjectsFound(state, "WindowMaterial:GasMixture");
     176         796 :     state.dataHeatBal->TotShades = ip->getNumObjectsFound(state, "WindowMaterial:Shade");
     177         796 :     state.dataMaterial->TotComplexShades = ip->getNumObjectsFound(state, "WindowMaterial:ComplexShade");
     178         796 :     state.dataHeatBal->TotComplexGaps = ip->getNumObjectsFound(state, "WindowMaterial:Gap");
     179         796 :     state.dataHeatBal->TotScreens = ip->getNumObjectsFound(state, "WindowMaterial:Screen");
     180         796 :     state.dataHeatBal->TotBlinds = ip->getNumObjectsFound(state, "WindowMaterial:Blind");
     181         796 :     EcoRoofMat = ip->getNumObjectsFound(state, "Material:RoofVegetation");
     182         796 :     state.dataHeatBal->TotSimpleWindow = ip->getNumObjectsFound(state, "WindowMaterial:SimpleGlazingSystem");
     183             : 
     184         796 :     state.dataHeatBal->W5GlsMatEQL = ip->getNumObjectsFound(state, "WindowMaterial:Glazing:EquivalentLayer");
     185         796 :     state.dataHeatBal->TotShadesEQL = ip->getNumObjectsFound(state, "WindowMaterial:Shade:EquivalentLayer");
     186         796 :     state.dataHeatBal->TotDrapesEQL = ip->getNumObjectsFound(state, "WindowMaterial:Drape:EquivalentLayer");
     187         796 :     state.dataHeatBal->TotBlindsEQL = ip->getNumObjectsFound(state, "WindowMaterial:Blind:EquivalentLayer");
     188         796 :     state.dataHeatBal->TotScreensEQL = ip->getNumObjectsFound(state, "WindowMaterial:Screen:EquivalentLayer");
     189         796 :     state.dataHeatBal->W5GapMatEQL = ip->getNumObjectsFound(state, "WindowMaterial:Gap:EquivalentLayer");
     190             : 
     191         796 :     state.dataMaterial->TotMaterials = RegMat + RegRMat + AirMat + state.dataHeatBal->W5GlsMat + state.dataHeatBal->W5GlsMatAlt +
     192         796 :                                        state.dataHeatBal->W5GasMat + state.dataHeatBal->W5GasMatMixture + state.dataHeatBal->TotShades +
     193         796 :                                        state.dataHeatBal->TotScreens + state.dataHeatBal->TotBlinds + EcoRoofMat + IRTMat +
     194         796 :                                        state.dataHeatBal->TotSimpleWindow + state.dataMaterial->TotComplexShades + state.dataHeatBal->TotComplexGaps +
     195         796 :                                        state.dataHeatBal->W5GlsMatEQL + state.dataHeatBal->TotShadesEQL + state.dataHeatBal->TotDrapesEQL +
     196         796 :                                        state.dataHeatBal->TotBlindsEQL + state.dataHeatBal->TotScreensEQL + state.dataHeatBal->W5GapMatEQL;
     197             : 
     198         796 :     TotFfactorConstructs = ip->getNumObjectsFound(state, "Construction:FfactorGroundFloor");
     199         796 :     TotCfactorConstructs = ip->getNumObjectsFound(state, "Construction:CfactorUndergroundWall");
     200             : 
     201         796 :     if (TotFfactorConstructs > 0) {
     202          15 :         state.dataHeatBal->NoFfactorConstructionsUsed = false;
     203             :     }
     204             : 
     205         796 :     if (TotCfactorConstructs > 0) {
     206           7 :         state.dataHeatBal->NoCfactorConstructionsUsed = false;
     207             :     }
     208             : 
     209         796 :     if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
     210             :         // Add a new fictitious insulation layer and a thermal mass layer for each F or C factor defined construction
     211          21 :         state.dataMaterial->TotMaterials += 1 + TotFfactorConstructs + TotCfactorConstructs;
     212             :     }
     213             : 
     214             :     // yujie: This looks kind of silly, but we need it to keep the Materials array in IDF order.
     215       14714 :     for (int i = 1; i <= state.dataMaterial->TotMaterials; i++) {
     216       13918 :         MaterialBase *p = new MaterialBase;
     217       13918 :         state.dataMaterial->Material.push_back(p);
     218             :     }
     219         796 :     state.dataHeatBalMgr->UniqueMaterialNames.reserve(static_cast<unsigned>(state.dataMaterial->TotMaterials));
     220             : 
     221         796 :     state.dataHeatBal->NominalR.dimension(state.dataMaterial->TotMaterials, 0.0);
     222             : 
     223         796 :     MaterNum = 0;
     224             : 
     225             :     // Regular Materials
     226             : 
     227         796 :     state.dataHeatBalMgr->CurrentModuleObject = "Material";
     228         796 :     auto const instances = ip->epJSON.find(state.dataHeatBalMgr->CurrentModuleObject);
     229         796 :     if (instances != ip->epJSON.end()) {
     230         763 :         auto const &objectSchemaProps = ip->getObjectSchemaProps(state, state.dataHeatBalMgr->CurrentModuleObject);
     231             : 
     232         763 :         int counter = 0;
     233         763 :         auto &instancesValue = instances.value();
     234        9361 :         for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     235        8598 :             auto const &objectFields = instance.value();
     236        8598 :             std::string const &thisObjectName = Util::makeUPPER(instance.key());
     237        8598 :             ip->markObjectAsUsed(state.dataHeatBalMgr->CurrentModuleObject, instance.key());
     238        8598 :             std::string materialName = thisObjectName;
     239             : 
     240       17196 :             if (GlobalNames::VerifyUniqueInterObjectName(state,
     241        8598 :                                                          state.dataHeatBalMgr->UniqueMaterialNames,
     242             :                                                          materialName,
     243        8598 :                                                          state.dataHeatBalMgr->CurrentModuleObject,
     244        8598 :                                                          ipsc->cAlphaFieldNames(1),
     245             :                                                          ErrorsFound)) {
     246           0 :                 continue;
     247             :             }
     248             :             // For incoming idf, maintain object order
     249        8598 :             ++counter;
     250        8598 :             MaterNum = ip->getIDFObjNum(state, state.dataHeatBalMgr->CurrentModuleObject, counter);
     251             : 
     252             :             // Load the material derived type from the input data.
     253        8598 :             auto *thisMaterial = new MaterialChild;
     254        8598 :             state.dataMaterial->Material(MaterNum) = thisMaterial;
     255        8598 :             thisMaterial->group = Group::Regular;
     256        8598 :             thisMaterial->Name = materialName;
     257             : 
     258       17196 :             std::string roughness = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "roughness");
     259        8598 :             thisMaterial->Roughness = static_cast<SurfaceRoughness>(getEnumValue(surfaceRoughnessNamesUC, Util::makeUPPER(roughness)));
     260        8598 :             thisMaterial->Thickness = ip->getRealFieldValue(objectFields, objectSchemaProps, "thickness");
     261        8598 :             thisMaterial->Conductivity = ip->getRealFieldValue(objectFields, objectSchemaProps, "conductivity");
     262        8598 :             thisMaterial->Density = ip->getRealFieldValue(objectFields, objectSchemaProps, "density");
     263        8598 :             thisMaterial->SpecHeat = ip->getRealFieldValue(objectFields, objectSchemaProps, "specific_heat");
     264        8598 :             thisMaterial->AbsorpThermal = ip->getRealFieldValue(objectFields, objectSchemaProps, "thermal_absorptance");
     265        8598 :             thisMaterial->AbsorpThermalInput = thisMaterial->AbsorpThermal;
     266        8598 :             thisMaterial->AbsorpSolar = ip->getRealFieldValue(objectFields, objectSchemaProps, "solar_absorptance");
     267        8598 :             thisMaterial->AbsorpSolarInput = thisMaterial->AbsorpSolar;
     268        8598 :             thisMaterial->AbsorpVisible = ip->getRealFieldValue(objectFields, objectSchemaProps, "visible_absorptance");
     269        8598 :             thisMaterial->AbsorpVisibleInput = thisMaterial->AbsorpVisible;
     270             : 
     271        8598 :             if (thisMaterial->Conductivity > 0.0) {
     272        8598 :                 state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Thickness / thisMaterial->Conductivity;
     273        8598 :                 thisMaterial->Resistance = state.dataHeatBal->NominalR(MaterNum);
     274             :             } else {
     275           0 :                 ShowSevereError(state, format("Positive thermal conductivity required for material {}", thisMaterial->Name));
     276           0 :                 ErrorsFound = true;
     277             :             }
     278        9361 :         }
     279         763 :         MaterNum = counter; // This works here, because this is the first material type processed
     280             :     }
     281             :     // Add the 6" heavy concrete for constructions defined with F or C factor method
     282         796 :     if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
     283          21 :         ++MaterNum;
     284          21 :         auto *thisMaterial = new MaterialChild;
     285          21 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
     286          21 :         thisMaterial->group = Group::Regular;
     287          21 :         thisMaterial->Name = "~FC_Concrete";
     288          21 :         thisMaterial->Thickness = 0.15;    // m, 0.15m = 6 inches
     289          21 :         thisMaterial->Conductivity = 1.95; // W/mK
     290          21 :         thisMaterial->Density = 2240.0;    // kg/m3
     291          21 :         thisMaterial->SpecHeat = 900.0;    // J/kgK
     292          21 :         thisMaterial->Roughness = SurfaceRoughness::MediumRough;
     293          21 :         thisMaterial->AbsorpSolar = 0.7;
     294          21 :         thisMaterial->AbsorpThermal = 0.9;
     295          21 :         thisMaterial->AbsorpVisible = 0.7;
     296          21 :         state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Thickness / thisMaterial->Conductivity;
     297          21 :         thisMaterial->Resistance = state.dataHeatBal->NominalR(MaterNum);
     298             : 
     299          21 :         ++RegMat;
     300             :     }
     301             : 
     302         796 :     state.dataHeatBalMgr->CurrentModuleObject = "Material:NoMass";
     303        2586 :     for (Loop = 1; Loop <= RegRMat; ++Loop) {
     304             : 
     305             :         // Call Input Get routine to retrieve material data
     306        5370 :         ip->getObjectItem(state,
     307        1790 :                           state.dataHeatBalMgr->CurrentModuleObject,
     308             :                           Loop,
     309             :                           MaterialNames,
     310             :                           MaterialNumAlpha,
     311             :                           MaterialProps,
     312             :                           MaterialNumProp,
     313             :                           IOStat,
     314        1790 :                           ipsc->lNumericFieldBlanks,
     315        1790 :                           ipsc->lAlphaFieldBlanks,
     316        1790 :                           ipsc->cAlphaFieldNames,
     317        1790 :                           ipsc->cNumericFieldNames);
     318        3580 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
     319        1790 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
     320        1790 :                                                      MaterialNames(1),
     321        1790 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
     322        1790 :                                                      ipsc->cAlphaFieldNames(1),
     323             :                                                      ErrorsFound)) {
     324           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
     325           0 :             continue;
     326             :         }
     327             : 
     328             :         // Load the material derived type from the input data.
     329        1790 :         ++MaterNum;
     330        1790 :         auto *thisMaterial = new MaterialChild;
     331        1790 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
     332        1790 :         thisMaterial->group = Group::Regular;
     333        1790 :         thisMaterial->Name = MaterialNames(1);
     334             : 
     335        1790 :         thisMaterial->Roughness = static_cast<SurfaceRoughness>(getEnumValue(surfaceRoughnessNamesUC, Util::makeUPPER(MaterialNames(2))));
     336             : 
     337        1790 :         thisMaterial->Resistance = MaterialProps(1);
     338        1790 :         thisMaterial->ROnly = true;
     339        1790 :         if (MaterialNumProp >= 2) {
     340        1653 :             thisMaterial->AbsorpThermal = MaterialProps(2);
     341        1653 :             thisMaterial->AbsorpThermalInput = MaterialProps(2);
     342             :         } else {
     343         137 :             thisMaterial->AbsorpThermal = 0.9;
     344         137 :             thisMaterial->AbsorpThermalInput = 0.9;
     345             :         }
     346        1790 :         if (MaterialNumProp >= 3) {
     347        1653 :             thisMaterial->AbsorpSolar = MaterialProps(3);
     348        1653 :             thisMaterial->AbsorpSolarInput = MaterialProps(3);
     349             :         } else {
     350         137 :             thisMaterial->AbsorpSolar = 0.7;
     351         137 :             thisMaterial->AbsorpSolarInput = 0.7;
     352             :         }
     353        1790 :         if (MaterialNumProp >= 4) {
     354        1549 :             thisMaterial->AbsorpVisible = MaterialProps(4);
     355        1549 :             thisMaterial->AbsorpVisibleInput = MaterialProps(4);
     356             :         } else {
     357         241 :             thisMaterial->AbsorpVisible = 0.7;
     358         241 :             thisMaterial->AbsorpVisibleInput = 0.7;
     359             :         }
     360             : 
     361        1790 :         state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Resistance;
     362             :     }
     363             : 
     364             :     // Add a fictitious insulation layer for each construction defined with F or C factor method
     365         796 :     if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
     366         238 :         for (Loop = 1; Loop <= TotFfactorConstructs + TotCfactorConstructs; ++Loop) {
     367         217 :             ++MaterNum;
     368         217 :             auto *thisMaterial = new MaterialChild;
     369         217 :             state.dataMaterial->Material(MaterNum) = thisMaterial;
     370         217 :             thisMaterial->group = Group::Regular;
     371         217 :             thisMaterial->Name = format("~FC_Insulation_{}", Loop);
     372         217 :             thisMaterial->ROnly = true;
     373         217 :             thisMaterial->Roughness = SurfaceRoughness::MediumRough;
     374         217 :             thisMaterial->AbsorpSolar = 0.0;
     375         217 :             thisMaterial->AbsorpThermal = 0.0;
     376         217 :             thisMaterial->AbsorpVisible = 0.0;
     377             :         }
     378          21 :         RegRMat += TotFfactorConstructs + TotCfactorConstructs;
     379             :     }
     380             : 
     381             :     // Air Materials (for air spaces in opaque constructions)
     382         796 :     state.dataHeatBalMgr->CurrentModuleObject = "Material:AirGap";
     383        1338 :     for (Loop = 1; Loop <= AirMat; ++Loop) {
     384             : 
     385             :         // Call Input Get routine to retrieve material data
     386        1626 :         ip->getObjectItem(state,
     387         542 :                           state.dataHeatBalMgr->CurrentModuleObject,
     388             :                           Loop,
     389             :                           MaterialNames,
     390             :                           MaterialNumAlpha,
     391             :                           MaterialProps,
     392             :                           MaterialNumProp,
     393             :                           IOStat,
     394         542 :                           ipsc->lNumericFieldBlanks,
     395         542 :                           ipsc->lAlphaFieldBlanks,
     396         542 :                           ipsc->cAlphaFieldNames,
     397         542 :                           ipsc->cNumericFieldNames);
     398        1084 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
     399         542 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
     400         542 :                                                      MaterialNames(1),
     401         542 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
     402         542 :                                                      ipsc->cAlphaFieldNames(1),
     403             :                                                      ErrorsFound)) {
     404           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
     405           0 :             continue;
     406             :         }
     407             : 
     408             :         // Load the material derived type from the input data.
     409         542 :         ++MaterNum;
     410         542 :         auto *thisMaterial = new MaterialChild;
     411         542 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
     412         542 :         thisMaterial->group = Group::Air;
     413         542 :         thisMaterial->Name = MaterialNames(1);
     414             : 
     415         542 :         thisMaterial->Roughness = SurfaceRoughness::MediumRough;
     416             : 
     417         542 :         thisMaterial->Resistance = MaterialProps(1);
     418         542 :         thisMaterial->ROnly = true;
     419             : 
     420         542 :         state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Resistance;
     421             :     }
     422             : 
     423         796 :     state.dataHeatBalMgr->CurrentModuleObject = "Material:InfraredTransparent";
     424         799 :     for (Loop = 1; Loop <= IRTMat; ++Loop) {
     425             : 
     426             :         // Call Input Get routine to retrieve material data
     427           9 :         ip->getObjectItem(state,
     428           3 :                           state.dataHeatBalMgr->CurrentModuleObject,
     429             :                           Loop,
     430             :                           MaterialNames,
     431             :                           MaterialNumAlpha,
     432             :                           MaterialProps,
     433             :                           MaterialNumProp,
     434             :                           IOStat,
     435           3 :                           ipsc->lNumericFieldBlanks,
     436           3 :                           ipsc->lAlphaFieldBlanks,
     437           3 :                           ipsc->cAlphaFieldNames,
     438           3 :                           ipsc->cNumericFieldNames);
     439           6 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
     440           3 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
     441           3 :                                                      MaterialNames(1),
     442           3 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
     443           3 :                                                      ipsc->cAlphaFieldNames(1),
     444             :                                                      ErrorsFound)) {
     445           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
     446           0 :             continue;
     447             :         }
     448             : 
     449           3 :         ++MaterNum;
     450           3 :         auto *thisMaterial = new MaterialChild;
     451           3 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
     452           3 :         thisMaterial->group = Group::IRTransparent;
     453             : 
     454             :         // Load the material derived type from the input data.
     455           3 :         thisMaterial->Name = MaterialNames(1);
     456             : 
     457             :         // Load data for other properties that need defaults
     458           3 :         thisMaterial->ROnly = true;
     459           3 :         thisMaterial->Resistance = 0.01;
     460           3 :         thisMaterial->AbsorpThermal = 0.9999;
     461           3 :         thisMaterial->AbsorpThermalInput = 0.9999;
     462           3 :         thisMaterial->AbsorpSolar = 1.0;
     463           3 :         thisMaterial->AbsorpSolarInput = 1.0;
     464           3 :         thisMaterial->AbsorpVisible = 1.0;
     465           3 :         thisMaterial->AbsorpVisibleInput = 1.0;
     466             : 
     467           3 :         state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Resistance;
     468             :     }
     469             : 
     470             :     // Glass materials, regular input: transmittance and front/back reflectance
     471             : 
     472         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Glazing";
     473        2509 :     for (Loop = 1; Loop <= state.dataHeatBal->W5GlsMat; ++Loop) {
     474             : 
     475             :         // Call Input Get routine to retrieve material data
     476        5139 :         ip->getObjectItem(state,
     477        1713 :                           state.dataHeatBalMgr->CurrentModuleObject,
     478             :                           Loop,
     479             :                           MaterialNames,
     480             :                           MaterialNumAlpha,
     481             :                           MaterialProps,
     482             :                           MaterialNumProp,
     483             :                           IOStat,
     484        1713 :                           ipsc->lNumericFieldBlanks,
     485        1713 :                           ipsc->lAlphaFieldBlanks,
     486        1713 :                           ipsc->cAlphaFieldNames,
     487        1713 :                           ipsc->cNumericFieldNames);
     488        3426 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
     489        1713 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
     490        1713 :                                                      MaterialNames(1),
     491        1713 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
     492        1713 :                                                      ipsc->cAlphaFieldNames(1),
     493             :                                                      ErrorsFound)) {
     494           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
     495           0 :             continue;
     496             :         }
     497             : 
     498        1713 :         ++MaterNum;
     499        1713 :         auto *thisMaterial = new MaterialChild;
     500        1713 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
     501        1713 :         thisMaterial->group = Group::WindowGlass;
     502             : 
     503             :         // Load the material derived type from the input data.
     504             : 
     505        1713 :         thisMaterial->Name = MaterialNames(1);
     506        1713 :         thisMaterial->Roughness = SurfaceRoughness::VerySmooth;
     507        1713 :         thisMaterial->ROnly = true;
     508        1713 :         thisMaterial->Thickness = MaterialProps(1);
     509        1713 :         if (!Util::SameString(MaterialNames(2), "SpectralAndAngle")) {
     510        1712 :             thisMaterial->Trans = MaterialProps(2);
     511        1712 :             thisMaterial->ReflectSolBeamFront = MaterialProps(3);
     512        1712 :             thisMaterial->ReflectSolBeamBack = MaterialProps(4);
     513        1712 :             thisMaterial->TransVis = MaterialProps(5);
     514        1712 :             thisMaterial->ReflectVisBeamFront = MaterialProps(6);
     515        1712 :             thisMaterial->ReflectVisBeamBack = MaterialProps(7);
     516        1712 :             thisMaterial->TransThermal = MaterialProps(8);
     517             :         }
     518        1713 :         thisMaterial->AbsorpThermalFront = MaterialProps(9);
     519        1713 :         thisMaterial->AbsorpThermalBack = MaterialProps(10);
     520        1713 :         thisMaterial->Conductivity = MaterialProps(11);
     521        1713 :         thisMaterial->GlassTransDirtFactor = MaterialProps(12);
     522        1713 :         thisMaterial->YoungModulus = MaterialProps(13);
     523        1713 :         thisMaterial->PoissonsRatio = MaterialProps(14);
     524        1713 :         if (MaterialProps(12) == 0.0) thisMaterial->GlassTransDirtFactor = 1.0;
     525        1713 :         thisMaterial->AbsorpThermal = thisMaterial->AbsorpThermalBack;
     526             : 
     527        1713 :         if (thisMaterial->Conductivity > 0.0) {
     528        1713 :             state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Thickness / thisMaterial->Conductivity;
     529        1713 :             thisMaterial->Resistance = state.dataHeatBal->NominalR(MaterNum);
     530             :         } else {
     531           0 :             ErrorsFound = true;
     532           0 :             ShowSevereError(state, format("Window glass material {} has Conductivity = 0.0, must be >0.0, default = .9", thisMaterial->Name));
     533             :         }
     534             : 
     535        1713 :         thisMaterial->GlassSpectralDataPtr = 0;
     536        1713 :         if (state.dataHeatBal->TotSpectralData > 0 && !ipsc->lAlphaFieldBlanks(3)) {
     537          83 :             thisMaterial->GlassSpectralDataPtr = Util::FindItemInList(MaterialNames(3), state.dataHeatBal->SpectralData);
     538             :         }
     539        1713 :         if (Util::SameString(MaterialNames(2), "SpectralAverage")) thisMaterial->GlassSpectralDataPtr = 0;
     540             :         // No need for spectral data for BSDF either
     541        1713 :         if (Util::SameString(MaterialNames(2), "BSDF")) thisMaterial->GlassSpectralDataPtr = 0;
     542        1713 :         if (Util::SameString(MaterialNames(2), "SpectralAndAngle")) thisMaterial->GlassSpectralAndAngle = true;
     543             : 
     544        1713 :         if (thisMaterial->GlassSpectralDataPtr == 0 && Util::SameString(MaterialNames(2), "Spectral")) {
     545           0 :             ErrorsFound = true;
     546           0 :             ShowSevereError(state,
     547           0 :                             format("{}=\"{}\" has {} = Spectral but has no matching MaterialProperty:GlazingSpectralData set",
     548           0 :                                    state.dataHeatBalMgr->CurrentModuleObject,
     549           0 :                                    thisMaterial->Name,
     550           0 :                                    ipsc->cAlphaFieldNames(2)));
     551           0 :             if (ipsc->lAlphaFieldBlanks(3)) {
     552           0 :                 ShowContinueError(state, format("...{} is blank.", ipsc->cAlphaFieldNames(3)));
     553             :             } else {
     554           0 :                 ShowContinueError(state,
     555           0 :                                   format("...{}=\"{}\" not found as item in MaterialProperty:GlazingSpectralData objects.",
     556           0 :                                          ipsc->cAlphaFieldNames(3),
     557             :                                          MaterialNames(3)));
     558             :             }
     559             :         }
     560             : 
     561        1813 :         if (!Util::SameString(MaterialNames(2), "SpectralAverage") && !Util::SameString(MaterialNames(2), "Spectral") &&
     562        1813 :             !Util::SameString(MaterialNames(2), "BSDF") && !Util::SameString(MaterialNames(2), "SpectralAndAngle")) {
     563           0 :             ErrorsFound = true;
     564           0 :             ShowSevereError(state, format("{}=\"{}\", invalid specification.", state.dataHeatBalMgr->CurrentModuleObject, thisMaterial->Name));
     565           0 :             ShowContinueError(
     566             :                 state,
     567           0 :                 format("{} must be SpectralAverage, Spectral, BSDF or SpectralAndAngle, value={}", ipsc->cAlphaFieldNames(2), MaterialNames(2)));
     568             :         }
     569             : 
     570             :         // TH 8/24/2011, allow glazing properties MaterialProps(2 to 10) to equal 0 or 1: 0.0 =< Prop <= 1.0
     571             :         // Fixed CR 8413 - modeling spandrel panels as glazing systems
     572        1713 :         if (Util::SameString(MaterialNames(2), "SpectralAverage")) {
     573             : 
     574        1613 :             if (MaterialProps(2) + MaterialProps(3) > 1.0) {
     575           0 :                 ErrorsFound = true;
     576           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     577           0 :                 ShowContinueError(state, format("{} + {} not <= 1.0", ipsc->cNumericFieldNames(2), ipsc->cNumericFieldNames(3)));
     578             :             }
     579             : 
     580        1613 :             if (MaterialProps(2) + MaterialProps(4) > 1.0) {
     581           0 :                 ErrorsFound = true;
     582           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     583           0 :                 ShowContinueError(state, format("{} + {} not <= 1.0", ipsc->cNumericFieldNames(2), ipsc->cNumericFieldNames(4)));
     584             :             }
     585             : 
     586        1613 :             if (MaterialProps(5) + MaterialProps(6) > 1.0) {
     587           0 :                 ErrorsFound = true;
     588           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     589           0 :                 ShowContinueError(state, format("{} + {} not <= 1.0", ipsc->cNumericFieldNames(5), ipsc->cNumericFieldNames(6)));
     590             :             }
     591             : 
     592        1613 :             if (MaterialProps(5) + MaterialProps(7) > 1.0) {
     593           0 :                 ErrorsFound = true;
     594           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     595           0 :                 ShowContinueError(state, format("{} + {} not <= 1.0", ipsc->cNumericFieldNames(5), ipsc->cNumericFieldNames(7)));
     596             :             }
     597             : 
     598        1613 :             if (MaterialProps(8) + MaterialProps(9) > 1.0) {
     599           0 :                 ErrorsFound = true;
     600           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     601           0 :                 ShowContinueError(state, format("{} + {} not <= 1.0", ipsc->cNumericFieldNames(8), ipsc->cNumericFieldNames(9)));
     602             :             }
     603             : 
     604        1613 :             if (MaterialProps(8) + MaterialProps(10) > 1.0) {
     605           0 :                 ErrorsFound = true;
     606           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     607           0 :                 ShowContinueError(state, format("{} + {} not <= 1.0", ipsc->cNumericFieldNames(8), ipsc->cNumericFieldNames(10)));
     608             :             }
     609             : 
     610        1613 :             if (MaterialProps(2) < 0.0) {
     611           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     612           0 :                 ShowContinueError(state, format("{} not >= 0.0", ipsc->cNumericFieldNames(2)));
     613           0 :                 ErrorsFound = true;
     614             :             }
     615             : 
     616        1613 :             if (MaterialProps(2) > 1.0) {
     617           0 :                 ErrorsFound = true;
     618           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     619           0 :                 ShowContinueError(state, format("{} not <= 1.0", ipsc->cNumericFieldNames(2)));
     620             :             }
     621             : 
     622        1613 :             if (MaterialProps(3) < 0.0 || MaterialProps(3) > 1.0) {
     623           0 :                 ErrorsFound = true;
     624           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     625           0 :                 ShowContinueError(state, format("{} not >= 0.0 and <= 1.0", ipsc->cNumericFieldNames(3)));
     626             :             }
     627             : 
     628        1613 :             if (MaterialProps(4) < 0.0 || MaterialProps(4) > 1.0) {
     629           0 :                 ErrorsFound = true;
     630           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     631           0 :                 ShowContinueError(state, format("{} not >= 0.0 and <= 1.0", ipsc->cNumericFieldNames(4)));
     632             :             }
     633             : 
     634        1613 :             if (MaterialProps(5) < 0.0) {
     635           0 :                 ShowWarningError(state, format("{}=\"{}\", minimal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     636           0 :                 ShowWarningError(state, format("{} not >= 0.0", ipsc->cNumericFieldNames(5)));
     637             :             }
     638             : 
     639        1613 :             if (MaterialProps(5) > 1.0) {
     640           0 :                 ErrorsFound = true;
     641           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     642           0 :                 ShowContinueError(state, format("{} not <= 1.0", ipsc->cNumericFieldNames(5)));
     643             :             }
     644             : 
     645        1613 :             if (MaterialProps(6) < 0.0 || MaterialProps(6) > 1.0) {
     646           0 :                 ErrorsFound = true;
     647           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     648           0 :                 ShowContinueError(state, format("{} not >= 0.0 and <= 1.0", ipsc->cNumericFieldNames(6)));
     649             :             }
     650             : 
     651        1613 :             if (MaterialProps(7) < 0.0 || MaterialProps(7) > 1.0) {
     652           0 :                 ErrorsFound = true;
     653           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     654           0 :                 ShowContinueError(state, format("{} not >= 0.0 and <= 1.0", ipsc->cNumericFieldNames(7)));
     655             :             }
     656             :         }
     657             : 
     658        1713 :         if (MaterialProps(8) > 1.0) {
     659           0 :             ErrorsFound = true;
     660           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     661           0 :             ShowContinueError(state, format("{} not <= 1.0", ipsc->cNumericFieldNames(8)));
     662             :         }
     663             : 
     664        1713 :         if (MaterialProps(9) <= 0.0 || MaterialProps(9) >= 1.0) {
     665           0 :             ErrorsFound = true;
     666           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     667           0 :             ShowContinueError(state, format("{} not > 0.0 and < 1.0", ipsc->cNumericFieldNames(9)));
     668             :         }
     669             : 
     670        1713 :         if (MaterialProps(10) <= 0.0 || MaterialProps(10) >= 1.0) {
     671           0 :             ErrorsFound = true;
     672           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     673           0 :             ShowContinueError(state, format("{} not > 0.0 and < 1.0", ipsc->cNumericFieldNames(10)));
     674             :         }
     675             : 
     676        1713 :         if (MaterialProps(11) <= 0.0) {
     677           0 :             ErrorsFound = true;
     678           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     679           0 :             ShowContinueError(state, format("{} not > 0.0", ipsc->cNumericFieldNames(11)));
     680             :         }
     681             : 
     682        1713 :         if (MaterialProps(13) < 0.0) {
     683           0 :             ErrorsFound = true;
     684           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     685           0 :             ShowContinueError(state, format("{} not > 0.0", ipsc->cNumericFieldNames(13)));
     686             :         }
     687             : 
     688        1713 :         if (MaterialProps(14) < 0.0 || MaterialProps(14) >= 1.0) {
     689           0 :             ErrorsFound = true;
     690           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     691           0 :             ShowContinueError(state, format("{} not > 0.0 and < 1.0", ipsc->cNumericFieldNames(14)));
     692             :         }
     693             : 
     694        1713 :         if (MaterialNames(4) == "") {
     695           0 :             thisMaterial->SolarDiffusing = false;
     696             :         } else {
     697        1713 :             BooleanSwitch answer = getYesNoValue(MaterialNames(4));
     698        1713 :             if (answer == BooleanSwitch::Invalid) {
     699           0 :                 ErrorsFound = true;
     700           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     701           0 :                 ShowContinueError(state, format("{} must be Yes or No, entered value={}", ipsc->cNumericFieldNames(4), MaterialNames(4)));
     702             :             } else {
     703        1713 :                 thisMaterial->SolarDiffusing = (answer == BooleanSwitch::Yes);
     704             :             }
     705             :         }
     706             :         // Get SpectralAndAngle table names
     707        1713 :         if (thisMaterial->GlassSpectralAndAngle) {
     708           1 :             if (ipsc->lAlphaFieldBlanks(5)) {
     709           0 :                 ErrorsFound = true;
     710           0 :                 ShowSevereError(state, format("{}=\"{}\", blank field.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     711           0 :                 ShowContinueError(state, " Table name must be entered when the key SpectralAndAngle is selected as Optical Data Type.");
     712             :             } else {
     713           1 :                 thisMaterial->GlassSpecAngTransDataPtr = Curve::GetCurveIndex(state, MaterialNames(5));
     714           1 :                 if (thisMaterial->GlassSpecAngTransDataPtr == 0) {
     715           0 :                     ErrorsFound = true;
     716           0 :                     ShowSevereError(state, format("{}=\"{}\", Invalid name.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     717           0 :                     ShowContinueError(state,
     718           0 :                                       format("{} requires a valid table object name, entered input={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     719             :                 } else {
     720           2 :                     ErrorsFound |= Curve::CheckCurveDims(state,
     721             :                                                          thisMaterial->GlassSpecAngTransDataPtr,    // Curve index
     722             :                                                          {2},                                       // Valid dimensions
     723             :                                                          RoutineName,                               // Routine name
     724           1 :                                                          state.dataHeatBalMgr->CurrentModuleObject, // Object Type
     725             :                                                          thisMaterial->Name,                        // Object Name
     726           1 :                                                          ipsc->cAlphaFieldNames(5));                // Field Name
     727             : 
     728           1 :                     GetCurveMinMaxValues(state, thisMaterial->GlassSpecAngTransDataPtr, minAngValue, maxAngValue, minLamValue, maxLamValue);
     729           1 :                     if (minAngValue > 1.0e-6) {
     730           0 :                         ErrorsFound = true;
     731           0 :                         ShowSevereError(state,
     732           0 :                                         format("{}=\"{}\", Invalid minimum value of angle = {:.2R}.",
     733           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     734             :                                                MaterialNames(1),
     735             :                                                minAngValue));
     736           0 :                         ShowContinueError(
     737             :                             state,
     738           0 :                             format("{} requires the minumum value = 0.0 in the entered table name={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     739             :                     }
     740           1 :                     if (std::abs(maxAngValue - 90.0) > 1.0e-6) {
     741           0 :                         ErrorsFound = true;
     742           0 :                         ShowSevereError(state,
     743           0 :                                         format("{}=\"{}\", Invalid maximum value of angle = {:.2R}.",
     744           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     745             :                                                MaterialNames(1),
     746             :                                                maxAngValue));
     747           0 :                         ShowContinueError(
     748             :                             state,
     749           0 :                             format("{} requires the maximum value = 90.0 in the entered table name={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     750             :                     }
     751           1 :                     if (minLamValue < 0.1) {
     752           0 :                         ErrorsFound = true;
     753           0 :                         ShowSevereError(state,
     754           0 :                                         format("{}=\"{}\", Invalid minimum value of wavelength = {:.2R}.",
     755           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     756             :                                                MaterialNames(1),
     757             :                                                minLamValue));
     758           0 :                         ShowContinueError(state,
     759           0 :                                           format("{} requires the minumum value = 0.1 micron in the entered table name={}",
     760           0 :                                                  ipsc->cAlphaFieldNames(5),
     761             :                                                  MaterialNames(5)));
     762             :                     }
     763           1 :                     if (maxLamValue > 4.0) {
     764           0 :                         ErrorsFound = true;
     765           0 :                         ShowSevereError(state,
     766           0 :                                         format("{}=\"{}\", Invalid maximum value of wavelength = {:.2R}.",
     767           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     768             :                                                MaterialNames(1),
     769             :                                                maxLamValue));
     770           0 :                         ShowContinueError(state,
     771           0 :                                           format("{} requires the maximum value = 4.0 microns in the entered table name={}",
     772           0 :                                                  ipsc->cAlphaFieldNames(5),
     773             :                                                  MaterialNames(5)));
     774             :                     }
     775             :                 }
     776             :             }
     777           1 :             if (ipsc->lAlphaFieldBlanks(6)) {
     778           0 :                 ErrorsFound = true;
     779           0 :                 ShowSevereError(state, format("{}=\"{}\", blank field.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     780           0 :                 ShowContinueError(state, " Table name must be entered when the key SpectralAndAngle is selected as Optical Data Type.");
     781             :             } else {
     782           1 :                 thisMaterial->GlassSpecAngFRefleDataPtr = Curve::GetCurveIndex(state, MaterialNames(6));
     783           1 :                 if (thisMaterial->GlassSpecAngFRefleDataPtr == 0) {
     784           0 :                     ErrorsFound = true;
     785           0 :                     ShowSevereError(state, format("{}=\"{}\", Invalid name.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     786           0 :                     ShowContinueError(state,
     787           0 :                                       format("{} requires a valid table object name, entered input={}", ipsc->cAlphaFieldNames(6), MaterialNames(6)));
     788             :                 } else {
     789           2 :                     ErrorsFound |= Curve::CheckCurveDims(state,
     790             :                                                          thisMaterial->GlassSpecAngFRefleDataPtr,   // Curve index
     791             :                                                          {2},                                       // Valid dimensions
     792             :                                                          RoutineName,                               // Routine name
     793           1 :                                                          state.dataHeatBalMgr->CurrentModuleObject, // Object Type
     794             :                                                          thisMaterial->Name,                        // Object Name
     795           1 :                                                          ipsc->cAlphaFieldNames(6));                // Field Name
     796             : 
     797           1 :                     GetCurveMinMaxValues(state, thisMaterial->GlassSpecAngFRefleDataPtr, minAngValue, maxAngValue, minLamValue, maxLamValue);
     798           1 :                     if (minAngValue > 1.0e-6) {
     799           0 :                         ErrorsFound = true;
     800           0 :                         ShowSevereError(state,
     801           0 :                                         format("{}=\"{}\", Invalid minimum value of angle = {:.2R}.",
     802           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     803             :                                                MaterialNames(1),
     804             :                                                minAngValue));
     805           0 :                         ShowContinueError(
     806             :                             state,
     807           0 :                             format("{} requires the minumum value = 0.0 in the entered table name={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     808             :                     }
     809           1 :                     if (std::abs(maxAngValue - 90.0) > 1.0e-6) {
     810           0 :                         ErrorsFound = true;
     811           0 :                         ShowSevereError(state,
     812           0 :                                         format("{}=\"{}\", Invalid maximum value of angle = {:.2R}.",
     813           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     814             :                                                MaterialNames(1),
     815             :                                                maxAngValue));
     816           0 :                         ShowContinueError(
     817             :                             state,
     818           0 :                             format("{} requires the maximum value = 90.0 in the entered table name={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     819             :                     }
     820           1 :                     if (minLamValue < 0.1) {
     821           0 :                         ErrorsFound = true;
     822           0 :                         ShowSevereError(state,
     823           0 :                                         format("{}=\"{}\", Invalid minimum value of wavelength = {:.2R}.",
     824           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     825             :                                                MaterialNames(1),
     826             :                                                minLamValue));
     827           0 :                         ShowContinueError(state,
     828           0 :                                           format("{} requires the minumum value = 0.1 micron in the entered table name={}",
     829           0 :                                                  ipsc->cAlphaFieldNames(5),
     830             :                                                  MaterialNames(5)));
     831             :                     }
     832           1 :                     if (maxLamValue > 4.0) {
     833           0 :                         ErrorsFound = true;
     834           0 :                         ShowSevereError(state,
     835           0 :                                         format("{}=\"{}\", Invalid maximum value of wavelength = {:.2R}.",
     836           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     837             :                                                MaterialNames(1),
     838             :                                                maxLamValue));
     839           0 :                         ShowContinueError(state,
     840           0 :                                           format("{} requires the maximum value = 4.0 microns in the entered table name={}",
     841           0 :                                                  ipsc->cAlphaFieldNames(5),
     842             :                                                  MaterialNames(5)));
     843             :                     }
     844             :                 }
     845             :             }
     846           1 :             if (ipsc->lAlphaFieldBlanks(7)) {
     847           0 :                 ErrorsFound = true;
     848           0 :                 ShowSevereError(state, format("{}=\"{}\", blank field.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     849           0 :                 ShowContinueError(state, " Table name must be entered when the key SpectralAndAngle is selected as Optical Data Type.");
     850             :             } else {
     851           1 :                 thisMaterial->GlassSpecAngBRefleDataPtr = Curve::GetCurveIndex(state, MaterialNames(7));
     852           1 :                 if (thisMaterial->GlassSpecAngBRefleDataPtr == 0) {
     853           0 :                     ErrorsFound = true;
     854           0 :                     ShowSevereError(state, format("{}=\"{}\", Invalid name.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     855           0 :                     ShowContinueError(state,
     856           0 :                                       format("{} requires a valid table object name, entered input={}", ipsc->cAlphaFieldNames(7), MaterialNames(7)));
     857             :                 } else {
     858           2 :                     ErrorsFound |= Curve::CheckCurveDims(state,
     859             :                                                          thisMaterial->GlassSpecAngBRefleDataPtr,   // Curve index
     860             :                                                          {2},                                       // Valid dimensions
     861             :                                                          RoutineName,                               // Routine name
     862           1 :                                                          state.dataHeatBalMgr->CurrentModuleObject, // Object Type
     863             :                                                          thisMaterial->Name,                        // Object Name
     864           1 :                                                          ipsc->cAlphaFieldNames(7));                // Field Name
     865             : 
     866           1 :                     GetCurveMinMaxValues(state, thisMaterial->GlassSpecAngBRefleDataPtr, minAngValue, maxAngValue, minLamValue, maxLamValue);
     867           1 :                     if (minAngValue > 1.0e-6) {
     868           0 :                         ErrorsFound = true;
     869           0 :                         ShowSevereError(state,
     870           0 :                                         format("{}=\"{}\", Invalid minimum value of angle = {:.2R}.",
     871           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     872             :                                                MaterialNames(1),
     873             :                                                minAngValue));
     874           0 :                         ShowContinueError(
     875             :                             state,
     876           0 :                             format("{} requires the minumum value = 0.0 in the entered table name={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     877             :                     }
     878           1 :                     if (std::abs(maxAngValue - 90.0) > 1.0e-6) {
     879           0 :                         ErrorsFound = true;
     880           0 :                         ShowSevereError(state,
     881           0 :                                         format("{}=\"{}\", Invalid maximum value of angle = {:.2R}.",
     882           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     883             :                                                MaterialNames(1),
     884             :                                                maxAngValue));
     885           0 :                         ShowContinueError(
     886             :                             state,
     887           0 :                             format("{} requires the maximum value = 90.0 in the entered table name={}", ipsc->cAlphaFieldNames(5), MaterialNames(5)));
     888             :                     }
     889           1 :                     if (minLamValue < 0.1) {
     890           0 :                         ErrorsFound = true;
     891           0 :                         ShowSevereError(state,
     892           0 :                                         format("{}=\"{}\", Invalid minimum value of wavelength = {:.2R}.",
     893           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     894             :                                                MaterialNames(1),
     895             :                                                minLamValue));
     896           0 :                         ShowContinueError(state,
     897           0 :                                           format("{} requires the minumum value = 0.1 micron in the entered table name={}",
     898           0 :                                                  ipsc->cAlphaFieldNames(5),
     899             :                                                  MaterialNames(5)));
     900             :                     }
     901           1 :                     if (maxLamValue > 4.0) {
     902           0 :                         ErrorsFound = true;
     903           0 :                         ShowSevereError(state,
     904           0 :                                         format("{}=\"{}\", Invalid maximum value of wavelength = {:.2R}.",
     905           0 :                                                state.dataHeatBalMgr->CurrentModuleObject,
     906             :                                                MaterialNames(1),
     907             :                                                maxLamValue));
     908           0 :                         ShowContinueError(state,
     909           0 :                                           format("{} requires the maximum value = 4.0 microns in the entered table name={}",
     910           0 :                                                  ipsc->cAlphaFieldNames(5),
     911             :                                                  MaterialNames(5)));
     912             :                     }
     913             :                 }
     914             :             }
     915             :         }
     916             :     }
     917             : 
     918             :     // Glass materials, alternative input: index of refraction and extinction coefficient
     919             : 
     920         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Glazing:RefractionExtinctionMethod";
     921         806 :     for (Loop = 1; Loop <= state.dataHeatBal->W5GlsMatAlt; ++Loop) {
     922             : 
     923             :         // Call Input Get routine to retrieve material data
     924          30 :         ip->getObjectItem(state,
     925          10 :                           state.dataHeatBalMgr->CurrentModuleObject,
     926             :                           Loop,
     927             :                           MaterialNames,
     928             :                           MaterialNumAlpha,
     929             :                           MaterialProps,
     930             :                           MaterialNumProp,
     931             :                           IOStat,
     932          10 :                           ipsc->lNumericFieldBlanks,
     933          10 :                           ipsc->lAlphaFieldBlanks,
     934          10 :                           ipsc->cAlphaFieldNames,
     935          10 :                           ipsc->cNumericFieldNames);
     936          20 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
     937          10 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
     938          10 :                                                      MaterialNames(1),
     939          10 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
     940          10 :                                                      ipsc->cAlphaFieldNames(1),
     941             :                                                      ErrorsFound)) {
     942           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
     943           0 :             continue;
     944             :         }
     945             : 
     946          10 :         ++MaterNum;
     947          10 :         auto *thisMaterial = new MaterialChild;
     948          10 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
     949          10 :         thisMaterial->group = Group::WindowGlass;
     950             : 
     951             :         // Load the material derived type from the input data.
     952             : 
     953          10 :         thisMaterial->Name = MaterialNames(1);
     954          10 :         thisMaterial->Roughness = SurfaceRoughness::VerySmooth;
     955          10 :         thisMaterial->Thickness = MaterialProps(1);
     956          10 :         thisMaterial->ROnly = true;
     957             : 
     958             :         // Calculate solar and visible transmittance and reflectance at normal incidence from thickness,
     959             :         // index of refraction and extinction coefficient. With the alternative input the front and back
     960             :         // properties are assumed to be the same.
     961             : 
     962          10 :         ReflectivitySol = pow_2((MaterialProps(2) - 1.0) / (MaterialProps(2) + 1.0));
     963          10 :         ReflectivityVis = pow_2((MaterialProps(4) - 1.0) / (MaterialProps(4) + 1.0));
     964          10 :         TransmittivitySol = std::exp(-MaterialProps(3) * MaterialProps(1));
     965          10 :         TransmittivityVis = std::exp(-MaterialProps(5) * MaterialProps(1));
     966          10 :         thisMaterial->Trans = TransmittivitySol * pow_2(1.0 - ReflectivitySol) / (1.0 - pow_2(ReflectivitySol * TransmittivitySol));
     967          10 :         thisMaterial->ReflectSolBeamFront =
     968          10 :             ReflectivitySol * (1.0 + pow_2(1.0 - ReflectivitySol) * pow_2(TransmittivitySol) / (1.0 - pow_2(ReflectivitySol * TransmittivitySol)));
     969          10 :         thisMaterial->ReflectSolBeamBack = thisMaterial->ReflectSolBeamFront;
     970          10 :         thisMaterial->TransVis = TransmittivityVis * pow_2(1.0 - ReflectivityVis) / (1.0 - pow_2(ReflectivityVis * TransmittivityVis));
     971             : 
     972          10 :         thisMaterial->ReflectVisBeamFront =
     973          10 :             ReflectivityVis * (1.0 + pow_2(1.0 - ReflectivityVis) * pow_2(TransmittivityVis) / (1.0 - pow_2(ReflectivityVis * TransmittivityVis)));
     974          10 :         thisMaterial->ReflectVisBeamBack = thisMaterial->ReflectSolBeamFront;
     975          10 :         thisMaterial->TransThermal = MaterialProps(6);
     976          10 :         thisMaterial->AbsorpThermalFront = MaterialProps(7);
     977          10 :         thisMaterial->AbsorpThermalBack = MaterialProps(7);
     978          10 :         thisMaterial->Conductivity = MaterialProps(8);
     979          10 :         thisMaterial->GlassTransDirtFactor = MaterialProps(9);
     980          10 :         if (MaterialProps(9) == 0.0) thisMaterial->GlassTransDirtFactor = 1.0;
     981          10 :         thisMaterial->AbsorpThermal = thisMaterial->AbsorpThermalBack;
     982             : 
     983          10 :         if (thisMaterial->Conductivity > 0.0) {
     984          10 :             state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Thickness / thisMaterial->Conductivity;
     985          10 :             thisMaterial->Resistance = state.dataHeatBal->NominalR(MaterNum);
     986             :         }
     987             : 
     988          10 :         thisMaterial->GlassSpectralDataPtr = 0;
     989             : 
     990          10 :         if (MaterialProps(6) + MaterialProps(7) >= 1.0) {
     991           0 :             ErrorsFound = true;
     992           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
     993           0 :             ShowContinueError(state, format("{} + {} not < 1.0", ipsc->cNumericFieldNames(6), ipsc->cNumericFieldNames(7)));
     994             :         }
     995             : 
     996          10 :         if (MaterialNames(2) == "") {
     997           0 :             thisMaterial->SolarDiffusing = false;
     998          10 :         } else if (MaterialNames(2) == "YES") {
     999           0 :             thisMaterial->SolarDiffusing = true;
    1000          10 :         } else if (MaterialNames(2) == "NO") {
    1001          10 :             thisMaterial->SolarDiffusing = false;
    1002             :         } else {
    1003           0 :             ErrorsFound = true;
    1004           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    1005           0 :             ShowContinueError(state, format("{} must be Yes or No, entered value={}", ipsc->cNumericFieldNames(2), MaterialNames(4)));
    1006             :         }
    1007             :     }
    1008             : 
    1009             :     // Glass materials, equivalent layer (ASHWAT) method
    1010         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Glazing:EquivalentLayer";
    1011         800 :     for (Loop = 1; Loop <= state.dataHeatBal->W5GlsMatEQL; ++Loop) {
    1012             : 
    1013             :         // Call Input Get routine to retrieve material data
    1014          12 :         ip->getObjectItem(state,
    1015           4 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1016             :                           Loop,
    1017             :                           MaterialNames,
    1018             :                           MaterialNumAlpha,
    1019             :                           MaterialProps,
    1020             :                           MaterialNumProp,
    1021             :                           IOStat,
    1022           4 :                           ipsc->lNumericFieldBlanks,
    1023           4 :                           ipsc->lAlphaFieldBlanks,
    1024           4 :                           ipsc->cAlphaFieldNames,
    1025           4 :                           ipsc->cNumericFieldNames);
    1026           8 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1027           4 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1028           4 :                                                      MaterialNames(1),
    1029           4 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1030           4 :                                                      ipsc->cAlphaFieldNames(1),
    1031             :                                                      ErrorsFound)) {
    1032           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1033           0 :             continue;
    1034             :         }
    1035             : 
    1036           4 :         ++MaterNum;
    1037           4 :         auto *thisMaterial = new MaterialChild;
    1038           4 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    1039           4 :         thisMaterial->group = Group::GlassEquivalentLayer;
    1040             : 
    1041             :         // Load the material derived type from the input data.
    1042           4 :         thisMaterial->Name = MaterialNames(1);
    1043           4 :         thisMaterial->Roughness = SurfaceRoughness::VerySmooth;
    1044           4 :         thisMaterial->ROnly = true;
    1045             : 
    1046           4 :         thisMaterial->TausFrontBeamBeam = MaterialProps(1);
    1047           4 :         thisMaterial->TausBackBeamBeam = MaterialProps(2);
    1048           4 :         thisMaterial->ReflFrontBeamBeam = MaterialProps(3);
    1049           4 :         thisMaterial->ReflBackBeamBeam = MaterialProps(4);
    1050           4 :         thisMaterial->TausFrontBeamBeamVis = MaterialProps(5);
    1051           4 :         thisMaterial->TausBackBeamBeamVis = MaterialProps(6);
    1052           4 :         thisMaterial->ReflFrontBeamBeamVis = MaterialProps(7);
    1053           4 :         thisMaterial->ReflBackBeamBeamVis = MaterialProps(8);
    1054           4 :         thisMaterial->TausFrontBeamDiff = MaterialProps(9);
    1055           4 :         thisMaterial->TausBackBeamDiff = MaterialProps(10);
    1056           4 :         thisMaterial->ReflFrontBeamDiff = MaterialProps(11);
    1057           4 :         thisMaterial->ReflBackBeamDiff = MaterialProps(12);
    1058           4 :         thisMaterial->TausFrontBeamDiffVis = MaterialProps(13);
    1059           4 :         thisMaterial->TausBackBeamDiffVis = MaterialProps(14);
    1060           4 :         thisMaterial->ReflFrontBeamDiffVis = MaterialProps(15);
    1061           4 :         thisMaterial->ReflBackBeamDiffVis = MaterialProps(16);
    1062           4 :         thisMaterial->TausDiffDiff = MaterialProps(17);
    1063           4 :         thisMaterial->ReflFrontDiffDiff = MaterialProps(18);
    1064           4 :         thisMaterial->ReflBackDiffDiff = MaterialProps(19);
    1065           4 :         thisMaterial->TausDiffDiffVis = MaterialProps(20);
    1066           4 :         thisMaterial->ReflFrontDiffDiffVis = MaterialProps(21);
    1067           4 :         thisMaterial->ReflBackDiffDiffVis = MaterialProps(22);
    1068           4 :         thisMaterial->TausThermal = MaterialProps(23);
    1069           4 :         thisMaterial->EmissThermalFront = MaterialProps(24);
    1070           4 :         thisMaterial->EmissThermalBack = MaterialProps(25);
    1071           4 :         thisMaterial->Resistance = MaterialProps(26);
    1072           4 :         if (thisMaterial->Resistance <= 0.0) thisMaterial->Resistance = 0.158; // equivalent to single pane of 1/4" inch standard glass
    1073             :         // Assumes thermal emissivity is the same as thermal absorptance
    1074           4 :         thisMaterial->AbsorpThermalFront = thisMaterial->EmissThermalFront;
    1075           4 :         thisMaterial->AbsorpThermalBack = thisMaterial->EmissThermalBack;
    1076           4 :         thisMaterial->TransThermal = thisMaterial->TausThermal;
    1077             : 
    1078           4 :         if (Util::SameString(MaterialNames(2), "SpectralAverage")) thisMaterial->GlassSpectralDataPtr = 0;
    1079             : 
    1080             :         // IF(dataMaterial.Material(MaterNum)%GlassSpectralDataPtr == 0 .AND. Util::SameString(MaterialNames(2),'Spectral')) THEN
    1081             :         //  ErrorsFound = .TRUE.
    1082             :         //  CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//Trim(dataMaterial.Material(MaterNum)%Name)// &
    1083             :         //        '" has '//TRIM(cAlphaFieldNames(2))//' = Spectral but has no matching MaterialProperty:GlazingSpectralData set')
    1084             :         //  if (ipsc->lAlphaFieldBlanks(3)) THEN
    1085             :         //    CALL ShowContinueError(state, '...'//TRIM(cAlphaFieldNames(3))//' is blank.')
    1086             :         //  ELSE
    1087             :         //    CALL ShowContinueError(state, '...'//TRIM(cAlphaFieldNames(3))//'="'//TRIM(MaterialNames(3))//  &
    1088             :         //       '" not found as item in MaterialProperty:GlazingSpectralData objects.')
    1089             :         //  END IF
    1090             :         // END IF
    1091             : 
    1092           4 :         if (!Util::SameString(MaterialNames(2), "SpectralAverage")) {
    1093           0 :             ErrorsFound = true;
    1094           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + thisMaterial->Name + "\", invalid specification.");
    1095           0 :             ShowContinueError(state, ipsc->cAlphaFieldNames(2) + " must be SpectralAverage, value=" + MaterialNames(2));
    1096             :         }
    1097             : 
    1098             :     } // W5GlsMatEQL loop
    1099             : 
    1100             :     // Window gas materials (for gaps with a single gas)
    1101             : 
    1102         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Gas";
    1103        1609 :     for (Loop = 1; Loop <= state.dataHeatBal->W5GasMat; ++Loop) {
    1104             : 
    1105             :         // Call Input Get routine to retrieve material data
    1106        2439 :         ip->getObjectItem(state,
    1107         813 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1108             :                           Loop,
    1109             :                           MaterialNames,
    1110             :                           MaterialNumAlpha,
    1111             :                           MaterialProps,
    1112             :                           MaterialNumProp,
    1113             :                           IOStat,
    1114         813 :                           ipsc->lNumericFieldBlanks,
    1115         813 :                           ipsc->lAlphaFieldBlanks,
    1116         813 :                           ipsc->cAlphaFieldNames,
    1117         813 :                           ipsc->cNumericFieldNames);
    1118        1626 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1119         813 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1120         813 :                                                      MaterialNames(1),
    1121         813 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1122         813 :                                                      ipsc->cAlphaFieldNames(1),
    1123             :                                                      ErrorsFound)) {
    1124           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1125           0 :             continue;
    1126             :         }
    1127             : 
    1128         813 :         ++MaterNum;
    1129         813 :         auto *matGas = new MaterialGasMix;
    1130         813 :         state.dataMaterial->Material(MaterNum) = matGas;
    1131         813 :         matGas->group = Group::WindowGas;
    1132         813 :         matGas->numGases = 1;
    1133         813 :         matGas->gasFracts[0] = 1.0;
    1134             : 
    1135             :         // Load the material derived type from the input data.
    1136             : 
    1137         813 :         matGas->Name = MaterialNames(1);
    1138         813 :         matGas->gases[0].type = static_cast<GasType>(getEnumValue(gasTypeNamesUC, Util::makeUPPER(MaterialNames(2))));
    1139         813 :         matGas->Roughness = SurfaceRoughness::MediumRough;
    1140             : 
    1141         813 :         matGas->Thickness = MaterialProps(1);
    1142         813 :         matGas->ROnly = true;
    1143             : 
    1144         813 :         gasType = matGas->gases[0].type;
    1145         813 :         if (gasType != GasType::Custom) {
    1146         811 :             matGas->gases[0] = gases[(int)gasType];
    1147             :         }
    1148             : 
    1149             :         // Custom gas
    1150             : 
    1151         813 :         if (gasType == GasType::Custom) {
    1152           2 :             matGas->gases[0].con.c0 = MaterialProps(2);
    1153           2 :             matGas->gases[0].con.c1 = MaterialProps(3);
    1154           2 :             matGas->gases[0].con.c2 = MaterialProps(4);
    1155           2 :             matGas->gases[0].vis.c0 = MaterialProps(5);
    1156           2 :             matGas->gases[0].vis.c1 = MaterialProps(6);
    1157           2 :             matGas->gases[0].vis.c2 = MaterialProps(7);
    1158           2 :             matGas->gases[0].cp.c0 = MaterialProps(8);
    1159           2 :             matGas->gases[0].cp.c1 = MaterialProps(9);
    1160           2 :             matGas->gases[0].cp.c2 = MaterialProps(10);
    1161           2 :             matGas->gases[0].wght = MaterialProps(11);
    1162           2 :             matGas->gases[0].specHeatRatio = MaterialProps(12);
    1163             : 
    1164             :             // Check for errors in custom gas properties
    1165             :             //      IF(dataMaterial.Material(MaterNum)%GasCon(1,1) <= 0.0) THEN
    1166             :             //        ErrorsFound = .TRUE.
    1167             :             //        CALL ShowSevereError(state, 'Conductivity Coefficient A for custom window gas='&
    1168             :             //                 //TRIM(MaterialNames(1))//' should be > 0.')
    1169             :             //      END IF
    1170             : 
    1171           2 :             if (matGas->gases[0].vis.c0 <= 0.0) {
    1172           0 :                 ErrorsFound = true;
    1173           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1174           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(5) + " not > 0.0");
    1175             :             }
    1176           2 :             if (matGas->gases[0].cp.c0 <= 0.0) {
    1177           0 :                 ErrorsFound = true;
    1178           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1179           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(8) + " not > 0.0");
    1180             :             }
    1181           2 :             if (matGas->gases[0].wght <= 0.0) {
    1182           0 :                 ErrorsFound = true;
    1183           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1184           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(11) + " not > 0.0");
    1185             :             }
    1186             :         }
    1187             : 
    1188             :         // Nominal resistance of gap at room temperature
    1189         813 :         if (!ErrorsFound) {
    1190         813 :             DenomRGas = (matGas->gases[0].con.c0 + matGas->gases[0].con.c1 * 300.0 + matGas->gases[0].con.c2 * 90000.0);
    1191         813 :             if (DenomRGas > 0.0) {
    1192         813 :                 state.dataHeatBal->NominalR(MaterNum) = matGas->Thickness / DenomRGas;
    1193             :             } else {
    1194           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1195           0 :                 ShowContinueError(state,
    1196           0 :                                   format("Nominal resistance of gap at room temperature calculated at a negative Conductivity=[{:.3R}].", DenomRGas));
    1197           0 :                 ErrorsFound = true;
    1198             :             }
    1199             :         }
    1200             :     }
    1201             : 
    1202             :     // Window gap materials (for gaps with a single gas for EquivalentLayer)
    1203             : 
    1204         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Gap:EquivalentLayer";
    1205         804 :     for (Loop = 1; Loop <= state.dataHeatBal->W5GapMatEQL; ++Loop) {
    1206             : 
    1207             :         // Call Input Get routine to retrieve material data
    1208          24 :         ip->getObjectItem(state,
    1209           8 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1210             :                           Loop,
    1211             :                           MaterialNames,
    1212             :                           MaterialNumAlpha,
    1213             :                           MaterialProps,
    1214             :                           MaterialNumProp,
    1215             :                           IOStat,
    1216           8 :                           ipsc->lNumericFieldBlanks,
    1217           8 :                           ipsc->lAlphaFieldBlanks,
    1218           8 :                           ipsc->cAlphaFieldNames,
    1219           8 :                           ipsc->cNumericFieldNames);
    1220          16 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1221           8 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1222           8 :                                                      MaterialNames(1),
    1223           8 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1224           8 :                                                      ipsc->cAlphaFieldNames(1),
    1225             :                                                      ErrorsFound)) {
    1226           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1227           0 :             continue;
    1228             :         }
    1229             : 
    1230           8 :         ++MaterNum;
    1231           8 :         auto *matGas = new MaterialGasMix;
    1232           8 :         state.dataMaterial->Material(MaterNum) = matGas;
    1233           8 :         matGas->group = Group::GapEquivalentLayer;
    1234           8 :         matGas->numGases = 1;
    1235           8 :         matGas->gasFracts[0] = 1.0;
    1236             : 
    1237             :         // Load the material derived type from the input data.
    1238             : 
    1239           8 :         matGas->Name = MaterialNames(1);
    1240           8 :         matGas->gases[0].type = static_cast<GasType>(getEnumValue(gasTypeNamesUC, Util::makeUPPER(MaterialNames(2)))); // Error check?
    1241             : 
    1242           8 :         matGas->Roughness = SurfaceRoughness::MediumRough;
    1243             : 
    1244           8 :         matGas->Thickness = MaterialProps(1);
    1245           8 :         matGas->ROnly = true;
    1246             : 
    1247           8 :         gasType = matGas->gases[0].type;
    1248           8 :         if (gasType != GasType::Custom) {
    1249           8 :             matGas->gases[0] = gases[(int)gasType];
    1250             :         }
    1251             : 
    1252           8 :         if (!ipsc->lAlphaFieldBlanks(2)) {
    1253             :             // Get gap vent type
    1254           8 :             matGas->gapVentType = static_cast<GapVentType>(getEnumValue(gapVentTypeNamesUC, Util::makeUPPER(MaterialNames(3))));
    1255             :         }
    1256             : 
    1257           8 :         if (gasType == GasType::Custom) {
    1258           0 :             for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
    1259           0 :                 matGas->gases[0].con.c0 = MaterialProps(2);
    1260           0 :                 matGas->gases[0].con.c1 = MaterialProps(3);
    1261           0 :                 matGas->gases[0].con.c2 = MaterialProps(4);
    1262           0 :                 matGas->gases[0].vis.c0 = MaterialProps(5);
    1263           0 :                 matGas->gases[0].vis.c1 = MaterialProps(6);
    1264           0 :                 matGas->gases[0].vis.c2 = MaterialProps(7);
    1265           0 :                 matGas->gases[0].cp.c0 = MaterialProps(8);
    1266           0 :                 matGas->gases[0].cp.c1 = MaterialProps(9);
    1267           0 :                 matGas->gases[0].cp.c2 = MaterialProps(10);
    1268             :             }
    1269           0 :             matGas->gases[0].wght = MaterialProps(11);
    1270           0 :             matGas->gases[0].specHeatRatio = MaterialProps(12);
    1271             : 
    1272           0 :             if (matGas->gases[0].vis.c0 <= 0.0) {
    1273           0 :                 ErrorsFound = true;
    1274           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    1275           0 :                 ShowContinueError(state, format("{} not > 0.0", ipsc->cNumericFieldNames(5)));
    1276             :             }
    1277           0 :             if (matGas->gases[0].cp.c0 <= 0.0) {
    1278           0 :                 ErrorsFound = true;
    1279           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    1280           0 :                 ShowContinueError(state, format("{} not > 0.0", ipsc->cNumericFieldNames(8)));
    1281             :             }
    1282           0 :             if (matGas->gases[0].wght <= 0.0) {
    1283           0 :                 ErrorsFound = true;
    1284           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    1285           0 :                 ShowContinueError(state, format("{} not > 0.0", ipsc->cNumericFieldNames(11)));
    1286             :             }
    1287             :         }
    1288             : 
    1289             :         // Nominal resistance of gap at room temperature
    1290           8 :         if (!ErrorsFound) {
    1291           8 :             DenomRGas = (matGas->gases[0].con.c0 + matGas->gases[0].con.c1 * 300.0 + matGas->gases[0].con.c2 * 90000.0);
    1292           8 :             if (DenomRGas > 0.0) {
    1293           8 :                 state.dataHeatBal->NominalR(MaterNum) = matGas->Thickness / DenomRGas;
    1294             :             } else {
    1295           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    1296           0 :                 ShowContinueError(state,
    1297           0 :                                   format("Nominal resistance of gap at room temperature calculated at a negative Conductivity=[{:.3R}].", DenomRGas));
    1298           0 :                 ErrorsFound = true;
    1299             :             }
    1300             :         }
    1301             :     } // for (Loop : W5MatEQL)
    1302             : 
    1303             :     // Window gas mixtures (for gaps with two or more gases)
    1304             : 
    1305         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:GasMixture";
    1306         812 :     for (Loop = 1; Loop <= state.dataHeatBal->W5GasMatMixture; ++Loop) {
    1307             : 
    1308             :         // Call Input Get routine to retrieve material data
    1309          32 :         ip->getObjectItem(state,
    1310          16 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1311             :                           Loop,
    1312          16 :                           ipsc->cAlphaArgs,
    1313             :                           MaterialNumAlpha,
    1314             :                           MaterialProps,
    1315             :                           MaterialNumProp,
    1316             :                           IOStat,
    1317          16 :                           ipsc->lNumericFieldBlanks,
    1318          16 :                           ipsc->lAlphaFieldBlanks,
    1319          16 :                           ipsc->cAlphaFieldNames,
    1320          16 :                           ipsc->cNumericFieldNames);
    1321          32 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1322          16 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1323          16 :                                                      ipsc->cAlphaArgs(1),
    1324          16 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1325          16 :                                                      ipsc->cAlphaFieldNames(1),
    1326             :                                                      ErrorsFound)) {
    1327           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1328           0 :             continue;
    1329             :         }
    1330             : 
    1331          16 :         ++MaterNum;
    1332          16 :         auto *matGas = new MaterialGasMix;
    1333          16 :         state.dataMaterial->Material(MaterNum) = matGas;
    1334          16 :         matGas->group = Group::WindowGasMixture;
    1335          16 :         matGas->gases[0].type = matGas->gases[1].type = matGas->gases[2].type = matGas->gases[3].type = matGas->gases[4].type = GasType::Invalid;
    1336             : 
    1337             :         // Load the material derived type from the input data.
    1338             : 
    1339          16 :         matGas->Name = ipsc->cAlphaArgs(1);
    1340          16 :         NumGases = MaterialProps(2);
    1341          16 :         matGas->numGases = NumGases;
    1342          48 :         for (NumGas = 0; NumGas < NumGases; ++NumGas) {
    1343          32 :             auto &gas = matGas->gases[NumGas];
    1344          32 :             gas.type = static_cast<GasType>(getEnumValue(gasTypeNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(2 + NumGas))));
    1345          32 :             if (gas.type == GasType::Invalid) {
    1346           0 :                 ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, ipsc->cAlphaArgs(1 + NumGas)));
    1347             :                 // Error check?
    1348           0 :                 ErrorsFound = true;
    1349             :             }
    1350             :         }
    1351             : 
    1352          16 :         matGas->Roughness = SurfaceRoughness::MediumRough; // Unused
    1353             : 
    1354          16 :         matGas->Thickness = MaterialProps(1);
    1355          16 :         if (matGas->Thickness <= 0.0) {
    1356           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, ipsc->cAlphaArgs(1)));
    1357           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(1) + " must be greater than 0.");
    1358             :         }
    1359          16 :         matGas->ROnly = true;
    1360             : 
    1361          48 :         for (NumGas = 0; NumGas < NumGases; ++NumGas) {
    1362          32 :             GasType gasType = matGas->gases[NumGas].type;
    1363          32 :             if (gasType != GasType::Custom) {
    1364          32 :                 matGas->gasFracts[NumGas] = MaterialProps(3 + NumGas);
    1365          32 :                 matGas->gases[NumGas] = gases[(int)gasType];
    1366             :             }
    1367             :         }
    1368             : 
    1369             :         // Nominal resistance of gap at room temperature (based on first gas in mixture)
    1370          16 :         state.dataHeatBal->NominalR(MaterNum) =
    1371          16 :             matGas->Thickness / (matGas->gases[0].con.c0 + matGas->gases[0].con.c1 * 300.0 + matGas->gases[0].con.c2 * 90000.0);
    1372             :     }
    1373             : 
    1374             :     // Window Shade Materials
    1375             : 
    1376         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Shade";
    1377         813 :     for (Loop = 1; Loop <= state.dataHeatBal->TotShades; ++Loop) {
    1378             : 
    1379             :         // Call Input Get routine to retrieve material data
    1380          51 :         ip->getObjectItem(state,
    1381          17 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1382             :                           Loop,
    1383             :                           MaterialNames,
    1384             :                           MaterialNumAlpha,
    1385             :                           MaterialProps,
    1386             :                           MaterialNumProp,
    1387             :                           IOStat,
    1388          17 :                           ipsc->lNumericFieldBlanks,
    1389          17 :                           ipsc->lAlphaFieldBlanks,
    1390          17 :                           ipsc->cAlphaFieldNames,
    1391          17 :                           ipsc->cNumericFieldNames);
    1392          34 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1393          17 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1394          17 :                                                      MaterialNames(1),
    1395          17 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1396          17 :                                                      ipsc->cAlphaFieldNames(1),
    1397             :                                                      ErrorsFound)) {
    1398           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1399           0 :             continue;
    1400             :         }
    1401             : 
    1402          17 :         ++MaterNum;
    1403          17 :         auto *thisMaterial = new MaterialChild;
    1404          17 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    1405          17 :         thisMaterial->group = Group::Shade;
    1406             : 
    1407             :         // Load the material derived type from the input data.
    1408             : 
    1409          17 :         thisMaterial->Name = MaterialNames(1);
    1410          17 :         thisMaterial->Roughness = SurfaceRoughness::MediumRough;
    1411          17 :         thisMaterial->Trans = MaterialProps(1);
    1412          17 :         thisMaterial->ReflectShade = MaterialProps(2);
    1413          17 :         thisMaterial->TransVis = MaterialProps(3);
    1414          17 :         thisMaterial->ReflectShadeVis = MaterialProps(4);
    1415          17 :         thisMaterial->AbsorpThermal = MaterialProps(5);
    1416          17 :         thisMaterial->AbsorpThermalInput = MaterialProps(5);
    1417          17 :         thisMaterial->TransThermal = MaterialProps(6);
    1418          17 :         thisMaterial->Thickness = MaterialProps(7);
    1419          17 :         thisMaterial->Conductivity = MaterialProps(8);
    1420          17 :         thisMaterial->AbsorpSolar = max(0.0, 1.0 - thisMaterial->Trans - thisMaterial->ReflectShade);
    1421          17 :         thisMaterial->AbsorpSolarInput = thisMaterial->AbsorpSolar;
    1422          17 :         thisMaterial->WinShadeToGlassDist = MaterialProps(9);
    1423          17 :         thisMaterial->WinShadeTopOpeningMult = MaterialProps(10);
    1424          17 :         thisMaterial->WinShadeBottomOpeningMult = MaterialProps(11);
    1425          17 :         thisMaterial->WinShadeLeftOpeningMult = MaterialProps(12);
    1426          17 :         thisMaterial->WinShadeRightOpeningMult = MaterialProps(13);
    1427          17 :         thisMaterial->WinShadeAirFlowPermeability = MaterialProps(14);
    1428          17 :         thisMaterial->ROnly = true;
    1429             : 
    1430          17 :         if (thisMaterial->Conductivity > 0.0) {
    1431          17 :             state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Thickness / thisMaterial->Conductivity;
    1432             :         } else {
    1433           0 :             state.dataHeatBal->NominalR(MaterNum) = 1.0;
    1434             :         }
    1435             : 
    1436          17 :         if (MaterialProps(1) + MaterialProps(2) >= 1.0) {
    1437           0 :             ErrorsFound = true;
    1438           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1439           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(1) + " + " + ipsc->cNumericFieldNames(2) + " not < 1.0");
    1440             :         }
    1441             : 
    1442          17 :         if (MaterialProps(3) + MaterialProps(4) >= 1.0) {
    1443           0 :             ErrorsFound = true;
    1444           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1445           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(3) + " + " + ipsc->cNumericFieldNames(4) + " not < 1.0");
    1446             :         }
    1447             : 
    1448          17 :         if (MaterialProps(5) + MaterialProps(6) >= 1.0) {
    1449           0 :             ErrorsFound = true;
    1450           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1451           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(5) + " + " + ipsc->cNumericFieldNames(6) + " not < 1.0");
    1452             :         }
    1453             :     }
    1454             : 
    1455             :     // Window Shade Materials
    1456             : 
    1457         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Shade:EquivalentLayer";
    1458         798 :     for (Loop = 1; Loop <= state.dataHeatBal->TotShadesEQL; ++Loop) {
    1459             : 
    1460           2 :         MaterialProps = 0;
    1461             : 
    1462             :         // Call Input Get routine to retrieve material data
    1463           6 :         ip->getObjectItem(state,
    1464           2 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1465             :                           Loop,
    1466             :                           MaterialNames,
    1467             :                           MaterialNumAlpha,
    1468             :                           MaterialProps,
    1469             :                           MaterialNumProp,
    1470             :                           IOStat,
    1471           2 :                           ipsc->lNumericFieldBlanks,
    1472           2 :                           ipsc->lAlphaFieldBlanks,
    1473           2 :                           ipsc->cAlphaFieldNames,
    1474           2 :                           ipsc->cNumericFieldNames);
    1475           4 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1476           2 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1477           2 :                                                      MaterialNames(1),
    1478           2 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1479           2 :                                                      ipsc->cAlphaFieldNames(1),
    1480             :                                                      ErrorsFound)) {
    1481           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1482           0 :             continue;
    1483             :         }
    1484             : 
    1485           2 :         ++MaterNum;
    1486           2 :         auto *thisMaterial = new MaterialChild;
    1487           2 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    1488           2 :         thisMaterial->group = Group::ShadeEquivalentLayer;
    1489             : 
    1490           2 :         thisMaterial->Name = MaterialNames(1);
    1491           2 :         thisMaterial->Roughness = SurfaceRoughness::MediumRough;
    1492           2 :         thisMaterial->ROnly = true;
    1493             : 
    1494             :         //  Front side and back side have the same beam-Beam Transmittance
    1495           2 :         thisMaterial->TausFrontBeamBeam = MaterialProps(1);
    1496           2 :         thisMaterial->TausBackBeamBeam = MaterialProps(1);
    1497           2 :         thisMaterial->TausFrontBeamDiff = MaterialProps(2);
    1498           2 :         thisMaterial->TausBackBeamDiff = MaterialProps(3);
    1499           2 :         thisMaterial->ReflFrontBeamDiff = MaterialProps(4);
    1500           2 :         thisMaterial->ReflBackBeamDiff = MaterialProps(5);
    1501           2 :         thisMaterial->TausFrontBeamBeamVis = MaterialProps(6);
    1502           2 :         thisMaterial->TausFrontBeamDiffVis = MaterialProps(7);
    1503           2 :         thisMaterial->ReflFrontBeamDiffVis = MaterialProps(8);
    1504           2 :         thisMaterial->TausThermal = MaterialProps(9);
    1505           2 :         thisMaterial->EmissThermalFront = MaterialProps(10);
    1506           2 :         thisMaterial->EmissThermalBack = MaterialProps(11);
    1507             :         // Assumes thermal emissivity is the same as thermal absorptance
    1508           2 :         thisMaterial->AbsorpThermalFront = thisMaterial->EmissThermalFront;
    1509           2 :         thisMaterial->AbsorpThermalBack = thisMaterial->EmissThermalBack;
    1510           2 :         thisMaterial->TransThermal = thisMaterial->TausThermal;
    1511             : 
    1512           2 :         if (MaterialProps(1) + MaterialProps(2) + MaterialProps(4) >= 1.0) {
    1513           0 :             ErrorsFound = true;
    1514           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1515           0 :             ShowContinueError(state,
    1516           0 :                               ipsc->cNumericFieldNames(1) + " + " + ipsc->cNumericFieldNames(2) + " + " + ipsc->cNumericFieldNames(4) + "not < 1.0");
    1517             :         }
    1518           2 :         if (MaterialProps(1) + MaterialProps(3) + MaterialProps(5) >= 1.0) {
    1519           0 :             ErrorsFound = true;
    1520           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1521           0 :             ShowContinueError(state,
    1522           0 :                               ipsc->cNumericFieldNames(1) + " + " + ipsc->cNumericFieldNames(3) + " + " + ipsc->cNumericFieldNames(5) + "not < 1.0");
    1523             :         }
    1524           2 :         if (MaterialProps(6) + MaterialProps(7) + MaterialProps(8) >= 1.0) {
    1525           0 :             ErrorsFound = true;
    1526           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1527           0 :             ShowContinueError(state,
    1528           0 :                               ipsc->cNumericFieldNames(6) + " + " + ipsc->cNumericFieldNames(7) + " + " + ipsc->cNumericFieldNames(8) + "not < 1.0");
    1529             :         }
    1530           2 :         if (MaterialProps(9) + MaterialProps(10) >= 1.0) {
    1531           0 :             ErrorsFound = true;
    1532           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1533           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(9) + " + " + ipsc->cNumericFieldNames(10) + " not < 1.0");
    1534             :         }
    1535           2 :         if (MaterialProps(9) + MaterialProps(11) >= 1.0) {
    1536           0 :             ErrorsFound = true;
    1537           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1538           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(9) + " + " + ipsc->cNumericFieldNames(11) + " not < 1.0");
    1539             :         }
    1540             : 
    1541             :     } // TotShadesEQL loop
    1542             : 
    1543             :     // Window drape materials
    1544             : 
    1545         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Drape:EquivalentLayer";
    1546         796 :     for (Loop = 1; Loop <= state.dataHeatBal->TotDrapesEQL; ++Loop) {
    1547             : 
    1548           0 :         MaterialProps = 0;
    1549             : 
    1550             :         // Call Input Get routine to retrieve material data
    1551           0 :         ip->getObjectItem(state,
    1552           0 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1553             :                           Loop,
    1554             :                           MaterialNames,
    1555             :                           MaterialNumAlpha,
    1556             :                           MaterialProps,
    1557             :                           MaterialNumProp,
    1558             :                           IOStat,
    1559           0 :                           ipsc->lNumericFieldBlanks,
    1560           0 :                           ipsc->lAlphaFieldBlanks,
    1561           0 :                           ipsc->cAlphaFieldNames,
    1562           0 :                           ipsc->cNumericFieldNames);
    1563           0 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1564           0 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1565           0 :                                                      MaterialNames(1),
    1566           0 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1567           0 :                                                      ipsc->cAlphaFieldNames(1),
    1568             :                                                      ErrorsFound)) {
    1569           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1570           0 :             continue;
    1571             :         }
    1572             : 
    1573           0 :         ++MaterNum;
    1574           0 :         auto *thisMaterial = new MaterialChild;
    1575           0 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    1576           0 :         thisMaterial->group = Group::DrapeEquivalentLayer;
    1577             : 
    1578           0 :         thisMaterial->Name = MaterialNames(1);
    1579           0 :         thisMaterial->Roughness = SurfaceRoughness::MediumRough;
    1580           0 :         thisMaterial->ROnly = true;
    1581             : 
    1582             :         //  Front side and back side have the same properties
    1583           0 :         thisMaterial->TausFrontBeamBeam = MaterialProps(1);
    1584           0 :         thisMaterial->TausBackBeamBeam = MaterialProps(1);
    1585             : 
    1586           0 :         thisMaterial->TausFrontBeamDiff = MaterialProps(2);
    1587           0 :         thisMaterial->TausBackBeamDiff = MaterialProps(3);
    1588             : 
    1589           0 :         thisMaterial->ReflFrontBeamDiff = MaterialProps(4);
    1590           0 :         thisMaterial->ReflBackBeamDiff = MaterialProps(5);
    1591           0 :         thisMaterial->TausFrontBeamBeamVis = MaterialProps(6);
    1592           0 :         thisMaterial->TausFrontBeamDiffVis = MaterialProps(7);
    1593           0 :         thisMaterial->ReflFrontBeamDiffVis = MaterialProps(8);
    1594           0 :         thisMaterial->TausThermal = MaterialProps(9);
    1595           0 :         thisMaterial->EmissThermalFront = MaterialProps(10);
    1596           0 :         thisMaterial->EmissThermalBack = MaterialProps(11);
    1597             :         // Assumes thermal emissivity is the same as thermal absorptance
    1598           0 :         thisMaterial->AbsorpThermalFront = thisMaterial->EmissThermalFront;
    1599           0 :         thisMaterial->AbsorpThermalBack = thisMaterial->EmissThermalBack;
    1600           0 :         thisMaterial->TransThermal = thisMaterial->TausThermal;
    1601             : 
    1602           0 :         if (!ipsc->lNumericFieldBlanks(12) && !ipsc->lNumericFieldBlanks(13)) {
    1603           0 :             if (MaterialProps(12) != 0.0 && MaterialProps(13) != 0.0) {
    1604           0 :                 thisMaterial->PleatedDrapeWidth = MaterialProps(12);
    1605           0 :                 thisMaterial->PleatedDrapeLength = MaterialProps(13);
    1606           0 :                 thisMaterial->ISPleatedDrape = true;
    1607             :             }
    1608             :         } else {
    1609           0 :             thisMaterial->ISPleatedDrape = false;
    1610             :         }
    1611           0 :         if (MaterialProps(1) + MaterialProps(2) + MaterialProps(4) >= 1.0) {
    1612           0 :             ErrorsFound = true;
    1613           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1614           0 :             ShowContinueError(state,
    1615           0 :                               ipsc->cNumericFieldNames(1) + " + " + ipsc->cNumericFieldNames(2) + " + " + ipsc->cNumericFieldNames(4) + "not < 1.0");
    1616             :         }
    1617           0 :         if (MaterialProps(6) + MaterialProps(7) + MaterialProps(8) >= 1.0) {
    1618           0 :             ErrorsFound = true;
    1619           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1620           0 :             ShowContinueError(state,
    1621           0 :                               ipsc->cNumericFieldNames(4) + " + " + ipsc->cNumericFieldNames(5) + " + " + ipsc->cNumericFieldNames(6) + "not < 1.0");
    1622             :         }
    1623           0 :         if (MaterialProps(9) + MaterialProps(10) > 1.0) {
    1624           0 :             ErrorsFound = true;
    1625           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1626           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(9) + " + " + ipsc->cNumericFieldNames(10) + " not < 1.0");
    1627             :         }
    1628             : 
    1629             :     } // TotDrapesEQL loop
    1630             : 
    1631             :     // Window Screen Materials
    1632             : 
    1633         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Screen";
    1634         798 :     for (Loop = 1; Loop <= state.dataHeatBal->TotScreens; ++Loop) {
    1635             : 
    1636             :         // Call GetObjectItem routine to retrieve material data
    1637           6 :         ip->getObjectItem(state,
    1638           2 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1639             :                           Loop,
    1640             :                           MaterialNames,
    1641             :                           MaterialNumAlpha,
    1642             :                           MaterialProps,
    1643             :                           MaterialNumProp,
    1644             :                           IOStat,
    1645           2 :                           ipsc->lNumericFieldBlanks,
    1646           2 :                           ipsc->lAlphaFieldBlanks,
    1647           2 :                           ipsc->cAlphaFieldNames,
    1648           2 :                           ipsc->cNumericFieldNames);
    1649           4 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1650           2 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1651           2 :                                                      MaterialNames(1),
    1652           2 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1653           2 :                                                      ipsc->cAlphaFieldNames(1),
    1654             :                                                      ErrorsFound)) {
    1655           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1656           0 :             continue;
    1657             :         }
    1658             : 
    1659           2 :         ++MaterNum;
    1660           2 :         auto *matScreen = new MaterialScreen;
    1661           2 :         state.dataMaterial->Material(MaterNum) = matScreen;
    1662             : 
    1663             :         // Load the material derived type from the input data.
    1664             : 
    1665           2 :         matScreen->Name = MaterialNames(1);
    1666           2 :         matScreen->bmRefModel =
    1667           2 :             static_cast<ScreenBeamReflectanceModel>(getEnumValue(screenBeamReflectanceModelNamesUC, Util::makeUPPER(MaterialNames(2))));
    1668           2 :         if (matScreen->bmRefModel == ScreenBeamReflectanceModel::Invalid) {
    1669           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    1670           0 :             ShowContinueError(
    1671             :                 state,
    1672           0 :                 format("{}=\"{}\", must be one of DoNotModel, ModelAsDirectBeam or ModelAsDiffuse.", ipsc->cAlphaFieldNames(2), MaterialNames(2)));
    1673           0 :             ErrorsFound = true;
    1674             :         }
    1675           2 :         matScreen->Roughness = SurfaceRoughness::MediumRough;
    1676           2 :         matScreen->ShadeRef = MaterialProps(1);
    1677           2 :         if (matScreen->ShadeRef < 0.0 || matScreen->ShadeRef > 1.0) {
    1678           0 :             ErrorsFound = true;
    1679           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1680           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(1) + " must be >= 0 and <= 1");
    1681             :         }
    1682           2 :         matScreen->ShadeRefVis = MaterialProps(2);
    1683           2 :         if (matScreen->ShadeRefVis < 0.0 || matScreen->ShadeRefVis > 1.0) {
    1684           0 :             ErrorsFound = true;
    1685           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1686           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(2) + " must be >= 0 and <= 1 for material " + matScreen->Name + '.');
    1687             :         }
    1688           2 :         matScreen->AbsorpThermal = MaterialProps(3);
    1689           2 :         matScreen->AbsorpThermalInput = MaterialProps(3);
    1690           2 :         if (matScreen->AbsorpThermal < 0.0 || matScreen->AbsorpThermal > 1.0) {
    1691           0 :             ErrorsFound = true;
    1692           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1693           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(3) + " must be >= 0 and <= 1");
    1694             :         }
    1695           2 :         matScreen->Conductivity = MaterialProps(4);
    1696           2 :         matScreen->Thickness = MaterialProps(6); // thickness = diameter
    1697             : 
    1698           2 :         if (MaterialProps(5) > 0.0) {
    1699             :             //      Screens(ScNum)%ScreenDiameterToSpacingRatio = MaterialProps(6)/MaterialProps(5) or
    1700             :             //      1-SQRT(dataMaterial.Material(MaterNum)%Trans
    1701           2 :             if (MaterialProps(6) / MaterialProps(5) >= 1.0) {
    1702           0 :                 ErrorsFound = true;
    1703           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1704           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(6) + " must be less than " + ipsc->cNumericFieldNames(5));
    1705             :             } else {
    1706             :                 //       Calculate direct normal transmittance (open area fraction)
    1707           2 :                 matScreen->Trans = pow_2(1.0 - MaterialProps(6) / MaterialProps(5));
    1708             :             }
    1709             :         } else {
    1710           0 :             ErrorsFound = true;
    1711           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1712           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(5) + " must be > 0.");
    1713           0 :             MaterialProps(5) = 0.000000001;
    1714             :         }
    1715             : 
    1716           2 :         if (MaterialProps(6) <= 0.0) {
    1717           0 :             ErrorsFound = true;
    1718           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1719           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(6) + " must be > 0.");
    1720             :         }
    1721             : 
    1722             :         //   Modify reflectance to account for the open area in the screen assembly
    1723           2 :         matScreen->ShadeRef *= (1.0 - matScreen->Trans);
    1724           2 :         matScreen->ShadeRefVis *= (1.0 - matScreen->Trans);
    1725             : 
    1726           2 :         matScreen->toGlassDist = MaterialProps(7);
    1727           2 :         if (matScreen->toGlassDist < 0.001 || matScreen->toGlassDist > 1.0) {
    1728           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1729           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(7) + " must be greater than or equal to 0.001 and less than or equal to 1.");
    1730             :         }
    1731             : 
    1732           2 :         matScreen->topOpeningMult = MaterialProps(8);
    1733           2 :         if (matScreen->topOpeningMult < 0.0 || matScreen->topOpeningMult > 1.0) {
    1734           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1735           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(8) + " must be greater than or equal to 0 and less than or equal to 1.");
    1736             :         }
    1737             : 
    1738           2 :         matScreen->bottomOpeningMult = MaterialProps(9);
    1739           2 :         if (matScreen->bottomOpeningMult < 0.0 || matScreen->bottomOpeningMult > 1.0) {
    1740           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1741           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(9) + " must be greater than or equal to 0 and less than or equal to 1.");
    1742             :         }
    1743             : 
    1744           2 :         matScreen->leftOpeningMult = MaterialProps(10);
    1745           2 :         if (matScreen->leftOpeningMult < 0.0 || matScreen->leftOpeningMult > 1.0) {
    1746           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1747           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(10) + " must be greater than or equal to 0 and less than or equal to 1.");
    1748             :         }
    1749             : 
    1750           2 :         matScreen->rightOpeningMult = MaterialProps(11);
    1751           2 :         if (matScreen->rightOpeningMult < 0.0 || matScreen->rightOpeningMult > 1.0) {
    1752           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1753           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(11) + " must be greater than or equal to 0 and less than or equal to 1.");
    1754             :         }
    1755             : 
    1756           2 :         matScreen->mapDegResolution = MaterialProps(12);
    1757           2 :         if (matScreen->mapDegResolution < 0 || matScreen->mapDegResolution > 5 || matScreen->mapDegResolution == 4) {
    1758           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1759           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(12) + " must be 0, 1, 2, 3, or 5.");
    1760           0 :             ErrorsFound = true;
    1761             :         }
    1762             : 
    1763             :         //   Default air flow permeability to open area fraction
    1764           2 :         matScreen->airFlowPermeability = matScreen->Trans;
    1765           2 :         matScreen->TransThermal = matScreen->Trans;
    1766           2 :         matScreen->TransVis = matScreen->Trans;
    1767             : 
    1768           2 :         matScreen->ROnly = true;
    1769             : 
    1770             :         //   Calculate absorptance accounting for the open area in the screen assembly (used only in CreateShadedWindowConstruction)
    1771           2 :         matScreen->AbsorpSolar = max(0.0, 1.0 - matScreen->Trans - matScreen->ShadeRef);
    1772           2 :         matScreen->AbsorpSolarInput = matScreen->AbsorpSolar;
    1773           2 :         matScreen->AbsorpVisible = max(0.0, 1.0 - matScreen->TransVis - matScreen->ShadeRefVis);
    1774           2 :         matScreen->AbsorpVisibleInput = matScreen->AbsorpVisible;
    1775           2 :         matScreen->AbsorpThermal *= (1.0 - matScreen->Trans);
    1776           2 :         matScreen->AbsorpThermalInput = matScreen->AbsorpThermal;
    1777             : 
    1778           2 :         if (matScreen->Conductivity > 0.0) {
    1779           2 :             state.dataHeatBal->NominalR(MaterNum) = (1.0 - matScreen->Trans) * matScreen->Thickness / matScreen->Conductivity;
    1780             :         } else {
    1781           0 :             state.dataHeatBal->NominalR(MaterNum) = 1.0;
    1782           0 :             ShowWarningError(
    1783             :                 state,
    1784           0 :                 "Conductivity for material=\"" + matScreen->Name +
    1785             :                     "\" must be greater than 0 for calculating Nominal R-value, Nominal R is defaulted to 1 and the simulation continues.");
    1786             :         }
    1787             : 
    1788           2 :         if (matScreen->Trans + matScreen->ShadeRef >= 1.0) {
    1789           0 :             ErrorsFound = true;
    1790           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1791           0 :             ShowContinueError(state, "Calculated solar transmittance + solar reflectance not < 1.0");
    1792           0 :             ShowContinueError(state, "See Engineering Reference for calculation procedure for solar transmittance.");
    1793             :         }
    1794             : 
    1795           2 :         if (matScreen->TransVis + matScreen->ShadeRefVis >= 1.0) {
    1796           0 :             ErrorsFound = true;
    1797           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1798           0 :             ShowContinueError(state, "Calculated visible transmittance + visible reflectance not < 1.0");
    1799           0 :             ShowContinueError(state, "See Engineering Reference for calculation procedure for visible solar transmittance.");
    1800             :         }
    1801             : 
    1802           2 :         if (matScreen->TransThermal + matScreen->AbsorpThermal >= 1.0) {
    1803           0 :             ErrorsFound = true;
    1804           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1805           0 :             ShowContinueError(state, "Thermal hemispherical emissivity plus open area fraction (1-diameter/spacing)**2 not < 1.0");
    1806             :         }
    1807             :     }
    1808             : 
    1809         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Screen:EquivalentLayer";
    1810         797 :     for (Loop = 1; Loop <= state.dataHeatBal->TotScreensEQL; ++Loop) {
    1811             : 
    1812           1 :         MaterialProps = 0;
    1813             : 
    1814             :         // Call GetObjectItem routine to retrieve material data
    1815           3 :         ip->getObjectItem(state,
    1816           1 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1817             :                           Loop,
    1818             :                           MaterialNames,
    1819             :                           MaterialNumAlpha,
    1820             :                           MaterialProps,
    1821             :                           MaterialNumProp,
    1822             :                           IOStat,
    1823           1 :                           ipsc->lNumericFieldBlanks,
    1824           1 :                           ipsc->lAlphaFieldBlanks,
    1825           1 :                           ipsc->cAlphaFieldNames,
    1826           1 :                           ipsc->cNumericFieldNames);
    1827           2 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1828           1 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1829           1 :                                                      MaterialNames(1),
    1830           1 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1831           1 :                                                      ipsc->cAlphaFieldNames(1),
    1832             :                                                      ErrorsFound)) {
    1833           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1834           0 :             continue;
    1835             :         }
    1836             : 
    1837           1 :         ++MaterNum;
    1838           1 :         auto *matScreen = new MaterialChild;
    1839           1 :         state.dataMaterial->Material(MaterNum) = matScreen;
    1840           1 :         matScreen->group = Group::ScreenEquivalentLayer;
    1841             : 
    1842             :         // Load the material derived type from the input data.
    1843             :         // WindowMaterial:Screen:EquivalentLayer,
    1844           1 :         matScreen->Name = MaterialNames(1);
    1845           1 :         matScreen->Roughness = SurfaceRoughness::MediumRough;
    1846           1 :         matScreen->ROnly = true;
    1847           1 :         matScreen->TausFrontBeamBeam = MaterialProps(1);
    1848           1 :         matScreen->TausBackBeamBeam = MaterialProps(1);
    1849           1 :         matScreen->TausFrontBeamDiff = MaterialProps(2);
    1850           1 :         matScreen->TausBackBeamDiff = MaterialProps(2);
    1851           1 :         matScreen->ReflFrontBeamDiff = MaterialProps(3);
    1852           1 :         matScreen->ReflBackBeamDiff = MaterialProps(3);
    1853           1 :         matScreen->TausFrontBeamBeamVis = MaterialProps(4);
    1854           1 :         matScreen->TausFrontBeamDiffVis = MaterialProps(5);
    1855           1 :         matScreen->ReflFrontDiffDiffVis = MaterialProps(6);
    1856           1 :         matScreen->TausThermal = MaterialProps(7);
    1857           1 :         matScreen->EmissThermalFront = MaterialProps(8);
    1858           1 :         matScreen->EmissThermalBack = MaterialProps(8);
    1859             : 
    1860             :         // Assumes thermal emissivity is the same as thermal absorptance
    1861           1 :         matScreen->AbsorpThermalFront = matScreen->EmissThermalFront;
    1862           1 :         matScreen->AbsorpThermalBack = matScreen->EmissThermalBack;
    1863           1 :         matScreen->TransThermal = matScreen->TausThermal;
    1864             : 
    1865           1 :         if (MaterialProps(3) < 0.0 || MaterialProps(3) > 1.0) {
    1866           0 :             ErrorsFound = true;
    1867           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1868           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(3) + " must be >= 0 and <= 1");
    1869             :         }
    1870             : 
    1871           1 :         if (MaterialProps(6) < 0.0 || MaterialProps(6) > 1.0) {
    1872           0 :             ErrorsFound = true;
    1873           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1874           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(6) + " must be >= 0 and <= 1 for material " + matScreen->Name + '.');
    1875             :         }
    1876             : 
    1877           1 :         if (!ipsc->lNumericFieldBlanks(9)) {
    1878           1 :             if (MaterialProps(9) > 0.00001) {
    1879           1 :                 matScreen->ScreenWireSpacing = MaterialProps(9); // screen wire spacing
    1880             :             } else {
    1881           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1882           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(9) + " must be > 0.");
    1883           0 :                 ShowContinueError(state, "...Setting screen wire spacing to a default value of 0.025m and simulation continues.");
    1884           0 :                 matScreen->ScreenWireSpacing = 0.025;
    1885             :             }
    1886             :         }
    1887             : 
    1888           1 :         if (!ipsc->lNumericFieldBlanks(10)) {
    1889           1 :             if (MaterialProps(10) > 0.00001 && MaterialProps(10) < matScreen->ScreenWireSpacing) {
    1890           1 :                 matScreen->ScreenWireDiameter = MaterialProps(10); // screen wire spacing
    1891             :             } else {
    1892           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
    1893           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(10) + " must be > 0.");
    1894           0 :                 ShowContinueError(state, "...Setting screen wire diameter to a default value of 0.005m and simulation continues.");
    1895           0 :                 matScreen->ScreenWireDiameter = 0.005;
    1896             :             }
    1897             :         }
    1898             : 
    1899           1 :         if (matScreen->ScreenWireSpacing > 0.0) {
    1900           1 :             if (matScreen->ScreenWireDiameter / matScreen->ScreenWireSpacing >= 1.0) {
    1901           0 :                 ErrorsFound = true;
    1902           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1903           0 :                 ShowContinueError(state, ipsc->cNumericFieldNames(10) + " must be less than " + ipsc->cNumericFieldNames(9));
    1904             :             } else {
    1905             :                 //  Calculate direct normal transmittance (open area fraction)
    1906           1 :                 Openness = pow_2(1.0 - matScreen->ScreenWireDiameter / matScreen->ScreenWireSpacing);
    1907           1 :                 if ((matScreen->TausFrontBeamBeam - Openness) / Openness > 0.01) {
    1908           0 :                     ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", screen openness specified.");
    1909           0 :                     ShowContinueError(state, ipsc->cNumericFieldNames(1) + " is > 1.0% of the value calculated from input fields:");
    1910           0 :                     ShowContinueError(state, ipsc->cNumericFieldNames(9) + " and " + (ipsc->cNumericFieldNames(10)));
    1911           0 :                     ShowContinueError(state, " using the formula (1-diameter/spacing)**2");
    1912           0 :                     ShowContinueError(state, " ...the screen diameter is recalculated from the material openness specified ");
    1913           0 :                     ShowContinueError(state, " ...and wire spacing using the formula = wire spacing * (1.0 - SQRT(Opennes))");
    1914           0 :                     matScreen->ScreenWireDiameter = matScreen->ScreenWireSpacing * (1.0 - std::sqrt(matScreen->TausFrontBeamBeam));
    1915           0 :                     ShowContinueError(state, format(" ...Recalculated {}={:.4R} m", ipsc->cNumericFieldNames(10), matScreen->ScreenWireDiameter));
    1916             :                 }
    1917             :             }
    1918             :         }
    1919             : 
    1920           1 :         if (matScreen->TausFrontBeamBeam + matScreen->ReflFrontBeamDiff >= 1.0) {
    1921           0 :             ErrorsFound = true;
    1922           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1923           0 :             ShowContinueError(state, "Calculated solar transmittance + solar reflectance not < 1.0");
    1924           0 :             ShowContinueError(state, "See Engineering Reference for calculation procedure for solar transmittance.");
    1925             :         }
    1926             : 
    1927           1 :         if (matScreen->TausFrontBeamBeamVis + matScreen->ReflFrontDiffDiffVis >= 1.0) {
    1928           0 :             ErrorsFound = true;
    1929           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1930           0 :             ShowContinueError(state, "Calculated visible transmittance + visible reflectance not < 1.0");
    1931           0 :             ShowContinueError(state, "See Engineering Reference for calculation procedure for visible solar transmittance.");
    1932             :         }
    1933           1 :         if (matScreen->TransThermal + matScreen->AbsorpThermal >= 1.0) {
    1934           0 :             ErrorsFound = true;
    1935           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    1936           0 :             ShowContinueError(state, "Thermal hemispherical emissivity plus open area fraction (1-diameter/spacing)**2 not < 1.0");
    1937             :         }
    1938             : 
    1939             :     } // TotScreensEQL loop
    1940             : 
    1941             :     // Window Blind Materials
    1942         796 :     if ((state.dataHeatBal->TotBlindsEQL == 0) && (state.dataHeatBal->TotBlinds == 0)) {
    1943         778 :         state.dataSurface->actualMaxSlatAngs = 1; // first slot is used for shades
    1944             :     }
    1945             : 
    1946         796 :     if (state.dataHeatBal->TotBlinds > 0) {
    1947          18 :         state.dataMaterial->Blind.allocate(state.dataHeatBal->TotBlinds); // Allocate the array Size to the number of blinds
    1948             :     }
    1949             : 
    1950         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Blind";
    1951         814 :     for (Loop = 1; Loop <= state.dataHeatBal->TotBlinds; ++Loop) {
    1952             : 
    1953             :         // Call Input Get routine to retrieve material data
    1954          54 :         ip->getObjectItem(state,
    1955          18 :                           state.dataHeatBalMgr->CurrentModuleObject,
    1956             :                           Loop,
    1957             :                           MaterialNames,
    1958             :                           MaterialNumAlpha,
    1959             :                           MaterialProps,
    1960             :                           MaterialNumProp,
    1961             :                           IOStat,
    1962          18 :                           ipsc->lNumericFieldBlanks,
    1963          18 :                           ipsc->lAlphaFieldBlanks,
    1964          18 :                           ipsc->cAlphaFieldNames,
    1965          18 :                           ipsc->cNumericFieldNames);
    1966          36 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    1967          18 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    1968          18 :                                                      MaterialNames(1),
    1969          18 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    1970          18 :                                                      ipsc->cAlphaFieldNames(1),
    1971             :                                                      ErrorsFound)) {
    1972           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    1973           0 :             continue;
    1974             :         }
    1975             : 
    1976          18 :         ++MaterNum;
    1977          18 :         auto *thisMaterial = new MaterialChild;
    1978          18 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    1979          18 :         thisMaterial->group = Group::WindowBlind;
    1980             : 
    1981             :         // Load the material derived type from the input data.
    1982             : 
    1983          18 :         thisMaterial->Name = MaterialNames(1);
    1984          18 :         state.dataMaterial->Blind(Loop).Name = MaterialNames(1);
    1985          18 :         thisMaterial->Roughness = SurfaceRoughness::Rough;
    1986          18 :         thisMaterial->BlindDataPtr = Loop;
    1987          18 :         thisMaterial->ROnly = true;
    1988             : 
    1989          18 :         state.dataMaterial->Blind(Loop).MaterialNumber = MaterNum;
    1990          18 :         if (Util::SameString(MaterialNames(2), "Horizontal")) {
    1991          18 :             state.dataMaterial->Blind(Loop).SlatOrientation = DataWindowEquivalentLayer::Orientation::Horizontal;
    1992           0 :         } else if (Util::SameString(MaterialNames(2), "Vertical")) {
    1993           0 :             state.dataMaterial->Blind(Loop).SlatOrientation = DataWindowEquivalentLayer::Orientation::Vertical;
    1994             :         }
    1995          18 :         state.dataMaterial->Blind(Loop).SlatWidth = MaterialProps(1);
    1996          18 :         state.dataMaterial->Blind(Loop).SlatSeparation = MaterialProps(2);
    1997          18 :         state.dataMaterial->Blind(Loop).SlatThickness = MaterialProps(3);
    1998          18 :         state.dataMaterial->Blind(Loop).SlatAngle = MaterialProps(4);
    1999          18 :         state.dataMaterial->Blind(Loop).SlatConductivity = MaterialProps(5);
    2000          18 :         state.dataMaterial->Blind(Loop).SlatTransSolBeamDiff = MaterialProps(6);
    2001          18 :         state.dataMaterial->Blind(Loop).SlatFrontReflSolBeamDiff = MaterialProps(7);
    2002          18 :         state.dataMaterial->Blind(Loop).SlatBackReflSolBeamDiff = MaterialProps(8);
    2003          18 :         state.dataMaterial->Blind(Loop).SlatTransSolDiffDiff = MaterialProps(9);
    2004          18 :         state.dataMaterial->Blind(Loop).SlatFrontReflSolDiffDiff = MaterialProps(10);
    2005          18 :         state.dataMaterial->Blind(Loop).SlatBackReflSolDiffDiff = MaterialProps(11);
    2006          18 :         state.dataMaterial->Blind(Loop).SlatTransVisBeamDiff = MaterialProps(12);
    2007          18 :         state.dataMaterial->Blind(Loop).SlatFrontReflVisBeamDiff = MaterialProps(13);
    2008          18 :         state.dataMaterial->Blind(Loop).SlatBackReflVisBeamDiff = MaterialProps(14);
    2009          18 :         state.dataMaterial->Blind(Loop).SlatTransVisDiffDiff = MaterialProps(15);
    2010          18 :         state.dataMaterial->Blind(Loop).SlatFrontReflVisDiffDiff = MaterialProps(16);
    2011          18 :         state.dataMaterial->Blind(Loop).SlatBackReflVisDiffDiff = MaterialProps(17);
    2012          18 :         state.dataMaterial->Blind(Loop).SlatTransIR = MaterialProps(18);
    2013          18 :         state.dataMaterial->Blind(Loop).SlatFrontEmissIR = MaterialProps(19);
    2014          18 :         state.dataMaterial->Blind(Loop).SlatBackEmissIR = MaterialProps(20);
    2015          18 :         state.dataMaterial->Blind(Loop).BlindToGlassDist = MaterialProps(21);
    2016          18 :         state.dataMaterial->Blind(Loop).BlindTopOpeningMult = MaterialProps(22);
    2017          18 :         state.dataMaterial->Blind(Loop).BlindBottomOpeningMult = MaterialProps(23);
    2018          18 :         state.dataMaterial->Blind(Loop).BlindLeftOpeningMult = MaterialProps(24);
    2019          18 :         state.dataMaterial->Blind(Loop).BlindRightOpeningMult = MaterialProps(25);
    2020          18 :         state.dataMaterial->Blind(Loop).MinSlatAngle = MaterialProps(26);
    2021          18 :         state.dataMaterial->Blind(Loop).MaxSlatAngle = MaterialProps(27);
    2022             : 
    2023             :         // TH 2/11/2010. For CR 8010
    2024             :         // By default all blinds have fixed slat angle, new blinds with variable slat angle are created if
    2025             :         //  they are used with window shading controls that adjust slat angles like ScheduledSlatAngle or BlockBeamSolar
    2026          18 :         state.dataMaterial->Blind(Loop).SlatAngleType = DataWindowEquivalentLayer::AngleType::Fixed;
    2027             : 
    2028          18 :         if (state.dataMaterial->Blind(Loop).SlatWidth < state.dataMaterial->Blind(Loop).SlatSeparation) {
    2029           0 :             ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Angles/Widths");
    2030           0 :             ShowContinueError(state,
    2031           0 :                               format("{} [{:.2R}] is less than {} [{:.2R}].",
    2032           0 :                                      ipsc->cNumericFieldNames(1),
    2033           0 :                                      state.dataMaterial->Blind(Loop).SlatWidth,
    2034           0 :                                      ipsc->cNumericFieldNames(2),
    2035           0 :                                      state.dataMaterial->Blind(Loop).SlatSeparation));
    2036           0 :             ShowContinueError(state, "This will allow direct beam to be transmitted when Slat angle = 0.");
    2037             :         }
    2038             : 
    2039          18 :         if (!Util::SameString(MaterialNames(2), "Horizontal") && !Util::SameString(MaterialNames(2), "Vertical")) {
    2040           0 :             ErrorsFound = true;
    2041           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value");
    2042           0 :             ShowContinueError(state, ipsc->cAlphaFieldNames(2) + "=\"" + MaterialNames(2) + "\", must be Horizontal or Vertical.");
    2043             :         }
    2044             : 
    2045          18 :         if ((MaterialProps(6) + MaterialProps(7) >= 1.0)) {
    2046           0 :             ErrorsFound = true;
    2047           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2048           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(6) + " + " + ipsc->cNumericFieldNames(7) + " not < 1.0");
    2049             :         }
    2050          18 :         if ((MaterialProps(6) + MaterialProps(8) >= 1.0)) {
    2051           0 :             ErrorsFound = true;
    2052           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2053           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(6) + " + " + ipsc->cNumericFieldNames(8) + " not < 1.0");
    2054             :         }
    2055             : 
    2056          18 :         if ((MaterialProps(9) + MaterialProps(10) >= 1.0)) {
    2057           0 :             ErrorsFound = true;
    2058           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2059           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(9) + " + " + ipsc->cNumericFieldNames(10) + " not < 1.0");
    2060             :         }
    2061          18 :         if ((MaterialProps(9) + MaterialProps(11) >= 1.0)) {
    2062           0 :             ErrorsFound = true;
    2063           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2064           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(9) + " + " + ipsc->cNumericFieldNames(11) + " not < 1.0");
    2065             :         }
    2066             : 
    2067          18 :         if ((MaterialProps(12) + MaterialProps(13) >= 1.0) || (MaterialProps(12) + MaterialProps(14) >= 1.0)) {
    2068           0 :             ErrorsFound = true;
    2069           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2070           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(12) + " + " + ipsc->cNumericFieldNames(13) + " not < 1.0 OR");
    2071           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(12) + " + " + ipsc->cNumericFieldNames(14) + " not < 1.0");
    2072             :         }
    2073             : 
    2074          18 :         if ((MaterialProps(12) + MaterialProps(13) >= 1.0)) {
    2075           0 :             ErrorsFound = true;
    2076           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2077           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(12) + " + " + ipsc->cNumericFieldNames(13) + " not < 1.0");
    2078             :         }
    2079          18 :         if ((MaterialProps(12) + MaterialProps(14) >= 1.0)) {
    2080           0 :             ErrorsFound = true;
    2081           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2082           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(12) + " + " + ipsc->cNumericFieldNames(14) + " not < 1.0");
    2083             :         }
    2084             : 
    2085          18 :         if ((MaterialProps(15) + MaterialProps(16) >= 1.0)) {
    2086           0 :             ErrorsFound = true;
    2087           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2088           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(15) + " + " + ipsc->cNumericFieldNames(16) + " not < 1.0");
    2089             :         }
    2090          18 :         if ((MaterialProps(15) + MaterialProps(17) >= 1.0)) {
    2091           0 :             ErrorsFound = true;
    2092           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2093           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(15) + " + " + ipsc->cNumericFieldNames(17) + " not < 1.0");
    2094             :         }
    2095             : 
    2096             :         // Require that beam and diffuse properties be the same
    2097          18 :         if (std::abs(MaterialProps(9) - MaterialProps(6)) > 1.e-5) {
    2098           0 :             ErrorsFound = true;
    2099           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2100           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(6) + " must equal " + ipsc->cNumericFieldNames(9));
    2101             :         }
    2102             : 
    2103          18 :         if (std::abs(MaterialProps(10) - MaterialProps(7)) > 1.e-5) {
    2104           0 :             ErrorsFound = true;
    2105           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2106           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(7) + " must equal " + ipsc->cNumericFieldNames(10));
    2107             :         }
    2108             : 
    2109          18 :         if (std::abs(MaterialProps(11) - MaterialProps(8)) > 1.e-5) {
    2110           0 :             ErrorsFound = true;
    2111           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2112           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(8) + " must equal " + ipsc->cNumericFieldNames(11));
    2113             :         }
    2114             : 
    2115          18 :         if (std::abs(MaterialProps(15) - MaterialProps(12)) > 1.e-5) {
    2116           0 :             ErrorsFound = true;
    2117           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2118           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(12) + " must equal " + ipsc->cNumericFieldNames(15));
    2119             :         }
    2120             : 
    2121          18 :         if (std::abs(MaterialProps(16) - MaterialProps(13)) > 1.e-5) {
    2122           0 :             ErrorsFound = true;
    2123           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2124           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(13) + " must equal " + ipsc->cNumericFieldNames(16));
    2125             :         }
    2126             : 
    2127          18 :         if (std::abs(MaterialProps(17) - MaterialProps(14)) > 1.e-5) {
    2128           0 :             ErrorsFound = true;
    2129           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2130           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(14) + " must equal " + ipsc->cNumericFieldNames(17));
    2131             :         }
    2132             : 
    2133          18 :         if ((MaterialProps(18) + MaterialProps(19) >= 1.0)) {
    2134           0 :             ErrorsFound = true;
    2135           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2136           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(18) + " + " + ipsc->cNumericFieldNames(19) + " not < 1.0");
    2137             :         }
    2138          18 :         if ((MaterialProps(18) + MaterialProps(20) >= 1.0)) {
    2139           0 :             ErrorsFound = true;
    2140           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2141           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(18) + " + " + ipsc->cNumericFieldNames(20) + " not < 1.0");
    2142             :         }
    2143             : 
    2144          18 :         if (state.dataMaterial->Blind(Loop).BlindToGlassDist < 0.5 * state.dataMaterial->Blind(Loop).SlatWidth) {
    2145           0 :             ErrorsFound = true;
    2146           0 :             ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2147           0 :             ShowContinueError(state, ipsc->cNumericFieldNames(21) + " is less than half of the " + ipsc->cNumericFieldNames(1));
    2148             :         }
    2149             : 
    2150             :         // Minimum and maximum slat angles allowed by slat geometry
    2151          18 :         if (state.dataMaterial->Blind(Loop).SlatWidth > state.dataMaterial->Blind(Loop).SlatSeparation) {
    2152          18 :             MinSlatAngGeom = std::asin(state.dataMaterial->Blind(Loop).SlatThickness /
    2153          18 :                                        (state.dataMaterial->Blind(Loop).SlatThickness + state.dataMaterial->Blind(Loop).SlatSeparation)) /
    2154             :                              Constant::DegToRadians;
    2155             :         } else {
    2156           0 :             MinSlatAngGeom = 0.0;
    2157             :         }
    2158          18 :         MaxSlatAngGeom = 180.0 - MinSlatAngGeom;
    2159             : 
    2160             :         // Error if input slat angle not in range allowed by slat geometry
    2161          18 :         if ((state.dataMaterial->Blind(Loop).SlatSeparation + state.dataMaterial->Blind(Loop).SlatThickness) <
    2162          18 :             state.dataMaterial->Blind(Loop).SlatWidth) {
    2163          18 :             if (state.dataMaterial->Blind(Loop).SlatAngle < MinSlatAngGeom) {
    2164           0 :                 ErrorsFound = true;
    2165           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2166           0 :                 ShowContinueError(state,
    2167           0 :                                   format("{}=[{:.1R}], is less than smallest allowed by slat dimensions and spacing, [{:.1R}] deg.",
    2168           0 :                                          ipsc->cNumericFieldNames(4),
    2169           0 :                                          state.dataMaterial->Blind(Loop).SlatAngle,
    2170             :                                          MinSlatAngGeom));
    2171          18 :             } else if (state.dataMaterial->Blind(Loop).SlatAngle > MaxSlatAngGeom) {
    2172           0 :                 ErrorsFound = true;
    2173           0 :                 ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
    2174           0 :                 ShowContinueError(state,
    2175           0 :                                   format("{}=[{:.1R}], is greater than largest allowed by slat dimensions and spacing, [{:.1R}] deg.",
    2176           0 :                                          ipsc->cNumericFieldNames(4),
    2177           0 :                                          state.dataMaterial->Blind(Loop).SlatAngle,
    2178             :                                          MinSlatAngGeom));
    2179             :             }
    2180             :         }
    2181             : 
    2182             :         // By default all Blinds are "fixed" slats.  Only with Shading Control is one considered variable and this check
    2183             :         // is now done when that happens.  9.3.2009 LKL
    2184             : 
    2185             :         //    IF(Blind(Loop)%SlatAngleType == VariableSlats) THEN
    2186             :         //      ! Error if maximum slat angle less than minimum
    2187             :         //      IF(Blind(Loop)%MaxSlatAngle < Blind(Loop)%MinSlatAngle) THEN
    2188             :         //        ErrorsFound = .TRUE.
    2189             :         //        CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
    2190             :         //        combination.') CALL ShowContinueError(state,
    2191             :         //        TRIM(cNumericFieldNames(26))//'=['//TRIM(RoundSigDigits(Blind(Loop)%MinSlatAngle,1))//  &
    2192             :         //           '], is greater than '//TRIM(cNumericFieldNames(27))//'=['//  &
    2193             :         //           TRIM(RoundSigDigits(Blind(Loop)%MaxSlatAngle,1))//'] deg.')
    2194             :         //      END IF
    2195             :         //      ! Error if input slat angle not in input min/max range
    2196             :         //      IF(Blind(Loop)%MaxSlatAngle > Blind(Loop)%MinSlatAngle .AND. (Blind(Loop)%SlatAngle < Blind(Loop)%MinSlatAngle &
    2197             :         //          .OR. Blind(Loop)%SlatAngle > Blind(Loop)%MaxSlatAngle)) THEN
    2198             :         //        ErrorsFound = .TRUE.
    2199             :         //        CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
    2200             :         //        combination.') CALL ShowContinueError(state, TRIM(cNumericFieldNames(4))//'=['//TRIM(RoundSigDigits(Blind(Loop)%SlatAngle,1))//
    2201             :         //        &
    2202             :         //           '] is outside of the input min/max range, min=['//TRIM(RoundSigDigits(Blind(Loop)%MinSlatAngle,1))//  &
    2203             :         //           '], max=['//TRIM(RoundSigDigits(Blind(Loop)%MaxSlatAngle,1))//'] deg.')
    2204             :         //      END IF
    2205             :         //      ! Error if input minimum slat angle is less than that allowed by slat geometry
    2206             :         //      IF(Blind(Loop)%MinSlatAngle < MinSlatAngGeom) THEN
    2207             :         //        CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
    2208             :         //        combination.') CALL ShowContinueError(state,
    2209             :         //        TRIM(cNumericFieldNames(26))//'=['//TRIM(RoundSigDigits(Blind(Loop)%MinSlatAngle,1))//  &
    2210             :         //           '] is less than the smallest allowed by slat dimensions and spacing, min=['//  &
    2211             :         //           TRIM(RoundSigDigits(MinSlatAngGeom,1))//'] deg.')
    2212             :         //        CALL ShowContinueError(state, 'Minimum Slat Angle will be set to '//TRIM(RoundSigDigits(MinSlatAngGeom,1))//' deg.')
    2213             :         //        Blind(Loop)%MinSlatAngle = MinSlatAngGeom
    2214             :         //      END IF
    2215             :         //      ! Error if input maximum slat angle is greater than that allowed by slat geometry
    2216             :         //      IF(Blind(Loop)%MaxSlatAngle > MaxSlatAngGeom) THEN
    2217             :         //        CALL ShowWarningError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
    2218             :         //        combination.') CALL ShowContinueError(state,
    2219             :         //        TRIM(cNumericFieldNames(27))//'=['//TRIM(RoundSigDigits(Blind(Loop)%MaxSlatAngle,1))//  &
    2220             :         //           '] is greater than the largest allowed by slat dimensions and spacing, ['//  &
    2221             :         //           TRIM(RoundSigDigits(MaxSlatAngGeom,1))//'] deg.')
    2222             :         //        CALL ShowContinueError(state, 'Maximum Slat Angle will be set to '//TRIM(RoundSigDigits(MaxSlatAngGeom,1))//' deg.')
    2223             :         //        Blind(Loop)%MaxSlatAngle = MaxSlatAngGeom
    2224             :         //      END IF
    2225             :         //    END IF  ! End of check if slat angle is variable
    2226             :     }
    2227             : 
    2228             :     // Window Blind Materials for EquivalentLayer Model
    2229             : 
    2230         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Blind:EquivalentLayer";
    2231         796 :     for (Loop = 1; Loop <= state.dataHeatBal->TotBlindsEQL; ++Loop) {
    2232             : 
    2233             :         // Call Input Get routine to retrieve material data
    2234           0 :         ip->getObjectItem(state,
    2235           0 :                           state.dataHeatBalMgr->CurrentModuleObject,
    2236             :                           Loop,
    2237             :                           MaterialNames,
    2238             :                           MaterialNumAlpha,
    2239             :                           MaterialProps,
    2240             :                           MaterialNumProp,
    2241             :                           IOStat,
    2242           0 :                           ipsc->lNumericFieldBlanks,
    2243           0 :                           ipsc->lAlphaFieldBlanks,
    2244           0 :                           ipsc->cAlphaFieldNames,
    2245           0 :                           ipsc->cNumericFieldNames);
    2246           0 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    2247           0 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    2248           0 :                                                      MaterialNames(1),
    2249           0 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    2250           0 :                                                      ipsc->cAlphaFieldNames(1),
    2251             :                                                      ErrorsFound)) {
    2252           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    2253           0 :             continue;
    2254             :         }
    2255             : 
    2256           0 :         ++MaterNum;
    2257           0 :         auto *thisMaterial = new MaterialChild;
    2258           0 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    2259           0 :         thisMaterial->group = Group::BlindEquivalentLayer;
    2260             : 
    2261           0 :         thisMaterial->Name = MaterialNames(1);
    2262           0 :         thisMaterial->Roughness = SurfaceRoughness::Rough;
    2263           0 :         thisMaterial->ROnly = true;
    2264             : 
    2265           0 :         if (Util::SameString(MaterialNames(2), "Horizontal")) {
    2266           0 :             thisMaterial->SlatOrientation = DataWindowEquivalentLayer::Orientation::Horizontal;
    2267           0 :         } else if (Util::SameString(MaterialNames(2), "Vertical")) {
    2268           0 :             thisMaterial->SlatOrientation = DataWindowEquivalentLayer::Orientation::Vertical;
    2269             :         }
    2270           0 :         thisMaterial->SlatWidth = MaterialProps(1);
    2271           0 :         thisMaterial->SlatSeparation = MaterialProps(2);
    2272           0 :         thisMaterial->SlatCrown = MaterialProps(3);
    2273           0 :         thisMaterial->SlatAngle = MaterialProps(4);
    2274             : 
    2275           0 :         thisMaterial->TausFrontBeamDiff = MaterialProps(5);
    2276           0 :         thisMaterial->TausBackBeamDiff = MaterialProps(6);
    2277           0 :         thisMaterial->ReflFrontBeamDiff = MaterialProps(7);
    2278           0 :         thisMaterial->ReflBackBeamDiff = MaterialProps(8);
    2279             : 
    2280           0 :         if (!ipsc->lNumericFieldBlanks(9) && !ipsc->lNumericFieldBlanks(10) && !ipsc->lNumericFieldBlanks(11) && !ipsc->lNumericFieldBlanks(12)) {
    2281           0 :             thisMaterial->TausFrontBeamDiffVis = MaterialProps(9);
    2282           0 :             thisMaterial->TausBackBeamDiffVis = MaterialProps(10);
    2283           0 :             thisMaterial->ReflFrontBeamDiffVis = MaterialProps(11);
    2284           0 :             thisMaterial->ReflBackBeamDiffVis = MaterialProps(12);
    2285             :         }
    2286           0 :         if (!ipsc->lNumericFieldBlanks(13) && !ipsc->lNumericFieldBlanks(14) && !ipsc->lNumericFieldBlanks(15)) {
    2287           0 :             thisMaterial->TausDiffDiff = MaterialProps(13);
    2288           0 :             thisMaterial->ReflFrontDiffDiff = MaterialProps(14);
    2289           0 :             thisMaterial->ReflBackDiffDiff = MaterialProps(15);
    2290             :         }
    2291           0 :         if (!ipsc->lNumericFieldBlanks(16) && !ipsc->lNumericFieldBlanks(17) && !ipsc->lNumericFieldBlanks(18)) {
    2292           0 :             thisMaterial->TausDiffDiffVis = MaterialProps(13);
    2293           0 :             thisMaterial->ReflFrontDiffDiffVis = MaterialProps(14);
    2294           0 :             thisMaterial->ReflBackDiffDiffVis = MaterialProps(15);
    2295             :         }
    2296           0 :         if (!ipsc->lNumericFieldBlanks(19)) {
    2297           0 :             thisMaterial->TausThermal = MaterialProps(19);
    2298             :         }
    2299           0 :         if (!ipsc->lNumericFieldBlanks(20)) {
    2300           0 :             thisMaterial->EmissThermalFront = MaterialProps(20);
    2301             :         }
    2302           0 :         if (!ipsc->lNumericFieldBlanks(21)) {
    2303           0 :             thisMaterial->EmissThermalBack = MaterialProps(21);
    2304             :         }
    2305             :         // Assumes thermal emissivity is the same as thermal absorptance
    2306           0 :         thisMaterial->AbsorpThermalFront = thisMaterial->EmissThermalFront;
    2307           0 :         thisMaterial->AbsorpThermalBack = thisMaterial->EmissThermalBack;
    2308           0 :         thisMaterial->TransThermal = thisMaterial->TausThermal;
    2309             : 
    2310             :         // By default all blinds have fixed slat angle,
    2311             :         //  they are used with window shading controls that adjust slat angles like
    2312             :         //  MaximizeSolar or BlockBeamSolar
    2313           0 :         thisMaterial->slatAngleType = SlatAngleType::FixedSlatAngle;
    2314           0 :         if (!ipsc->lAlphaFieldBlanks(3)) {
    2315           0 :             thisMaterial->slatAngleType = static_cast<SlatAngleType>(getEnumValue(slatAngleTypeNamesUC, Util::makeUPPER(MaterialNames(3))));
    2316             :         }
    2317           0 :         if (thisMaterial->SlatWidth < thisMaterial->SlatSeparation) {
    2318           0 :             ShowWarningError(state, format("{}=\"{}\", Slat Seperation/Width", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2319           0 :             ShowContinueError(state,
    2320           0 :                               format("{} [{:.2R}] is less than {} [{:.2R}].",
    2321           0 :                                      ipsc->cNumericFieldNames(1),
    2322           0 :                                      thisMaterial->SlatWidth,
    2323           0 :                                      ipsc->cNumericFieldNames(2),
    2324           0 :                                      thisMaterial->SlatSeparation));
    2325           0 :             ShowContinueError(state, "This will allow direct beam to be transmitted when Slat angle = 0.");
    2326             :         }
    2327           0 :         if (thisMaterial->SlatSeparation < 0.001) {
    2328           0 :             ShowWarningError(state, format("{}=\"{}\", Slat Seperation", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2329           0 :             ShowContinueError(state, format("{} [{:.2R}]. Slate spacing must be > 0.0", ipsc->cNumericFieldNames(2), thisMaterial->SlatSeparation));
    2330           0 :             ShowContinueError(state,
    2331             :                               "...Setting slate spacing to default value of 0.025 m and "
    2332             :                               "simulation continues.");
    2333           0 :             thisMaterial->SlatSeparation = 0.025;
    2334             :         }
    2335           0 :         if (thisMaterial->SlatWidth < 0.001 || thisMaterial->SlatWidth >= 2.0 * thisMaterial->SlatSeparation) {
    2336           0 :             ShowWarningError(state, format("{}=\"{}\", Slat Width", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2337           0 :             ShowContinueError(
    2338           0 :                 state, format("{} [{:.2R}]. Slat width range is 0 < Width <= 2*Spacing", ipsc->cNumericFieldNames(1), thisMaterial->SlatWidth));
    2339           0 :             ShowContinueError(state, "...Setting slate width equal to slate spacing and simulation continues.");
    2340           0 :             thisMaterial->SlatWidth = thisMaterial->SlatSeparation;
    2341             :         }
    2342           0 :         if (thisMaterial->SlatCrown < 0.0 || thisMaterial->SlatCrown >= 0.5 * thisMaterial->SlatWidth) {
    2343           0 :             ShowWarningError(state, format("{}=\"{}\", Slat Crown", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2344           0 :             ShowContinueError(
    2345           0 :                 state, format("{} [{:.2R}]. Slat crwon range is 0 <= crown < 0.5*Width", ipsc->cNumericFieldNames(3), thisMaterial->SlatCrown));
    2346           0 :             ShowContinueError(state, "...Setting slate crown to 0.0 and simulation continues.");
    2347           0 :             thisMaterial->SlatCrown = 0.0;
    2348             :         }
    2349           0 :         if (thisMaterial->SlatAngle < -90.0 || thisMaterial->SlatAngle > 90.0) {
    2350           0 :             ShowWarningError(state, format("{}=\"{}\", Slat Angle", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2351           0 :             ShowContinueError(state,
    2352           0 :                               format("{} [{:.2R}]. Slat angle range is -90.0 <= Angle < 90.0", ipsc->cNumericFieldNames(4), thisMaterial->SlatAngle));
    2353           0 :             ShowContinueError(state, "...Setting slate angle to 0.0 and simulation continues.");
    2354           0 :             thisMaterial->SlatAngle = 0.0;
    2355             :         }
    2356             : 
    2357           0 :         if (!Util::SameString(MaterialNames(2), "Horizontal") && !Util::SameString(MaterialNames(2), "Vertical")) {
    2358           0 :             ErrorsFound = true;
    2359           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2360           0 :             ShowContinueError(state, format("{}=\"{}\", must be Horizontal or Vertical.", ipsc->cAlphaFieldNames(2), MaterialNames(2)));
    2361             :         }
    2362             : 
    2363           0 :         if ((MaterialProps(5) + MaterialProps(7) >= 1.0)) {
    2364           0 :             ErrorsFound = true;
    2365           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2366           0 :             ShowContinueError(state, format("{} + {} not < 1.0", ipsc->cNumericFieldNames(5), ipsc->cNumericFieldNames(7)));
    2367             :         }
    2368           0 :         if ((MaterialProps(6) + MaterialProps(8) >= 1.0)) {
    2369           0 :             ErrorsFound = true;
    2370           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2371           0 :             ShowContinueError(state, format("{} + {} not < 1.0", ipsc->cNumericFieldNames(6), ipsc->cNumericFieldNames(8)));
    2372             :         }
    2373           0 :         if ((MaterialProps(9) + MaterialProps(11) >= 1.0)) {
    2374           0 :             ErrorsFound = true;
    2375           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2376           0 :             ShowContinueError(state, format("{} + {} not < 1.0", ipsc->cNumericFieldNames(9), ipsc->cNumericFieldNames(11)));
    2377             :         }
    2378           0 :         if ((MaterialProps(10) + MaterialProps(12) >= 1.0)) {
    2379           0 :             ErrorsFound = true;
    2380           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2381           0 :             ShowContinueError(state, format("{} + {} not < 1.0", ipsc->cNumericFieldNames(10), ipsc->cNumericFieldNames(12)));
    2382             :         }
    2383             : 
    2384             :     } // TotBlindsEQL loop
    2385             : 
    2386             :     // EcoRoof Materials
    2387             :     // PSU 2006
    2388         796 :     state.dataHeatBalMgr->CurrentModuleObject = "Material:RoofVegetation";
    2389         808 :     for (Loop = 1; Loop <= EcoRoofMat; ++Loop) {
    2390             :         // Call Input Get Routine to retrieve material data from ecoroof
    2391             : 
    2392          36 :         ip->getObjectItem(state,
    2393          12 :                           state.dataHeatBalMgr->CurrentModuleObject,
    2394             :                           Loop,
    2395             :                           MaterialNames,
    2396             :                           MaterialNumAlpha,
    2397             :                           MaterialProps,
    2398             :                           MaterialNumProp,
    2399             :                           IOStat,
    2400          12 :                           ipsc->lNumericFieldBlanks,
    2401          12 :                           ipsc->lAlphaFieldBlanks,
    2402          12 :                           ipsc->cAlphaFieldNames,
    2403          12 :                           ipsc->cNumericFieldNames);
    2404          24 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    2405          12 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    2406          12 :                                                      MaterialNames(1),
    2407          12 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    2408          12 :                                                      ipsc->cAlphaFieldNames(1),
    2409             :                                                      ErrorsFound)) {
    2410           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    2411           0 :             continue;
    2412             :         }
    2413             : 
    2414             :         // this part is similar to the regular material
    2415             :         // Load the material derived type from the input data.
    2416          12 :         ++MaterNum;
    2417          12 :         auto *thisMaterial = new MaterialChild;
    2418          12 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    2419          12 :         thisMaterial->group = Group::EcoRoof;
    2420             : 
    2421             :         // this part is new for Ecoroof properties,
    2422             :         // especially for the Plant Layer of the ecoroof
    2423          12 :         thisMaterial->HeightOfPlants = MaterialProps(1);
    2424          12 :         thisMaterial->LAI = MaterialProps(2);
    2425          12 :         thisMaterial->Lreflectivity = MaterialProps(3); // Albedo
    2426          12 :         thisMaterial->LEmissitivity = MaterialProps(4);
    2427          12 :         thisMaterial->RStomata = MaterialProps(5);
    2428             : 
    2429          12 :         thisMaterial->Name = MaterialNames(1);
    2430             :         // need to treat the A2 with is just the name of the soil(it is
    2431             :         // not important)
    2432          12 :         thisMaterial->Roughness = static_cast<SurfaceRoughness>(getEnumValue(surfaceRoughnessNamesUC, Util::makeUPPER(MaterialNames(3))));
    2433          12 :         if (Util::SameString(MaterialNames(4), "Simple")) {
    2434           6 :             thisMaterial->EcoRoofCalculationMethod = 1;
    2435           6 :         } else if (Util::SameString(MaterialNames(4), "Advanced") || ipsc->lAlphaFieldBlanks(4)) {
    2436           6 :             thisMaterial->EcoRoofCalculationMethod = 2;
    2437             :         } else {
    2438           0 :             ShowSevereError(state, format("{}=\"{}\", Illegal value", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2439           0 :             ShowContinueError(state, format("{}=\"{}\".", ipsc->cAlphaFieldNames(4), MaterialNames(4)));
    2440           0 :             ShowContinueError(state, "...Valid values are \"Simple\" or \"Advanced\".");
    2441           0 :             ErrorsFound = true;
    2442             :         }
    2443             : 
    2444          12 :         thisMaterial->Thickness = MaterialProps(6);
    2445          12 :         thisMaterial->Conductivity = MaterialProps(7);
    2446          12 :         thisMaterial->Density = MaterialProps(8);
    2447          12 :         thisMaterial->SpecHeat = MaterialProps(9);
    2448          12 :         thisMaterial->AbsorpThermal = MaterialProps(10); // emissivity
    2449          12 :         thisMaterial->AbsorpSolar = MaterialProps(11);   // (1 - Albedo)
    2450          12 :         thisMaterial->AbsorpVisible = MaterialProps(12);
    2451          12 :         thisMaterial->Porosity = MaterialProps(13);
    2452          12 :         thisMaterial->MinMoisture = MaterialProps(14);
    2453          12 :         thisMaterial->InitMoisture = MaterialProps(15);
    2454             : 
    2455          12 :         if (thisMaterial->Conductivity > 0.0) {
    2456          12 :             state.dataHeatBal->NominalR(MaterNum) = thisMaterial->Thickness / thisMaterial->Conductivity;
    2457          12 :             thisMaterial->Resistance = state.dataHeatBal->NominalR(MaterNum);
    2458             :         } else {
    2459           0 :             ShowSevereError(state, format("{}=\"{}\" is not defined correctly.", state.dataHeatBalMgr->CurrentModuleObject, ipsc->cAlphaArgs(1)));
    2460           0 :             ShowContinueError(state, format("{} is <=0.", ipsc->cNumericFieldNames(7)));
    2461           0 :             ErrorsFound = true;
    2462             :         }
    2463             : 
    2464          12 :         if (thisMaterial->InitMoisture > thisMaterial->Porosity) {
    2465           0 :             ShowWarningError(state, format("{}=\"{}\", Illegal value combination.", state.dataHeatBalMgr->CurrentModuleObject, MaterialNames(1)));
    2466           0 :             ShowContinueError(state,
    2467           0 :                               format("{} is greater than {}. It must be less or equal.", ipsc->cNumericFieldNames(15), ipsc->cNumericFieldNames(13)));
    2468           0 :             ShowContinueError(state, format("{} = {:.3T}.", ipsc->cNumericFieldNames(13), thisMaterial->Porosity));
    2469           0 :             ShowContinueError(state, format("{} = {:.3T}.", ipsc->cNumericFieldNames(15), thisMaterial->InitMoisture));
    2470           0 :             ShowContinueError(
    2471           0 :                 state, format("{} is reset to the maximum (saturation) value = {:.3T}.", ipsc->cNumericFieldNames(15), thisMaterial->Porosity));
    2472           0 :             ShowContinueError(state, "Simulation continues.");
    2473           0 :             thisMaterial->InitMoisture = thisMaterial->Porosity;
    2474             :         }
    2475             :     }
    2476             : 
    2477             :     // Thermochromic glazing group
    2478             :     // get the number of WindowMaterial:GlazingGroup:Thermochromic objects in the idf file
    2479         796 :     state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:GlazingGroup:Thermochromic";
    2480         796 :     state.dataHeatBal->TotTCGlazings = ip->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
    2481         796 :     if (state.dataHeatBal->TotTCGlazings >= 1) {
    2482             :         // Read TC glazings
    2483           1 :         state.dataHeatBal->TCGlazings.allocate(state.dataHeatBal->TotTCGlazings);
    2484             : 
    2485           2 :         for (Loop = 1; Loop <= state.dataHeatBal->TotTCGlazings; ++Loop) {
    2486             :             // Get each TCGlazings from the input processor
    2487           2 :             ip->getObjectItem(state,
    2488           1 :                               state.dataHeatBalMgr->CurrentModuleObject,
    2489             :                               Loop,
    2490           1 :                               ipsc->cAlphaArgs,
    2491             :                               MaterialNumAlpha,
    2492           1 :                               ipsc->rNumericArgs,
    2493             :                               MaterialNumProp,
    2494             :                               IOStat,
    2495           1 :                               ipsc->lNumericFieldBlanks,
    2496           1 :                               ipsc->lAlphaFieldBlanks,
    2497           1 :                               ipsc->cAlphaFieldNames,
    2498           1 :                               ipsc->cNumericFieldNames);
    2499             : 
    2500           1 :             if (Util::IsNameEmpty(state, ipsc->cAlphaArgs(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) {
    2501           0 :                 ShowContinueError(state, "...All Thermochromic Glazing names must be unique regardless of subtype.");
    2502           0 :                 continue;
    2503             :             }
    2504             : 
    2505           1 :             if (MaterialNumProp + 1 != MaterialNumAlpha) {
    2506           0 :                 ShowSevereError(state, format("{}=\"{}\" is not defined correctly.", state.dataHeatBalMgr->CurrentModuleObject, ipsc->cAlphaArgs(1)));
    2507           0 :                 ShowContinueError(state,
    2508           0 :                                   format("Check number of {} compared to number of {}", ipsc->cAlphaFieldNames(2), ipsc->cNumericFieldNames(1)));
    2509           0 :                 ErrorsFound = true;
    2510           0 :                 continue;
    2511             :             }
    2512             : 
    2513             :             // Allocate arrays
    2514           1 :             state.dataHeatBal->TCGlazings(Loop).SpecTemp.allocate(MaterialNumProp);
    2515           1 :             state.dataHeatBal->TCGlazings(Loop).LayerName.allocate(MaterialNumProp);
    2516           1 :             state.dataHeatBal->TCGlazings(Loop).LayerPoint.allocate(MaterialNumProp);
    2517           1 :             state.dataHeatBal->TCGlazings(Loop).SpecTemp = 0.0;
    2518           1 :             state.dataHeatBal->TCGlazings(Loop).LayerName = "";
    2519           1 :             state.dataHeatBal->TCGlazings(Loop).LayerPoint = 0;
    2520             : 
    2521           1 :             state.dataHeatBal->TCGlazings(Loop).Name = ipsc->cAlphaArgs(1);
    2522           1 :             state.dataHeatBal->TCGlazings(Loop).NumGlzMat = MaterialNumProp;
    2523             : 
    2524          20 :             for (iTC = 1; iTC <= MaterialNumProp; ++iTC) {
    2525          19 :                 state.dataHeatBal->TCGlazings(Loop).SpecTemp(iTC) = ipsc->rNumericArgs(iTC);
    2526          19 :                 state.dataHeatBal->TCGlazings(Loop).LayerName(iTC) = ipsc->cAlphaArgs(1 + iTC);
    2527             : 
    2528             :                 // Find this glazing material in the material list
    2529          19 :                 iMat = Util::FindItemInPtrList(ipsc->cAlphaArgs(1 + iTC), state.dataMaterial->Material);
    2530          19 :                 if (iMat != 0) {
    2531             :                     // TC glazing
    2532          19 :                     auto *thisMaterial = dynamic_cast<MaterialChild *>(state.dataMaterial->Material(iMat));
    2533          19 :                     assert(thisMaterial != nullptr);
    2534          19 :                     thisMaterial->SpecTemp = ipsc->rNumericArgs(iTC);
    2535          19 :                     thisMaterial->TCParent = Loop;
    2536          19 :                     state.dataHeatBal->TCGlazings(Loop).LayerPoint(iTC) = iMat;
    2537             : 
    2538             :                     // test that named material is of the right type
    2539          19 :                     if (thisMaterial->group != Group::WindowGlass) {
    2540           0 :                         ShowSevereError(
    2541           0 :                             state, format("{}=\"{}\" is not defined correctly.", state.dataHeatBalMgr->CurrentModuleObject, ipsc->cAlphaArgs(1)));
    2542           0 :                         ShowContinueError(state, format("Material named: {} is not a window glazing ", ipsc->cAlphaArgs(1 + iTC)));
    2543           0 :                         ErrorsFound = true;
    2544             :                     }
    2545             : 
    2546             :                 } else { // thow error because not found
    2547           0 :                     ShowSevereError(state,
    2548           0 :                                     format("{}=\"{}\" is not defined correctly.", state.dataHeatBalMgr->CurrentModuleObject, ipsc->cAlphaArgs(1)));
    2549           0 :                     ShowContinueError(state, format("Material named: {} was not found ", ipsc->cAlphaArgs(1 + iTC)));
    2550           0 :                     ErrorsFound = true;
    2551             :                 }
    2552             :             }
    2553             :         }
    2554             :     }
    2555         796 :     auto &cCurrentModuleObject = ipsc->cCurrentModuleObject;
    2556         796 :     cCurrentModuleObject = "WindowMaterial:SimpleGlazingSystem";
    2557         904 :     for (Loop = 1; Loop <= state.dataHeatBal->TotSimpleWindow; ++Loop) {
    2558             : 
    2559         216 :         ip->getObjectItem(state,
    2560             :                           cCurrentModuleObject,
    2561             :                           Loop,
    2562         108 :                           ipsc->cAlphaArgs,
    2563             :                           MaterialNumAlpha,
    2564         108 :                           ipsc->rNumericArgs,
    2565             :                           MaterialNumProp,
    2566             :                           IOStat,
    2567         108 :                           ipsc->lNumericFieldBlanks,
    2568         108 :                           ipsc->lAlphaFieldBlanks,
    2569         108 :                           ipsc->cAlphaFieldNames,
    2570         108 :                           ipsc->cNumericFieldNames);
    2571         216 :         if (GlobalNames::VerifyUniqueInterObjectName(state,
    2572         108 :                                                      state.dataHeatBalMgr->UniqueMaterialNames,
    2573         108 :                                                      ipsc->cAlphaArgs(1),
    2574         108 :                                                      state.dataHeatBalMgr->CurrentModuleObject,
    2575         108 :                                                      ipsc->cAlphaFieldNames(1),
    2576             :                                                      ErrorsFound)) {
    2577           0 :             ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
    2578           0 :             continue;
    2579             :         }
    2580             : 
    2581         108 :         ++MaterNum;
    2582         108 :         auto *thisMaterial = new MaterialChild;
    2583         108 :         state.dataMaterial->Material(MaterNum) = thisMaterial;
    2584         108 :         thisMaterial->group = Group::WindowSimpleGlazing;
    2585         108 :         thisMaterial->Name = ipsc->cAlphaArgs(1);
    2586         108 :         thisMaterial->SimpleWindowUfactor = ipsc->rNumericArgs(1);
    2587         108 :         thisMaterial->SimpleWindowSHGC = ipsc->rNumericArgs(2);
    2588         108 :         if (!ipsc->lNumericFieldBlanks(3)) {
    2589          48 :             thisMaterial->SimpleWindowVisTran = ipsc->rNumericArgs(3);
    2590          48 :             thisMaterial->SimpleWindowVTinputByUser = true;
    2591             :         }
    2592             : 
    2593         108 :         HeatBalanceManager::SetupSimpleWindowGlazingSystem(state, MaterNum);
    2594             :     }
    2595             : 
    2596             :     // Simon: Place to load materials for complex fenestrations
    2597         796 :     if ((state.dataMaterial->TotComplexShades > 0) || (state.dataHeatBal->TotComplexGaps > 0)) {
    2598          10 :         HeatBalanceManager::SetupComplexFenestrationMaterialInput(state, MaterNum, ErrorsFound);
    2599          10 :         if (ErrorsFound) {
    2600           0 :             ShowSevereError(state, "Errors found in processing complex fenestration material input");
    2601             :         }
    2602             :     }
    2603         796 :     ScanForReports(state, "Constructions", state.dataHeatBalMgr->DoReport, "Materials");
    2604             : 
    2605         796 :     if (state.dataHeatBalMgr->DoReport) {
    2606             : 
    2607          14 :         print(state.files.eio,
    2608             :               "! <Material Details>,Material Name,ThermalResistance {{m2-K/w}},Roughness,Thickness {{m}},Conductivity "
    2609             :               "{{w/m-K}},Density {{kg/m3}},Specific Heat "
    2610             :               "{{J/kg-K}},Absorptance:Thermal,Absorptance:Solar,Absorptance:Visible\n");
    2611             : 
    2612          14 :         print(state.files.eio, "! <Material:Air>,Material Name,ThermalResistance {{m2-K/w}}\n");
    2613             : 
    2614             :         // Formats
    2615          14 :         constexpr std::string_view Format_701(" Material Details,{},{:.4R},{},{:.4R},{:.3R},{:.3R},{:.3R},{:.4R},{:.4R},{:.4R}\n");
    2616          14 :         constexpr std::string_view Format_702(" Material:Air,{},{:.4R}\n");
    2617             : 
    2618         279 :         for (auto const *mat : state.dataMaterial->Material) {
    2619             : 
    2620         265 :             switch (mat->group) {
    2621          11 :             case Group::Air: {
    2622          11 :                 print(state.files.eio, Format_702, mat->Name, mat->Resistance);
    2623          11 :             } break;
    2624         254 :             default: {
    2625         254 :                 print(state.files.eio,
    2626             :                       Format_701,
    2627         254 :                       mat->Name,
    2628         254 :                       mat->Resistance,
    2629         254 :                       surfaceRoughnessNames[(int)mat->Roughness],
    2630         254 :                       mat->Thickness,
    2631         254 :                       mat->Conductivity,
    2632         254 :                       mat->Density,
    2633         254 :                       mat->SpecHeat,
    2634         254 :                       mat->AbsorpThermal,
    2635         254 :                       mat->AbsorpSolar,
    2636         254 :                       mat->AbsorpVisible);
    2637         254 :             } break;
    2638             :             }
    2639          14 :         }
    2640             :     }
    2641             : 
    2642             :     //  FORMATS.
    2643             : 
    2644         796 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) { // setup surface property EMS actuators
    2645             : 
    2646        2198 :         for (auto *mat : state.dataMaterial->Material) {
    2647        2125 :             if (mat->group != Group::Regular) continue;
    2648             : 
    2649        1793 :             auto *matReg = dynamic_cast<MaterialChild *>(mat);
    2650        1793 :             assert(matReg != nullptr);
    2651        1793 :             SetupEMSActuator(state,
    2652             :                              "Material",
    2653             :                              matReg->Name,
    2654             :                              "Surface Property Solar Absorptance",
    2655             :                              "[ ]",
    2656        1793 :                              matReg->AbsorpSolarEMSOverrideOn,
    2657        1793 :                              matReg->AbsorpSolarEMSOverride);
    2658        1793 :             SetupEMSActuator(state,
    2659             :                              "Material",
    2660             :                              matReg->Name,
    2661             :                              "Surface Property Thermal Absorptance",
    2662             :                              "[ ]",
    2663        1793 :                              matReg->AbsorpThermalEMSOverrideOn,
    2664        1793 :                              matReg->AbsorpThermalEMSOverride);
    2665        1793 :             SetupEMSActuator(state,
    2666             :                              "Material",
    2667             :                              matReg->Name,
    2668             :                              "Surface Property Visible Absorptance",
    2669             :                              "[ ]",
    2670        1793 :                              matReg->AbsorpVisibleEMSOverrideOn,
    2671        1793 :                              matReg->AbsorpVisibleEMSOverride);
    2672          73 :         }
    2673             :     }
    2674             : 
    2675             :     // try assigning phase change material properties for each material, won't do anything for non pcm surfaces
    2676       14714 :     for (auto *mBase : state.dataMaterial->Material) {
    2677       13918 :         if (mBase->group == Material::Group::Screen || mBase->group == Material::Group::WindowGas ||
    2678       13103 :             mBase->group == Material::Group::WindowGasMixture || mBase->group == Material::Group::GapEquivalentLayer)
    2679         839 :             continue;
    2680             : 
    2681       13079 :         auto *m = dynamic_cast<MaterialChild *>(mBase);
    2682       13079 :         assert(m != nullptr);
    2683       13079 :         m->phaseChange = HysteresisPhaseChange::HysteresisPhaseChange::factory(state, m->Name);
    2684         796 :     }
    2685             : 
    2686         796 :     GetVariableAbsorptanceInput(state, ErrorsFound); // Read variable thermal and solar absorptance add-on data
    2687         796 : }
    2688             : 
    2689         796 : void GetVariableAbsorptanceInput(EnergyPlusData &state, bool &errorsFound)
    2690             : {
    2691             :     int IOStat; // IO Status when calling get input subroutine
    2692             :     int numAlphas;
    2693             :     int numNumbers;
    2694         796 :     Array1D_string alphas(7);   // character string data
    2695         796 :     Array1D<Real64> numbers(1); // numeric data
    2696         796 :     std::string_view cCurrentModuleObject{"MaterialProperty:VariableAbsorptance"};
    2697             : 
    2698         796 :     auto &ip = state.dataInputProcessing->inputProcessor;
    2699         796 :     auto &ipsc = state.dataIPShortCut;
    2700             : 
    2701         796 :     int numVariAbs = ip->getNumObjectsFound(state, cCurrentModuleObject);
    2702         796 :     state.dataHeatBal->AnyVariableAbsorptance = (numVariAbs > 0);
    2703         797 :     for (int i = 1; i <= numVariAbs; ++i) {
    2704             :         // Call Input Get routine to retrieve material data
    2705           2 :         ip->getObjectItem(state,
    2706             :                           cCurrentModuleObject,
    2707             :                           i,
    2708             :                           alphas,
    2709             :                           numAlphas,
    2710             :                           numbers,
    2711             :                           numNumbers,
    2712             :                           IOStat,
    2713           1 :                           ipsc->lNumericFieldBlanks,
    2714           1 :                           ipsc->lAlphaFieldBlanks,
    2715           1 :                           ipsc->cAlphaFieldNames,
    2716           1 :                           ipsc->cNumericFieldNames);
    2717             : 
    2718             :         // Load the material derived type from the input data.
    2719           1 :         int MaterNum = Util::FindItemInPtrList(alphas(2), state.dataMaterial->Material);
    2720           1 :         if (MaterNum == 0) {
    2721           0 :             ShowSevereError(
    2722             :                 state,
    2723           0 :                 format(
    2724           0 :                     "{}: invalid {} entered={}, must match to a valid Material name.", cCurrentModuleObject, ipsc->cAlphaFieldNames(2), alphas(2)));
    2725           0 :             errorsFound = true;
    2726           0 :             return;
    2727             :         }
    2728           1 :         auto *thisMaterial = dynamic_cast<MaterialChild *>(state.dataMaterial->Material(MaterNum));
    2729           1 :         assert(thisMaterial != nullptr);
    2730             : 
    2731           1 :         if (thisMaterial->group != Group::Regular) {
    2732           0 :             ShowSevereError(
    2733             :                 state,
    2734           0 :                 format("{}: Reference Material is not appropriate type for Thermal/Solar Absorptance properties, material={}, must have regular "
    2735             :                        "properties (Thermal/Solar Absorptance)",
    2736             :                        cCurrentModuleObject,
    2737           0 :                        thisMaterial->Name));
    2738           0 :             errorsFound = true;
    2739           0 :             return;
    2740             :         }
    2741             : 
    2742           1 :         thisMaterial->absorpVarCtrlSignal = VariableAbsCtrlSignal::SurfaceTemperature; // default value
    2743           1 :         thisMaterial->absorpVarCtrlSignal =
    2744           1 :             static_cast<VariableAbsCtrlSignal>(getEnumValue(variableAbsCtrlSignalNamesUC, Util::makeUPPER(alphas(3))));
    2745             :         //    init to 0 as GetScheduleIndex returns 0 for not-found schedule
    2746           1 :         thisMaterial->absorpThermalVarFuncIdx = Curve::GetCurveIndex(state, alphas(4));
    2747           1 :         thisMaterial->absorpThermalVarSchedIdx = ScheduleManager::GetScheduleIndex(state, alphas(5));
    2748           1 :         thisMaterial->absorpSolarVarFuncIdx = Curve::GetCurveIndex(state, alphas(6));
    2749           1 :         thisMaterial->absorpSolarVarSchedIdx = ScheduleManager::GetScheduleIndex(state, alphas(7));
    2750           1 :         if (thisMaterial->absorpVarCtrlSignal == VariableAbsCtrlSignal::Scheduled) {
    2751           0 :             if ((thisMaterial->absorpThermalVarSchedIdx == 0) && (thisMaterial->absorpSolarVarSchedIdx == 0)) {
    2752           0 :                 ShowSevereError(
    2753             :                     state,
    2754           0 :                     format("{}: Control signal \"Scheduled\" is chosen but both thermal and solar absorptance schedules are undefined, for object {}",
    2755             :                            cCurrentModuleObject,
    2756             :                            alphas(1)));
    2757           0 :                 errorsFound = true;
    2758           0 :                 return;
    2759             :             }
    2760           0 :             if ((thisMaterial->absorpThermalVarFuncIdx > 0) || (thisMaterial->absorpSolarVarFuncIdx > 0)) {
    2761           0 :                 ShowWarningError(state,
    2762           0 :                                  format("{}: Control signal \"Scheduled\" is chosen. Thermal or solar absorptance function name is going to be "
    2763             :                                         "ignored, for object {}",
    2764             :                                         cCurrentModuleObject,
    2765             :                                         alphas(1)));
    2766           0 :                 errorsFound = true;
    2767           0 :                 return;
    2768             :             }
    2769             :         } else { // controlled by performance table or curve
    2770           1 :             if ((thisMaterial->absorpThermalVarFuncIdx == 0) && (thisMaterial->absorpSolarVarFuncIdx == 0)) {
    2771           0 :                 ShowSevereError(state,
    2772           0 :                                 format("{}: Non-schedule control signal is chosen but both thermal and solar absorptance table or curve are "
    2773             :                                        "undefined, for object {}",
    2774             :                                        cCurrentModuleObject,
    2775             :                                        alphas(1)));
    2776           0 :                 errorsFound = true;
    2777           0 :                 return;
    2778             :             }
    2779           1 :             if ((thisMaterial->absorpThermalVarSchedIdx > 0) || (thisMaterial->absorpSolarVarSchedIdx > 0)) {
    2780           0 :                 ShowWarningError(state,
    2781           0 :                                  format("{}: Non-schedule control signal is chosen. Thermal or solar absorptance schedule name is going to be "
    2782             :                                         "ignored, for object {}",
    2783             :                                         cCurrentModuleObject,
    2784             :                                         alphas(1)));
    2785           0 :                 errorsFound = true;
    2786           0 :                 return;
    2787             :             }
    2788             :         }
    2789             :     }
    2790         796 : }
    2791             : 
    2792        3386 : void CalcScreenTransmittance(EnergyPlusData &state,
    2793             :                              MaterialScreen const *screen,
    2794             :                              Real64 phi,   // Sun altitude relative to surface outward normal (radians, 0 to Pi)
    2795             :                              Real64 theta, // Optional sun azimuth relative to surface outward normal (radians, 0 to Pi)
    2796             :                              ScreenBmTransAbsRef &tar)
    2797             : {
    2798             : 
    2799             :     // FUNCTION INFORMATION:
    2800             :     //       AUTHOR         Richard Raustad
    2801             :     //       DATE WRITTEN   May 2006
    2802             :     //       MODIFIED       na
    2803             :     //       RE-ENGINEERED  na
    2804             : 
    2805             :     // PURPOSE OF THIS FUNCTION:
    2806             :     //  Calculate transmittance of window screen given azimuth and altitude angle
    2807             :     //  of sun and surface orientation.
    2808             : 
    2809             :     // METHODOLOGY EMPLOYED:
    2810             :     //  Window screen solar beam transmittance varies as the sun moves across the sky
    2811             :     //  due to the geometry of the screen material and the angle of incidence
    2812             :     //  of the solar beam. Azimuth and altitude angle are calculated with respect
    2813             :     //  to the surface outward normal. Solar beam reflectance and absorptance are also
    2814             :     //  accounted for.
    2815             : 
    2816        3386 :     Real64 constexpr Small(1.E-9); // Small Number used to approximate zero
    2817             : 
    2818             :     Real64 Tdirect;          // Beam solar transmitted through screen (dependent on sun angle)
    2819             :     Real64 Tscattered;       // Beam solar reflected through screen (dependent on sun angle)
    2820             :     Real64 TscatteredVis;    // Visible beam solar reflected through screen (dependent on sun angle)
    2821             :     Real64 Tscattermax;      // Maximum solar beam  scattered transmittance
    2822             :     Real64 TscattermaxVis;   // Maximum visible beam scattered transmittance
    2823             :     Real64 ExponentInterior; // Exponent used in scattered transmittance calculation
    2824             :     // when Delta < DeltaMax (0,0 to peak)
    2825             :     Real64 ExponentExterior; // Exponent used in scattered transmittance calculation
    2826             :     // when Delta > DeltaMax (peak to max)
    2827             : 
    2828        3386 :     assert(phi >= 0.0 && phi <= Constant::Pi);
    2829        3386 :     assert(theta >= 0.0 && theta <= Constant::Pi);
    2830             : 
    2831        3386 :     Real64 sinPhi = std::sin(phi);
    2832        3386 :     Real64 cosPhi = std::cos(phi);
    2833        3386 :     Real64 tanPhi = sinPhi / cosPhi;
    2834        3386 :     Real64 sinTheta = std::sin(theta);
    2835        3386 :     Real64 cosTheta = std::cos(theta);
    2836        3386 :     Real64 tanTheta = sinTheta / cosTheta;
    2837             : 
    2838        3386 :     bool sunInFront = (phi < Constant::PiOvr2) && (theta < Constant::PiOvr2); // Sun is in front of screen
    2839             : 
    2840             :     // ratio of screen material diameter to screen material spacing
    2841        3386 :     Real64 Gamma = screen->diameterToSpacingRatio;
    2842             : 
    2843             :     // ************************************************************************************************
    2844             :     // * calculate transmittance of totally absorbing screen material (beam passing through open area)*
    2845             :     // ************************************************************************************************
    2846             : 
    2847             :     // Now we need to normalize phi and theta to the 0 to Pi/2 range using reflection.
    2848        3386 :     if (phi > Constant::PiOvr2) phi = Constant::Pi - phi;
    2849        3386 :     if (theta > Constant::PiOvr2) theta = Constant::Pi - theta;
    2850             : 
    2851             :     // calculate compliment of relative solar azimuth
    2852        3386 :     Real64 Beta = Constant::PiOvr2 - theta;
    2853             : 
    2854             :     // Catch all divide by zero instances
    2855             :     Real64 TransYDir;
    2856             :     Real64 TransXDir;
    2857        3386 :     if (Beta > Small && std::abs(phi - Constant::PiOvr2) > Small) {
    2858        3240 :         Real64 AlphaDblPrime = std::atan(tanPhi / cosTheta);
    2859        3240 :         TransYDir = 1.0 - Gamma * (std::cos(AlphaDblPrime) + std::sin(AlphaDblPrime) * tanPhi * std::sqrt(1.0 + pow_2(1.0 / std::tan(Beta))));
    2860        3240 :         TransYDir = max(0.0, TransYDir);
    2861             :     } else {
    2862         146 :         TransYDir = 0.0;
    2863             :     }
    2864             : 
    2865        3386 :     Real64 COSMu = std::sqrt(pow_2(cosPhi) * pow_2(cosTheta) + pow_2(sinPhi));
    2866        3386 :     if (COSMu <= Small) {
    2867           4 :         TransXDir = 1.0 - Gamma;
    2868             :     } else {
    2869        3382 :         Real64 Epsilon = std::acos(cosPhi * cosTheta / COSMu);
    2870        3382 :         Real64 Eta = Constant::PiOvr2 - Epsilon;
    2871        3382 :         if (std::cos(Epsilon) != 0.0 && Eta != 0.0) {
    2872        3282 :             Real64 MuPrime = std::atan(std::tan(std::acos(COSMu)) / std::cos(Epsilon));
    2873        3282 :             TransXDir =
    2874        3282 :                 1.0 - Gamma * (std::cos(MuPrime) + std::sin(MuPrime) * std::tan(std::acos(COSMu)) * std::sqrt(1.0 + pow_2(1.0 / std::tan(Eta))));
    2875        3282 :             TransXDir = max(0.0, TransXDir);
    2876        3282 :         } else {
    2877         100 :             TransXDir = 0.0;
    2878             :         }
    2879             :     }
    2880        3386 :     Tdirect = max(0.0, TransXDir * TransYDir);
    2881             : 
    2882             :     // *******************************************************************************
    2883             :     // * calculate transmittance of scattered beam due to reflecting screen material *
    2884             :     // *******************************************************************************
    2885             : 
    2886        3386 :     Real64 ReflCyl = screen->CylinderRef;
    2887        3386 :     Real64 ReflCylVis = screen->CylinderRefVis;
    2888             : 
    2889        3386 :     if ((Constant::PiOvr2 - theta) < Small || (Constant::PiOvr2 - phi) < Small) {
    2890         146 :         Tscattered = 0.0;
    2891         146 :         TscatteredVis = 0.0;
    2892             :     } else {
    2893             :         //   DeltaMax and Delta are in degrees
    2894        3240 :         Real64 DeltaMax = 89.7 - (10.0 * Gamma / 0.16);
    2895        3240 :         Real64 Delta = std::sqrt(pow_2(theta / Constant::DegToRad) + pow_2(phi / Constant::DegToRad));
    2896             : 
    2897             :         //   Use empirical model to determine maximum (peak) scattering
    2898        3240 :         Real64 Tscattermax = 0.0229 * Gamma + 0.2971 * ReflCyl - 0.03624 * pow_2(Gamma) + 0.04763 * pow_2(ReflCyl) - 0.44416 * Gamma * ReflCyl;
    2899             :         Real64 TscattermaxVis =
    2900        3240 :             0.0229 * Gamma + 0.2971 * ReflCylVis - 0.03624 * pow_2(Gamma) + 0.04763 * pow_2(ReflCylVis) - 0.44416 * Gamma * ReflCylVis;
    2901             : 
    2902             :         //   Vary slope of interior and exterior surface of scattering model
    2903        3240 :         Real64 ExponentInterior = -pow_2(Delta - DeltaMax) / 600.0;
    2904        3240 :         Real64 ExponentExterior = -std::pow(std::abs(Delta - DeltaMax), 2.5) / 600.0;
    2905             : 
    2906             :         //   Determine ratio of scattering at 0,0 incident angle to maximum (peak) scattering
    2907        3240 :         Real64 PeakToPlateauRatio = 1.0 / (0.2 * (1 - Gamma) * ReflCyl);
    2908        3240 :         Real64 PeakToPlateauRatioVis = 1.0 / (0.2 * (1 - Gamma) * ReflCylVis);
    2909             : 
    2910             :         //     Apply offset for plateau and use exterior exponential function to simulate actual scattering as a function of solar angles
    2911        3240 :         if (Delta > DeltaMax) {
    2912         968 :             Tscattered = 0.2 * (1.0 - Gamma) * ReflCyl * Tscattermax * (1.0 + (PeakToPlateauRatio - 1.0) * std::exp(ExponentExterior));
    2913         968 :             TscatteredVis = 0.2 * (1.0 - Gamma) * ReflCylVis * TscattermaxVis * (1.0 + (PeakToPlateauRatioVis - 1.0) * std::exp(ExponentExterior));
    2914             :             //     Trim off offset if solar angle (delta) is greater than maximum (peak) scattering angle
    2915         968 :             Tscattered -= (0.2 * (1.0 - Gamma) * ReflCyl * Tscattermax) * max(0.0, (Delta - DeltaMax) / (90.0 - DeltaMax));
    2916         968 :             TscatteredVis -= (0.2 * (1.0 - Gamma) * ReflCylVis * TscattermaxVis) * max(0.0, (Delta - DeltaMax) / (90.0 - DeltaMax));
    2917             :         } else {
    2918        2272 :             Tscattered = 0.2 * (1.0 - Gamma) * ReflCyl * Tscattermax * (1.0 + (PeakToPlateauRatio - 1.0) * std::exp(ExponentInterior));
    2919        2272 :             TscatteredVis = 0.2 * (1.0 - Gamma) * ReflCylVis * TscattermaxVis * (1.0 + (PeakToPlateauRatioVis - 1.0) * std::exp(ExponentInterior));
    2920             :         }
    2921             :     }
    2922             : 
    2923        3386 :     if (screen->bmRefModel == Material::ScreenBeamReflectanceModel::DoNotModel) {
    2924           0 :         if (sunInFront) {
    2925           0 :             tar.BmTrans = Tdirect;
    2926           0 :             tar.BmTransVis = Tdirect;
    2927           0 :             tar.BmTransBack = 0.0;
    2928             :         } else {
    2929           0 :             tar.BmTrans = 0.0;
    2930           0 :             tar.BmTransVis = 0.0;
    2931           0 :             tar.BmTransBack = Tdirect;
    2932             :         }
    2933           0 :         Tscattered = 0.0;
    2934           0 :         TscatteredVis = 0.0;
    2935        3386 :     } else if (screen->bmRefModel == Material::ScreenBeamReflectanceModel::DirectBeam) {
    2936           0 :         if (sunInFront) {
    2937           0 :             tar.BmTrans = Tdirect + Tscattered;
    2938           0 :             tar.BmTransVis = Tdirect + TscatteredVis;
    2939           0 :             tar.BmTransBack = 0.0;
    2940             :         } else {
    2941           0 :             tar.BmTrans = 0.0;
    2942           0 :             tar.BmTransVis = 0.0;
    2943           0 :             tar.BmTransBack = Tdirect + Tscattered;
    2944             :         }
    2945           0 :         Tscattered = 0.0;
    2946           0 :         TscatteredVis = 0.0;
    2947        3386 :     } else if (screen->bmRefModel == Material::ScreenBeamReflectanceModel::Diffuse) {
    2948        3386 :         if (sunInFront) {
    2949        1296 :             tar.BmTrans = Tdirect;
    2950        1296 :             tar.BmTransVis = Tdirect;
    2951        1296 :             tar.BmTransBack = 0.0;
    2952             :         } else {
    2953        2090 :             tar.BmTrans = 0.0;
    2954        2090 :             tar.BmTransVis = 0.0;
    2955        2090 :             tar.BmTransBack = Tdirect;
    2956             :         }
    2957        3386 :         Tscattered = max(0.0, Tscattered);
    2958        3386 :         TscatteredVis = max(0.0, TscatteredVis);
    2959             :     }
    2960             : 
    2961        3386 :     if (sunInFront) {
    2962        1296 :         tar.DfTrans = Tscattered;
    2963        1296 :         tar.DfTransVis = TscatteredVis;
    2964        1296 :         tar.DfTransBack = 0.0;
    2965        1296 :         tar.RefSolFront = max(0.0, ReflCyl * (1.0 - Tdirect) - Tscattered);
    2966        1296 :         tar.RefVisFront = max(0.0, ReflCylVis * (1.0 - Tdirect) - TscatteredVis);
    2967        1296 :         tar.AbsSolFront = max(0.0, (1.0 - Tdirect) * (1.0 - ReflCyl));
    2968        1296 :         tar.RefSolBack = 0.0;
    2969        1296 :         tar.RefVisBack = 0.0;
    2970        1296 :         tar.AbsSolBack = 0.0;
    2971             :     } else {
    2972        2090 :         tar.DfTrans = 0.0;
    2973        2090 :         tar.DfTransVis = 0.0;
    2974        2090 :         tar.DfTransBack = Tscattered;
    2975        2090 :         tar.RefSolFront = 0.0;
    2976        2090 :         tar.RefVisFront = 0.0;
    2977        2090 :         tar.AbsSolFront = 0.0;
    2978        2090 :         tar.RefSolBack = max(0.0, ReflCyl * (1.0 - Tdirect) - Tscattered);
    2979        2090 :         tar.RefVisBack = max(0.0, ReflCylVis * (1.0 - Tdirect) - TscatteredVis);
    2980        2090 :         tar.AbsSolBack = max(0.0, (1.0 - Tdirect) * (1.0 - ReflCyl));
    2981             :     }
    2982        3386 : } // CalcScreenTransmittance()
    2983             : 
    2984           0 : void GetRelativePhiTheta(Real64 phiWin, Real64 thetaWin, Vector3<Real64> const &solcos, Real64 &phi, Real64 &theta)
    2985             : {
    2986           0 :     phi = std::abs(std::acos(solcos.z) - phiWin);
    2987           0 :     theta = std::abs(std::atan2(solcos.x, solcos.y) - thetaWin);
    2988             : 
    2989           0 :     NormalizePhiTheta(phi, theta);
    2990           0 : } // GetRelativePhiTheta()
    2991             : 
    2992             : // Use reflection around Pi to normalize to the range 0 to Pi
    2993        3248 : void NormalizePhiTheta(Real64 &phi, Real64 &theta)
    2994             : {
    2995             : 
    2996        3248 :     while (phi > 2 * Constant::Pi)
    2997           0 :         phi -= 2 * Constant::Pi;
    2998        3248 :     if (phi > Constant::Pi) phi = 2 * Constant::Pi - phi;
    2999             : 
    3000        3724 :     while (theta > 2 * Constant::Pi)
    3001         476 :         theta -= 2 * Constant::Pi;
    3002        3248 :     if (theta > Constant::Pi) theta = 2 * Constant::Pi - theta;
    3003        3248 : } // NormalizePhiTheta()
    3004             : 
    3005        4692 : void GetPhiThetaIndices(Real64 phi, Real64 theta, Real64 dPhi, Real64 dTheta, int &iPhi1, int &iPhi2, int &iTheta1, int &iTheta2)
    3006             : {
    3007        4692 :     iPhi1 = int(phi / dPhi);
    3008        4692 :     iPhi2 = (iPhi1 == maxIPhi - 1) ? iPhi1 : iPhi1 + 1;
    3009        4692 :     iTheta1 = int(theta / dTheta);
    3010        4692 :     iTheta2 = (iTheta1 == maxITheta - 1) ? iTheta1 : iTheta1 + 1;
    3011        4692 : } // GetPhiThetaIndices()
    3012             : 
    3013             : } // namespace EnergyPlus::Material

Generated by: LCOV version 1.14