Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, 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 : #include <EnergyPlus/Data/EnergyPlusData.hh>
51 : #include <EnergyPlus/DataBSDFWindow.hh>
52 : #include <EnergyPlus/DataHeatBalance.hh>
53 : #include <EnergyPlus/UtilityRoutines.hh>
54 : #include <EnergyPlus/WindowComplexManager.hh>
55 : #include <EnergyPlus/WindowManager.hh>
56 : #include <EnergyPlus/WindowManagerExteriorData.hh>
57 :
58 : #include <WCEMultiLayerOptics.hpp>
59 :
60 : namespace EnergyPlus {
61 :
62 : using namespace DataSurfaces;
63 : using namespace DataHeatBalance;
64 : using namespace WindowComplexManager;
65 :
66 : using namespace SingleLayerOptics;
67 : using namespace FenestrationCommon;
68 : using namespace SpectralAveraging;
69 : using namespace MultiLayerOptics;
70 :
71 : namespace Window {
72 :
73 0 : bool isSurfaceHit(EnergyPlusData &state, const int t_SurfNum, const Vector &t_Ray)
74 : {
75 0 : Real64 DotProd = dot(t_Ray, state.dataSurface->Surface(t_SurfNum).NewellSurfaceNormalVector);
76 0 : return (DotProd > 0);
77 : }
78 :
79 1652 : std::pair<Real64, Real64> getWCECoordinates(EnergyPlusData &state, int const t_SurfNum, Vector const &t_Ray, const BSDFDirection t_Direction)
80 : {
81 1652 : Real64 Theta = 0;
82 1652 : Real64 Phi = 0;
83 :
84 : // get window tilt and azimuth
85 1652 : Real64 Gamma = Constant::DegToRad * state.dataSurface->Surface(t_SurfNum).Tilt;
86 1652 : Real64 Alpha = Constant::DegToRad * state.dataSurface->Surface(t_SurfNum).Azimuth;
87 :
88 1652 : RayIdentificationType RadType = RayIdentificationType::Front_Incident;
89 :
90 1652 : if (t_Direction == BSDFDirection::Outgoing) {
91 0 : RadType = RayIdentificationType::Back_Incident;
92 : }
93 :
94 : // get the corresponding local Theta, Phi for ray
95 1652 : W6CoordsFromWorldVect(state, t_Ray, RadType, Gamma, Alpha, Theta, Phi);
96 :
97 1652 : Theta = 180 / Constant::Pi * Theta;
98 1652 : Phi = 180 / Constant::Pi * Phi;
99 :
100 3304 : return std::make_pair(Theta, Phi);
101 : }
102 :
103 1652 : std::pair<Real64, Real64> getSunWCEAngles(EnergyPlusData &state, const int t_SurfNum, const BSDFDirection t_Direction)
104 : {
105 1652 : return getWCECoordinates(
106 1652 : state, t_SurfNum, state.dataBSDFWindow->SUNCOSTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay), t_Direction);
107 : }
108 :
109 : ///////////////////////////////////////////////////////////////////////////////
110 : // CWCESpecturmProperties
111 : ///////////////////////////////////////////////////////////////////////////////
112 8 : CSeries CWCESpecturmProperties::getDefaultSolarRadiationSpectrum(EnergyPlusData &state)
113 : {
114 : // SUBROUTINE INFORMATION:
115 : // AUTHOR Simon Vidanovic
116 : // DATE WRITTEN September 2016
117 : // MODIFIED na
118 : // RE-ENGINEERED
119 : // April 2021: returning CSeries instead of pointer to CSeries
120 :
121 : // PURPOSE OF THIS SUBROUTINE:
122 : // Handles solar radiation spetrum from defalut location or IDF
123 8 : CSeries solarRadiation;
124 :
125 864 : for (int i = 1; i <= nume; ++i) {
126 856 : solarRadiation.addProperty(state.dataWindowManager->wle[i - 1], state.dataWindowManager->e[i - 1]);
127 : }
128 :
129 8 : return solarRadiation;
130 0 : }
131 :
132 : ///////////////////////////////////////////////////////////////////////////////
133 0 : CSeries CWCESpecturmProperties::getDefaultVisiblePhotopicResponse(EnergyPlusData &state)
134 : {
135 : // SUBROUTINE INFORMATION:
136 : // AUTHOR Simon Vidanovic
137 : // DATE WRITTEN September 2016
138 : // MODIFIED na
139 : // RE-ENGINEERED
140 : // April 2021: Function now returns CSeries instead of pointer to CSeries
141 :
142 : // PURPOSE OF THIS SUBROUTINE:
143 : // Handles solar radiation spetrum from defalut location or IDF
144 0 : CSeries visibleResponse;
145 :
146 0 : for (int i = 1; i <= numt3; ++i) {
147 0 : visibleResponse.addProperty(state.dataWindowManager->wlt3[i - 1], state.dataWindowManager->y30[i - 1]);
148 : }
149 :
150 0 : return visibleResponse;
151 0 : }
152 :
153 : ///////////////////////////////////////////////////////////////////////////////
154 0 : std::shared_ptr<CSpectralSampleData> CWCESpecturmProperties::getSpectralSample(EnergyPlusData &state, int const t_SampleDataPtr)
155 : {
156 : // SUBROUTINE INFORMATION:
157 : // AUTHOR Simon Vidanovic
158 : // DATE WRITTEN September 2016
159 : // MODIFIED na
160 : // RE-ENGINEERED na
161 :
162 : // PURPOSE OF THIS SUBROUTINE:
163 : // Reads spectral data value
164 :
165 0 : auto &s_mat = state.dataMaterial;
166 :
167 0 : assert(t_SampleDataPtr != 0); // It must not be called for zero value
168 0 : std::shared_ptr<CSpectralSampleData> aSampleData = std::make_shared<CSpectralSampleData>();
169 0 : auto spectralData = s_mat->SpectralData(t_SampleDataPtr); // (AUTO_OK_OBJ)
170 0 : int numOfWl = spectralData.NumOfWavelengths;
171 0 : for (int i = 1; i <= numOfWl; ++i) {
172 0 : Real64 wl = spectralData.WaveLength(i);
173 0 : Real64 T = spectralData.Trans(i);
174 0 : Real64 Rf = spectralData.ReflFront(i);
175 0 : Real64 Rb = spectralData.ReflBack(i);
176 0 : aSampleData->addRecord(wl, T, Rf, Rb);
177 : }
178 :
179 0 : return aSampleData;
180 0 : }
181 :
182 : ///////////////////////////////////////////////////////////////////////////////
183 0 : std::shared_ptr<CSpectralSampleData> CWCESpecturmProperties::getSpectralSample(Material::MaterialGlass const &t_MaterialProperties)
184 : {
185 0 : Real64 Tsol = t_MaterialProperties.Trans;
186 0 : Real64 Rfsol = t_MaterialProperties.ReflectSolBeamFront;
187 0 : Real64 Rbsol = t_MaterialProperties.ReflectSolBeamBack;
188 0 : std::shared_ptr<CMaterial> aSolMat = std::make_shared<CMaterialSingleBand>(Tsol, Tsol, Rfsol, Rbsol, 0.3, 2.5);
189 :
190 0 : Real64 Tvis = t_MaterialProperties.TransVis;
191 0 : Real64 Rfvis = t_MaterialProperties.ReflectVisBeamFront;
192 0 : Real64 Rbvis = t_MaterialProperties.ReflectVisBeamBack;
193 0 : std::shared_ptr<CMaterial> aVisMat = std::make_shared<CMaterialSingleBand>(Tvis, Tvis, Rfvis, Rbvis, 0.38, 0.78);
194 :
195 0 : CMaterialDualBand aMat = CMaterialDualBand(aVisMat, aSolMat, 0.49);
196 0 : std::vector<Real64> aWl = aMat.getBandWavelengths();
197 0 : std::vector<Real64> aTf = aMat.getBandProperties(Property::T, Side::Front);
198 0 : std::vector<Real64> aRf = aMat.getBandProperties(Property::R, Side::Front);
199 0 : std::vector<Real64> aRb = aMat.getBandProperties(Property::R, Side::Back);
200 0 : std::shared_ptr<CSpectralSampleData> aSampleData = std::make_shared<CSpectralSampleData>();
201 0 : for (size_t i = 0; i < aWl.size(); ++i) {
202 0 : aSampleData->addRecord(aWl[i], aTf[i], aRf[i], aRb[i]);
203 : }
204 :
205 0 : return aSampleData;
206 0 : }
207 :
208 9725 : CWindowConstructionsSimplified &CWindowConstructionsSimplified::instance(EnergyPlusData &state)
209 : {
210 9725 : if (state.dataWindowManagerExterior->p_inst == nullptr) {
211 3 : state.dataWindowManagerExterior->p_inst = std::unique_ptr<CWindowConstructionsSimplified>(new CWindowConstructionsSimplified());
212 : }
213 9725 : return *state.dataWindowManagerExterior->p_inst;
214 : }
215 :
216 3 : CWindowConstructionsSimplified::CWindowConstructionsSimplified()
217 : {
218 3 : m_Layers[WavelengthRange::Solar] = Layers_Map();
219 3 : m_Layers[WavelengthRange::Visible] = Layers_Map();
220 3 : }
221 :
222 16 : void CWindowConstructionsSimplified::pushLayer(WavelengthRange const t_Range, int const t_ConstrNum, const CScatteringLayer &t_Layer)
223 : {
224 16 : Layers_Map &aMap = m_Layers.at(t_Range);
225 16 : const auto it = aMap.find(t_ConstrNum);
226 16 : if (it == aMap.end()) {
227 10 : aMap[t_ConstrNum] = IGU_Layers();
228 : }
229 16 : aMap.at(t_ConstrNum).push_back(t_Layer);
230 16 : }
231 :
232 : std::shared_ptr<CMultiLayerScattered>
233 9722 : CWindowConstructionsSimplified::getEquivalentLayer(EnergyPlusData &state, WavelengthRange const t_Range, int const t_ConstrNum)
234 : {
235 9722 : auto it = m_Equivalent.find(std::make_pair(t_Range, t_ConstrNum));
236 9722 : if (it == m_Equivalent.end()) {
237 : // Layer was not requested before. Need to create it now.
238 : // shared_ptr< vector< double > > commonWl = getCommonWavelengths( t_Range, t_ConstrNum );
239 8 : IGU_Layers iguLayers = getLayers(state, t_Range, t_ConstrNum);
240 8 : std::shared_ptr<CMultiLayerScattered> aEqLayer = std::make_shared<CMultiLayerScattered>(iguLayers[0]);
241 12 : for (size_t i = 1u; i < iguLayers.size(); ++i) {
242 4 : aEqLayer->addLayer(iguLayers[i]);
243 : }
244 :
245 8 : auto aSolarSpectrum = CWCESpecturmProperties::getDefaultSolarRadiationSpectrum(state); // (AUTO_OK_OBJ)
246 8 : aEqLayer->setSourceData(aSolarSpectrum);
247 8 : m_Equivalent[std::make_pair(t_Range, t_ConstrNum)] = aEqLayer;
248 8 : }
249 :
250 19444 : return m_Equivalent.at(std::make_pair(t_Range, t_ConstrNum));
251 9722 : }
252 :
253 0 : void CWindowConstructionsSimplified::clearState()
254 : {
255 0 : }
256 :
257 8 : IGU_Layers CWindowConstructionsSimplified::getLayers(EnergyPlusData &state, WavelengthRange const t_Range, int const t_ConstrNum) const
258 : {
259 8 : Layers_Map aMap = m_Layers.at(t_Range); // Do you mean to make a copy of the entire map here?
260 8 : auto it = aMap.find(t_ConstrNum);
261 8 : if (it == aMap.end()) {
262 0 : ShowFatalError(state, "Incorrect construction selection.");
263 : // throw std::runtime_error("Incorrect construction selection.");
264 : }
265 16 : return it->second;
266 8 : }
267 :
268 : } // namespace Window
269 :
270 : } // namespace EnergyPlus
|