Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #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 WindowManager {
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 = DataGlobalConstants::DegToRadians * state.dataSurface->Surface(t_SurfNum).Tilt;
86 1652 : Real64 Alpha = DataGlobalConstants::DegToRadians * 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 / DataGlobalConstants::Pi * Theta;
98 1652 : Phi = 180 / DataGlobalConstants::Pi * Phi;
99 :
100 1652 : 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 : 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 (auto i = 1; i <= state.dataWindowManager->nume; ++i) {
126 856 : solarRadiation.addProperty(state.dataWindowManager->wle[i - 1], state.dataWindowManager->e[i - 1]);
127 : }
128 :
129 8 : return solarRadiation;
130 : }
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 (auto i = 1; i <= state.dataWindowManager->numt3; ++i) {
147 0 : visibleResponse.addProperty(state.dataWindowManager->wlt3[i - 1], state.dataWindowManager->y30[i - 1]);
148 : }
149 :
150 0 : return visibleResponse;
151 : }
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 0 : assert(t_SampleDataPtr != 0); // It must not be called for zero value
165 0 : std::shared_ptr<CSpectralSampleData> aSampleData = std::make_shared<CSpectralSampleData>();
166 0 : auto spectralData = state.dataHeatBal->SpectralData(t_SampleDataPtr);
167 0 : int numOfWl = spectralData.NumOfWavelengths;
168 0 : for (auto i = 1; i <= numOfWl; ++i) {
169 0 : Real64 wl = spectralData.WaveLength(i);
170 0 : Real64 T = spectralData.Trans(i);
171 0 : Real64 Rf = spectralData.ReflFront(i);
172 0 : Real64 Rb = spectralData.ReflBack(i);
173 0 : aSampleData->addRecord(wl, T, Rf, Rb);
174 : }
175 :
176 0 : return aSampleData;
177 : }
178 :
179 : ///////////////////////////////////////////////////////////////////////////////
180 0 : std::shared_ptr<CSpectralSampleData> CWCESpecturmProperties::getSpectralSample(Material::MaterialProperties const &t_MaterialProperties)
181 : {
182 0 : Real64 Tsol = t_MaterialProperties.Trans;
183 0 : Real64 Rfsol = t_MaterialProperties.ReflectSolBeamFront;
184 0 : Real64 Rbsol = t_MaterialProperties.ReflectSolBeamBack;
185 0 : std::shared_ptr<CMaterial> aSolMat = std::make_shared<CMaterialSingleBand>(Tsol, Tsol, Rfsol, Rbsol, 0.3, 2.5);
186 :
187 0 : Real64 Tvis = t_MaterialProperties.TransVis;
188 0 : Real64 Rfvis = t_MaterialProperties.ReflectVisBeamFront;
189 0 : Real64 Rbvis = t_MaterialProperties.ReflectVisBeamBack;
190 0 : std::shared_ptr<CMaterial> aVisMat = std::make_shared<CMaterialSingleBand>(Tvis, Tvis, Rfvis, Rbvis, 0.38, 0.78);
191 :
192 0 : CMaterialDualBand aMat = CMaterialDualBand(aVisMat, aSolMat, 0.49);
193 0 : std::vector<Real64> aWl = aMat.getBandWavelengths();
194 0 : std::vector<Real64> aTf = aMat.getBandProperties(Property::T, Side::Front);
195 0 : std::vector<Real64> aRf = aMat.getBandProperties(Property::R, Side::Front);
196 0 : std::vector<Real64> aRb = aMat.getBandProperties(Property::R, Side::Back);
197 0 : std::shared_ptr<CSpectralSampleData> aSampleData = std::make_shared<CSpectralSampleData>();
198 0 : for (size_t i = 0; i < aWl.size(); ++i) {
199 0 : aSampleData->addRecord(aWl[i], aTf[i], aRf[i], aRb[i]);
200 : }
201 :
202 0 : return aSampleData;
203 : }
204 :
205 : ///////////////////////////////////////////////////////////////////////////////
206 : // CWindowConstructionsSimplified
207 : ///////////////////////////////////////////////////////////////////////////////
208 771 : std::unique_ptr<CWindowConstructionsSimplified> CWindowConstructionsSimplified::p_inst = nullptr;
209 :
210 9725 : CWindowConstructionsSimplified &CWindowConstructionsSimplified::instance()
211 : {
212 9725 : if (p_inst == nullptr) {
213 3 : p_inst = std::unique_ptr<CWindowConstructionsSimplified>(new CWindowConstructionsSimplified());
214 : }
215 9725 : return *p_inst;
216 : }
217 :
218 3 : CWindowConstructionsSimplified::CWindowConstructionsSimplified()
219 : {
220 3 : m_Layers[WavelengthRange::Solar] = Layers_Map();
221 3 : m_Layers[WavelengthRange::Visible] = Layers_Map();
222 3 : }
223 :
224 16 : void CWindowConstructionsSimplified::pushLayer(WavelengthRange const t_Range, int const t_ConstrNum, const CScatteringLayer &t_Layer)
225 : {
226 16 : Layers_Map &aMap = m_Layers.at(t_Range);
227 32 : const auto it = aMap.find(t_ConstrNum);
228 16 : if (it == aMap.end()) {
229 10 : aMap[t_ConstrNum] = IGU_Layers();
230 : }
231 16 : aMap.at(t_ConstrNum).push_back(t_Layer);
232 16 : }
233 :
234 : std::shared_ptr<CMultiLayerScattered>
235 9722 : CWindowConstructionsSimplified::getEquivalentLayer(EnergyPlusData &state, WavelengthRange const t_Range, int const t_ConstrNum)
236 : {
237 38896 : auto it = m_Equivalent.find(std::make_pair(t_Range, t_ConstrNum));
238 9722 : if (it == m_Equivalent.end()) {
239 : // Layer was not requested before. Need to create it now.
240 : // shared_ptr< vector< double > > commonWl = getCommonWavelengths( t_Range, t_ConstrNum );
241 16 : IGU_Layers iguLayers = getLayers(state, t_Range, t_ConstrNum);
242 16 : std::shared_ptr<CMultiLayerScattered> aEqLayer = std::make_shared<CMultiLayerScattered>(iguLayers[0]);
243 12 : for (auto i = 1u; i < iguLayers.size(); ++i) {
244 4 : aEqLayer->addLayer(iguLayers[i]);
245 : }
246 :
247 16 : auto aSolarSpectrum = CWCESpecturmProperties::getDefaultSolarRadiationSpectrum(state);
248 8 : aEqLayer->setSourceData(aSolarSpectrum);
249 8 : m_Equivalent[std::make_pair(t_Range, t_ConstrNum)] = aEqLayer;
250 : }
251 :
252 19444 : return m_Equivalent.at(std::make_pair(t_Range, t_ConstrNum));
253 : }
254 :
255 0 : void CWindowConstructionsSimplified::clearState()
256 : {
257 0 : p_inst = nullptr;
258 0 : }
259 :
260 8 : IGU_Layers CWindowConstructionsSimplified::getLayers(EnergyPlusData &state, WavelengthRange const t_Range, int const t_ConstrNum) const
261 : {
262 16 : Layers_Map aMap = m_Layers.at(t_Range);
263 16 : auto it = aMap.find(t_ConstrNum);
264 8 : if (it == aMap.end()) {
265 0 : ShowFatalError(state, "Incorrect construction selection.");
266 : // throw std::runtime_error("Incorrect construction selection.");
267 : }
268 16 : return aMap.at(t_ConstrNum);
269 : }
270 :
271 : } // namespace WindowManager
272 :
273 2313 : } // namespace EnergyPlus
|