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 : #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::DegToRadians * state.dataSurface->Surface(t_SurfNum).Tilt;
86 1652 : Real64 Alpha = Constant::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 / 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 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); // (AUTO_OK_OBJ)
167 0 : int numOfWl = spectralData.NumOfWavelengths;
168 0 : for (int 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 0 : }
178 :
179 : ///////////////////////////////////////////////////////////////////////////////
180 0 : std::shared_ptr<CSpectralSampleData> CWCESpecturmProperties::getSpectralSample(Material::MaterialChild 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 0 : }
204 :
205 9725 : CWindowConstructionsSimplified &CWindowConstructionsSimplified::instance(EnergyPlusData &state)
206 : {
207 9725 : if (state.dataWindowManagerExterior->p_inst == nullptr) {
208 3 : state.dataWindowManagerExterior->p_inst = std::unique_ptr<CWindowConstructionsSimplified>(new CWindowConstructionsSimplified());
209 : }
210 9725 : return *state.dataWindowManagerExterior->p_inst;
211 : }
212 :
213 3 : CWindowConstructionsSimplified::CWindowConstructionsSimplified()
214 : {
215 3 : m_Layers[WavelengthRange::Solar] = Layers_Map();
216 3 : m_Layers[WavelengthRange::Visible] = Layers_Map();
217 3 : }
218 :
219 16 : void CWindowConstructionsSimplified::pushLayer(WavelengthRange const t_Range, int const t_ConstrNum, const CScatteringLayer &t_Layer)
220 : {
221 16 : Layers_Map &aMap = m_Layers.at(t_Range);
222 16 : const auto it = aMap.find(t_ConstrNum);
223 16 : if (it == aMap.end()) {
224 10 : aMap[t_ConstrNum] = IGU_Layers();
225 : }
226 16 : aMap.at(t_ConstrNum).push_back(t_Layer);
227 16 : }
228 :
229 : std::shared_ptr<CMultiLayerScattered>
230 9722 : CWindowConstructionsSimplified::getEquivalentLayer(EnergyPlusData &state, WavelengthRange const t_Range, int const t_ConstrNum)
231 : {
232 9722 : auto it = m_Equivalent.find(std::make_pair(t_Range, t_ConstrNum));
233 9722 : if (it == m_Equivalent.end()) {
234 : // Layer was not requested before. Need to create it now.
235 : // shared_ptr< vector< double > > commonWl = getCommonWavelengths( t_Range, t_ConstrNum );
236 8 : IGU_Layers iguLayers = getLayers(state, t_Range, t_ConstrNum);
237 8 : std::shared_ptr<CMultiLayerScattered> aEqLayer = std::make_shared<CMultiLayerScattered>(iguLayers[0]);
238 12 : for (size_t i = 1u; i < iguLayers.size(); ++i) {
239 4 : aEqLayer->addLayer(iguLayers[i]);
240 : }
241 :
242 8 : auto aSolarSpectrum = CWCESpecturmProperties::getDefaultSolarRadiationSpectrum(state); // (AUTO_OK_OBJ)
243 8 : aEqLayer->setSourceData(aSolarSpectrum);
244 8 : m_Equivalent[std::make_pair(t_Range, t_ConstrNum)] = aEqLayer;
245 8 : }
246 :
247 19444 : return m_Equivalent.at(std::make_pair(t_Range, t_ConstrNum));
248 9722 : }
249 :
250 0 : void CWindowConstructionsSimplified::clearState()
251 : {
252 0 : }
253 :
254 8 : IGU_Layers CWindowConstructionsSimplified::getLayers(EnergyPlusData &state, WavelengthRange const t_Range, int const t_ConstrNum) const
255 : {
256 8 : Layers_Map aMap = m_Layers.at(t_Range); // Do you mean to make a copy of the entire map here?
257 8 : auto it = aMap.find(t_ConstrNum);
258 8 : if (it == aMap.end()) {
259 0 : ShowFatalError(state, "Incorrect construction selection.");
260 : // throw std::runtime_error("Incorrect construction selection.");
261 : }
262 16 : return it->second;
263 8 : }
264 :
265 : } // namespace Window
266 :
267 : } // namespace EnergyPlus
|