LCOV - code coverage report
Current view: top level - EnergyPlus - WindowManagerExteriorOptical.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 244 318 76.7 %
Date: 2024-08-24 18:31:18 Functions: 33 42 78.6 %

          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             : #include <cassert>
      49             : 
      50             : // EnergyPlus headers
      51             : #include <EnergyPlus/Construction.hh>
      52             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      53             : #include <EnergyPlus/DataEnvironment.hh>
      54             : #include <EnergyPlus/DataHeatBalance.hh>
      55             : #include <EnergyPlus/DataSurfaces.hh>
      56             : #include <EnergyPlus/Material.hh>
      57             : #include <EnergyPlus/WindowManager.hh>
      58             : 
      59             : // Windows library headers
      60             : #include <WCEMultiLayerOptics.hpp>
      61             : 
      62             : #include "WindowManagerExteriorData.hh"
      63             : #include "WindowManagerExteriorOptical.hh"
      64             : 
      65             : namespace EnergyPlus {
      66             : 
      67             : using namespace FenestrationCommon;
      68             : using namespace SpectralAveraging;
      69             : using namespace SingleLayerOptics;
      70             : 
      71             : using namespace DataEnvironment;
      72             : using namespace DataSurfaces;
      73             : using namespace DataHeatBalance;
      74             : namespace Window {
      75             : 
      76           0 :     std::shared_ptr<CBSDFLayer> getBSDFLayer(EnergyPlusData &state, const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
      77             :     {
      78             :         // SUBROUTINE INFORMATION:
      79             :         //       AUTHOR         Simon Vidanovic
      80             :         //       DATE WRITTEN   September 2016
      81             :         //       MODIFIED       na
      82             :         //       RE-ENGINEERED  na
      83             : 
      84             :         // PURPOSE OF THIS SUBROUTINE:
      85             :         // BSDF will be created in different ways that is based on material type
      86             : 
      87           0 :         std::shared_ptr<CWCELayerFactory> aFactory = nullptr;
      88           0 :         if (t_Material.group == Material::Group::WindowGlass) {
      89           0 :             aFactory = std::make_shared<CWCESpecularLayerFactory>(t_Material, t_Range);
      90           0 :         } else if (t_Material.group == Material::Group::WindowBlind) {
      91           0 :             aFactory = std::make_shared<CWCEVenetianBlindLayerFactory>(t_Material, t_Range);
      92           0 :         } else if (t_Material.group == Material::Group::Screen) {
      93           0 :             aFactory = std::make_shared<CWCEScreenLayerFactory>(t_Material, t_Range);
      94           0 :         } else if (t_Material.group == Material::Group::Shade) {
      95           0 :             aFactory = std::make_shared<CWCEDiffuseShadeLayerFactory>(t_Material, t_Range);
      96             :         }
      97           0 :         return aFactory->getBSDFLayer(state);
      98           0 :     }
      99             : 
     100          16 :     CScatteringLayer getScatteringLayer(EnergyPlusData &state, const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     101             :     {
     102             :         // SUBROUTINE INFORMATION:
     103             :         //       AUTHOR         Simon Vidanovic
     104             :         //       DATE WRITTEN   May 2017
     105             :         //       MODIFIED       na
     106             :         //       RE-ENGINEERED
     107             :         //          April 2021: returning CScatteringLayer instead of pointer to it
     108             : 
     109             :         // PURPOSE OF THIS SUBROUTINE:
     110             :         // Scattering will be created in different ways that is based on material type
     111             : 
     112          16 :         std::shared_ptr<CWCELayerFactory> aFactory = nullptr;
     113          16 :         if (t_Material.group == Material::Group::WindowGlass || t_Material.group == Material::Group::WindowSimpleGlazing) {
     114          12 :             aFactory = std::make_shared<CWCESpecularLayerFactory>(t_Material, t_Range);
     115           4 :         } else if (t_Material.group == Material::Group::WindowBlind) {
     116           2 :             aFactory = std::make_shared<CWCEVenetianBlindLayerFactory>(t_Material, t_Range);
     117           2 :         } else if (t_Material.group == Material::Group::Screen) {
     118           0 :             aFactory = std::make_shared<CWCEScreenLayerFactory>(t_Material, t_Range);
     119           2 :         } else if (t_Material.group == Material::Group::Shade) {
     120           2 :             aFactory = std::make_shared<CWCEDiffuseShadeLayerFactory>(t_Material, t_Range);
     121             :         }
     122          32 :         return aFactory->getLayer(state);
     123          16 :     }
     124             : 
     125             :     // void InitWCE_BSDFOpticalData() {
     126             :     //     // SUBROUTINE INFORMATION:
     127             :     //     //       AUTHOR         Simon Vidanovic
     128             :     //     //       DATE WRITTEN   September 2016
     129             :     //     //       MODIFIED       na
     130             :     //     //       RE-ENGINEERED  na
     131             :     //
     132             :     //     // PURPOSE OF THIS SUBROUTINE:
     133             :     //     // Initialize BSDF construction layers in Solar and Visible spectrum.
     134             :     //
     135             :     //     auto aWinConstBSDF = CWindowConstructionsBSDF::instance();
     136             :     //     for ( auto ConstrNum = 1; ConstrNum <= TotConstructs; ++ConstrNum ) {
     137             :     //         auto& construction( Construct( ConstrNum ) );
     138             :     //         if ( construction.isGlazingConstruction() ) {
     139             :     //             for ( auto LayNum = 1; LayNum <= construction.TotLayers; ++LayNum ) {
     140             :     //                 auto& material( dataMaterial.Material( construction.LayerPoint( LayNum ) ) );
     141             :     //                 if ( material->group != WindowGas && material->group != WindowGasMixture &&
     142             :     //                     material->group != ComplexWindowGap && material->group != ComplexWindowShade ) {
     143             :     //                     auto aMaterial = std::make_shared< Material::MaterialBase >();
     144             :     //                     *aMaterial = material;
     145             :     //
     146             :     //                     // This is necessary because rest of EnergyPlus code relies on TransDiff property
     147             :     //                     // of construction. It will basically trigger Window optical calculations if this
     148             :     //                     // property is >0.
     149             :     //                     construction.TransDiff = 0.1;
     150             :     //
     151             :     //                     auto aRange = WavelengthRange::Solar;
     152             :     //                     auto aSolarLayer = getBSDFLayer( aMaterial, aRange );
     153             :     //                     aWinConstBSDF.pushBSDFLayer( aRange, ConstrNum, aSolarLayer );
     154             :     //
     155             :     //                     aRange = WavelengthRange::Visible;
     156             :     //                     auto aVisibleLayer = getBSDFLayer( aMaterial, aRange );
     157             :     //                     aWinConstBSDF.pushBSDFLayer( aRange, ConstrNum, aVisibleLayer );
     158             :     //                 }
     159             :     //
     160             :     //             }
     161             :     //         }
     162             :     //     }
     163             :     // }
     164             : 
     165           3 :     void InitWCE_SimplifiedOpticalData(EnergyPlusData &state)
     166             :     {
     167             :         // SUBROUTINE INFORMATION:
     168             :         //       AUTHOR         Simon Vidanovic
     169             :         //       DATE WRITTEN   May 2017
     170             :         //       MODIFIED       na
     171             :         //       RE-ENGINEERED  na
     172             : 
     173             :         // PURPOSE OF THIS SUBROUTINE:
     174             :         // Initialize scattering construction layers in Solar and Visible spectrum.
     175             : 
     176             :         // Calculate optical properties of blind-type layers entered with MATERIAL:WindowBlind
     177             :         // Calculation from this is used for IR properties. Need to make sure that properties
     178             :         // are calculated with new WCE optical engine (for both blinds and screens)
     179           3 :         if (state.dataHeatBal->TotBlinds > 0) CalcWindowBlindProperties(state);
     180             : 
     181             :         // Initialize SurfaceScreen structure
     182           3 :         state.dataHeatBal->NumScreens = state.dataHeatBal->TotScreens;
     183           3 :         if (state.dataHeatBal->NumScreens > 0) CalcWindowScreenProperties(state);
     184             : 
     185           3 :         auto &aWinConstSimp = CWindowConstructionsSimplified::instance(state);
     186          23 :         for (int ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) {
     187          20 :             auto &construction = state.dataConstruction->Construct(ConstrNum);
     188          20 :             if (construction.isGlazingConstruction(state)) {
     189          14 :                 for (int LayNum = 1; LayNum <= construction.TotLayers; ++LayNum) {
     190           9 :                     auto *materialBase(state.dataMaterial->Material(construction.LayerPoint(LayNum)));
     191           9 :                     auto *material = dynamic_cast<Material::MaterialChild *>(materialBase);
     192           9 :                     assert(material != nullptr);
     193           9 :                     if (material->group != Material::Group::WindowGas && material->group != Material::Group::WindowGasMixture &&
     194           9 :                         material->group != Material::Group::ComplexWindowGap && material->group != Material::Group::ComplexWindowShade) {
     195             :                         // This is necessary because rest of EnergyPlus code relies on TransDiff property
     196             :                         // of construction. It will basically trigger Window optical calculations if this
     197             :                         // property is >0.
     198           8 :                         construction.TransDiff = 0.1;
     199             : 
     200           8 :                         WavelengthRange aRange = WavelengthRange::Solar;
     201           8 :                         auto aSolarLayer = getScatteringLayer(state, *material, aRange); // (AUTO_OK_OBJ)
     202           8 :                         aWinConstSimp.pushLayer(aRange, ConstrNum, aSolarLayer);
     203             : 
     204           8 :                         aRange = WavelengthRange::Visible;
     205           8 :                         auto aVisibleLayer = getScatteringLayer(state, *material, aRange); // (AUTO_OK_OBJ)
     206           8 :                         aWinConstSimp.pushLayer(aRange, ConstrNum, aVisibleLayer);
     207           8 :                     }
     208             :                 }
     209             :             }
     210             :         }
     211             : 
     212             :         // Get effective glass and shade/blind emissivities for windows that have interior blind or
     213             :         // shade. These are used to calculate zone MRT contribution from window when
     214             :         // interior blind/shade is deployed.
     215             : 
     216          24 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     217          21 :             if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue;
     218          21 :             if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow) continue;
     219           3 :             if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) continue; // Irrelevant for Complex Fen
     220           3 :             if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) continue; // not required
     221           3 :             int ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
     222           3 :             if (ConstrNumSh == 0) continue;
     223           2 :             int TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers;
     224           2 :             bool IntShade = false;
     225           2 :             bool IntBlind = false;
     226           2 :             int ShadeLayPtr = 0;
     227           2 :             int BlNum = 0;
     228           2 :             auto const *thisMaterial = dynamic_cast<Material::MaterialChild *>(
     229           2 :                 state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)));
     230           2 :             assert(thisMaterial != nullptr);
     231           2 :             if (thisMaterial->group == Material::Group::Shade) {
     232           1 :                 IntShade = true;
     233           1 :                 ShadeLayPtr = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay);
     234             :             }
     235           2 :             if (thisMaterial->group == Material::Group::WindowBlind) {
     236           1 :                 IntBlind = true;
     237           1 :                 BlNum = thisMaterial->BlindDataPtr;
     238             :             }
     239             : 
     240           2 :             if (IntShade || IntBlind) {
     241           2 :                 for (int ISlatAng = 1; ISlatAng <= Material::MaxSlatAngs; ++ISlatAng) {
     242           2 :                     Real64 EpsGlIR = 0.0;
     243           2 :                     Real64 RhoGlIR = 0.0;
     244           2 :                     if (IntShade || IntBlind) {
     245           2 :                         EpsGlIR = dynamic_cast<const Material::MaterialChild *>(
     246           2 :                                       state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay - 1)))
     247             :                                       ->AbsorpThermalBack;
     248           2 :                         RhoGlIR = 1 - EpsGlIR;
     249             :                     }
     250           2 :                     if (IntShade) {
     251           1 :                         auto const *thisMaterialShade = dynamic_cast<const Material::MaterialChild *>(state.dataMaterial->Material(ShadeLayPtr));
     252           1 :                         Real64 TauShIR = thisMaterialShade->TransThermal;
     253           1 :                         Real64 EpsShIR = thisMaterialShade->AbsorpThermal;
     254           1 :                         Real64 RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
     255           1 :                         state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[1] =
     256           1 :                             EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR));
     257           1 :                         state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss[1] = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR);
     258             :                     }
     259           2 :                     if (IntBlind) {
     260           1 :                         Real64 TauShIR = state.dataMaterial->Blind(BlNum).IRFrontTrans(ISlatAng);
     261           1 :                         Real64 EpsShIR = state.dataMaterial->Blind(BlNum).IRBackEmiss(ISlatAng);
     262           1 :                         Real64 RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
     263           1 :                         state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss[ISlatAng] =
     264           1 :                             EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR));
     265           1 :                         state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss[ISlatAng] = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR);
     266             :                     }
     267             :                     // Loop over remaining slat angles only if blind with movable slats
     268           2 :                     if (IntShade) break; // Loop over remaining slat angles only if blind
     269           1 :                     if (IntBlind) {
     270           1 :                         if (state.dataMaterial->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
     271             :                     }
     272             :                 } // End of slat angle loop
     273             :             }     // End of check if interior shade or interior blind
     274             :         }         // End of surface loop
     275           3 :     }
     276             : 
     277           3 :     Real64 GetSolarTransDirectHemispherical(EnergyPlusData &state, int ConstrNum)
     278             :     {
     279             :         const auto aWinConstSimp = // (AUTO_OK_SHARED_PTR)
     280           3 :             CWindowConstructionsSimplified::instance(state).getEquivalentLayer(state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
     281           3 :         return aWinConstSimp->getPropertySimple(
     282           6 :             0.3, 2.5, FenestrationCommon::PropertySimple::T, FenestrationCommon::Side::Front, FenestrationCommon::Scattering::DirectHemispherical);
     283           3 :     }
     284             : 
     285           3 :     Real64 GetVisibleTransDirectHemispherical(EnergyPlusData &state, int ConstrNum)
     286             :     {
     287             :         const auto aWinConstSimp = // (AUTO_OK_SHARED_PTR)
     288           3 :             CWindowConstructionsSimplified::instance(state).getEquivalentLayer(state, FenestrationCommon::WavelengthRange::Visible, ConstrNum);
     289           3 :         return aWinConstSimp->getPropertySimple(
     290           6 :             0.38, 0.78, FenestrationCommon::PropertySimple::T, FenestrationCommon::Side::Front, FenestrationCommon::Scattering::DirectHemispherical);
     291           3 :     }
     292             : 
     293             :     ///////////////////////////////////////////////////////////////////////////////
     294             :     //   CWCEMaterialFactory
     295             :     ///////////////////////////////////////////////////////////////////////////////
     296          16 :     CWCEMaterialFactory::CWCEMaterialFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     297          16 :         : m_MaterialProperties(t_Material), m_Range(t_Range), m_Initialized(false)
     298             :     {
     299          16 :     }
     300             : 
     301          16 :     std::shared_ptr<CMaterial> CWCEMaterialFactory::getMaterial(EnergyPlusData &state)
     302             :     {
     303          16 :         if (!m_Initialized) {
     304          16 :             init(state);
     305          16 :             m_Initialized = true;
     306             :         }
     307          16 :         return m_Material;
     308             :     }
     309             : 
     310             :     ///////////////////////////////////////////////////////////////////////////////
     311             :     //   CWCESpecularMaterialsFactory
     312             :     ///////////////////////////////////////////////////////////////////////////////
     313          12 :     CWCESpecularMaterialsFactory::CWCESpecularMaterialsFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     314          12 :         : CWCEMaterialFactory(t_Material, t_Range)
     315             :     {
     316          12 :     }
     317             : 
     318          12 :     void CWCESpecularMaterialsFactory::init(EnergyPlusData &state)
     319             :     {
     320          12 :         if (m_MaterialProperties.GlassSpectralDataPtr > 0) {
     321           0 :             auto aSolarSpectrum = CWCESpecturmProperties::getDefaultSolarRadiationSpectrum(state); // (AUTO_OK_OBJ)
     322           0 :             std::shared_ptr<CSpectralSampleData> aSampleData = nullptr;
     323           0 :             aSampleData = CWCESpecturmProperties::getSpectralSample(state, m_MaterialProperties.GlassSpectralDataPtr);
     324             : 
     325           0 :             auto aSample = std::make_shared<CSpectralSample>(aSampleData, aSolarSpectrum); // (AUTO_OK_SHARED_PTR)
     326             : 
     327           0 :             FenestrationCommon::MaterialType aType = MaterialType::Monolithic;
     328           0 :             CWavelengthRange aRange(m_Range);
     329           0 :             Real64 lowLambda = aRange.minLambda();
     330           0 :             Real64 highLambda = aRange.maxLambda();
     331             : 
     332             :             // Do not apply detector data if we do not have spectral data. This will only cause more inaccurate results at the end. (Simon)
     333           0 :             if (m_Range == WavelengthRange::Visible && m_MaterialProperties.GlassSpectralDataPtr != 0) {
     334           0 :                 const auto aPhotopicResponse = CWCESpecturmProperties::getDefaultVisiblePhotopicResponse(state); // (AUTO_OK_OBJ)
     335           0 :                 aSample->setDetectorData(aPhotopicResponse);
     336           0 :             }
     337             : 
     338           0 :             Real64 thickness = m_MaterialProperties.Thickness;
     339           0 :             m_Material = std::make_shared<CMaterialSample>(aSample, thickness, aType, lowLambda, highLambda);
     340           0 :         } else {
     341          12 :             if (m_Range == WavelengthRange::Solar) {
     342           6 :                 m_Material = std::make_shared<CMaterialSingleBand>(m_MaterialProperties.Trans,
     343           6 :                                                                    m_MaterialProperties.Trans,
     344           6 :                                                                    m_MaterialProperties.ReflectSolBeamFront,
     345           6 :                                                                    m_MaterialProperties.ReflectSolBeamBack,
     346           6 :                                                                    m_Range);
     347             :             }
     348          12 :             if (m_Range == WavelengthRange::Visible) {
     349           6 :                 m_Material = std::make_shared<CMaterialSingleBand>(m_MaterialProperties.TransVis,
     350           6 :                                                                    m_MaterialProperties.TransVis,
     351           6 :                                                                    m_MaterialProperties.ReflectVisBeamFront,
     352           6 :                                                                    m_MaterialProperties.ReflectVisBeamBack,
     353           6 :                                                                    m_Range);
     354             :             }
     355             :         }
     356          12 :     }
     357             : 
     358             :     ///////////////////////////////////////////////////////////////////////////////
     359             :     //   CWCEMaterialDualBandFactory
     360             :     ///////////////////////////////////////////////////////////////////////////////
     361           4 :     CWCEMaterialDualBandFactory::CWCEMaterialDualBandFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     362           4 :         : CWCEMaterialFactory(t_Material, t_Range)
     363             :     {
     364           4 :     }
     365             : 
     366           4 :     void CWCEMaterialDualBandFactory::init([[maybe_unused]] EnergyPlusData &state)
     367             :     {
     368           4 :         if (m_Range == WavelengthRange::Visible) {
     369           2 :             m_Material = createVisibleRangeMaterial(state);
     370             :         } else {
     371           2 :             auto aVisibleRangeMaterial = createVisibleRangeMaterial(state); // (AUTO_OK_OBJ)
     372           2 :             auto aSolarRangeMaterial = createSolarRangeMaterial(state);     // (AUTO_OK_OBJ)
     373             :             // Ratio visible to solar range. It can be calculated from solar spectrum.
     374           2 :             Real64 ratio = 0.49;
     375           2 :             m_Material = std::make_shared<CMaterialDualBand>(aVisibleRangeMaterial, aSolarRangeMaterial, ratio);
     376           2 :         }
     377           4 :     }
     378             : 
     379             :     ///////////////////////////////////////////////////////////////////////////////
     380             :     //   CWCEVenetianBlindMaterialsFactory
     381             :     ///////////////////////////////////////////////////////////////////////////////
     382           2 :     CWCEVenetianBlindMaterialsFactory::CWCEVenetianBlindMaterialsFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     383           2 :         : CWCEMaterialDualBandFactory(t_Material, t_Range)
     384             :     {
     385           2 :     }
     386             : 
     387           2 :     std::shared_ptr<CMaterialSingleBand> CWCEVenetianBlindMaterialsFactory::createVisibleRangeMaterial(EnergyPlusData &state)
     388             :     {
     389           2 :         int blindDataPtr = m_MaterialProperties.BlindDataPtr;
     390           2 :         assert(blindDataPtr > 0);
     391           2 :         auto &blind = state.dataMaterial->Blind(blindDataPtr);
     392             : 
     393           2 :         CWavelengthRange aRange(WavelengthRange::Visible);
     394           2 :         Real64 lowLambda = aRange.minLambda();
     395           2 :         Real64 highLambda = aRange.maxLambda();
     396             : 
     397           2 :         Real64 Tf = blind.SlatTransVisDiffDiff;
     398           2 :         Real64 Tb = blind.SlatTransVisDiffDiff;
     399           2 :         Real64 Rf = blind.SlatFrontReflVisDiffDiff;
     400           2 :         Real64 Rb = blind.SlatBackReflVisDiffDiff;
     401             : 
     402           4 :         return std::make_shared<CMaterialSingleBand>(Tf, Tb, Rf, Rb, lowLambda, highLambda);
     403           2 :     }
     404             : 
     405           1 :     std::shared_ptr<CMaterialSingleBand> CWCEVenetianBlindMaterialsFactory::createSolarRangeMaterial([[maybe_unused]] EnergyPlusData &state)
     406             :     {
     407           1 :         int blindDataPtr = m_MaterialProperties.BlindDataPtr;
     408           1 :         assert(blindDataPtr > 0);
     409           1 :         auto &blind = state.dataMaterial->Blind(blindDataPtr);
     410             : 
     411           1 :         CWavelengthRange aRange(WavelengthRange::Solar);
     412           1 :         Real64 lowLambda = aRange.minLambda();
     413           1 :         Real64 highLambda = aRange.maxLambda();
     414             : 
     415           1 :         Real64 Tf = blind.SlatTransSolDiffDiff;
     416           1 :         Real64 Tb = blind.SlatTransSolDiffDiff;
     417           1 :         Real64 Rf = blind.SlatFrontReflSolDiffDiff;
     418           1 :         Real64 Rb = blind.SlatBackReflSolDiffDiff;
     419             : 
     420           2 :         return std::make_shared<CMaterialSingleBand>(Tf, Tb, Rf, Rb, lowLambda, highLambda);
     421           1 :     }
     422             : 
     423             :     ///////////////////////////////////////////////////////////////////////////////
     424             :     //   CWCEScreenMaterialsFactory
     425             :     ///////////////////////////////////////////////////////////////////////////////
     426           0 :     CWCEScreenMaterialsFactory::CWCEScreenMaterialsFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     427           0 :         : CWCEMaterialDualBandFactory(t_Material, t_Range)
     428             :     {
     429             :         // Current EnergyPlus model does not support material transmittance different from zero.
     430             :         // To enable that, it would be necessary to change input in IDF
     431           0 :     }
     432             : 
     433           0 :     std::shared_ptr<CMaterialSingleBand> CWCEScreenMaterialsFactory::createVisibleRangeMaterial([[maybe_unused]] EnergyPlusData &state)
     434             :     {
     435           0 :         CWavelengthRange aRange(WavelengthRange::Visible);
     436           0 :         Real64 lowLambda = aRange.minLambda();
     437           0 :         Real64 highLambda = aRange.maxLambda();
     438             : 
     439           0 :         Real64 Tf = 0.0;
     440           0 :         Real64 Tb = 0.0;
     441           0 :         Real64 Rf = m_MaterialProperties.ReflectShadeVis;
     442           0 :         Real64 Rb = m_MaterialProperties.ReflectShadeVis;
     443             : 
     444           0 :         return std::make_shared<CMaterialSingleBand>(Tf, Tb, Rf, Rb, lowLambda, highLambda);
     445           0 :     }
     446             : 
     447           0 :     std::shared_ptr<CMaterialSingleBand> CWCEScreenMaterialsFactory::createSolarRangeMaterial([[maybe_unused]] EnergyPlusData &state)
     448             :     {
     449           0 :         CWavelengthRange aRange(WavelengthRange::Solar);
     450           0 :         Real64 lowLambda = aRange.minLambda();
     451           0 :         Real64 highLambda = aRange.maxLambda();
     452             : 
     453           0 :         Real64 Tf = 0.0;
     454           0 :         Real64 Tb = 0.0;
     455           0 :         Real64 Rf = m_MaterialProperties.ReflectShade;
     456           0 :         Real64 Rb = m_MaterialProperties.ReflectShade;
     457             : 
     458           0 :         return std::make_shared<CMaterialSingleBand>(Tf, Tb, Rf, Rb, lowLambda, highLambda);
     459           0 :     }
     460             : 
     461             :     ///////////////////////////////////////////////////////////////////////////////
     462             :     //   CWCEDiffuseShadeMaterialsFactory
     463             :     ///////////////////////////////////////////////////////////////////////////////
     464           2 :     CWCEDiffuseShadeMaterialsFactory::CWCEDiffuseShadeMaterialsFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     465           2 :         : CWCEMaterialDualBandFactory(t_Material, t_Range)
     466             :     {
     467           2 :     }
     468             : 
     469           2 :     std::shared_ptr<CMaterialSingleBand> CWCEDiffuseShadeMaterialsFactory::createVisibleRangeMaterial([[maybe_unused]] EnergyPlusData &state)
     470             :     {
     471           2 :         CWavelengthRange aRange(WavelengthRange::Visible);
     472           2 :         Real64 lowLambda = aRange.minLambda();
     473           2 :         Real64 highLambda = aRange.maxLambda();
     474             : 
     475           2 :         Real64 Tf = m_MaterialProperties.TransVis;
     476           2 :         Real64 Tb = m_MaterialProperties.TransVis;
     477           2 :         Real64 Rf = m_MaterialProperties.ReflectShadeVis;
     478           2 :         Real64 Rb = m_MaterialProperties.ReflectShadeVis;
     479             : 
     480           4 :         return std::make_shared<CMaterialSingleBand>(Tf, Tb, Rf, Rb, lowLambda, highLambda);
     481           2 :     }
     482             : 
     483           1 :     std::shared_ptr<CMaterialSingleBand> CWCEDiffuseShadeMaterialsFactory::createSolarRangeMaterial([[maybe_unused]] EnergyPlusData &state)
     484             :     {
     485           1 :         CWavelengthRange aRange(WavelengthRange::Solar);
     486           1 :         Real64 lowLambda = aRange.minLambda();
     487           1 :         Real64 highLambda = aRange.maxLambda();
     488             : 
     489           1 :         Real64 Tf = m_MaterialProperties.Trans;
     490           1 :         Real64 Tb = m_MaterialProperties.Trans;
     491           1 :         Real64 Rf = m_MaterialProperties.ReflectShade;
     492           1 :         Real64 Rb = m_MaterialProperties.ReflectShade;
     493             : 
     494           2 :         return std::make_shared<CMaterialSingleBand>(Tf, Tb, Rf, Rb, lowLambda, highLambda);
     495           1 :     }
     496             : 
     497             :     ///////////////////////////////////////////////////////////////////////////////
     498             :     //   CWCECellFactory
     499             :     ///////////////////////////////////////////////////////////////////////////////
     500          16 :     IWCECellDescriptionFactory::IWCECellDescriptionFactory(const Material::MaterialChild &t_Material) : m_Material(t_Material)
     501             :     {
     502          16 :     }
     503             : 
     504             :     ///////////////////////////////////////////////////////////////////////////////
     505             :     //   CWCESpecularCellFactory
     506             :     ///////////////////////////////////////////////////////////////////////////////
     507             : 
     508          12 :     CWCESpecularCellFactory::CWCESpecularCellFactory(const Material::MaterialChild &t_Material) : IWCECellDescriptionFactory(t_Material)
     509             :     {
     510          12 :     }
     511             : 
     512          12 :     std::shared_ptr<ICellDescription> CWCESpecularCellFactory::getCellDescription([[maybe_unused]] EnergyPlusData &state)
     513             :     {
     514          12 :         return std::make_shared<CSpecularCellDescription>();
     515             :     }
     516             : 
     517             :     ///////////////////////////////////////////////////////////////////////////////
     518             :     //   CWCEVenetianBlindCellFactory
     519             :     ///////////////////////////////////////////////////////////////////////////////
     520           2 :     CWCEVenetianBlindCellFactory::CWCEVenetianBlindCellFactory(const Material::MaterialChild &t_Material) : IWCECellDescriptionFactory(t_Material)
     521             :     {
     522           2 :     }
     523             : 
     524           2 :     std::shared_ptr<ICellDescription> CWCEVenetianBlindCellFactory::getCellDescription([[maybe_unused]] EnergyPlusData &state)
     525             :     {
     526           2 :         const int blindDataPtr = m_Material.BlindDataPtr;
     527           2 :         assert(blindDataPtr > 0);
     528           2 :         auto &blind = state.dataMaterial->Blind(blindDataPtr);
     529             : 
     530           2 :         Real64 slatWidth = blind.SlatWidth;
     531           2 :         Real64 slatSpacing = blind.SlatSeparation;
     532           2 :         Real64 slatTiltAngle = 90.0 - blind.SlatAngle; // Need to convert to WCE system
     533           2 :         Real64 curvatureRadius = 0.0;                  // No curvature radius in current IDF definition
     534           2 :         size_t numOfSlatSegments = 5;                  // Number of segments to use in venetian calculations
     535           2 :         return std::make_shared<CVenetianCellDescription>(slatWidth, slatSpacing, slatTiltAngle, curvatureRadius, numOfSlatSegments);
     536             :     }
     537             : 
     538             :     ///////////////////////////////////////////////////////////////////////////////
     539             :     //   CWCEScreenCellFactory
     540             :     ///////////////////////////////////////////////////////////////////////////////
     541           0 :     CWCEScreenCellFactory::CWCEScreenCellFactory(const Material::MaterialChild &t_Material) : IWCECellDescriptionFactory(t_Material)
     542             :     {
     543           0 :     }
     544             : 
     545           0 :     std::shared_ptr<ICellDescription> CWCEScreenCellFactory::getCellDescription([[maybe_unused]] EnergyPlusData &state)
     546             :     {
     547           0 :         Real64 diameter = m_Material.Thickness; // Thickness in this case is diameter
     548             :         // ratio is not saved withing material but rather calculated from transmittance
     549           0 :         const Real64 ratio = 1.0 - sqrt(m_Material.Trans);
     550           0 :         Real64 spacing = diameter / ratio;
     551           0 :         return std::make_shared<CWovenCellDescription>(diameter, spacing);
     552             :     }
     553             : 
     554             :     ///////////////////////////////////////////////////////////////////////////////
     555             :     //   CWCEDiffuseShadeCellFactory
     556             :     ///////////////////////////////////////////////////////////////////////////////
     557           2 :     CWCEDiffuseShadeCellFactory::CWCEDiffuseShadeCellFactory(const Material::MaterialChild &t_Material) : IWCECellDescriptionFactory(t_Material)
     558             :     {
     559           2 :     }
     560             : 
     561           2 :     std::shared_ptr<ICellDescription> CWCEDiffuseShadeCellFactory::getCellDescription([[maybe_unused]] EnergyPlusData &state)
     562             :     {
     563           2 :         return std::make_shared<CFlatCellDescription>();
     564             :     }
     565             : 
     566             :     ///////////////////////////////////////////////////////////////////////////////
     567             :     //   CWCEBSDFLayerFactory
     568             :     ///////////////////////////////////////////////////////////////////////////////
     569          16 :     CWCELayerFactory::CWCELayerFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     570          16 :         : m_Material(t_Material), m_Range(t_Range), m_BSDFInitialized(false), m_SimpleInitialized(false), m_MaterialFactory(nullptr)
     571             :     {
     572          16 :     }
     573             : 
     574          16 :     std::pair<std::shared_ptr<CMaterial>, std::shared_ptr<ICellDescription>> CWCELayerFactory::init(EnergyPlusData &state)
     575             :     {
     576          16 :         createMaterialFactory();
     577          16 :         auto aMaterial = m_MaterialFactory->getMaterial(state); // (AUTO_OK_SHARED_PTR)
     578          16 :         assert(aMaterial != nullptr);
     579          16 :         auto aCellDescription = getCellDescription(state); // (AUTO_OK_SHARED_PTR)
     580          16 :         assert(aCellDescription != nullptr);
     581             : 
     582          32 :         return std::make_pair(aMaterial, aCellDescription);
     583          16 :     }
     584             : 
     585           0 :     std::shared_ptr<CBSDFLayer> CWCELayerFactory::getBSDFLayer(EnergyPlusData &state)
     586             :     {
     587           0 :         if (!m_BSDFInitialized) {
     588           0 :             auto res = init(state);                                      // (AUTO_OK_SHARED_PTR)
     589           0 :             const auto aBSDF = CBSDFHemisphere::create(BSDFBasis::Full); // (AUTO_OK_OBJ)
     590             : 
     591           0 :             CBSDFLayerMaker aMaker(res.first, aBSDF, res.second);
     592           0 :             m_BSDFLayer = aMaker.getLayer();
     593           0 :             m_BSDFInitialized = true;
     594           0 :         }
     595           0 :         return m_BSDFLayer;
     596             :     }
     597             : 
     598          16 :     CScatteringLayer CWCELayerFactory::getLayer(EnergyPlusData &state)
     599             :     {
     600          16 :         if (!m_SimpleInitialized) {
     601          16 :             auto res = init(state); // (AUTO_OK_SHARED_PTR)
     602             : 
     603          16 :             m_ScatteringLayer = CScatteringLayer(res.first, res.second);
     604          16 :             m_SimpleInitialized = true;
     605          16 :         }
     606          16 :         return m_ScatteringLayer;
     607             :     }
     608             : 
     609          16 :     std::shared_ptr<ICellDescription> CWCELayerFactory::getCellDescription([[maybe_unused]] EnergyPlusData &state) const
     610             :     {
     611          16 :         return m_CellFactory->getCellDescription(state);
     612             :     }
     613             : 
     614             :     ///////////////////////////////////////////////////////////////////////////////
     615             :     //   CWCESpecularLayerFactory
     616             :     ///////////////////////////////////////////////////////////////////////////////
     617          12 :     CWCESpecularLayerFactory::CWCESpecularLayerFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     618          12 :         : CWCELayerFactory(t_Material, t_Range)
     619             :     {
     620          12 :         m_CellFactory = std::make_shared<CWCESpecularCellFactory>(t_Material);
     621          12 :     }
     622             : 
     623          12 :     void CWCESpecularLayerFactory::createMaterialFactory()
     624             :     {
     625          12 :         m_MaterialFactory = std::make_shared<CWCESpecularMaterialsFactory>(m_Material, m_Range);
     626          12 :     }
     627             : 
     628             :     ///////////////////////////////////////////////////////////////////////////////
     629             :     //   CWCEVenetianBlindLayerFactory
     630             :     ///////////////////////////////////////////////////////////////////////////////
     631           2 :     CWCEVenetianBlindLayerFactory::CWCEVenetianBlindLayerFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     632           2 :         : CWCELayerFactory(t_Material, t_Range)
     633             :     {
     634           2 :         m_CellFactory = std::make_shared<CWCEVenetianBlindCellFactory>(t_Material);
     635           2 :     }
     636             : 
     637           2 :     void CWCEVenetianBlindLayerFactory::createMaterialFactory()
     638             :     {
     639           2 :         m_MaterialFactory = std::make_shared<CWCEVenetianBlindMaterialsFactory>(m_Material, m_Range);
     640           2 :     }
     641             : 
     642             :     ///////////////////////////////////////////////////////////////////////////////
     643             :     //   CWCEScreenLayerFactory
     644             :     ///////////////////////////////////////////////////////////////////////////////
     645           0 :     CWCEScreenLayerFactory::CWCEScreenLayerFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     646           0 :         : CWCELayerFactory(t_Material, t_Range)
     647             :     {
     648           0 :         m_CellFactory = std::make_shared<CWCEScreenCellFactory>(t_Material);
     649           0 :     }
     650             : 
     651           0 :     void CWCEScreenLayerFactory::createMaterialFactory()
     652             :     {
     653           0 :         m_MaterialFactory = std::make_shared<CWCEScreenMaterialsFactory>(m_Material, m_Range);
     654           0 :     }
     655             : 
     656             :     ///////////////////////////////////////////////////////////////////////////////
     657             :     //   CWCEDiffuseShadeLayerFactory
     658             :     ///////////////////////////////////////////////////////////////////////////////
     659           2 :     CWCEDiffuseShadeLayerFactory::CWCEDiffuseShadeLayerFactory(const Material::MaterialChild &t_Material, const WavelengthRange t_Range)
     660           2 :         : CWCELayerFactory(t_Material, t_Range)
     661             :     {
     662           2 :         m_CellFactory = std::make_shared<CWCEDiffuseShadeCellFactory>(t_Material);
     663           2 :     }
     664             : 
     665           2 :     void CWCEDiffuseShadeLayerFactory::createMaterialFactory()
     666             :     {
     667           2 :         m_MaterialFactory = std::make_shared<CWCEDiffuseShadeMaterialsFactory>(m_Material, m_Range);
     668           2 :     }
     669             : 
     670             : } // namespace Window
     671             : } // namespace EnergyPlus

Generated by: LCOV version 1.14