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 : // C++ Headers
49 : #include <algorithm>
50 : #include <cassert>
51 : #include <cmath>
52 : #include <memory>
53 : #include <string>
54 :
55 : // ObjexxFCL Headers
56 : #include <ObjexxFCL/Array.functions.hh>
57 : #include <ObjexxFCL/Fmath.hh>
58 :
59 : // EnergyPlus Headers
60 : #include <EnergyPlus/Construction.hh>
61 : #include <EnergyPlus/ConvectionCoefficients.hh>
62 : #include <EnergyPlus/CurveManager.hh>
63 : #include <EnergyPlus/Data/EnergyPlusData.hh>
64 : #include <EnergyPlus/DataBSDFWindow.hh>
65 : #include <EnergyPlus/DataEnvironment.hh>
66 : #include <EnergyPlus/DataHeatBalSurface.hh>
67 : #include <EnergyPlus/DataHeatBalance.hh>
68 : #include <EnergyPlus/DataIPShortCuts.hh>
69 : #include <EnergyPlus/DataLoopNode.hh>
70 : #include <EnergyPlus/DataSurfaces.hh>
71 : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
72 : #include <EnergyPlus/DataZoneEquipment.hh>
73 : #include <EnergyPlus/General.hh>
74 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
75 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
76 : #include <EnergyPlus/Psychrometrics.hh>
77 : #include <EnergyPlus/ScheduleManager.hh>
78 : #include <EnergyPlus/UtilityRoutines.hh>
79 : #include <EnergyPlus/WindowComplexManager.hh>
80 : #include <EnergyPlus/WindowEquivalentLayer.hh>
81 : #include <EnergyPlus/WindowManager.hh>
82 : #include <EnergyPlus/WindowManagerExteriorOptical.hh>
83 : #include <EnergyPlus/WindowManagerExteriorThermal.hh>
84 : #include <EnergyPlus/WindowModel.hh>
85 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
86 :
87 : namespace EnergyPlus {
88 :
89 : namespace WindowManager {
90 :
91 : // MODULE INFORMATION
92 : // AUTHOR Fred Winkelmann
93 : // DATE WRITTEN September 1999
94 : // MODIFIED August 2001 (FW): add window shade thermal calculation;
95 : // add window blind optical and thermal model.
96 : // February 2003 (FW/LKL): Name changed to WindowManager
97 : // RE-ENGINEERED na
98 :
99 : // PURPOSE OF THIS MODULE:
100 : // Manages the window optical and thermal calculations derived
101 : // from WINDOW 4 and WINDOW 5.
102 :
103 : // METHODOLOGY EMPLOYED:
104 :
105 : // REFERENCES:
106 : // WINDOW 4:
107 : // D.Arasteh, M.Reilly and M.Rubin. A versative procedure for
108 : // calculating heat transfer through windows. ASHRAE Trans. 1989, Vol. 95, Pt. 2.
109 :
110 : // E.Finlayson, D.Arasteh, C.Huizenga, M.Rubin, and M.Reilly. WINDOW 4.0:
111 : // Documentation of calculation procedures. LBL-33943. July 1993.
112 :
113 : // WINDOW 5:
114 : // ASHRAE Standard 142P (draft 1/13/98): Standard method for determining and expressing
115 : // the heat transfer and total optical properties of fenestration products.
116 :
117 : // Shade and blind thermal model:
118 : // ISO/DIS 15099, Thermal Performance of Windows, Doors and Shading Devices,
119 : // Detailed Calculations, 1/12/00.
120 :
121 : // Blind optical model:
122 : // H. Simmler, U. Fischer and Frederick Winkelmann, Solar-Thermal Window Blind Model
123 : // for DOE-2, Lawrence Berkeley National Laboratory, Jan. 1996.
124 :
125 : // Using/Aliasing
126 : using namespace DataEnvironment;
127 : using namespace DataHeatBalance;
128 : using namespace DataSurfaces;
129 :
130 : // SUBROUTINE SPECIFICATIONS FOR MODULE WindowManager:
131 : // Optical Calculation Routines
132 : // Heat Balance Routines
133 :
134 771 : void InitWindowOpticalCalculations(EnergyPlusData &state)
135 : {
136 : // SUBROUTINE INFORMATION:
137 : // AUTHOR Simon Vidanovic
138 : // DATE WRITTEN September 2016
139 : // MODIFIED na
140 : // RE-ENGINEERED na
141 :
142 : // PURPOSE OF THIS SUBROUTINE:
143 : // Manages if optical calculation will be performed with internal or external routines
144 :
145 : // check and read custom solar and/or visible spectrum data if any
146 771 : CheckAndReadCustomSprectrumData(state);
147 :
148 : // allocate surface level adj ratio data member
149 771 : state.dataHeatBalSurf->SurfWinCoeffAdjRatio.dimension(state.dataSurface->TotSurfaces, 1.0);
150 :
151 771 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
152 3 : InitWCE_SimplifiedOpticalData(state);
153 : } else {
154 768 : InitGlassOpticalCalculations(state);
155 : }
156 771 : }
157 :
158 768 : void InitGlassOpticalCalculations(EnergyPlusData &state)
159 : {
160 :
161 : // SUBROUTINE INFORMATION:
162 : // AUTHOR F. Winkelmann
163 : // DATE WRITTEN August 1999
164 : // MODIFIED May 2001 (FW): add window blinds
165 : // Jan 2002 (FW): add blinds with variable slat angle
166 : // Jan 2003 (FW): add between-glass shade/blind
167 : // May 2006 (RR): add exterior window screen
168 : // Aug 2010 (TH): allow spectral data for between-glass shade/blind
169 : // Aug 2013 (TH): allow user defined solar and visible spectrum data
170 : // RE-ENGINEERED na
171 :
172 : // PURPOSE OF THIS SUBROUTINE:
173 : // Manages the calculation of the solar and visible properties of a multi-layer glazing
174 : // system from the properties of the individual glazing and shading layers
175 :
176 : // Using/Aliasing
177 : using namespace Vectors;
178 :
179 : using WindowEquivalentLayer::InitEquivalentLayerWindowCalculations;
180 :
181 : int CoefNum; // Polynomial coefficient number
182 : int j; // Wavelength counter
183 : int TotLay; // Total solid and gas layers in a window construction
184 : int ConstrNum; // Construction number
185 : int ConstrNumSh; // Shaded construction number
186 : int SurfNum; // Surface number
187 : int ShadeLayNum; // Layer number for shade or blind, if present
188 : int ShadeLayPtr; // Material number for shade or blind
189 : bool lquasi; // True if one or more glass layers have no spectral data
190 : bool AllGlassIsSpectralAverage; // True if all glazing in a construction is spectral average
191 : bool IntShade; // True if construction has an interior,exterior or between-glass shade
192 : bool ExtShade;
193 : bool BGShade;
194 : bool IntBlind; // True if construction has an interior,exterior or between-glass blind
195 : bool ExtBlind;
196 : bool BGBlind;
197 : bool ExtScreen; // True if construction has an exterior screen
198 : bool ScreenOn; // True if construction has an exterior screen
199 : bool BlindOn; // True if IntBlind, ExtBlind or BGBlind is true
200 : bool ShadeOn; // True if IntShade, ExtShade or BGShade is true
201 : int BlNum; // Blind number
202 : int ScNum; // Screen number
203 1536 : Array1D<Real64> sabsPhi(state.dataWindowManager->nume); // Glazing system absorptance for a glass layer
204 : // and angle of incidence, for each wavelength
205 : // glass layer for an angle of incidence, for each wavelength
206 1536 : Array1D<Real64> solabsDiff(5); // Glazing system layer solar absorptance for each glass layer
207 : Array1D<Real64> solabsPhiLay(
208 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Glazing system solar absorptance for a layer at each incidence angle
209 : Array1D<Real64> tsolPhiFit(
210 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Glazing system solar transmittance from fit at each incidence angle
211 : Array1D<Real64> tvisPhiFit(
212 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Glazing system visible transmittance from fit at each incidence angle
213 : Array2D<Real64> tBareSolPhi(5,
214 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass solar transmittance for each incidence angle
215 : Real64 t1; // = tBareSolPhi(,1)(,2)
216 : Real64 t2;
217 : Array2D<Real64> tBareVisPhi(5,
218 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass visible transmittance for each incidence angle
219 : Real64 t1v; // = tBareVisPhi(,1)(,2)
220 : Real64 t2v;
221 : Array2D<Real64> rfBareSolPhi(
222 : 5,
223 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass front solar reflectance for each incidence angle
224 : Array2D<Real64> rfBareVisPhi(
225 : 5,
226 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass front visible reflectance for each incidence angle
227 : Array2D<Real64> rbBareSolPhi(
228 : 5,
229 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass back solar reflectance for each incidence angle
230 : Array2D<Real64> rbBareVisPhi(
231 : 5,
232 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass back visible reflectance for each incidence angle
233 : Array2D<Real64> afBareSolPhi(
234 : 5,
235 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass front solar absorptance for each incidence angle
236 : Real64 af1; // = afBareSolPhi(,1)(,2)
237 : Real64 af2;
238 : Real64 rbmf2; // Isolated glass #2 front beam reflectance
239 : Array2D<Real64> abBareSolPhi(
240 : 5,
241 1536 : state.dataWindowManager->MaxNumOfIncidentAngles); // Isolated glass back solar absorptance for each incidence angle
242 : Real64 ab1; // = abBareSolPhi(,1)(,2)
243 : Real64 ab2;
244 : Real64 td1; // Isolated glass diffuse solar transmittance
245 : Real64 td2;
246 : Real64 td3;
247 : Real64 td1v; // Isolated glass diffuse visible transmittance
248 : Real64 td2v;
249 : Real64 td3v;
250 : Real64 rf1; // Isolated glass diffuse solar front reflectance
251 : Real64 rf2;
252 : Real64 rf3;
253 : Real64 rf1v; // Isolated glass diffuse visible front reflectance
254 : Real64 rf2v;
255 : Real64 rf3v;
256 : Real64 rb1; // Isolated glass diffuse solar back reflectance
257 : Real64 rb2;
258 : Real64 rb3;
259 : Real64 rb1v; // Isolated glass diffuse visible back reflectance
260 : Real64 rb2v;
261 : Real64 rb3v;
262 : Real64 afd1; // Isolated glass diffuse solar front absorptance
263 : Real64 afd2;
264 : Real64 afd3;
265 : Real64 abd1; // Isolated glass diffuse solar back absorptance
266 : Real64 abd2;
267 : Real64 abd3;
268 : Real64 TauShIR; // IR transmittance of isolated shade
269 : Real64 EpsShIR; // IR absorptance of isolated shade
270 : Real64 RhoShIR; // IR reflectance of isolated shade
271 : Real64 EpsGlIR; // IR absorptance of front or back of isolated glass
272 : Real64 RhoGlIR; // IR reflectance of inside face of inside glass
273 : int NGlass; // Number of glass layers in a construction
274 : int IGlass; // Glass layer counter
275 : int LayNum; // Layer number for a glass layer
276 : int LayPtr; // Material number corresponding to LayNum
277 : int IPhi; // Incidence angle counter
278 : Real64 Phi; // Incidence angle (deg)
279 : Real64 CosPhi; // Cosine of incidence angle
280 : int ILam; // Wavelength counter
281 : Real64 tsolDiff; // Glazing system diffuse solar transmittance
282 : Real64 tvisDiff; // Glazing system diffuse visible transmittance
283 : int IGlassBack; // Glass layer number counted from back of window
284 : Real64 ShadeAbs; // Solar absorptance of isolated shade
285 : Real64 ash; // = ShadeAbs
286 : Real64 afsh; // Diffuse solar front absorptance of isolated blind
287 : Real64 afshGnd; // Ground and sky diffuse solar front absorptance of isolated blind
288 : Real64 afshSky;
289 : Real64 absh; // Diffuse solar back absorptance of isolated blind
290 : Real64 ShadeTrans; // Solar transmittance of isolated shade/blind
291 : Real64 ShadeTransGnd; // Diffuse-diffuse transmittance of isolated vertical blind with
292 : // horizontal slats for isotropic ground solar
293 : Real64 ShadeTransSky; // Diffuse-diffuse transmittance of isolated vertical blind with
294 : // horizontal slats for isotropic sky solar
295 : Real64 tsh; // = ShadeTrans
296 : Real64 tshGnd; // = ShadeTransGnd,ShadeTransSky
297 : Real64 tshSky;
298 : Real64 tsh2; // = tsh**2
299 : Real64 ShadeRefl; // Solar reflectance of isolated shade
300 : Real64 ShadeReflGnd; // Front blind reflectance for ground diffuse solar
301 : Real64 ShadeReflSky; // Front blind reflectance for sky diffuse solar
302 : Real64 rsh; // = ShadeRefl
303 : Real64 rfsh; // Diffuse solar front reflectance of isolated blind
304 : Real64 rfshGnd; // Ground and sky diffuse solar front reflectance of isolated blind
305 : Real64 rfshSky;
306 : Real64 rbsh; // Diffuse solar back reflectance of isolated blind
307 : Real64 ShadeReflFac; // Shade/blind solar reflection factor
308 : Real64 ShadeTransVis; // Visible transmittance of isolated shade/blind
309 : Real64 tshv; // = ShadeTransVis
310 : Real64 tshv2; // = tshv**2
311 : Real64 ShadeReflVis; // Visible reflectance of isolated shade
312 : Real64 rshv; // = ShadeReflVis
313 : Real64 rfshv; // Diffuse visible front reflectance of isolated blind
314 : Real64 rbshv; // Diffuse visible back reflectance of isolated blind
315 : Real64 ShadeReflFacVis; // Shade/blind visible reflection factor
316 : int SpecDataNum; // Spectral data set number
317 : int numptDAT; // Number of wavelengths in a spectral data set
318 : int ISlatAng; // Slat angle counter
319 : bool StormWinConst; // True if a construction with a storm window
320 : bool Triangle; // True if window is triangular
321 : bool Rectangle; // True if window is rectangular
322 1536 : Array1D<Real64> W1(3); // Window vertices (m)
323 1536 : Array1D<Real64> W2(3);
324 1536 : Array1D<Real64> W3(3);
325 1536 : Array1D<Real64> W21(3); // W1-W2, W3-W2, resp. (m)
326 1536 : Array1D<Real64> W23(3);
327 :
328 768 : W5InitGlassParameters(state);
329 :
330 : // Calculate optical properties of blind-type layers entered with MATERIAL:WindowBlind
331 768 : if (state.dataHeatBal->TotBlinds > 0) CalcWindowBlindProperties(state);
332 :
333 : // Initialize SurfaceScreen structure
334 768 : if (state.dataHeatBal->NumSurfaceScreens > 0) CalcWindowScreenProperties(state);
335 :
336 : // Get glazing system optical properties of constructions with glass or glass plus
337 : // shade, screen or blind
338 : // Loop over constructions and find those that are glazing constructions
339 6616 : for (ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) {
340 10385 : if (!state.dataConstruction->Construct(ConstrNum).TypeIsWindow) continue;
341 1327 : if (state.dataConstruction->Construct(ConstrNum).WindowTypeBSDF) continue; // Skip Complex Fenestrations, they have separate
342 1314 : if (state.dataConstruction->Construct(ConstrNum).WindowTypeEQL) continue; // skip Equivalent Layer Fenestration
343 : // handling of optical properties
344 :
345 14421 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
346 13110 : state.dataWindowManager->CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * DataGlobalConstants::DegToRadians);
347 : }
348 :
349 1311 : TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers;
350 :
351 : // First layer must be glass, shade, screen or blind to be a glazing construction
352 2622 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
353 129 : DataHeatBalance::MaterialGroup::WindowGlass &&
354 129 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
355 126 : DataHeatBalance::MaterialGroup::Shade &&
356 126 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
357 124 : DataHeatBalance::MaterialGroup::Screen &&
358 124 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
359 1433 : DataHeatBalance::MaterialGroup::WindowBlind &&
360 122 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group !=
361 : DataHeatBalance::MaterialGroup::WindowSimpleGlazing)
362 0 : continue;
363 :
364 1311 : ShadeLayNum = 0;
365 1311 : ExtShade = false;
366 1311 : IntShade = false;
367 1311 : BGShade = false;
368 1311 : ExtBlind = false;
369 1311 : IntBlind = false;
370 1311 : BGBlind = false;
371 1311 : ExtScreen = false;
372 1311 : StormWinConst = false;
373 1311 : state.dataWindowManager->lSimpleGlazingSystem = false;
374 :
375 1311 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
376 : DataHeatBalance::MaterialGroup::WindowSimpleGlazing) {
377 : // what if outside layer is shade, blind, or screen?
378 122 : state.dataWindowManager->lSimpleGlazingSystem = true;
379 122 : state.dataWindowManager->SimpleGlazingSHGC =
380 122 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).SimpleWindowSHGC;
381 122 : state.dataWindowManager->SimpleGlazingU =
382 122 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).SimpleWindowUfactor;
383 : }
384 :
385 3932 : if (has_prefix(state.dataConstruction->Construct(ConstrNum).Name, "BARECONSTRUCTIONWITHSTORMWIN") ||
386 2621 : has_prefix(state.dataConstruction->Construct(ConstrNum).Name, "SHADEDCONSTRUCTIONWITHSTORMWIN"))
387 1 : StormWinConst = true;
388 :
389 : // Get layer number of shade/blind
390 1311 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
391 : DataHeatBalance::MaterialGroup::Shade) {
392 3 : ExtShade = true;
393 3 : ShadeLayNum = 1;
394 1308 : } else if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay)).Group ==
395 : DataHeatBalance::MaterialGroup::Shade) {
396 24 : IntShade = true;
397 24 : ShadeLayNum = TotLay;
398 1284 : } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 5) {
399 68 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
400 : DataHeatBalance::MaterialGroup::Shade) {
401 1 : BGShade = true;
402 1 : ShadeLayNum = 3;
403 : }
404 1216 : } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 7) {
405 8 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
406 : DataHeatBalance::MaterialGroup::Shade) {
407 1 : BGShade = true;
408 1 : ShadeLayNum = 5;
409 : }
410 : }
411 :
412 1311 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
413 : DataHeatBalance::MaterialGroup::WindowBlind) {
414 2 : ExtBlind = true;
415 2 : ShadeLayNum = 1;
416 2 : BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
417 1309 : } else if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay)).Group ==
418 : DataHeatBalance::MaterialGroup::WindowBlind) {
419 11 : IntBlind = true;
420 11 : ShadeLayNum = TotLay;
421 11 : BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
422 1298 : } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 5) {
423 68 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
424 : DataHeatBalance::MaterialGroup::WindowBlind) {
425 2 : BGBlind = true;
426 2 : ShadeLayNum = 3;
427 2 : BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
428 : }
429 1230 : } else if (state.dataConstruction->Construct(ConstrNum).TotLayers == 7) {
430 8 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
431 : DataHeatBalance::MaterialGroup::WindowBlind) {
432 1 : BGBlind = true;
433 1 : ShadeLayNum = 5;
434 1 : BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).BlindDataPtr;
435 : }
436 : }
437 :
438 1311 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Group ==
439 : DataHeatBalance::MaterialGroup::Screen) {
440 2 : ShadeLayNum = 1;
441 2 : ScNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).ScreenDataPtr;
442 : // Disregard orphaned constructs with exterior screen
443 2 : if (ScNum == 0) continue;
444 2 : ExtScreen = true;
445 : }
446 :
447 1311 : ScreenOn = ExtScreen;
448 1311 : BlindOn = IntBlind || ExtBlind || BGBlind;
449 1311 : ShadeOn = IntShade || ExtShade || BGShade;
450 1311 : state.dataWindowManager->BGFlag = BGBlind || BGShade;
451 :
452 : // For construction with interior or exterior shade, get shade thermal absorptance (emissivity)
453 : // (accounting for inter-reflection with glazing) and correct the inside glass InsideAbsorpThermal
454 : // for presence of interior shade. Assumes inner and outer glass layers have zero thermal transmittance.
455 :
456 1311 : if (IntShade || ExtShade || ExtScreen) {
457 29 : ShadeLayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum);
458 29 : if (ExtScreen) {
459 2 : TauShIR = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans;
460 : } else {
461 27 : TauShIR = state.dataMaterial->Material(ShadeLayPtr).TransThermal;
462 : }
463 29 : EpsShIR = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
464 29 : RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
465 29 : if (ExtShade || ExtScreen) { // Exterior shade or screen
466 5 : EpsGlIR = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(2)).AbsorpThermalFront;
467 : } else { // Interior shade
468 24 : EpsGlIR = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay - 1)).AbsorpThermalBack;
469 : }
470 29 : RhoGlIR = max(0.0, 1.0 - EpsGlIR);
471 29 : state.dataConstruction->Construct(ConstrNum).ShadeAbsorpThermal = EpsShIR * (1.0 + TauShIR * RhoGlIR / (1.0 - RhoShIR * RhoGlIR));
472 29 : if (IntShade) state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal *= TauShIR / (1.0 - RhoShIR * RhoGlIR);
473 : }
474 :
475 : // From the individual glass layer properties, get the glazing system optical properties
476 : // for BARE GLASS (i.e., interior, exterior or between-glass shade or blind, or exterior screen, if present, not in place).
477 : // Get one set of system properties for solar incident on front of
478 : // window and a second set for solar incident on back of window. (The back-incident
479 : // properties are used with interior short-wave radiation striking the window from inside.)
480 :
481 : // After the front and back system optical properties are calculated for bare glass,
482 : // a correction is made for the effect of a shade, screen or blind if one of these
483 : // is present in the construction.
484 :
485 1311 : NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
486 :
487 : //--------------------------------------------------------------------------------------------
488 : // Front calculation (solar incident from outside of room); bare glass portion of construction
489 : //--------------------------------------------------------------------------------------------
490 :
491 1311 : lquasi = false;
492 1311 : AllGlassIsSpectralAverage = true;
493 1311 : int TotalIPhi = 10;
494 1311 : state.dataWindowManager->LayerNum = {0};
495 :
496 : // Loop over glass layers in the construction
497 3277 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
498 1966 : LayNum = 1 + 2 * (IGlass - 1);
499 1966 : if (ExtShade || ExtBlind || ExtScreen) LayNum = 2 + 2 * (IGlass - 1);
500 1966 : if (BGShade || BGBlind) {
501 12 : LayNum = 1;
502 12 : if (NGlass == 2) {
503 6 : if (IGlass == 2) LayNum = 5;
504 : } else { // NGlass = 3
505 6 : if (IGlass == 2) LayNum = 3;
506 6 : if (IGlass == 3) LayNum = 7;
507 : }
508 : }
509 :
510 1966 : state.dataWindowManager->LayerNum[IGlass - 1] = LayNum;
511 1966 : LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(LayNum);
512 1966 : SpecDataNum = state.dataMaterial->Material(LayPtr).GlassSpectralDataPtr;
513 1966 : if (SpecDataNum != 0) {
514 213 : if (!state.dataWindowManager->BGFlag) AllGlassIsSpectralAverage = false;
515 :
516 : // Get the spectral data for the transmittance, front reflectance and
517 : // back reflectance (all at normal incidence) for this layer.
518 : // In this case, "front" means incident from the outside and "back"
519 : // means incident from the inside.
520 213 : numptDAT = state.dataHeatBal->SpectralData(SpecDataNum).NumOfWavelengths;
521 213 : state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
522 :
523 42312 : for (ILam = 1; ILam <= numptDAT; ++ILam) {
524 42099 : state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).WaveLength(ILam);
525 42099 : state.dataWindowManager->t[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).Trans(ILam);
526 42099 : if ((IGlass == 1 || (IGlass == 2 && StormWinConst)) && (!state.dataWindowManager->BGFlag))
527 6549 : state.dataWindowManager->t[IGlass - 1][ILam - 1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
528 42099 : state.dataWindowManager->rff[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflFront(ILam);
529 42099 : state.dataWindowManager->rbb[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflBack(ILam);
530 : }
531 :
532 : // If there is spectral data for between-glass shades or blinds, calc the average spectral properties for use.
533 213 : if (state.dataWindowManager->BGFlag) {
534 : // Add warning message for the glazing defined with full spectral data.
535 0 : ShowWarningError(state,
536 0 : "Window glazing material \"" + state.dataMaterial->Material(LayPtr).Name +
537 : "\" was defined with full spectral data and has been converted to average spectral data");
538 0 : ShowContinueError(state,
539 0 : "due to its use with between-glass shades or blinds of the window construction \"" +
540 0 : state.dataConstruction->Construct(ConstrNum).Name + "\".");
541 0 : ShowContinueError(state, "All occurrences of this glazing material will be modeled as SpectralAverage.");
542 0 : ShowContinueError(state,
543 : "If this material is also used in other window constructions without between-glass shades or blinds,");
544 0 : ShowContinueError(state,
545 : "then make a duplicate material (with new name) if you want to model those windows (and reference the new "
546 : "material) using the full spectral data.");
547 : // calc Trans, TransVis, ReflectSolBeamFront, ReflectSolBeamBack, ReflectVisBeamFront, ReflectVisBeamBack
548 : // assuming wlt same as wle
549 0 : state.dataWindowManager->tmpTrans = solarSpectrumAverage(state, state.dataWindowManager->t[0]);
550 0 : state.dataWindowManager->tmpReflectSolBeamFront = solarSpectrumAverage(state, state.dataWindowManager->rff[0]);
551 0 : state.dataWindowManager->tmpReflectSolBeamBack = solarSpectrumAverage(state, state.dataWindowManager->rbb[0]);
552 :
553 : // visible properties
554 0 : state.dataWindowManager->tmpTransVis = visibleSpectrumAverage(state, state.dataWindowManager->t[0]);
555 0 : state.dataWindowManager->tmpReflectVisBeamFront = visibleSpectrumAverage(state, state.dataWindowManager->rff[0]);
556 0 : state.dataWindowManager->tmpReflectVisBeamBack = visibleSpectrumAverage(state, state.dataWindowManager->rbb[0]);
557 :
558 : // set this material to average spectral data
559 0 : state.dataMaterial->Material(LayPtr).GlassSpectralDataPtr = 0;
560 0 : state.dataMaterial->Material(LayPtr).Trans = state.dataWindowManager->tmpTrans;
561 0 : state.dataMaterial->Material(LayPtr).TransVis = state.dataWindowManager->tmpTransVis;
562 0 : state.dataMaterial->Material(LayPtr).ReflectSolBeamFront = state.dataWindowManager->tmpReflectSolBeamFront;
563 0 : state.dataMaterial->Material(LayPtr).ReflectSolBeamBack = state.dataWindowManager->tmpReflectSolBeamBack;
564 0 : state.dataMaterial->Material(LayPtr).ReflectVisBeamFront = state.dataWindowManager->tmpReflectVisBeamFront;
565 0 : state.dataMaterial->Material(LayPtr).ReflectVisBeamBack = state.dataWindowManager->tmpReflectVisBeamBack;
566 0 : SpecDataNum = 0;
567 : }
568 : }
569 :
570 3719 : if (SpecDataNum == 0 &&
571 1753 : !state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) { // No spectral data for this layer; use spectral average values
572 1751 : lquasi = true;
573 1751 : state.dataWindowManager->numpt[IGlass - 1] = 2;
574 1751 : state.dataWindowManager->t[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).Trans;
575 1751 : if (IGlass == 1 || (IGlass == 2 && StormWinConst))
576 1251 : state.dataWindowManager->t[IGlass - 1][0] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
577 1751 : state.dataWindowManager->t[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).TransVis;
578 1751 : if (IGlass == 1 || (IGlass == 2 && StormWinConst))
579 1251 : state.dataWindowManager->t[IGlass - 1][1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
580 1751 : state.dataWindowManager->rff[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamFront;
581 1751 : state.dataWindowManager->rbb[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamBack;
582 1751 : state.dataWindowManager->rff[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamFront;
583 1751 : state.dataWindowManager->rbb[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamBack;
584 : }
585 1966 : if (state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
586 2 : if (!state.dataWindowManager->BGFlag) AllGlassIsSpectralAverage = false;
587 2 : numptDAT = state.dataWindowManager->wle.size();
588 2 : state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
589 2 : if (state.dataWindowManager->BGFlag) {
590 : // 5/16/2012 CR 8793. Add warning message for the glazing defined with full spectral data.
591 0 : ShowWarningError(state,
592 0 : "Window glazing material \"" + state.dataMaterial->Material(LayPtr).Name +
593 : "\" was defined with full spectral and angular data and has been converted to average spectral data");
594 0 : ShowContinueError(state,
595 0 : "due to its use with between-glass shades or blinds of the window construction \"" +
596 0 : state.dataConstruction->Construct(ConstrNum).Name + "\".");
597 0 : ShowContinueError(state, "All occurrences of this glazing material will be modeled as SpectralAverage.");
598 0 : ShowContinueError(state,
599 : "If this material is also used in other window constructions without between-glass shades or blinds,");
600 0 : ShowContinueError(state,
601 : "then make a duplicate material (with new name) if you want to model those windows (and reference the new "
602 : "material) using the full spectral data.");
603 : // calc Trans, TransVis, ReflectSolBeamFront, ReflectSolBeamBack, ReflectVisBeamFront, ReflectVisBeamBack
604 : // assuming wlt same as wle
605 0 : for (ILam = 1; ILam <= (int)state.dataWindowManager->wle.size(); ++ILam) {
606 0 : auto lam = state.dataWindowManager->wle[ILam - 1];
607 0 : state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = lam;
608 0 : state.dataWindowManager->t[IGlass - 1][ILam - 1] =
609 0 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngTransDataPtr, 0.0, lam);
610 0 : state.dataWindowManager->rff[IGlass - 1][ILam - 1] =
611 0 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngFRefleDataPtr, 0.0, lam);
612 0 : state.dataWindowManager->rbb[IGlass - 1][ILam - 1] =
613 0 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngBRefleDataPtr, 0.0, lam);
614 : }
615 0 : state.dataWindowManager->tmpTrans = solarSpectrumAverage(state, state.dataWindowManager->t[0]);
616 0 : state.dataWindowManager->tmpReflectSolBeamFront = solarSpectrumAverage(state, state.dataWindowManager->rff[0]);
617 0 : state.dataWindowManager->tmpReflectSolBeamBack = solarSpectrumAverage(state, state.dataWindowManager->rbb[0]);
618 :
619 : // visible properties
620 0 : state.dataWindowManager->tmpTransVis = visibleSpectrumAverage(state, state.dataWindowManager->t[0]);
621 0 : state.dataWindowManager->tmpReflectVisBeamFront = visibleSpectrumAverage(state, state.dataWindowManager->rff[0]);
622 0 : state.dataWindowManager->tmpReflectVisBeamBack = visibleSpectrumAverage(state, state.dataWindowManager->rbb[0]);
623 :
624 : // set this material to average spectral data
625 0 : state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle = false;
626 0 : state.dataMaterial->Material(LayPtr).Trans = state.dataWindowManager->tmpTrans;
627 0 : state.dataMaterial->Material(LayPtr).TransVis = state.dataWindowManager->tmpTransVis;
628 0 : state.dataMaterial->Material(LayPtr).ReflectSolBeamFront = state.dataWindowManager->tmpReflectSolBeamFront;
629 0 : state.dataMaterial->Material(LayPtr).ReflectSolBeamBack = state.dataWindowManager->tmpReflectSolBeamBack;
630 0 : state.dataMaterial->Material(LayPtr).ReflectVisBeamFront = state.dataWindowManager->tmpReflectVisBeamFront;
631 0 : state.dataMaterial->Material(LayPtr).ReflectVisBeamBack = state.dataWindowManager->tmpReflectVisBeamBack;
632 0 : SpecDataNum = 0;
633 : }
634 : }
635 : } // End of loop over glass layers in the construction for front calculation
636 :
637 1311 : if (TotalIPhi > state.dataWindowManager->MaxNumOfIncidentAngles) {
638 0 : ShowSevereError(state,
639 0 : format("WindowManage::InitGlassOpticalCalculations = {}, Invalid maximum value of common incidet angles = {}.",
640 0 : state.dataConstruction->Construct(ConstrNum).Name,
641 0 : TotalIPhi));
642 0 : ShowContinueError(state,
643 0 : format("The maximum number of incident angles for each construct is {}. Please rearrange the dataset.",
644 0 : state.dataWindowManager->MaxNumOfIncidentAngles));
645 0 : ShowFatalError(state, "Errors found getting inputs. Previous error(s) cause program termination.");
646 : }
647 :
648 : // Loop over incidence angle from 0 to 90 deg in 10 deg increments.
649 : // Get glass layer properties, then glazing system properties (which include the
650 : // effect of inter-reflection among glass layers) at each incidence angle.
651 :
652 14421 : for (IPhi = 1; IPhi <= TotalIPhi; ++IPhi) {
653 : // 10 degree increment for incident angle is only value for a construction without a layer = SpectralAndAngle
654 13110 : Phi = double(IPhi - 1) * 10.0;
655 13110 : CosPhi = std::cos(Phi * DataGlobalConstants::DegToRadians);
656 13110 : if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0;
657 :
658 : // For each wavelength, get glass layer properties at this angle of incidence
659 : // from properties at normal incidence
660 32770 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
661 19660 : LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataWindowManager->LayerNum[IGlass - 1]);
662 19660 : if (!state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
663 475650 : for (ILam = 1; ILam <= state.dataWindowManager->numpt[IGlass - 1]; ++ILam) {
664 2736060 : TransAndReflAtPhi(CosPhi,
665 456010 : state.dataWindowManager->t[IGlass - 1][ILam - 1],
666 456010 : state.dataWindowManager->rff[IGlass - 1][ILam - 1],
667 456010 : state.dataWindowManager->rbb[IGlass - 1][ILam - 1],
668 456010 : state.dataWindowManager->tPhi[IGlass - 1][ILam - 1],
669 456010 : state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1],
670 456010 : state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1],
671 456010 : state.dataWindowManager->lSimpleGlazingSystem,
672 456010 : state.dataWindowManager->SimpleGlazingSHGC,
673 456010 : state.dataWindowManager->SimpleGlazingU);
674 : }
675 : } else {
676 2160 : for (ILam = 1; ILam <= (int)state.dataWindowManager->wle.size(); ++ILam) {
677 2140 : auto lam = state.dataWindowManager->wle[ILam - 1];
678 2140 : state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = lam;
679 2140 : state.dataWindowManager->tPhi[IGlass - 1][ILam - 1] =
680 4280 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngTransDataPtr, Phi, lam);
681 2140 : state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1] =
682 4280 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngFRefleDataPtr, Phi, lam);
683 2140 : state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1] =
684 4280 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngBRefleDataPtr, Phi, lam);
685 : }
686 : }
687 : // For use with between-glass shade/blind, save angular properties of isolated glass
688 : // for case that all glass layers were input with spectral-average properties
689 : // only used by between-glass shades or blinds
690 19660 : if (AllGlassIsSpectralAverage) {
691 17150 : tBareSolPhi(IGlass, IPhi) = state.dataWindowManager->tPhi[IGlass - 1][0];
692 17150 : tBareVisPhi(IGlass, IPhi) = state.dataWindowManager->tPhi[IGlass - 1][1];
693 17150 : rfBareSolPhi(IGlass, IPhi) = state.dataWindowManager->rfPhi[IGlass - 1][0];
694 17150 : rfBareVisPhi(IGlass, IPhi) = state.dataWindowManager->rfPhi[IGlass - 1][1];
695 17150 : rbBareSolPhi(IGlass, IPhi) = state.dataWindowManager->rbPhi[IGlass - 1][0];
696 17150 : rbBareVisPhi(IGlass, IPhi) = state.dataWindowManager->rbPhi[IGlass - 1][1];
697 17150 : afBareSolPhi(IGlass, IPhi) = max(0.0, 1.0 - (tBareSolPhi(IGlass, IPhi) + rfBareSolPhi(IGlass, IPhi)));
698 17150 : abBareSolPhi(IGlass, IPhi) = max(0.0, 1.0 - (tBareSolPhi(IGlass, IPhi) + rbBareSolPhi(IGlass, IPhi)));
699 : }
700 : }
701 :
702 : // For each wavelength in the solar spectrum, calculate system properties
703 : // stPhi, srfPhi, srbPhi and saPhi at this angle of incidence.
704 : // In the following the argument "1" indicates that spectral average solar values
705 : // should be used for layers without spectral data.
706 13110 : SystemSpectralPropertiesAtPhi(state, 1, NGlass, 0.0, 2.54);
707 :
708 : // Get solar properties of system by integrating over solar irradiance spectrum.
709 : // For now it is assumed that the exterior and interior irradiance spectra are the same.
710 13110 : state.dataWindowManager->tsolPhi(IPhi) = solarSpectrumAverage(state, state.dataWindowManager->stPhi);
711 13110 : state.dataWindowManager->rfsolPhi(IPhi) = solarSpectrumAverage(state, state.dataWindowManager->srfPhi);
712 13110 : state.dataWindowManager->rbsolPhi(IPhi) = solarSpectrumAverage(state, state.dataWindowManager->srbPhi);
713 :
714 32770 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
715 2123280 : for (ILam = 1; ILam <= state.dataWindowManager->nume; ++ILam) {
716 2103620 : sabsPhi(ILam) = state.dataWindowManager->saPhi(IGlass, ILam);
717 : }
718 19660 : SolarSprectrumAverage(state, sabsPhi, state.dataWindowManager->solabsPhi(IGlass, IPhi));
719 : }
720 :
721 : // Get visible properties of system by integrating over solar irradiance
722 : // spectrum weighted by photopic response.
723 : // Need to redo the calculation of system spectral properties here only if
724 : // one or more glass layers have no spectral data (lquasi = .TRUE.); in this
725 : // case the spectral average visible properties will be used for the layers
726 : // without spectral data, as indicated by the argument "2".
727 :
728 13110 : if (lquasi) SystemSpectralPropertiesAtPhi(state, 2, NGlass, 0.37, 0.78);
729 13110 : state.dataWindowManager->tvisPhi(IPhi) = visibleSpectrumAverage(state, state.dataWindowManager->stPhi);
730 13110 : state.dataWindowManager->rfvisPhi(IPhi) = visibleSpectrumAverage(state, state.dataWindowManager->srfPhi);
731 13110 : state.dataWindowManager->rbvisPhi(IPhi) = visibleSpectrumAverage(state, state.dataWindowManager->srbPhi);
732 :
733 : } // End of loop over incidence angles for front calculation
734 :
735 : // only used by between-glass shades or blinds
736 1311 : if (AllGlassIsSpectralAverage) {
737 2929 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
738 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
739 3430 : tBareSolPhi(IGlass, _),
740 : 6,
741 : 1,
742 : TotalIPhi,
743 1715 : state.dataConstruction->Construct(ConstrNum).tBareSolCoef(IGlass));
744 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
745 3430 : tBareVisPhi(IGlass, _),
746 : 6,
747 : 1,
748 : TotalIPhi,
749 1715 : state.dataConstruction->Construct(ConstrNum).tBareVisCoef(IGlass));
750 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
751 3430 : rfBareSolPhi(IGlass, _),
752 : 6,
753 : 1,
754 : TotalIPhi,
755 1715 : state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(IGlass));
756 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
757 3430 : rfBareVisPhi(IGlass, _),
758 : 6,
759 : 1,
760 : TotalIPhi,
761 1715 : state.dataConstruction->Construct(ConstrNum).rfBareVisCoef(IGlass));
762 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
763 3430 : rbBareSolPhi(IGlass, _),
764 : 6,
765 : 1,
766 : TotalIPhi,
767 1715 : state.dataConstruction->Construct(ConstrNum).rbBareSolCoef(IGlass));
768 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
769 3430 : rbBareVisPhi(IGlass, _),
770 : 6,
771 : 1,
772 : TotalIPhi,
773 1715 : state.dataConstruction->Construct(ConstrNum).rbBareVisCoef(IGlass));
774 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
775 3430 : afBareSolPhi(IGlass, _),
776 : 6,
777 : 1,
778 : TotalIPhi,
779 1715 : state.dataConstruction->Construct(ConstrNum).afBareSolCoef(IGlass));
780 5145 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
781 3430 : abBareSolPhi(IGlass, _),
782 : 6,
783 : 1,
784 : TotalIPhi,
785 1715 : state.dataConstruction->Construct(ConstrNum).abBareSolCoef(IGlass));
786 : }
787 : }
788 :
789 1311 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront = DiffuseAverage(state.dataWindowManager->rfsolPhi);
790 1311 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack = DiffuseAverage(state.dataWindowManager->rbsolPhi);
791 1311 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront = DiffuseAverage(state.dataWindowManager->rfvisPhi);
792 1311 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack = DiffuseAverage(state.dataWindowManager->rbvisPhi);
793 :
794 1311 : tsolDiff = DiffuseAverage(state.dataWindowManager->tsolPhi);
795 1311 : tvisDiff = DiffuseAverage(state.dataWindowManager->tvisPhi);
796 1311 : state.dataConstruction->Construct(ConstrNum).TransDiff = tsolDiff;
797 1311 : state.dataConstruction->Construct(ConstrNum).TransDiffVis = tvisDiff;
798 3277 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
799 1966 : solabsPhiLay({1, TotalIPhi}) = state.dataWindowManager->solabsPhi(IGlass, {1, TotalIPhi});
800 1966 : solabsDiff(IGlass) = DiffuseAverage(solabsPhiLay);
801 1966 : state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) = solabsDiff(IGlass);
802 :
803 : // For use with between-glass shade/blind, get diffuse properties of isolated glass for case when
804 : // all glass layers were input with spectral-average properties
805 : // only used by between-glass shades or blinds
806 1966 : if (AllGlassIsSpectralAverage) {
807 1715 : state.dataConstruction->Construct(ConstrNum).tBareSolDiff(IGlass) = DiffuseAverage(tBareSolPhi(IGlass, {1, TotalIPhi}));
808 1715 : state.dataConstruction->Construct(ConstrNum).tBareVisDiff(IGlass) = DiffuseAverage(tBareVisPhi(IGlass, {1, TotalIPhi}));
809 1715 : state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(IGlass) = DiffuseAverage(rfBareSolPhi(IGlass, {1, TotalIPhi}));
810 1715 : state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(IGlass) = DiffuseAverage(rfBareVisPhi(IGlass, {1, TotalIPhi}));
811 1715 : state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(IGlass) = DiffuseAverage(rbBareSolPhi(IGlass, {1, TotalIPhi}));
812 1715 : state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(IGlass) = DiffuseAverage(rbBareVisPhi(IGlass, {1, TotalIPhi}));
813 1715 : state.dataConstruction->Construct(ConstrNum).afBareSolDiff(IGlass) =
814 1715 : max(0.0,
815 3430 : 1.0 - (state.dataConstruction->Construct(ConstrNum).tBareSolDiff(IGlass) +
816 1715 : state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(IGlass)));
817 1715 : state.dataConstruction->Construct(ConstrNum).abBareSolDiff(IGlass) =
818 1715 : max(0.0,
819 3430 : 1.0 - (state.dataConstruction->Construct(ConstrNum).tBareSolDiff(IGlass) +
820 1715 : state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(IGlass)));
821 : }
822 : }
823 :
824 : //------------------------------------------------------------------------------------------
825 : // Back calculation (solar incident from inside of room); bare glass portion of construction
826 : //------------------------------------------------------------------------------------------
827 :
828 1311 : lquasi = false;
829 1311 : state.dataWindowManager->LayerNum = {0};
830 :
831 : // Loop over glass layers in the construction.
832 3277 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
833 1966 : LayNum = 1 + (NGlass - IGlass) * 2;
834 1966 : if (ExtShade || ExtBlind || ExtScreen) LayNum = 2 + (NGlass - IGlass) * 2;
835 1966 : if (BGShade || BGBlind) {
836 12 : if (NGlass == 2) {
837 6 : if (IGlass == 1) LayNum = 5;
838 6 : if (IGlass == 2) LayNum = 1;
839 : } else { // NGlass = 3
840 6 : if (IGlass == 1) LayNum = 7;
841 6 : if (IGlass == 2) LayNum = 3;
842 6 : if (IGlass == 3) LayNum = 1;
843 : }
844 : }
845 1966 : state.dataWindowManager->LayerNum[IGlass - 1] = LayNum;
846 1966 : LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(LayNum);
847 :
848 1966 : SpecDataNum = state.dataMaterial->Material(LayPtr).GlassSpectralDataPtr;
849 1966 : if (SpecDataNum != 0) {
850 :
851 : // Get the spectral data for the transmittance, front reflectance and
852 : // back reflectance (all at normal incidence) for this layer.
853 : // In this case, "front" means incident from the inside and "back"
854 : // means incident from the outside.
855 :
856 213 : numptDAT = state.dataHeatBal->SpectralData(SpecDataNum).NumOfWavelengths;
857 213 : state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
858 :
859 42312 : for (ILam = 1; ILam <= numptDAT; ++ILam) {
860 42099 : state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).WaveLength(ILam);
861 42099 : state.dataWindowManager->t[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).Trans(ILam);
862 42099 : if (IGlass == NGlass || (IGlass == (NGlass - 1) && StormWinConst))
863 6549 : state.dataWindowManager->t[IGlass - 1][ILam - 1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
864 42099 : state.dataWindowManager->rff[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflBack(ILam);
865 42099 : state.dataWindowManager->rbb[IGlass - 1][ILam - 1] = state.dataHeatBal->SpectralData(SpecDataNum).ReflFront(ILam);
866 : }
867 :
868 : } else { // No spectral data for this layer; use spectral average values
869 1753 : if (!state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
870 1751 : lquasi = true;
871 1751 : state.dataWindowManager->numpt[IGlass - 1] = 2;
872 1751 : state.dataWindowManager->t[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).Trans;
873 1751 : if (IGlass == NGlass || (IGlass == (NGlass - 1) && StormWinConst))
874 1251 : state.dataWindowManager->t[IGlass - 1][0] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
875 1751 : state.dataWindowManager->t[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).TransVis;
876 1751 : if (IGlass == NGlass || (IGlass == (NGlass - 1) && StormWinConst))
877 1251 : state.dataWindowManager->t[IGlass - 1][1] *= state.dataMaterial->Material(LayPtr).GlassTransDirtFactor;
878 1751 : state.dataWindowManager->rff[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamBack;
879 1751 : state.dataWindowManager->rbb[IGlass - 1][0] = state.dataMaterial->Material(LayPtr).ReflectSolBeamFront;
880 1751 : state.dataWindowManager->rff[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamBack;
881 1751 : state.dataWindowManager->rbb[IGlass - 1][1] = state.dataMaterial->Material(LayPtr).ReflectVisBeamFront;
882 : }
883 : }
884 1966 : if (state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
885 2 : numptDAT = state.dataWindowManager->wle.size();
886 2 : state.dataWindowManager->numpt[IGlass - 1] = numptDAT;
887 : }
888 : } // End of loop over glass layers in the construction for back calculation
889 :
890 : // Loop over incidence angle from 0 to 90 deg in 10 deg increments.
891 : // Get bare glass layer properties, then glazing system properties at each incidence angle.
892 : // The glazing system properties include the effect of inter-reflection among glass layers,
893 : // but exclude the effect of a shade or blind if present in the construction.
894 : // When a construction has a layer = SpectralAndAngle, the 10 degree increment will be overridden.
895 14421 : for (IPhi = 1; IPhi <= TotalIPhi; ++IPhi) {
896 13110 : Phi = double(IPhi - 1) * 10.0;
897 13110 : CosPhi = std::cos(Phi * DataGlobalConstants::DegToRadians);
898 13110 : if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0;
899 :
900 : // For each wavelength, get glass layer properties at this angle of incidence
901 : // from properties at normal incidence
902 32770 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
903 19660 : LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataWindowManager->LayerNum[IGlass - 1]);
904 19660 : if (!state.dataMaterial->Material(LayPtr).GlassSpectralAndAngle) {
905 475650 : for (ILam = 1; ILam <= state.dataWindowManager->numpt[IGlass - 1]; ++ILam) {
906 :
907 2736060 : TransAndReflAtPhi(CosPhi,
908 456010 : state.dataWindowManager->t[IGlass - 1][ILam - 1],
909 456010 : state.dataWindowManager->rff[IGlass - 1][ILam - 1],
910 456010 : state.dataWindowManager->rbb[IGlass - 1][ILam - 1],
911 456010 : state.dataWindowManager->tPhi[IGlass - 1][ILam - 1],
912 456010 : state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1],
913 456010 : state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1],
914 456010 : state.dataWindowManager->lSimpleGlazingSystem,
915 456010 : state.dataWindowManager->SimpleGlazingSHGC,
916 456010 : state.dataWindowManager->SimpleGlazingU);
917 : }
918 : } else {
919 2160 : for (ILam = 1; ILam <= (int)state.dataWindowManager->wle.size(); ++ILam) {
920 2140 : auto lam = state.dataWindowManager->wle[ILam - 1];
921 2140 : state.dataWindowManager->wlt[IGlass - 1][ILam - 1] = lam;
922 2140 : state.dataWindowManager->tPhi[IGlass - 1][ILam - 1] =
923 4280 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngTransDataPtr, Phi, lam);
924 2140 : state.dataWindowManager->rfPhi[IGlass - 1][ILam - 1] =
925 4280 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngFRefleDataPtr, Phi, lam);
926 2140 : state.dataWindowManager->rbPhi[IGlass - 1][ILam - 1] =
927 4280 : Curve::CurveValue(state, state.dataMaterial->Material(LayPtr).GlassSpecAngBRefleDataPtr, Phi, lam);
928 : }
929 : }
930 : }
931 :
932 : // For each wavelength in the solar spectrum, calculate system properties
933 : // stPhi, srfPhi, srbPhi and saPhi at this angle of incidence
934 13110 : SystemSpectralPropertiesAtPhi(state, 1, NGlass, 0.0, 2.54);
935 :
936 : // Get back absorptance properties of system by integrating over solar irradiance spectrum.
937 : // For now it is assumed that the exterior and interior irradiance spectra are the same.
938 :
939 32770 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
940 2123280 : for (j = 1; j <= state.dataWindowManager->nume; ++j) {
941 2103620 : sabsPhi(j) = state.dataWindowManager->saPhi(IGlass, j);
942 : }
943 19660 : SolarSprectrumAverage(state, sabsPhi, state.dataWindowManager->solabsBackPhi(IGlass, IPhi));
944 : }
945 :
946 : } // End of loop over incidence angles for back calculation
947 :
948 3277 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
949 1966 : IGlassBack = NGlass - IGlass + 1;
950 1966 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) =
951 3932 : DiffuseAverage(state.dataWindowManager->solabsBackPhi(IGlassBack, {1, 10}));
952 : }
953 :
954 : //-----------------------------------------------------------------------
955 : // Correction for effect of shade, screen or blind if present in the construction
956 : //-----------------------------------------------------------------------
957 :
958 : // For construction with shade, screen or blind, get system shading device absorptance
959 : // and correct the system glass layer absorptances for the effect of reflection
960 : // and transmission by shade, screen or blind. Get system reflectance (front and back,
961 : // solar and visible)
962 :
963 1311 : if (ShadeOn || BlindOn || ScreenOn) {
964 :
965 : // Solar and visible properties of isolated shade or blind
966 : // (Note: for shades or screen we go through the following loop over slat angles only once.)
967 :
968 47 : Real64 const tsolDiff_2(pow_2(tsolDiff));
969 47 : Real64 const tvisDiff_2(pow_2(tvisDiff));
970 104 : for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
971 :
972 101 : if (ShadeOn) {
973 29 : ShadeAbs = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).AbsorpSolar;
974 29 : ShadeTrans = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).Trans;
975 29 : ShadeTransVis = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).TransVis;
976 29 : ShadeRefl = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).ReflectShade;
977 29 : ShadeReflVis =
978 29 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(ShadeLayNum)).ReflectShadeVis;
979 29 : rsh = ShadeRefl;
980 29 : rshv = ShadeReflVis;
981 29 : tsh = ShadeTrans;
982 29 : tshv = ShadeTransVis;
983 29 : ash = ShadeAbs;
984 72 : } else if (IntBlind || ExtBlind) {
985 67 : ShadeTrans = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(ISlatAng);
986 67 : ShadeTransGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransGnd(ISlatAng);
987 67 : ShadeTransSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransSky(ISlatAng);
988 67 : ShadeTransVis = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffTrans(ISlatAng);
989 134 : if (IntBlind) { // Interior blind
990 47 : ShadeAbs = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(ISlatAng);
991 47 : ShadeRefl = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(ISlatAng);
992 47 : ShadeReflGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflGnd(ISlatAng);
993 47 : ShadeReflSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflSky(ISlatAng);
994 47 : ShadeReflVis = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffRefl(ISlatAng);
995 : } else { // Exterior blind
996 20 : ShadeAbs = state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(ISlatAng);
997 20 : ShadeRefl = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(ISlatAng);
998 20 : ShadeReflVis = state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl(ISlatAng);
999 : }
1000 5 : } else if (BGBlind) {
1001 3 : tsh = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(ISlatAng);
1002 3 : tshGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransGnd(ISlatAng);
1003 3 : tshSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTransSky(ISlatAng);
1004 3 : tshv = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffTrans(ISlatAng);
1005 3 : rfsh = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(ISlatAng);
1006 3 : rfshGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflGnd(ISlatAng);
1007 3 : rfshSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffReflSky(ISlatAng);
1008 3 : rfshv = state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffRefl(ISlatAng);
1009 3 : rbsh = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(ISlatAng);
1010 3 : rbshv = state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl(ISlatAng);
1011 3 : afsh = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(ISlatAng);
1012 3 : afshGnd = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsGnd(ISlatAng);
1013 3 : afshSky = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsSky(ISlatAng);
1014 3 : absh = state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(ISlatAng);
1015 2 : } else if (ScreenOn && ScNum > 0) {
1016 : // diffuse screen properties are calculated during initialization (quarter-hemispherical integration of beam properties)
1017 2 : ShadeAbs = state.dataHeatBal->SurfaceScreens(ScNum).DifScreenAbsorp;
1018 2 : ShadeTrans = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans;
1019 2 : ShadeTransVis = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTransVis;
1020 2 : ShadeRefl = state.dataHeatBal->SurfaceScreens(ScNum).DifReflect;
1021 2 : ShadeReflVis = state.dataHeatBal->SurfaceScreens(ScNum).DifReflectVis;
1022 2 : rsh = ShadeRefl;
1023 2 : rshv = ShadeReflVis;
1024 2 : tsh = ShadeTrans;
1025 2 : tshv = ShadeTransVis;
1026 2 : ash = ShadeAbs;
1027 : }
1028 :
1029 : // Correction factors for inter-reflections between glass and shading device
1030 :
1031 101 : if (ExtShade || ExtBlind || ExtScreen) {
1032 25 : ShadeReflFac = 1.0 / (1.0 - ShadeRefl * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront);
1033 25 : ShadeReflFacVis = 1.0 / (1.0 - ShadeReflVis * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront);
1034 76 : } else if (IntShade || IntBlind) {
1035 71 : ShadeReflFac = 1.0 / (1.0 - ShadeRefl * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack);
1036 71 : ShadeReflFacVis = 1.0 / (1.0 - ShadeReflVis * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack);
1037 : }
1038 :
1039 101 : if (ExtShade || ExtBlind || ExtScreen) { // Exterior shade or blind
1040 :
1041 : // Front incident solar, beam, exterior shade, screen or blind
1042 :
1043 25 : if (ExtShade) {
1044 33 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
1045 80 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1046 50 : state.dataWindowManager->solabsPhi(IGlass, IPhi) = ShadeTrans * solabsDiff(IGlass) * ShadeReflFac;
1047 : }
1048 30 : state.dataWindowManager->tsolPhi(IPhi) = ShadeTrans * ShadeReflFac * tsolDiff;
1049 30 : state.dataWindowManager->tvisPhi(IPhi) = ShadeTransVis * ShadeReflFacVis * tvisDiff;
1050 30 : state.dataWindowManager->solabsShadePhi(IPhi) =
1051 30 : ShadeAbs * (1.0 + ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront);
1052 : }
1053 : }
1054 :
1055 : // Front incident solar, diffuse, exterior shade/screen/blind
1056 :
1057 53 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1058 28 : if (ExtBlind) {
1059 20 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, IGlass) =
1060 20 : ShadeTrans * ShadeReflFac * solabsDiff(IGlass);
1061 20 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, IGlass) =
1062 20 : ShadeTransGnd * ShadeReflFac * solabsDiff(IGlass);
1063 20 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, IGlass) =
1064 20 : ShadeTransSky * ShadeReflFac * solabsDiff(IGlass);
1065 : }
1066 28 : if (ExtShade || ExtScreen)
1067 8 : state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) = ShadeTrans * ShadeReflFac * solabsDiff(IGlass);
1068 : }
1069 25 : if (ExtBlind) {
1070 20 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) =
1071 40 : state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(ISlatAng) +
1072 20 : ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeAbs;
1073 20 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
1074 40 : state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsGnd(ISlatAng) +
1075 20 : ShadeTransGnd * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeAbs;
1076 20 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
1077 40 : state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsSky(ISlatAng) +
1078 20 : ShadeTransSky * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeAbs;
1079 20 : state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTrans;
1080 20 : state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransGnd;
1081 20 : state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransSky;
1082 20 : state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) = tvisDiff * ShadeReflFacVis * ShadeTransVis;
1083 20 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
1084 20 : ShadeRefl + pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeReflFac;
1085 20 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
1086 20 : ShadeReflVis +
1087 20 : pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront * ShadeReflFacVis;
1088 : }
1089 25 : if (ExtShade || ExtScreen) {
1090 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffShade =
1091 5 : ShadeAbs * (1.0 + ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront);
1092 5 : state.dataConstruction->Construct(ConstrNum).TransDiff = tsolDiff * ShadeReflFac * ShadeTrans;
1093 5 : state.dataConstruction->Construct(ConstrNum).TransDiffVis = tvisDiff * ShadeReflFacVis * ShadeTransVis;
1094 5 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront =
1095 5 : ShadeRefl + pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront * ShadeReflFac;
1096 5 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront =
1097 5 : ShadeReflVis +
1098 5 : pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront * ShadeReflFacVis;
1099 : }
1100 :
1101 : // Back incident solar, diffuse, exterior shade/blind
1102 :
1103 25 : if (ExtBlind) {
1104 40 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1105 20 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, IGlass) =
1106 40 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) +
1107 20 : tsolDiff * ShadeRefl * ShadeReflFac * solabsDiff(IGlass);
1108 : }
1109 20 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) = tsolDiff * ShadeReflFac * ShadeAbs;
1110 20 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
1111 20 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack + tsolDiff_2 * ShadeRefl * ShadeReflFac;
1112 20 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
1113 20 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack + tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
1114 : }
1115 25 : if (ExtShade || ExtScreen) {
1116 13 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1117 8 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) +=
1118 8 : tsolDiff * ShadeRefl * ShadeReflFac * solabsDiff(IGlass);
1119 : }
1120 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = tsolDiff * ShadeReflFac * ShadeAbs;
1121 5 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack += tsolDiff_2 * ShadeRefl * ShadeReflFac;
1122 5 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack += tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
1123 : }
1124 :
1125 : } // End check if exterior shade, screen or blind
1126 :
1127 101 : if (IntShade || IntBlind) { // Interior shade or blind
1128 :
1129 : // Front incident solar, beam, interior shade
1130 :
1131 71 : if (IntShade) {
1132 264 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
1133 620 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1134 380 : state.dataWindowManager->solabsPhi(IGlass, IPhi) +=
1135 760 : state.dataWindowManager->tsolPhi(IPhi) * ShadeRefl * ShadeReflFac *
1136 380 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
1137 : }
1138 240 : state.dataWindowManager->solabsShadePhi(IPhi) = state.dataWindowManager->tsolPhi(IPhi) * ShadeReflFac * ShadeAbs;
1139 240 : state.dataWindowManager->tsolPhi(IPhi) *= ShadeReflFac * ShadeTrans;
1140 240 : state.dataWindowManager->tvisPhi(IPhi) *= ShadeReflFacVis * ShadeTransVis;
1141 : }
1142 : } // End of check if interior shade
1143 :
1144 : // Front incident solar, diffuse, interior blind
1145 :
1146 71 : if (IntBlind) {
1147 94 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1148 47 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, IGlass) =
1149 94 : state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +
1150 47 : tsolDiff * ShadeRefl * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
1151 47 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, IGlass) =
1152 94 : state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +
1153 47 : tsolDiff * ShadeReflGnd * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
1154 47 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, IGlass) =
1155 94 : state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +
1156 47 : tsolDiff * ShadeReflSky * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
1157 : }
1158 :
1159 47 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) = tsolDiff * ShadeReflFac * ShadeAbs;
1160 47 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
1161 47 : tsolDiff * ShadeReflFac * state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsGnd(ISlatAng);
1162 47 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
1163 47 : tsolDiff * ShadeReflFac * state.dataHeatBal->Blind(BlNum).SolFrontDiffAbsSky(ISlatAng);
1164 47 : state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTrans;
1165 47 : state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransGnd;
1166 47 : state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) = tsolDiff * ShadeReflFac * ShadeTransSky;
1167 47 : state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) = tvisDiff * ShadeReflFacVis * ShadeTransVis;
1168 47 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
1169 47 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront + tsolDiff_2 * ShadeRefl * ShadeReflFac;
1170 47 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
1171 47 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront + tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
1172 :
1173 : // Back incident solar, diffuse, interior blind
1174 :
1175 94 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1176 47 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, IGlass) =
1177 47 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) * ShadeTrans * ShadeReflFac;
1178 : }
1179 :
1180 47 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) =
1181 94 : state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(ISlatAng) +
1182 47 : ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack * ShadeAbs;
1183 47 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
1184 94 : state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(ISlatAng) +
1185 47 : pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack * ShadeReflFac;
1186 47 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
1187 94 : state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl(ISlatAng) +
1188 47 : pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack * ShadeReflFacVis;
1189 : } // End of check if interior blind
1190 :
1191 : // Front incident solar, diffuse, interior shade
1192 :
1193 71 : if (IntShade) {
1194 62 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1195 38 : state.dataConstruction->Construct(ConstrNum).AbsDiff(IGlass) +=
1196 38 : tsolDiff * ShadeRefl * ShadeReflFac * solabsDiff(IGlass);
1197 : }
1198 :
1199 24 : state.dataConstruction->Construct(ConstrNum).AbsDiffShade = tsolDiff * ShadeReflFac * ShadeAbs;
1200 24 : state.dataConstruction->Construct(ConstrNum).TransDiff = tsolDiff * ShadeReflFac * ShadeTrans;
1201 24 : state.dataConstruction->Construct(ConstrNum).TransDiffVis = tvisDiff * ShadeReflFacVis * ShadeTransVis;
1202 24 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront += tsolDiff_2 * ShadeRefl * ShadeReflFac;
1203 24 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront += tvisDiff_2 * ShadeReflVis * ShadeReflFacVis;
1204 :
1205 : // Back incident solar, diffuse, interior shade
1206 :
1207 62 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1208 38 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass) *= ShadeTrans * ShadeReflFac;
1209 : }
1210 :
1211 24 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade =
1212 24 : ShadeAbs * (1 + ShadeTrans * ShadeReflFac * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack);
1213 24 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack =
1214 24 : ShadeRefl + pow_2(ShadeTrans) * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack * ShadeReflFac;
1215 24 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack =
1216 24 : ShadeReflVis +
1217 24 : pow_2(ShadeTransVis) * state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack * ShadeReflFacVis;
1218 : } // End of check if interior shade
1219 :
1220 : } // End check if interior shade or blind
1221 :
1222 101 : if (BGShade || BGBlind) { // Between-glass shade/blind; assumed to be between glass #2 and glass #3
1223 :
1224 5 : tsh2 = pow_2(tsh);
1225 5 : tshv2 = pow_2(tshv);
1226 5 : td1 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(1);
1227 5 : td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
1228 5 : td1v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(1);
1229 5 : td2v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(2);
1230 5 : afd1 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(1);
1231 5 : afd2 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(2);
1232 5 : abd1 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(1);
1233 5 : abd2 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(2);
1234 5 : rb1 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(1);
1235 5 : rb2 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(2);
1236 5 : rb1v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(1);
1237 5 : rb2v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(2);
1238 5 : rf1 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(1);
1239 5 : rf2 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(2);
1240 5 : rf1v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(1);
1241 5 : rf2v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(2);
1242 :
1243 5 : if (BGShade) {
1244 2 : if (NGlass == 2) {
1245 :
1246 : // Front incident solar, beam, between-glass shade, NGlass = 2
1247 :
1248 11 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
1249 10 : t1 = tBareSolPhi(1, IPhi);
1250 10 : t1v = tBareVisPhi(1, IPhi);
1251 10 : af1 = afBareSolPhi(1, IPhi);
1252 10 : ab1 = abBareSolPhi(1, IPhi);
1253 10 : state.dataWindowManager->tsolPhi(IPhi) = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * td2;
1254 10 : state.dataWindowManager->tvisPhi(IPhi) = t1v * (tshv + rshv * rb1v * tshv + tshv * rf2v * rshv) * td2v;
1255 10 : state.dataWindowManager->solabsShadePhi(IPhi) = t1 * (ash + rsh * rb1 + tsh * rf2) * ash;
1256 10 : state.dataWindowManager->solabsPhi(1, IPhi) = af1 + t1 * (rsh + rsh * rb1 * rsh + tsh * rf2 * tsh) * abd1;
1257 10 : state.dataWindowManager->solabsPhi(2, IPhi) = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * afd2;
1258 : } // End of loop over incidence angles
1259 :
1260 : // Front incident solar, diffuse, between-glass shade, NGlass = 2
1261 :
1262 1 : state.dataConstruction->Construct(ConstrNum).TransDiff = td1 * (tsh + rsh * rb1 * tsh + tsh * rb2 * rsh) * td2;
1263 1 : state.dataConstruction->Construct(ConstrNum).TransDiffVis =
1264 1 : td1v * (tshv + rshv * rb1v * tshv + tshv * rb2v * rshv) * td2v;
1265 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffShade = td1 * (ash + rsh * rb1 * ash + tsh * rf2 * ash);
1266 1 : state.dataConstruction->Construct(ConstrNum).AbsDiff(1) = afd1 + td1 * (rsh + tsh * rb2 * tsh) * abd1;
1267 1 : state.dataConstruction->Construct(ConstrNum).AbsDiff(2) = td1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * afd2;
1268 1 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront =
1269 1 : rf1 + td1 * (rsh + rsh * rb1 * rsh + tsh * rf2 * tsh) * td1;
1270 1 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront =
1271 1 : rf1v + td1v * (rshv + rshv * rb1v * rshv + tshv * rf2v * tshv) * td1v;
1272 :
1273 : // Back incident solar, diffuse, between-glass shade, NGlass = 2
1274 :
1275 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = td2 * (ash + rsh * rf2 * ash + tsh * rb1 * ash);
1276 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(1) = td2 * (tsh + rsh * rf2 * tsh + tsh * rb1 * rsh) * abd1;
1277 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(2) =
1278 1 : abd2 + td2 * (rsh + rsh * rf2 * rsh + tsh * rb1 * tsh) * afd2;
1279 1 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack =
1280 1 : rb2 + td2 * (rsh + rsh * rf2 * rsh + tsh * rb1 * tsh) * td2;
1281 1 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack =
1282 1 : rb2v + td2v * (rshv + rshv * rf2v * rshv + tshv * rb1v * tshv) * td2v;
1283 :
1284 : } // End of check if NGlass = 2
1285 :
1286 2 : if (NGlass == 3) {
1287 :
1288 1 : td3 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(3);
1289 1 : td3v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(3);
1290 1 : afd3 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(3);
1291 1 : abd3 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(3);
1292 1 : rb3 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(3);
1293 1 : rb3v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(3);
1294 1 : rf3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
1295 1 : rf3v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(3);
1296 :
1297 : // Front incident solar, beam, between-glass shade, NGlass = 3
1298 :
1299 11 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
1300 10 : t1 = tBareSolPhi(1, IPhi);
1301 10 : t1v = tBareVisPhi(1, IPhi);
1302 10 : t2 = tBareSolPhi(2, IPhi);
1303 10 : t2v = tBareVisPhi(2, IPhi);
1304 10 : af1 = afBareSolPhi(1, IPhi);
1305 10 : af2 = afBareSolPhi(2, IPhi);
1306 10 : ab1 = abBareSolPhi(1, IPhi);
1307 10 : ab2 = abBareSolPhi(2, IPhi);
1308 10 : rbmf2 = max(0.0, 1.0 - (t2 + af2));
1309 :
1310 10 : state.dataWindowManager->tsolPhi(IPhi) =
1311 10 : t1 * t2 * (tsh + tsh * rf3 * rsh + rsh * td2 * rb1 * td2 * tsh + rsh * rb2 * tsh) * td3;
1312 10 : state.dataWindowManager->tvisPhi(IPhi) =
1313 10 : t1v * t2v * (tshv + tshv * rf3v * rshv + rshv * td2v * rb1v * td2v * tshv + rshv * rb2v * tshv) * td3v;
1314 10 : state.dataWindowManager->solabsShadePhi(IPhi) = t1 * t2 * (1 + rsh * td2 * rb1 * td2 + rsh * rb2) * ash;
1315 10 : state.dataWindowManager->solabsPhi(1, IPhi) =
1316 10 : af1 + rbmf2 * ab1 + t1 * t2 * rsh * (1 + rf3 * tsh + rb2 * rsh + td2 * rb1 * td2 * rsh) * td2 * abd1;
1317 10 : state.dataWindowManager->solabsPhi(2, IPhi) =
1318 10 : t1 * af2 + t1 * t2 * ((rsh + tsh * rf3 * tsh + rsh * rb2 * rsh) * abd2 + rsh * td2 * rb1 * afd2);
1319 10 : state.dataWindowManager->solabsPhi(3, IPhi) =
1320 10 : t1 * t2 * (tsh + rsh * (rb2 * tsh + td2 * rb2 * td2 * tsh + rf3 * rsh)) * afd3;
1321 : } // End of loop over incidence angle
1322 :
1323 : // Front incident solar, diffuse, between-glass shade, NGlass = 3
1324 :
1325 1 : state.dataConstruction->Construct(ConstrNum).TransDiff =
1326 1 : td1 * td2 * (tsh + rsh * td2 * rb1 * td2 * tsh + rsh * rb2 * tsh + tsh * rf3 * rsh) * td3;
1327 1 : state.dataConstruction->Construct(ConstrNum).TransDiffVis =
1328 1 : td1v * td2v * (tshv + rshv * td2v * rb1v * td2v * tshv + rshv * rb2v * tshv + tshv * rf3v * rshv) * td3v;
1329 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffShade =
1330 1 : td1 * td2 * (ash * (1 + rsh * td2 * rb1 * td2 + rsh * rb2 * ash) + tsh * rf3 * ash);
1331 1 : state.dataConstruction->Construct(ConstrNum).AbsDiff(1) =
1332 1 : afd1 + td1 * (rf2 + td2 * (rsh + rsh * rb2 * rsh + tsh * rf3 * tsh + rsh * td2 * rb1 * td2 * rsh) * td2) * abd1;
1333 1 : state.dataConstruction->Construct(ConstrNum).AbsDiff(2) =
1334 1 : td1 * (afd2 + td2 * (rsh + rsh * rb2 * rsh + tsh * rf3 * tsh) * abd2);
1335 1 : state.dataConstruction->Construct(ConstrNum).AbsDiff(3) =
1336 1 : td1 * td2 * (tsh + rsh * rb2 * tsh + rsh * td2 * rb1 * td2 * tsh + tsh * rf3 * rsh) * afd3;
1337 1 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront =
1338 2 : rf1 + td1 * rf2 * td1 +
1339 1 : td1 * td2 * (rsh + tsh * rf3 * tsh + rsh * rb2 * rsh + rsh * td2 * rb1 * td2 * rsh) * td2 * td1;
1340 1 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront =
1341 2 : rf1v + td1v * rf2v * td1v +
1342 1 : td1v * td2v * (rshv + tshv * rf3v * tshv + rshv * rb2v * rshv + rshv * td2v * rb1v * td2v * rshv) * td2v * td1v;
1343 :
1344 : // Back incident solar, diffuse, between-glass shade, NGlass = 3
1345 :
1346 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade =
1347 1 : td3 * ((1 + rsh * rf3) * ash + (tsh * td2 * rb1 * td2 + tsh * rb2) * ash);
1348 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(1) =
1349 1 : td3 * (tsh + rsh * rf3 * tsh + tsh * rb2 * rsh + tsh * td2 * rb1 * td2 * rsh) * td2 * abd1;
1350 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(2) =
1351 1 : td3 * ((tsh + rsh * rf3 * tsh) * abd2 + (tsh * td2 * rb1 * td2 + tsh * rb2) * afd2);
1352 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(3) =
1353 1 : abd3 + td3 * (rsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * afd3;
1354 1 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack =
1355 1 : rb3 + td3 * (rsh + rsh * rf3 * rsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * td3;
1356 1 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack =
1357 1 : rb3v + td3v * (rshv + rshv * rf3 * rshv + tshv * rb2v * tshv + tshv * td2v * rb1v * td2v * tshv) * td3v;
1358 :
1359 : } // End of check if NGlass = 3
1360 :
1361 : } // End of check if between-glass shade
1362 :
1363 5 : if (BGBlind) {
1364 :
1365 3 : if (NGlass == 2) {
1366 :
1367 : // Front incident solar, diffuse, between-glass blind, NGlass = 2
1368 :
1369 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 1) =
1370 2 : afd1 + td1 * (rfsh + rfsh * rb1 * rfsh + tsh * rb2 * tsh) * abd1;
1371 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 1) =
1372 2 : afd1 + td1 * (rfshGnd + rfshGnd * rb1 * rfshGnd + tshGnd * rb2 * tsh) * abd1;
1373 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 1) =
1374 2 : afd1 + td1 * (rfshSky + rfshSky * rb1 * rfshSky + tshSky * rb2 * tsh) * abd1;
1375 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 2) =
1376 2 : td1 * (tsh + rfsh * rb1 * tsh + tsh * rf2 * rbsh) * afd2;
1377 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 2) =
1378 2 : td1 * (tshGnd + rfshGnd * rb1 * tsh + tshGnd * rf2 * rbsh) * afd2;
1379 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 2) =
1380 2 : td1 * (tshSky + rfshSky * rb1 * tsh + tshSky * rf2 * rbsh) * afd2;
1381 2 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) =
1382 2 : td1 * (afsh + rfsh * rb1 * afsh + tsh * rf2 * absh);
1383 2 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
1384 2 : td1 * (afshGnd + rfsh * rb1 * afsh + tshGnd * rf2 * absh);
1385 2 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
1386 2 : td1 * (afshSky + rfsh * rb1 * afsh + tshSky * rf2 * absh);
1387 2 : state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) =
1388 2 : td1 * (tsh + rfsh * rb1 * tsh + tsh * rb2 * rbsh) * td2;
1389 2 : state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) =
1390 2 : td1 * (tshGnd + rfsh * rb1 * tshGnd + tshGnd * rb2 * rbsh) * td2;
1391 2 : state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) =
1392 2 : td1 * (tshSky + rfsh * rb1 * tshSky + tshSky * rb2 * rbsh) * td2;
1393 2 : state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) =
1394 2 : td1v * (tshv + rfshv * rb1v * tshv + tshv * rb2v * rbshv) * td2v;
1395 2 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
1396 2 : rf1 + td1 * (rfsh + rfsh * rb1 * rfsh + tsh * rf2 * tsh) * td1;
1397 2 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
1398 2 : rf1v + td1v * (rfshv + rfshv * rb1v * rfshv + tshv * rf2v * tshv) * td1v;
1399 :
1400 : // Back incident solar, diffuse, between-glass blind, NGlass = 2
1401 :
1402 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 1) =
1403 2 : td2 * (tsh + rbsh * rf2 * tsh + tsh * rb1 * rfsh) * abd1;
1404 2 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 2) =
1405 2 : abd2 + td2 * (rbsh + rbsh * rf2 * rbsh + tsh * rb1 * tsh) * afd2;
1406 2 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) =
1407 2 : td2 * (absh + rbsh * rf2 * absh + tsh * rb1 * afsh);
1408 2 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
1409 2 : rb2 + td2 * (rbsh + rbsh * rf2 * rbsh + tsh * rb1 * tsh) * td2;
1410 2 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
1411 2 : rb2v + td2v * (rbshv + rbshv * rf2v * rbshv + tshv * rb1v * tshv) * td2v;
1412 :
1413 : } // End of check if NGlass = 2
1414 :
1415 3 : if (NGlass == 3) {
1416 :
1417 1 : td3 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(3);
1418 1 : td3v = state.dataConstruction->Construct(ConstrNum).tBareVisDiff(3);
1419 1 : afd3 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(3);
1420 1 : abd3 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(3);
1421 1 : rb3 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(3);
1422 1 : rb3v = state.dataConstruction->Construct(ConstrNum).rbBareVisDiff(3);
1423 1 : rf3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
1424 1 : rf3v = state.dataConstruction->Construct(ConstrNum).rfBareVisDiff(3);
1425 :
1426 : // Front incident solar, diffuse, between-glass blind, NGlass = 3
1427 :
1428 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 1) =
1429 1 : afd1 +
1430 1 : td1 * (rf2 + td2 * (rfsh + rfsh * rb2 * rfsh + tsh * rf3 * tsh + rfsh * td2 * rb1 * td2 * rfsh) * td2) * abd1;
1431 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 1) =
1432 1 : afd1 +
1433 1 : td1 *
1434 2 : (rf2 + td2 * (rfshGnd + rfshGnd * rb2 * rfsh + tshGnd * rf3 * tsh + rfshGnd * td2 * rb1 * td2 * rfsh) * td2) *
1435 : abd1;
1436 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 1) =
1437 1 : afd1 +
1438 1 : td1 *
1439 2 : (rf2 + td2 * (rfshSky + rfshSky * rb2 * rfsh + tshSky * rf3 * tsh + rfshSky * td2 * rb1 * td2 * rfsh) * td2) *
1440 : abd1;
1441 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 2) =
1442 1 : td1 * (afd2 + td2 * (rfsh + rfsh * rb2 * rfsh + tsh * rf3 * tsh) * abd2);
1443 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 2) =
1444 1 : td1 * (afd2 + td2 * (rfshGnd + rfshGnd * rb2 * rfsh + tshGnd * rf3 * tsh) * abd2);
1445 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 2) =
1446 1 : td1 * (afd2 + td2 * (rfshSky + rfshSky * rb2 * rfsh + tshSky * rf3 * tsh) * abd2);
1447 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiff(ISlatAng, 3) =
1448 1 : td1 * td2 * (tsh + rfsh * rb2 * tsh + rfsh * td2 * rb1 * td2 * tsh + tsh * rf3 * rbsh) * afd3;
1449 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffGnd(ISlatAng, 3) =
1450 1 : td1 * td2 * (tshGnd + rfshGnd * rb2 * tsh + rfshGnd * td2 * rb1 * td2 * tsh + tshGnd * rf3 * rbsh) * afd3;
1451 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffSky(ISlatAng, 3) =
1452 1 : td1 * td2 * (tshSky + rfshSky * rb2 * tsh + rfshSky * td2 * rb1 * td2 * tsh + tshSky * rf3 * rbsh) * afd3;
1453 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlind(ISlatAng) =
1454 1 : td1 * td2 * (afsh * (1 + rfsh * td2 * rb1 * td2) + rfsh * rb2 * afsh + tsh * rf3 * absh);
1455 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindGnd(ISlatAng) =
1456 1 : td1 * td2 * (afshGnd + afsh * rfsh * (td2 * rb1 * td2 + rb2) + tshGnd * rf3 * absh);
1457 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBlindSky(ISlatAng) =
1458 1 : td1 * td2 * (afshSky + afsh * rfsh * (td2 * rb1 * td2 + rb2) + tshSky * rf3 * absh);
1459 1 : state.dataConstruction->Construct(ConstrNum).BlTransDiff(ISlatAng) =
1460 1 : td1 * td2 * (tsh + rfsh * td2 * rb1 * td2 * tsh + rfsh * rb2 * tsh + tsh * rf3 * rbsh) * td3;
1461 1 : state.dataConstruction->Construct(ConstrNum).BlTransDiffGnd(ISlatAng) =
1462 1 : td1 * td2 * (tshGnd + rfsh * td2 * rb1 * td2 * tshGnd + rfsh * rb2 * tshGnd + tshGnd * rf3 * rbsh) * td3;
1463 1 : state.dataConstruction->Construct(ConstrNum).BlTransDiffSky(ISlatAng) =
1464 1 : td1 * td2 * (tshSky + rfsh * td2 * rb1 * td2 * tshSky + rfsh * rb2 * tshSky + tshSky * rf3 * rbsh) * td3;
1465 1 : state.dataConstruction->Construct(ConstrNum).BlTransDiffVis(ISlatAng) =
1466 1 : td1v * td2v * (tshv + rfshv * td2v * rb1v * td2v * tshv + rfshv * rb2v * tshv + tshv * rf3v * rbshv) * td3v;
1467 1 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffFront(ISlatAng) =
1468 2 : rf1 + td1 * rf2 * td1 +
1469 1 : td1 * td2 * (rfsh + tsh * rf3 * tsh + rfsh * rb2 * rfsh + rfsh * td2 * rb1 * td2 * rfsh) * td2 * td1;
1470 1 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffFront(ISlatAng) =
1471 2 : rf1v + td1v * rf2v * td1v +
1472 1 : td1v * td2v * (rfshv + tshv * rf3v * tshv + rfshv * rb2v * rfshv + rfshv * td2v * rb1v * td2v * rfshv) * td2v *
1473 : td1v;
1474 :
1475 : // Back incident solar, diffuse, between-glass blind, NGlass = 3
1476 :
1477 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 1) =
1478 1 : td3 * (tsh + rbsh * rf3 * tsh + tsh * rb2 * rfsh + tsh * td2 * rb1 * td2 * rfsh) * td2 * abd1;
1479 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 2) =
1480 1 : td3 * ((tsh + rbsh * rf3 * tsh) * abd2 + (tsh * td2 * rb1 * td2 + tsh * rb2) * afd2);
1481 1 : state.dataConstruction->Construct(ConstrNum).BlAbsDiffBack(ISlatAng, 3) =
1482 1 : abd3 + td3 * (rbsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * afd3;
1483 1 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackBlind(ISlatAng) =
1484 1 : td3 * ((1 + rbsh * rf3) * absh + (tsh * td2 * rb1 * td2 + tsh * rb2) * afsh);
1485 1 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(ISlatAng) =
1486 1 : rb3 + td3 * (rbsh + rbsh * rf3 * rbsh + tsh * rb2 * tsh + tsh * td2 * rb1 * td2 * tsh) * td3;
1487 1 : state.dataConstruction->Construct(ConstrNum).BlReflectVisDiffBack(ISlatAng) =
1488 1 : rb3v + td3v * (rbshv + rbshv * rf3v * rbshv + tshv * rb2v * tshv + tshv * td2v * rb1v * td2v * tshv) * td3v;
1489 :
1490 : } // End of check if NGlass = 3
1491 :
1492 : } // End of check if between-glass blind
1493 :
1494 : } // End of check if between-glass shade or blind
1495 :
1496 : // Continue loop over slat angles only for blinds with variable slat angle
1497 101 : if (ShadeOn || ScreenOn) break;
1498 70 : if (BlindOn) {
1499 70 : if (state.dataHeatBal->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
1500 : }
1501 : } // End of slat angle loop
1502 : } // End of check if construction has a shade or blind
1503 :
1504 : // Curve fits to get solar transmittance, reflectance, layer absorptance and
1505 : // visible transmittance as polynomials in cosine of incidence angle
1506 :
1507 1311 : if (!BlindOn && !ScreenOn) { // Bare glass or shade on
1508 2586 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1509 1293 : state.dataWindowManager->tsolPhi,
1510 : 6,
1511 : 1,
1512 : TotalIPhi,
1513 1293 : state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
1514 2586 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1515 1293 : state.dataWindowManager->rfsolPhi,
1516 : 6,
1517 : 1,
1518 : TotalIPhi,
1519 1293 : state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef);
1520 2586 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1521 1293 : state.dataWindowManager->rbsolPhi,
1522 : 6,
1523 : 1,
1524 : TotalIPhi,
1525 1293 : state.dataConstruction->Construct(ConstrNum).ReflSolBeamBackCoef);
1526 2586 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1527 1293 : state.dataWindowManager->tvisPhi,
1528 : 6,
1529 : 1,
1530 : TotalIPhi,
1531 1293 : state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
1532 3236 : for (IGlass = 1; IGlass <= NGlass; ++IGlass) {
1533 : // Front absorptance coefficients for glass layers
1534 1943 : state.dataWindowManager->DepVarCurveFit({1, TotalIPhi}) = state.dataWindowManager->solabsPhi(IGlass, {1, TotalIPhi});
1535 3886 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1536 1943 : state.dataWindowManager->DepVarCurveFit,
1537 : 6,
1538 : 1,
1539 : TotalIPhi,
1540 1943 : state.dataWindowManager->CoeffsCurveFit);
1541 1943 : state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(IGlass) = state.dataWindowManager->CoeffsCurveFit;
1542 : // Back absorptance coefficients for glass layers
1543 1943 : IGlassBack = NGlass - IGlass + 1;
1544 1943 : state.dataWindowManager->DepVarCurveFit({1, TotalIPhi}) = state.dataWindowManager->solabsBackPhi(IGlassBack, {1, TotalIPhi});
1545 3886 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1546 1943 : state.dataWindowManager->DepVarCurveFit,
1547 : 6,
1548 : 1,
1549 : TotalIPhi,
1550 1943 : state.dataWindowManager->CoeffsCurveFit);
1551 1943 : state.dataConstruction->Construct(ConstrNum).AbsBeamBackCoef(IGlass) = state.dataWindowManager->CoeffsCurveFit;
1552 : }
1553 :
1554 : // To check goodness of fit //Tuned
1555 1293 : auto const &solBeamCoef(state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
1556 1293 : auto const &visBeamCoef(state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
1557 14223 : for (IPhi = 1; IPhi <= TotalIPhi; ++IPhi) {
1558 12930 : tsolPhiFit(IPhi) = 0.0;
1559 12930 : tvisPhiFit(IPhi) = 0.0;
1560 :
1561 12930 : Phi = double(IPhi - 1) * 10.0;
1562 12930 : CosPhi = std::cos(Phi * DataGlobalConstants::DegToRadians);
1563 12930 : if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0;
1564 12930 : Real64 cos_pow(1.0);
1565 90510 : for (CoefNum = 1; CoefNum <= 6; ++CoefNum) {
1566 77580 : cos_pow *= CosPhi;
1567 77580 : tsolPhiFit(IPhi) += solBeamCoef(CoefNum) * cos_pow;
1568 77580 : tvisPhiFit(IPhi) += visBeamCoef(CoefNum) * cos_pow;
1569 : }
1570 : }
1571 : }
1572 :
1573 1311 : if (ShadeOn)
1574 58 : W5LsqFit(state.dataWindowManager->CosPhiIndepVar,
1575 29 : state.dataWindowManager->solabsShadePhi,
1576 : 6,
1577 : 1,
1578 : TotalIPhi,
1579 29 : state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef);
1580 :
1581 : } // End of loop over constructions
1582 :
1583 : // Get effective glass and shade/blind emissivities for windows that have interior blind or
1584 : // shade. These are used to calculate zone MRT contribution from window when
1585 : // interior blind/shade is deployed.
1586 :
1587 : // Loop for ordinary windows
1588 44509 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
1589 43741 : if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue;
1590 42185 : if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow) continue;
1591 5973 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) continue; // Irrelevant for Complex Fen
1592 5973 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) continue; // not required
1593 5970 : ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
1594 5970 : if (ConstrNumSh == 0) continue;
1595 141 : TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers;
1596 141 : IntShade = false;
1597 141 : IntBlind = false;
1598 141 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)).Group ==
1599 : DataHeatBalance::MaterialGroup::Shade) {
1600 48 : IntShade = true;
1601 48 : ShadeLayPtr = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay);
1602 : }
1603 141 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)).Group ==
1604 : DataHeatBalance::MaterialGroup::WindowBlind) {
1605 26 : IntBlind = true;
1606 26 : BlNum = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay)).BlindDataPtr;
1607 : }
1608 :
1609 141 : if (IntShade || IntBlind) {
1610 112 : for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
1611 110 : if (IntShade || IntBlind) {
1612 110 : EpsGlIR =
1613 110 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay - 1)).AbsorpThermalBack;
1614 110 : RhoGlIR = 1 - EpsGlIR;
1615 : }
1616 110 : if (IntShade) {
1617 48 : TauShIR = state.dataMaterial->Material(ShadeLayPtr).TransThermal;
1618 48 : EpsShIR = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
1619 48 : RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
1620 48 : state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1) =
1621 48 : EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR));
1622 48 : state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(1) = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR);
1623 : }
1624 110 : if (IntBlind) {
1625 62 : TauShIR = state.dataHeatBal->Blind(BlNum).IRFrontTrans(ISlatAng);
1626 62 : EpsShIR = state.dataHeatBal->Blind(BlNum).IRBackEmiss(ISlatAng);
1627 62 : RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR);
1628 62 : state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(ISlatAng) =
1629 62 : EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR));
1630 62 : state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(ISlatAng) = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR);
1631 : }
1632 : // Loop over remaining slat angles only if blind with movable slats
1633 110 : if (IntShade) break; // Loop over remaining slat angles only if blind
1634 62 : if (IntBlind) {
1635 62 : if (state.dataHeatBal->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
1636 : }
1637 : } // End of slat angle loop
1638 : } // End of check if interior shade or interior blind
1639 : } // End of surface loop
1640 :
1641 44509 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
1642 43741 : if (state.dataSurface->Surface(SurfNum).Construction <= 0) continue;
1643 42199 : if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow) continue;
1644 5973 : ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
1645 : // Total thickness of glazing system (used in calculation of inside reveal reflection/absorption
1646 5973 : state.dataSurface->SurfWinTotGlazingThickness(SurfNum) = 0.0;
1647 15982 : for (LayNum = 1; LayNum <= state.dataConstruction->Construct(ConstrNum).TotLayers; ++LayNum) {
1648 10009 : state.dataSurface->SurfWinTotGlazingThickness(SurfNum) +=
1649 10009 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(LayNum)).Thickness;
1650 : }
1651 : // Sine and cosine of azimuth and tilt
1652 : // SurfaceWindow(SurfNum)%SinAzim = Surface(SurfNum)%SinAzim
1653 : // SurfaceWindow(SurfNum)%CosAzim = Surface(SurfNum)%CosAzim
1654 : // SurfaceWindow(SurfNum)%SinTilt = Surface(SurfNum)%SinTilt
1655 : // SurfaceWindow(SurfNum)%CosTilt = Surface(SurfNum)%CosTilt
1656 : // ! Outward normal unit vector (pointing away from room)
1657 : // SurfaceWindow(SurfNum)%OutNormVec(1) = Surface(SurfNum)%OutNormVec(1)
1658 : // SurfaceWindow(SurfNum)%OutNormVec(2) = Surface(SurfNum)%OutNormVec(2)
1659 : // SurfaceWindow(SurfNum)%OutNormVec(3) = Surface(SurfNum)%OutNormVec(3)
1660 : // write(outputfiledebug,*) 'window='//TRIM(surface(SurfNum)%name)
1661 : // write(outputfiledebug,*) ' swindow%outnormvec=',surfacewindow(SurfNum)%outnormvec
1662 : // write(outputfiledebug,*) ' surface%outnormvec=',surface(SurfNum)%outnormvec
1663 : // Window center
1664 5973 : Rectangle = false;
1665 5973 : Triangle = false;
1666 5973 : if (state.dataSurface->Surface(SurfNum).Sides == 3) Triangle = true;
1667 5973 : if (state.dataSurface->Surface(SurfNum).Sides == 4) Rectangle = true;
1668 5973 : if (Rectangle) {
1669 : // Vertices of window (numbered counter-clockwise starting at upper left as viewed from inside of room).
1670 : // Assumes original vertices are numbered counter-clockwise from upper left as viewed from outside.
1671 5971 : W3 = state.dataSurface->Surface(SurfNum).Vertex(2);
1672 5971 : W2 = state.dataSurface->Surface(SurfNum).Vertex(3);
1673 5971 : W1 = state.dataSurface->Surface(SurfNum).Vertex(4);
1674 2 : } else if (Triangle) {
1675 2 : W3 = state.dataSurface->Surface(SurfNum).Vertex(2);
1676 2 : W2 = state.dataSurface->Surface(SurfNum).Vertex(3);
1677 2 : W1 = state.dataSurface->Surface(SurfNum).Vertex(1);
1678 : }
1679 5973 : W21 = W1 - W2;
1680 5973 : W23 = W3 - W2;
1681 5973 : if (Rectangle) {
1682 5971 : state.dataSurface->SurfaceWindow(SurfNum).WinCenter = W2 + (W23 + W21) / 2.0;
1683 2 : } else if (Triangle) {
1684 2 : state.dataSurface->SurfaceWindow(SurfNum).WinCenter = W2 + (W23 + W21) / 3.0;
1685 : }
1686 : } // End of surface loop
1687 :
1688 768 : ReportGlass(state);
1689 768 : }
1690 :
1691 : //*****************************************************************************************
1692 :
1693 768 : void W5InitGlassParameters(EnergyPlusData &state)
1694 : {
1695 : // Initializes variables used in the window optical and thermal calculation.
1696 :
1697 : int ConstrNum; // Construction number
1698 : int SurfNum; // Surface number
1699 : int IPhi; // Angle of incidence counter
1700 : int FrDivNum; // Pointer to frame/divider
1701 : Real64 FrWidth; // Window frame width {m}
1702 : Real64 FrEdgeWidth; // Frame edge width {m}
1703 : Real64 DivWidth; // Window divider width {m}
1704 : Real64 DivEdgeWidth; // Divider edge width {m}
1705 : Real64 GlHeight; // Height of glazed part of window {m}
1706 : Real64 GlWidth; // Width of glazed part of window {m}
1707 : int NumHorDividers; // Number of horizontal divider elements
1708 : int NumVertDividers; // Number of vertical divider elements
1709 : int BaseSurfNum; // Base surface number
1710 : int MatNum; // Material number
1711 : int DifOverrideCount; // Count the number of SolarDiffusing material overrides
1712 :
1713 6616 : for (ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) {
1714 5848 : if (state.dataConstruction->Construct(ConstrNum).FromWindow5DataFile) continue;
1715 5843 : if (state.dataConstruction->Construct(ConstrNum).WindowTypeBSDF) continue;
1716 5830 : state.dataConstruction->Construct(ConstrNum).TransDiff = 0.0;
1717 5830 : state.dataConstruction->Construct(ConstrNum).TransDiffVis = 0.0;
1718 5830 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = 0.0;
1719 5830 : state.dataConstruction->Construct(ConstrNum).ShadeAbsorpThermal = 0.0;
1720 5830 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack = 0.0;
1721 5830 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront = 0.0;
1722 5830 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront = 0.0;
1723 5830 : state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef = 0.0;
1724 5830 : state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef = 0.0;
1725 5830 : state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef = 0.0;
1726 5830 : state.dataConstruction->Construct(ConstrNum).ReflSolBeamBackCoef = 0.0;
1727 5830 : state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef = 0.0;
1728 5830 : state.dataConstruction->Construct(ConstrNum).AbsDiff = 0.0;
1729 5830 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack = 0.0;
1730 46812 : for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) {
1731 286874 : for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) {
1732 245892 : state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamCoef(Layer)(index) = 0.0;
1733 245892 : state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamBackCoef(Layer)(index) = 0.0;
1734 : }
1735 : }
1736 : }
1737 :
1738 44509 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
1739 : // For a window with shading device, get number of shaded construction and, if window
1740 : // has a blind (interior, exterior or between glass), get blind data pointer.
1741 :
1742 43741 : if (state.dataSurface->Surface(SurfNum).HasShadeControl) {
1743 278 : for (int winShadCtrl : state.dataSurface->Surface(SurfNum).windowShadingControlList) {
1744 145 : WinShadingType ShadingType = state.dataSurface->WindowShadingControl(winShadCtrl).ShadingType;
1745 145 : if (ShadingType == WinShadingType::ExtScreen) {
1746 : // Count number of exterior window screens, initialize in InitGlassOpticalCalculations after returning
1747 : // from this subroutine. The blind structure is initialized first and then the screen structure is initialized.
1748 8 : ++state.dataHeatBal->NumSurfaceScreens;
1749 8 : break; // only need to find the first window shading control since they should be identical
1750 : }
1751 : }
1752 : }
1753 : }
1754 :
1755 : // Set some static exterior-window frame and divider SurfaceWindow values
1756 : // from values in FrameDivider derived type
1757 44509 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
1758 43741 : FrDivNum = state.dataSurface->Surface(SurfNum).FrameDivider;
1759 43741 : if (FrDivNum > 0) { // Surface is a window with a frame and/or divider
1760 381 : FrWidth = state.dataSurface->FrameDivider(FrDivNum).FrameWidth;
1761 381 : GlHeight = state.dataSurface->Surface(SurfNum).Height;
1762 381 : GlWidth = state.dataSurface->Surface(SurfNum).Width;
1763 381 : NumVertDividers = state.dataSurface->FrameDivider(FrDivNum).VertDividers;
1764 381 : NumHorDividers = state.dataSurface->FrameDivider(FrDivNum).HorDividers;
1765 381 : BaseSurfNum = state.dataSurface->Surface(SurfNum).BaseSurf;
1766 381 : state.dataSurface->SurfWinFrameConductance(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameConductance;
1767 381 : state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameSolAbsorp;
1768 381 : state.dataSurface->SurfWinFrameVisAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameVisAbsorp;
1769 381 : state.dataSurface->SurfWinFrameEmis(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrameEmis;
1770 381 : state.dataSurface->SurfWinFrEdgeToCenterGlCondRatio(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).FrEdgeToCenterGlCondRatio;
1771 381 : state.dataSurface->SurfWinDividerType(SurfNum) = DataSurfaces::FrameDividerType::DividedLite;
1772 381 : if (state.dataSurface->FrameDivider(FrDivNum).DividerType == DataSurfaces::FrameDividerType::Suspended)
1773 11 : state.dataSurface->SurfWinDividerType(SurfNum) = DataSurfaces::FrameDividerType::Suspended;
1774 381 : DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
1775 381 : state.dataSurface->SurfWinDividerConductance(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerConductance;
1776 381 : state.dataSurface->SurfWinDividerSolAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerSolAbsorp;
1777 381 : state.dataSurface->SurfWinDividerVisAbsorp(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerVisAbsorp;
1778 381 : state.dataSurface->SurfWinDividerEmis(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DividerEmis;
1779 381 : state.dataSurface->SurfWinDivEdgeToCenterGlCondRatio(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).DivEdgeToCenterGlCondRatio;
1780 :
1781 381 : state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).OutsideRevealSolAbs;
1782 381 : state.dataSurface->SurfWinInsideSillDepth(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideSillDepth;
1783 381 : state.dataSurface->SurfWinInsideReveal(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideReveal;
1784 381 : state.dataSurface->SurfWinInsideSillSolAbs(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideSillSolAbs;
1785 381 : state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum) = state.dataSurface->FrameDivider(FrDivNum).InsideRevealSolAbs;
1786 :
1787 381 : FrEdgeWidth = state.dataSurface->FrameDivider(FrDivNum).FrameEdgeWidth;
1788 381 : DivEdgeWidth = state.dataSurface->FrameDivider(FrDivNum).DividerEdgeWidth;
1789 381 : state.dataSurface->SurfWinFrameEdgeArea(SurfNum) =
1790 381 : 2 * FrEdgeWidth * (GlHeight - FrEdgeWidth - NumHorDividers * DivWidth + GlWidth - FrEdgeWidth - NumVertDividers * DivWidth);
1791 381 : state.dataSurface->SurfWinDividerEdgeArea(SurfNum) =
1792 762 : 2 * DivEdgeWidth * (NumHorDividers * (GlWidth - 2 * FrEdgeWidth) + NumVertDividers * (GlHeight - 2 * FrEdgeWidth)) -
1793 381 : NumHorDividers * NumVertDividers * (4 * pow_2(DivEdgeWidth) + 4 * FrEdgeWidth * DivWidth);
1794 1143 : state.dataSurface->SurfWinCenterGlArea(SurfNum) = state.dataSurface->Surface(SurfNum).Area -
1795 762 : state.dataSurface->SurfWinFrameEdgeArea(SurfNum) -
1796 381 : state.dataSurface->SurfWinDividerEdgeArea(SurfNum);
1797 381 : state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) =
1798 762 : (state.dataSurface->SurfWinFrameEdgeArea(SurfNum) * state.dataSurface->SurfWinFrEdgeToCenterGlCondRatio(SurfNum) +
1799 762 : state.dataSurface->SurfWinDividerEdgeArea(SurfNum) * state.dataSurface->SurfWinDivEdgeToCenterGlCondRatio(SurfNum) +
1800 762 : state.dataSurface->SurfWinCenterGlArea(SurfNum)) /
1801 762 : (state.dataSurface->SurfWinFrameEdgeArea(SurfNum) + state.dataSurface->SurfWinDividerEdgeArea(SurfNum) +
1802 381 : state.dataSurface->SurfWinCenterGlArea(SurfNum));
1803 : }
1804 : }
1805 :
1806 : // Set SolarDiffusing to true for exterior windows that have a construction with an innermost diffusing glass layer
1807 768 : DifOverrideCount = 0;
1808 44509 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
1809 43741 : state.dataSurface->SurfWinSolarDiffusing(SurfNum) = false;
1810 93453 : if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window &&
1811 49698 : state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment && state.dataSurface->SurfWinStormWinConstr(SurfNum) == 0) {
1812 5956 : ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
1813 5956 : MatNum = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataConstruction->Construct(ConstrNum).TotLayers);
1814 5956 : if (state.dataMaterial->Material(MatNum).SolarDiffusing) {
1815 0 : if (!state.dataSurface->Surface(SurfNum).HasShadeControl) {
1816 0 : state.dataSurface->SurfWinSolarDiffusing(SurfNum) = true;
1817 : } else { // There is a shading control
1818 0 : if (state.dataSurface->WindowShadingControl(state.dataSurface->Surface(SurfNum).activeWindowShadingControl).ShadingType ==
1819 : WinShadingType::SwitchableGlazing) {
1820 0 : state.dataSurface->SurfWinSolarDiffusing(SurfNum) = true;
1821 : } else {
1822 0 : state.dataSurface->SurfWinSolarDiffusing(SurfNum) = false;
1823 0 : ++DifOverrideCount;
1824 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1825 0 : ShowWarningError(
1826 : state,
1827 0 : "W5InitGlassParameters: Window=\"" + state.dataSurface->Surface(SurfNum).Name +
1828 : "\" has interior material with Solar Diffusing=Yes, but existing Window Shading Device sets Diffusing=No.");
1829 : }
1830 : }
1831 : }
1832 : }
1833 : }
1834 : }
1835 :
1836 768 : if (DifOverrideCount > 0) {
1837 0 : if (!state.dataGlobal->DisplayExtraWarnings) {
1838 0 : ShowWarningError(state,
1839 0 : format("W5InitGlassParameters: {} Windows had Solar Diffusing=Yes overridden by presence of Window Shading Device.",
1840 0 : DifOverrideCount));
1841 : } else {
1842 0 : ShowMessage(state,
1843 0 : format("W5InitGlassParameters: {} Windows had Solar Diffusing=Yes overridden by presence of Window Shading Device.",
1844 0 : DifOverrideCount));
1845 : }
1846 : }
1847 :
1848 8448 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
1849 7680 : state.dataWindowManager->CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * DataGlobalConstants::DegToRadians);
1850 : }
1851 768 : }
1852 :
1853 : //****************************************************************************
1854 : // WINDOW 5 Optical Calculation Subroutines
1855 : //****************************************************************************
1856 :
1857 38720 : void SystemSpectralPropertiesAtPhi(EnergyPlusData &state,
1858 : int const iquasi, // When there is no spectral data, this is the wavelength
1859 : int const ngllayer, // Number of glass layers in construction
1860 : Real64 const wlbot, // Lowest and highest wavelength considered
1861 : Real64 const wltop)
1862 : {
1863 :
1864 : // SUBROUTINE INFORMATION:
1865 : // AUTHOR Adapted by F.Winkelmann from WINDOW 5
1866 : // subroutine opcalc
1867 : // DATE WRITTEN August 1999
1868 : // MODIFIED na
1869 : // RE-ENGINEERED na
1870 :
1871 : // PURPOSE OF THIS SUBROUTINE:
1872 : // For a particular angle of incidence, calculates system properties
1873 : // for a multi-layer glazing for each wavelength in the solar spectrum.
1874 : // Handles the special case of one or more layers that do not have spectral data.
1875 :
1876 : // Returns, for a particular angle of incidence:
1877 : // stPhi transmissivity of system at each wavelength in swl
1878 : // srfPhi front reflectance of system at each wavelength in swl
1879 : // srbPhi back reflectance of system at each wavelength in swl
1880 : // sabsPhi absorptance by layer at each wavelength in swl
1881 :
1882 77440 : Array1D<Real64> sabsPhi(5); // System solar absorptance in each glass layer for
1883 : // particular angle of incidence
1884 : int in; // Glass layer counter
1885 : int i;
1886 : int iwl; // Wavelength counter
1887 : int j;
1888 : Real64 wl; // Wavelength
1889 : // index to use in tPhi, rfPhi and rbPhi
1890 :
1891 : // For each glass layer find tPhi, rfPhi, and rbPhi at each wavelength
1892 :
1893 95910 : for (in = 1; in <= ngllayer; ++in) {
1894 6176520 : for (iwl = 1; iwl <= state.dataWindowManager->nume; ++iwl) {
1895 6119330 : wl = state.dataWindowManager->wle[iwl - 1];
1896 6119330 : if (wl < wlbot || wl > wltop) continue;
1897 : // In the following numpt is the number of spectral data points for each layer;
1898 : // numpt = 2 if there is no spectral data for a layer.
1899 4832690 : if (state.dataWindowManager->numpt[in - 1] <= 2) {
1900 4359990 : state.dataWindowManager->tadjPhi[in - 1][iwl - 1] = state.dataWindowManager->tPhi[in - 1][iquasi - 1];
1901 4359990 : state.dataWindowManager->rfadjPhi[in - 1][iwl - 1] = state.dataWindowManager->rfPhi[in - 1][iquasi - 1];
1902 4359990 : state.dataWindowManager->rbadjPhi[in - 1][iwl - 1] = state.dataWindowManager->rbPhi[in - 1][iquasi - 1];
1903 : } else {
1904 : // Interpolate to get properties at the solar spectrum wavelengths
1905 1418100 : state.dataWindowManager->tadjPhi[in - 1][iwl - 1] = Interpolate(
1906 1418100 : state.dataWindowManager->wlt[in - 1], state.dataWindowManager->tPhi[in - 1], state.dataWindowManager->numpt[in - 1], wl);
1907 1418100 : state.dataWindowManager->rfadjPhi[in - 1][iwl - 1] = Interpolate(
1908 1418100 : state.dataWindowManager->wlt[in - 1], state.dataWindowManager->rfPhi[in - 1], state.dataWindowManager->numpt[in - 1], wl);
1909 1418100 : state.dataWindowManager->rbadjPhi[in - 1][iwl - 1] = Interpolate(
1910 1418100 : state.dataWindowManager->wlt[in - 1], state.dataWindowManager->rbPhi[in - 1], state.dataWindowManager->numpt[in - 1], wl);
1911 : }
1912 : }
1913 : }
1914 :
1915 : // Calculate system properties at each wavelength
1916 4181760 : for (j = 1; j <= state.dataWindowManager->nume; ++j) {
1917 4143040 : wl = state.dataWindowManager->wle[j - 1];
1918 4143040 : if (wl < wlbot || wl > wltop) continue;
1919 :
1920 : // Set diagonal of matrix for subroutine SystemPropertiesAtLambdaAndPhi
1921 8075730 : for (i = 1; i <= ngllayer; ++i) {
1922 4832690 : state.dataWindowManager->top[i - 1][i - 1] = state.dataWindowManager->tadjPhi[i - 1][j - 1];
1923 4832690 : state.dataWindowManager->rfop[i - 1][i - 1] = state.dataWindowManager->rfadjPhi[i - 1][j - 1];
1924 4832690 : state.dataWindowManager->rbop[i - 1][i - 1] = state.dataWindowManager->rbadjPhi[i - 1][j - 1];
1925 : }
1926 :
1927 : // Calculate glazing system properties
1928 3243040 : if (ngllayer == 1) { // Single-layer system
1929 1832290 : state.dataWindowManager->stPhi[j - 1] = state.dataWindowManager->top[0][0];
1930 1832290 : state.dataWindowManager->srfPhi[j - 1] = state.dataWindowManager->rfop[0][0];
1931 1832290 : state.dataWindowManager->srbPhi[j - 1] = state.dataWindowManager->rbop[0][0];
1932 1832290 : sabsPhi(1) = 1.0 - state.dataWindowManager->stPhi[j - 1] - state.dataWindowManager->srfPhi[j - 1];
1933 : } else { // Multilayer system
1934 : // Get glazing system properties stPhi, etc., at this wavelength and incidence angle
1935 2821500 : SystemPropertiesAtLambdaAndPhi(state,
1936 : ngllayer,
1937 1410750 : state.dataWindowManager->stPhi[j - 1],
1938 1410750 : state.dataWindowManager->srfPhi[j - 1],
1939 1410750 : state.dataWindowManager->srbPhi[j - 1],
1940 : sabsPhi);
1941 : }
1942 :
1943 8075730 : for (i = 1; i <= ngllayer; ++i) {
1944 4832690 : state.dataWindowManager->saPhi(i, j) = sabsPhi(i);
1945 : }
1946 :
1947 : } // End of wavelength loop
1948 38720 : }
1949 :
1950 : //************************************************************************
1951 :
1952 1410750 : void SystemPropertiesAtLambdaAndPhi(EnergyPlusData &state,
1953 : int const n, // Number of glass layers
1954 : Real64 &tt, // System transmittance
1955 : Real64 &rft, // System front and back reflectance
1956 : Real64 &rbt,
1957 : Array1A<Real64> aft // System absorptance of each glass layer
1958 : )
1959 : {
1960 :
1961 : // SUBROUTINE INFORMATION:
1962 : // AUTHOR Adapted by F. Winkelmann from WINDOW 5
1963 : // subroutine op
1964 : // DATE WRITTEN August 1999
1965 : // MODIFIED na
1966 : // RE-ENGINEERED na
1967 :
1968 : // PURPOSE OF THIS SUBROUTINE:
1969 : // For a given angle of incidence, finds the overall properties of
1970 : // of a series of layers at a particular wavelength
1971 :
1972 : // Argument array dimensioning
1973 1410750 : aft.dim(5);
1974 :
1975 : int i; // Glass layer counters
1976 : int j;
1977 : Real64 denom; // Intermediate variables
1978 : Real64 denom1;
1979 : Real64 denom2;
1980 : Real64 t0; // Transmittance, back reflectance and front
1981 : Real64 rb0;
1982 : Real64 rf0;
1983 : // reflectance variables
1984 : Real64 af; // Front and back absorptance variables
1985 : Real64 ab;
1986 :
1987 : // Calculate perimeter elements of rt matrix
1988 3000400 : for (i = 1; i <= n - 1; ++i) {
1989 3373140 : for (j = i + 1; j <= n; ++j) {
1990 1783490 : denom = 1.0 - state.dataWindowManager->rfop[j - 1][j - 1] * state.dataWindowManager->rbop[i - 1][j - 2];
1991 1783490 : if (denom == 0.0) {
1992 178349 : state.dataWindowManager->top[j - 1][i - 1] = 0.0;
1993 178349 : state.dataWindowManager->rfop[j - 1][i - 1] = 1.0;
1994 178349 : state.dataWindowManager->rbop[i - 1][j - 1] = 1.0;
1995 : } else {
1996 1605141 : state.dataWindowManager->top[j - 1][i - 1] =
1997 1605141 : state.dataWindowManager->top[j - 2][i - 1] * state.dataWindowManager->top[j - 1][j - 1] / denom;
1998 1605141 : state.dataWindowManager->rfop[j - 1][i - 1] =
1999 3210282 : state.dataWindowManager->rfop[j - 2][i - 1] +
2000 1605141 : pow_2(state.dataWindowManager->top[j - 2][i - 1]) * state.dataWindowManager->rfop[j - 1][j - 1] / denom;
2001 1605141 : state.dataWindowManager->rbop[i - 1][j - 1] =
2002 3210282 : state.dataWindowManager->rbop[j - 1][j - 1] +
2003 1605141 : pow_2(state.dataWindowManager->top[j - 1][j - 1]) * state.dataWindowManager->rbop[i - 1][j - 2] / denom;
2004 : }
2005 : }
2006 : }
2007 : // System properties: transmittance, front and back reflectance
2008 1410750 : tt = state.dataWindowManager->top[n - 1][0];
2009 1410750 : rft = state.dataWindowManager->rfop[n - 1][0];
2010 1410750 : rbt = state.dataWindowManager->rbop[0][n - 1];
2011 :
2012 : // Absorptance in each layer
2013 4411150 : for (j = 1; j <= n; ++j) {
2014 3000400 : if (j == 1) {
2015 1410750 : t0 = 1.0;
2016 1410750 : rb0 = 0.0;
2017 : } else {
2018 1589650 : t0 = state.dataWindowManager->top[j - 2][0];
2019 1589650 : rb0 = state.dataWindowManager->rbop[0][j - 2];
2020 : }
2021 :
2022 3000400 : if (j == n) {
2023 1410750 : rf0 = 0.0;
2024 : } else {
2025 1589650 : rf0 = state.dataWindowManager->rfop[n - 1][j];
2026 : }
2027 :
2028 3000400 : af = 1.0 - state.dataWindowManager->top[j - 1][j - 1] - state.dataWindowManager->rfop[j - 1][j - 1];
2029 3000400 : ab = 1.0 - state.dataWindowManager->top[j - 1][j - 1] - state.dataWindowManager->rbop[j - 1][j - 1];
2030 3000400 : denom1 = 1.0 - state.dataWindowManager->rfop[n - 1][j - 1] * rb0;
2031 3000400 : denom2 = 1.0 - state.dataWindowManager->rbop[0][j - 1] * rf0;
2032 :
2033 3000400 : if (denom1 == 0.0 || denom2 == 0.0) {
2034 300040 : aft(j) = 0.0;
2035 : } else {
2036 2700360 : aft(j) = (t0 * af) / denom1 + (state.dataWindowManager->top[j - 1][0] * rf0 * ab) / denom2;
2037 : }
2038 : }
2039 1410750 : }
2040 :
2041 : //*************************************************************************
2042 :
2043 39320 : void SolarSprectrumAverage(EnergyPlusData &state,
2044 : Array1A<Real64> p, // Quantity to be weighted by solar spectrum
2045 : Real64 &psol // Quantity p weighted by solar spectrum
2046 : )
2047 : {
2048 :
2049 : // SUBROUTINE INFORMATION:
2050 : // AUTHOR Adapted by F.Winkelmann from WINDOW 5 subroutine solar
2051 : // DATE WRITTEN August 1999
2052 : // MODIFIED na
2053 : // RE-ENGINEERED na
2054 :
2055 : // PURPOSE OF THIS SUBROUTINE:
2056 : // Calculates average of property p weighted by solar spectral irradiance, e
2057 :
2058 : // Argument array dimensioning
2059 39320 : p.dim(state.dataWindowManager->nume);
2060 :
2061 : // Locals
2062 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2063 :
2064 : Real64 up; // Intermediate variables
2065 : Real64 down;
2066 : int i; // Wavelength counter
2067 : Real64 esol; // Solar spectrum value times delta wavelength
2068 :
2069 39320 : up = 0.0;
2070 39320 : down = 0.0;
2071 :
2072 4207240 : for (i = 1; i <= state.dataWindowManager->nume - 1; ++i) {
2073 8335840 : esol = (state.dataWindowManager->wle[i] - state.dataWindowManager->wle[i - 1]) * 0.5 *
2074 4167920 : (state.dataWindowManager->e[i - 1] + state.dataWindowManager->e[i]);
2075 4167920 : up += 0.5 * (p(i) + p(i + 1)) * esol;
2076 4167920 : down += esol;
2077 : }
2078 :
2079 39320 : psol = up / down;
2080 39320 : }
2081 :
2082 39330 : Real64 solarSpectrumAverage(EnergyPlusData &state, gsl::span<Real64> p)
2083 : {
2084 39330 : Real64 num = 0.0;
2085 39330 : Real64 denom = 0.0;
2086 4208310 : for (int i = 1; i <= state.dataWindowManager->nume - 1; ++i) {
2087 4168980 : Real64 const esol = (state.dataWindowManager->wle[i] - state.dataWindowManager->wle[i - 1]) * 0.5 *
2088 4168980 : (state.dataWindowManager->e[i - 1] + state.dataWindowManager->e[i]);
2089 4168980 : num += 0.5 * (p[i - 1] + p[i]) * esol;
2090 4168980 : denom += esol;
2091 : }
2092 39330 : return num / denom; // dangerous, doesn't check for zero denominator
2093 : }
2094 :
2095 39330 : Real64 visibleSpectrumAverage(EnergyPlusData &state, gsl::span<Real64> p)
2096 : {
2097 : // AUTHOR Adapted by F.Winkelmann from WINDOW 5
2098 : // subroutine w4vis
2099 : // DATE WRITTEN August 1999
2100 :
2101 : // Calculates visible average of property p by weighting with solar
2102 : // spectral irradiance, e, and photopic response, y30
2103 :
2104 39330 : Real64 num = 0.0;
2105 39330 : Real64 denom = 0.0;
2106 39330 : Real64 y30new = 0.0;
2107 39330 : Real64 y30ils1 = 0.0;
2108 4208310 : for (int i = 2; i <= state.dataWindowManager->nume;
2109 : ++i) { // Autodesk:BoundsViolation e|wle|p(i-1) @ i=1: Changed start index from 1 to 2: wle
2110 : // values prevented this violation from occurring in practice
2111 : // Restrict to visible range
2112 4168980 : if (state.dataWindowManager->wle[i - 1] >= 0.37 && state.dataWindowManager->wle[i - 1] <= 0.78) {
2113 4129650 : y30new = Interpolate(
2114 4129650 : state.dataWindowManager->wlt3, state.dataWindowManager->y30, state.dataWindowManager->numt3, state.dataWindowManager->wle[i - 1]);
2115 1376550 : Real64 evis = state.dataWindowManager->e[i - 2] * 0.5 * (y30new + y30ils1) *
2116 1376550 : (state.dataWindowManager->wle[i - 1] - state.dataWindowManager->wle[i - 2]);
2117 1376550 : num += 0.5 * (p[i - 1] + p[i - 2]) * evis;
2118 1376550 : denom += evis;
2119 1376550 : y30ils1 = y30new;
2120 : }
2121 : }
2122 39330 : return num / denom; // dangerous, doesn't check for zero denominator
2123 : }
2124 :
2125 2794650 : Real64 Interpolate(gsl::span<Real64> x, // Array of data points for independent variable
2126 : gsl::span<Real64> y, // Array of data points for dependent variable
2127 : int const npts, // Number of data pairs
2128 : Real64 const xin // Given value of x
2129 : )
2130 : {
2131 :
2132 : // SUBROUTINE INFORMATION:
2133 : // AUTHOR Adapted by F.Winkelmann from WINDOW 5 subroutine interp
2134 : // DATE WRITTEN August 1999
2135 : // MODIFIED na
2136 : // RE-ENGINEERED na
2137 :
2138 : // PURPOSE OF THIS SUBROUTINE:
2139 : // Linearly interpolates between data points. Outputs yout, interpolated
2140 : // value of y corresponding to xin
2141 :
2142 169381500 : for (int i = 1; i <= npts; ++i) {
2143 169368720 : if (xin <= x[i - 1]) {
2144 2781870 : if (i - 1 == 0) {
2145 91560 : return y[0];
2146 : } else {
2147 2690310 : return y[i - 2] + (y[i - 1] - y[i - 2]) * (xin - x[i - 2]) / (x[i - 1] - x[i - 2]);
2148 : }
2149 : }
2150 : }
2151 :
2152 : // Past the end of the array, so return endpoint
2153 12780 : return y[npts - 1];
2154 : }
2155 :
2156 : //***********************************************************************************
2157 : // Window Thermal Calculation Subroutines
2158 : //***********************************************************************************
2159 :
2160 22760394 : void CalcWindowHeatBalance(EnergyPlusData &state,
2161 : int const SurfNum, // Surface number
2162 : Real64 const HextConvCoeff, // Outside air film conductance coefficient
2163 : Real64 &SurfInsideTemp, // Inside window surface temperature
2164 : Real64 &SurfOutsideTemp // Outside surface temperature (C)
2165 : )
2166 : {
2167 : // SUBROUTINE INFORMATION:
2168 : // AUTHOR S. Vidanovic
2169 : // DATE WRITTEN June 2016
2170 : // MODIFIED na
2171 : // RE-ENGINEERED na
2172 : //
2173 : // PURPOSE OF THIS SUBROUTINE:
2174 : // Subroutine to direct whether to use exterior or interior window routines
2175 22760394 : if (state.dataGlobal->KickOffSizing || state.dataGlobal->KickOffSimulation) return;
2176 :
2177 22657349 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
2178 4032 : CalcWindowHeatBalanceExternalRoutines(state, SurfNum, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp);
2179 : } else {
2180 22653317 : CalcWindowHeatBalanceInternalRoutines(state, SurfNum, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp);
2181 : }
2182 : }
2183 :
2184 22653317 : void CalcWindowHeatBalanceInternalRoutines(EnergyPlusData &state,
2185 : int const SurfNum, // Surface number
2186 : Real64 const HextConvCoeff, // Outside air film conductance coefficient
2187 : Real64 &SurfInsideTemp, // Inside window surface temperature
2188 : Real64 &SurfOutsideTemp // Outside surface temperature (C)
2189 : )
2190 : {
2191 :
2192 : // SUBROUTINE INFORMATION:
2193 : // AUTHOR F. Winkelmann
2194 : // DATE WRITTEN November 1999
2195 : // MODIFIED FW, July 2000 (call better solution method)
2196 : // FW, June 2001 (handle window blinds)
2197 : // FW, Dec 2002 (add between-glass shades and blinds)
2198 : // FW, Mar 2003 (extend condensation flag to airflow windows)
2199 : // CC, Jul 2003 (set the reference temperatures for inside surface heat balance
2200 : // depending on convection algorithms and/or air models used)
2201 : // FW, Sep 2003 (increment ZoneWinHeatGain only for exterior windows)
2202 : // RR, May 2006 (add exterior window screen)
2203 : // TH, Dec 2008 (add thermochromic windows)
2204 : // RE-ENGINEERED na
2205 :
2206 : // PURPOSE OF THIS SUBROUTINE:
2207 : // Sets up information needed to calculate the window thermal behavior.
2208 : // Calls SolveForWindowTemperatures, which calculates the inside and outside
2209 : // face temperature of each glass layer by solving the heat balance
2210 : // equations on each face. Also calls CalcWinFrameAndDividerTemps,
2211 : // which calculates the outside and inside face temperatures of the
2212 : // window frame and divider if either of these are present.
2213 : // The resulting inside face temperature of the inner glass pane and the
2214 : // inside surface temperatures of frame and divider are used in the zone
2215 : // heat balance calculation. The inside face temperature of an interior shade
2216 : // or blind, if present, and the natural convection air flow between the
2217 : // shade/blind and inside glass face also appear in the zone heat balance calculation.
2218 : // The logical variable NRSolution is currently set to false, which means
2219 : // that the Newton-Raphson solution method for the glass layer heat balance
2220 : // is not used (because it sometimes didn't converge for 3- and 4-pane
2221 : // constructions with one or more low-emissivity layers). Instead, a more
2222 : // robust solution method is used that successively solves linearized heat
2223 : // balance equations until convergence is reached (see SolveForWindowTemperatures).
2224 : // CalcWindowHeatBalance is called by CalcHeatBalanceInsideSurface once each
2225 : // time step for each window.
2226 :
2227 : // Using/Aliasing
2228 : using namespace DataBSDFWindow;
2229 : using Psychrometrics::PsyCpAirFnW;
2230 : using Psychrometrics::PsyTdpFnWPb;
2231 : // unused0909 USE DataEnvironment, ONLY: CurMnDyHr
2232 : using ScheduleManager::GetCurrentScheduleValue;
2233 : using WindowComplexManager::CalcComplexWindowThermal;
2234 : using WindowEquivalentLayer::EQLWindowSurfaceHeatBalance;
2235 :
2236 : // SUBROUTINE ARGUMENT DEFINITIONS:
2237 : // (temperature of innermost face) [C]
2238 :
2239 : int BlNum; // Window blind number
2240 : int SurfNumAdj; // An interzone surface's number in the adjacent zone
2241 : int ZoneNumAdj; // An interzone surface's adjacent zone number
2242 : int TotLay; // Total number of layers in a construction
2243 : // (sum of solid layers and gap layers)
2244 : int TotGlassLay; // Total number of glass layers in a construction
2245 : int Lay; // Layer number
2246 : int LayPtr; // Material number for a layer
2247 : int IGlass; // glass layer number (1,2,3,...)
2248 : int IGap; // Gap layer number (1,2,...)
2249 : int IMix; // Gas number in a mixture of gases
2250 : int ICoeff; // Gas property index (1,2,3)
2251 : WinShadingType ShadeFlag; // Flag indicating whether shade or blind is on, and shade/blind position
2252 : int k; // Layer counter
2253 : // REAL(r64) :: tsky ! Sky temperature [K]
2254 : int ShadeLayPtr; // Material number corresponding to a shade layer
2255 : Real64 dth1; // Temperature difference across glass layers [K]
2256 : Real64 dth2;
2257 : Real64 dth3;
2258 : Real64 dth4;
2259 : Real64 EffShBlEmiss; // Effective interior shade or blind emissivity
2260 : Real64 EffGlEmiss; // Effective inside glass emissivity when interior shade or blind
2261 : Real64 RoomHumRat; // Room air humidity ratio
2262 : Real64 RoomDewPoint; // Room air dewpoint temperature (C)
2263 : Real64 InsideGlassTemp; // Temperature of room side of innermost glass layer (C)
2264 : Real64 Tleft; // For airflow windows, temperature of the glass faces adjacent
2265 : Real64 Tright;
2266 :
2267 : Real64 SrdSurfTempAbs; // Absolute temperature of a surrounding surface
2268 : Real64 SrdSurfViewFac; // View factor of a surrounding surface
2269 : Real64 OutSrdIR; // LWR from surrouding srfs
2270 :
2271 : // New variables for thermochromic windows calc
2272 : Real64 locTCSpecTemp; // The temperature corresponding to the specified optical properties of the TC layer
2273 : Real64 locTCLayerTemp; // TC layer temperature at each time step. C
2274 : int i;
2275 22653317 : auto &deltaTemp = state.dataWindowManager->deltaTemp;
2276 22653317 : auto &iMinDT = state.dataWindowManager->iMinDT;
2277 22653317 : auto &IDConst = state.dataWindowManager->IDConst;
2278 22653317 : Real64 dT0(0.0);
2279 22653317 : Real64 dT1(0.0);
2280 : Real64 SurfOutsideEmiss; // temporary for result of outside surface emissivity
2281 : Real64 Tsout; // temporary for result of outside surface temp in Kelvin
2282 : int temp;
2283 :
2284 : // Shorthand references
2285 22653317 : auto &window(state.dataSurface->SurfaceWindow(SurfNum));
2286 22653317 : auto &surface(state.dataSurface->Surface(SurfNum));
2287 22653317 : int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
2288 22653317 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone);
2289 :
2290 22653317 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
2291 :
2292 37968 : temp = 0;
2293 :
2294 : // Simon: Complex fenestration state works only with tarcog
2295 37968 : CalcComplexWindowThermal(
2296 : state, SurfNum, temp, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp, SurfOutsideEmiss, DataBSDFWindow::Condition::Invalid);
2297 :
2298 37968 : TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
2299 37968 : state.dataWindowManager->ngllayer =
2300 37968 : state.dataConstruction->Construct(ConstrNum).TotSolidLayers; // Simon: This is necessary to keep for frame calculations
2301 : // Simon: need to transfer surface temperatures because of frames calculation
2302 250992 : for (i = 1; i <= 2 * state.dataConstruction->Construct(ConstrNum).TotSolidLayers; ++i) {
2303 213024 : state.dataWindowManager->thetas[i - 1] = window.ThetaFace(i);
2304 : }
2305 37968 : state.dataWindowManager->hcout = HextConvCoeff;
2306 37968 : state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
2307 37968 : state.dataWindowManager->tin = thisZoneHB.MAT + state.dataWindowManager->TKelvin; // Inside air temperature
2308 :
2309 : // This is code repeating and it is necessary to calculate report variables. Do not know
2310 : // how to solve this in more elegant way :(
2311 37968 : if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
2312 37968 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
2313 0 : state.dataWindowManager->tout = state.dataSurface->SurfOutWetBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2314 : } else { // Dry
2315 37968 : state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2316 : }
2317 : } else { // Window not exposed to wind
2318 0 : state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2319 : }
2320 :
2321 37968 : state.dataWindowManager->Ebout = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tout);
2322 37968 : state.dataWindowManager->Outir =
2323 75936 : surface.ViewFactorSkyIR *
2324 113904 : (state.dataSurface->SurfAirSkyRadSplit(SurfNum) * state.dataWindowManager->sigma * pow_4(state.dataEnvrn->SkyTempKelvin) +
2325 75936 : (1.0 - state.dataSurface->SurfAirSkyRadSplit(SurfNum)) * state.dataWindowManager->Ebout) +
2326 37968 : surface.ViewFactorGroundIR * state.dataWindowManager->Ebout;
2327 :
2328 22615349 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
2329 :
2330 8064 : EQLWindowSurfaceHeatBalance(
2331 : state, SurfNum, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp, SurfOutsideEmiss, DataBSDFWindow::Condition::Invalid);
2332 8064 : state.dataWindowManager->hcout = HextConvCoeff;
2333 : // Required for report variables calculations.
2334 8064 : if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
2335 8064 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
2336 0 : state.dataWindowManager->tout = state.dataSurface->SurfOutWetBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2337 : } else { // Dry
2338 8064 : state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2339 : }
2340 : } else { // Window not exposed to wind
2341 0 : state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2342 : }
2343 :
2344 : } else { // regular window, not BSDF, not EQL Window
2345 : // Added for thermochromic windows
2346 22607285 : state.dataWindowManager->locTCFlag = (state.dataConstruction->Construct(ConstrNum).TCFlag == 1);
2347 :
2348 22607285 : if (state.dataWindowManager->locTCFlag) {
2349 4032 : locTCSpecTemp = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).TCLayer).SpecTemp;
2350 4032 : state.dataSurface->SurfWinSpecTemp(SurfNum) = locTCSpecTemp;
2351 : // Check to see whether needs to switch to a new TC window construction
2352 4032 : locTCLayerTemp = state.dataSurface->SurfWinTCLayerTemp(SurfNum);
2353 4032 : dT0 = std::abs(locTCLayerTemp - locTCSpecTemp);
2354 4032 : if (dT0 >= 1) {
2355 : // Find the TC construction that is closed to the TCLayerTemp
2356 2509 : i = 0;
2357 2509 : deltaTemp = 0.0;
2358 2509 : IDConst = 0;
2359 82797 : for (k = 1; k <= state.dataHeatBal->TotConstructs; ++k) {
2360 80288 : if (state.dataConstruction->Construct(k).TCMasterConst == state.dataConstruction->Construct(ConstrNum).TCMasterConst) {
2361 50180 : dT1 = std::abs(locTCLayerTemp - state.dataMaterial->Material(state.dataConstruction->Construct(k).TCLayer).SpecTemp);
2362 50180 : if (dT1 < dT0) {
2363 327 : ++i;
2364 327 : deltaTemp(i) = dT1;
2365 327 : IDConst(i) = k;
2366 : }
2367 : }
2368 : }
2369 2509 : if (i >= 1) {
2370 : // Find the closest item
2371 313 : iMinDT = minloc(deltaTemp, deltaTemp > 0.0);
2372 : // Use the new TC window construction
2373 313 : ConstrNum = IDConst(iMinDT(1));
2374 313 : surface.Construction = ConstrNum;
2375 313 : state.dataSurface->SurfActiveConstruction(SurfNum) = ConstrNum;
2376 313 : state.dataSurface->SurfWinSpecTemp(SurfNum) =
2377 313 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).TCLayer).SpecTemp;
2378 : }
2379 : }
2380 : }
2381 : // end new TC code
2382 :
2383 22607285 : TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers;
2384 22607285 : TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
2385 22607285 : state.dataWindowManager->ngllayer = TotGlassLay;
2386 22607285 : state.dataWindowManager->nglface = 2 * state.dataWindowManager->ngllayer;
2387 22607285 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
2388 22607285 : state.dataWindowManager->tilt = surface.Tilt;
2389 22607285 : state.dataWindowManager->tiltr = state.dataWindowManager->tilt * DataGlobalConstants::DegToRadians;
2390 22607285 : SurfNumAdj = surface.ExtBoundCond;
2391 22607285 : state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum); // Room-side surface convective film conductance
2392 22607285 : Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
2393 22607285 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = RefAirTemp;
2394 22607285 : state.dataWindowManager->tin = RefAirTemp + state.dataWindowManager->TKelvin; // Inside air temperature
2395 :
2396 : // Reset hcin if necessary since too small a value sometimes causes non-convergence
2397 : // of window layer heat balance solution.
2398 22607285 : if (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == 0) {
2399 45214570 : if (state.dataWindowManager->hcin <=
2400 22607285 : state.dataHeatBal->LowHConvLimit) { // may be redundent now, check is also in HeatBalanceConvectionCoeffs.cc
2401 : // hcin = 3.076d0 !BG this is rather high value and abrupt change. changed to set to lower limit
2402 22278 : state.dataWindowManager->hcin = state.dataHeatBal->LowHConvLimit;
2403 22278 : state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataWindowManager->hcin; // store for accurate reporting.
2404 : }
2405 : }
2406 :
2407 : // IR incident on window from zone surfaces and high-temp radiant sources
2408 22607285 : state.dataWindowManager->Rmir =
2409 22607285 : state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum);
2410 :
2411 : // Short-wave radiation (from interior and exterior solar and zone lights)
2412 : // absorbed at each face. Assumes equal split between faces of short-wave absorbed in glass layer.
2413 :
2414 51818397 : for (IGlass = 1; IGlass <= TotGlassLay; ++IGlass) {
2415 29211112 : state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 2] = state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) / 2.0;
2416 29211112 : state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 1] = state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) / 2.0;
2417 : }
2418 :
2419 : // IR from zone internal gains (lights, equipment and people) absorbed on zone-side face
2420 : // (assumes inside glass layer is opaque to IR, so no contribution to other layers)
2421 22607285 : state.dataWindowManager->AbsRadGlassFace[2 * TotGlassLay - 1] += state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum);
2422 :
2423 : // Fill the layer properties needed for the thermal calculation.
2424 : // For switchable glazing it is assumed that thermal properties, such
2425 : // as surface emissivity, are the same for the unswitched and switched state,
2426 : // so the thermal properties of the unswitched state are used.
2427 : // For windows with a blind or shade it is assumed
2428 : // that the blind or shade does not affect the thermal properties of the glazing,
2429 : // so the thermal properties of the construction without the blind or shade are used.
2430 :
2431 : // The layer and face numbering are as follows (for the triple glazing case):
2432 : // Glass layers are 1,2 and 3, where 1 is the outside (outside environment facing)
2433 : // layer and 3 is the inside (room-facing) layer;
2434 : // Faces (also called surfaces) are 1,2,3,4,5 and 6, where face 1 is the
2435 : // outside (front) face of glass layer 1, face 2 is the inside (back)
2436 : // face of glass layer 1, face 3 is the outer face of glass layer 2, face 4 is the
2437 : // inner face of glass layer 2, etc.
2438 : // Gap layers are 1 and 2, where gap layer 1 is between glass layers 1 and 2
2439 : // and gap layer 2 is between glass layers 2 and 3.
2440 : // If an exterior, interior or between-glass blind or shade is in place, 7 and 8
2441 : // are the blind/shade faces, from outside to inside. If an exterior or interior
2442 : // blind/shade is in place, gap layer 3 is between the blind/shade and adjacent
2443 : // glass layer and is assumed to be air.
2444 : // Between-glass blind/shade is modeled only for double and triple glazing.
2445 : // For double glazing, gap 1 is between glass 1 and blind/shade and gap 2 is between
2446 : // blind/shade and glass 2.
2447 : // For triple glazing, the blind/shade is assumed to be between the inner two glass
2448 : // layers, i.e., between glass layers 2 and 3. In this case gap 1 is between glass 1
2449 : // and glass 2, gap 2 is between glass 2 and blind/shade, and gap 3 is between
2450 : // blind/shade and glass 3.
2451 :
2452 22607285 : int IConst = ConstrNum;
2453 22607285 : if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) {
2454 71522 : IConst = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
2455 : }
2456 22607285 : TotLay = state.dataConstruction->Construct(IConst).TotLayers;
2457 22607285 : IGlass = 0;
2458 22607285 : IGap = 0;
2459 :
2460 : // Fill window layer properties needed for window layer heat balance calculation
2461 :
2462 58510616 : for (Lay = 1; Lay <= TotLay; ++Lay) {
2463 35903331 : LayPtr = state.dataConstruction->Construct(IConst).LayerPoint(Lay);
2464 :
2465 51395182 : if ((state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGlass) ||
2466 15491851 : (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowSimpleGlazing)) {
2467 29211112 : ++IGlass;
2468 29211112 : state.dataWindowManager->thick[IGlass - 1] = state.dataMaterial->Material(LayPtr).Thickness;
2469 29211112 : state.dataWindowManager->scon[IGlass - 1] =
2470 29211112 : state.dataMaterial->Material(LayPtr).Conductivity / state.dataMaterial->Material(LayPtr).Thickness;
2471 29211112 : state.dataWindowManager->emis[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).AbsorpThermalFront;
2472 29211112 : state.dataWindowManager->emis[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).AbsorpThermalBack;
2473 29211112 : state.dataWindowManager->tir[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).TransThermal;
2474 29211112 : state.dataWindowManager->tir[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).TransThermal;
2475 : }
2476 :
2477 107673651 : if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::Shade ||
2478 71740516 : state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowBlind ||
2479 35837185 : state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::Screen) {
2480 71522 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag))
2481 40940 : ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(state.dataConstruction->Construct(IConst).TotLayers);
2482 71522 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(1);
2483 71522 : if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
2484 16870 : ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(3);
2485 16870 : if (TotGlassLay == 3) ShadeLayPtr = state.dataConstruction->Construct(IConst).LayerPoint(5);
2486 : }
2487 71522 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
2488 : // Shade or screen on
2489 41718 : if (state.dataGlobal
2490 41718 : ->AnyEnergyManagementSystemInModel) { // check to make sure the user hasn't messed up the shade control values
2491 0 : if (state.dataMaterial->Material(ShadeLayPtr).Group == DataHeatBalance::MaterialGroup::WindowBlind) {
2492 0 : ShowSevereError(state,
2493 0 : "CalcWindowHeatBalance: ShadeFlag indicates Shade but Blind=\"" +
2494 0 : state.dataMaterial->Material(ShadeLayPtr).Name + "\" is being used.");
2495 0 : ShowContinueError(state, "This is most likely a fault of the EMS values for shading control.");
2496 0 : ShowFatalError(state, "Preceding condition terminates program.");
2497 : }
2498 : }
2499 41718 : state.dataWindowManager->thick[TotGlassLay] = state.dataMaterial->Material(ShadeLayPtr).Thickness;
2500 41718 : state.dataWindowManager->scon[TotGlassLay] =
2501 41718 : state.dataMaterial->Material(ShadeLayPtr).Conductivity / state.dataMaterial->Material(ShadeLayPtr).Thickness;
2502 41718 : if (ShadeFlag == WinShadingType::ExtScreen) {
2503 5376 : state.dataWindowManager->emis[state.dataWindowManager->nglface] =
2504 5376 : state.dataMaterial->Material(ShadeLayPtr).AbsorpThermalFront;
2505 5376 : state.dataWindowManager->tir[state.dataWindowManager->nglface] =
2506 5376 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(ShadeLayPtr).ScreenDataPtr).DifDifTrans;
2507 5376 : state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] =
2508 5376 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(ShadeLayPtr).ScreenDataPtr).DifDifTrans;
2509 : } else {
2510 36342 : state.dataWindowManager->emis[state.dataWindowManager->nglface] = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
2511 36342 : state.dataWindowManager->tir[state.dataWindowManager->nglface] = state.dataMaterial->Material(ShadeLayPtr).TransThermal;
2512 36342 : state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] =
2513 36342 : state.dataMaterial->Material(ShadeLayPtr).TransThermal;
2514 : }
2515 41718 : state.dataWindowManager->emis[state.dataWindowManager->nglface + 1] = state.dataMaterial->Material(ShadeLayPtr).AbsorpThermal;
2516 :
2517 : } else {
2518 29804 : if (state.dataGlobal
2519 29804 : ->AnyEnergyManagementSystemInModel) { // check to make sure the user hasn't messed up the shade control values
2520 32392 : if (state.dataMaterial->Material(ShadeLayPtr).Group == DataHeatBalance::MaterialGroup::Shade ||
2521 16196 : state.dataMaterial->Material(ShadeLayPtr).Group == DataHeatBalance::MaterialGroup::Screen) {
2522 0 : ShowSevereError(state,
2523 0 : "CalcWindowHeatBalance: ShadeFlag indicates Blind but Shade/Screen=\"" +
2524 0 : state.dataMaterial->Material(ShadeLayPtr).Name + "\" is being used.");
2525 0 : ShowContinueError(state, "This is most likely a fault of the EMS values for shading control.");
2526 0 : ShowFatalError(state, "Preceding condition terminates program.");
2527 : }
2528 : }
2529 : // Blind on
2530 29804 : BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
2531 29804 : state.dataWindowManager->thick[TotGlassLay] = state.dataHeatBal->Blind(BlNum).SlatThickness;
2532 29804 : state.dataWindowManager->scon[TotGlassLay] =
2533 29804 : state.dataHeatBal->Blind(BlNum).SlatConductivity / state.dataHeatBal->Blind(BlNum).SlatThickness;
2534 :
2535 29804 : if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
2536 3122 : int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
2537 3122 : Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
2538 3122 : state.dataWindowManager->emis[state.dataWindowManager->nglface] =
2539 3122 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRFrontEmiss(SurfWinSlatsAngIndex),
2540 6244 : state.dataHeatBal->Blind(BlNum).IRFrontEmiss(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
2541 : SurfWinSlatsAngInterpFac);
2542 3122 : state.dataWindowManager->emis[state.dataWindowManager->nglface + 1] =
2543 3122 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRBackEmiss(SurfWinSlatsAngIndex),
2544 6244 : state.dataHeatBal->Blind(BlNum).IRBackEmiss(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
2545 : SurfWinSlatsAngInterpFac);
2546 3122 : state.dataWindowManager->tir[state.dataWindowManager->nglface] =
2547 3122 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRFrontTrans(SurfWinSlatsAngIndex),
2548 6244 : state.dataHeatBal->Blind(BlNum).IRFrontTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
2549 : SurfWinSlatsAngInterpFac);
2550 3122 : state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] =
2551 3122 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRBackTrans(SurfWinSlatsAngIndex),
2552 6244 : state.dataHeatBal->Blind(BlNum).IRBackTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
2553 : SurfWinSlatsAngInterpFac);
2554 : } else {
2555 26682 : state.dataWindowManager->emis[state.dataWindowManager->nglface] = state.dataHeatBal->Blind(BlNum).IRFrontEmiss(1);
2556 26682 : state.dataWindowManager->emis[state.dataWindowManager->nglface + 1] = state.dataHeatBal->Blind(BlNum).IRBackEmiss(1);
2557 26682 : state.dataWindowManager->tir[state.dataWindowManager->nglface] = state.dataHeatBal->Blind(BlNum).IRFrontTrans(1);
2558 26682 : state.dataWindowManager->tir[state.dataWindowManager->nglface + 1] = state.dataHeatBal->Blind(BlNum).IRBackTrans(1);
2559 : }
2560 : }
2561 : }
2562 :
2563 65242413 : if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGas ||
2564 29339082 : state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGasMixture) {
2565 6620697 : ++IGap;
2566 6620697 : state.dataWindowManager->gap[IGap - 1] = state.dataMaterial->Material(LayPtr).Thickness;
2567 6620697 : state.dataWindowManager->gnmix[IGap - 1] = state.dataMaterial->Material(LayPtr).NumberOfGasesInMixture;
2568 13297842 : for (IMix = 1; IMix <= state.dataWindowManager->gnmix[IGap - 1]; ++IMix) {
2569 6677145 : state.dataWindowManager->gwght[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasWght(IMix);
2570 6677145 : state.dataWindowManager->gfract[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasFract(IMix);
2571 26708580 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2572 20031435 : state.dataWindowManager->gcon[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCon(ICoeff, IMix);
2573 20031435 : state.dataWindowManager->gvis[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasVis(ICoeff, IMix);
2574 20031435 : state.dataWindowManager->gcp[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCp(ICoeff, IMix);
2575 : }
2576 : }
2577 : }
2578 :
2579 : } // End of loop over glass, gap and blind/shade layers in a window construction
2580 :
2581 22607285 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) || ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
2582 : // Interior or exterior blind, shade or screen is on.
2583 : // Fill gap between blind/shade and adjacent glass with air properties.
2584 54652 : ++IGap;
2585 54652 : if (ShadeFlag == WinShadingType::IntShade || ShadeFlag == WinShadingType::ExtShade ||
2586 : ShadeFlag == WinShadingType::ExtScreen) { // Interior or exterior shade
2587 33654 : state.dataWindowManager->gap[IGap - 1] = state.dataMaterial->Material(ShadeLayPtr).WinShadeToGlassDist;
2588 : } else { // Interior or exterior blind
2589 20998 : state.dataWindowManager->gap[IGap - 1] =
2590 20998 : state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).BlindToGlassDist;
2591 : }
2592 54652 : state.dataWindowManager->gnmix[IGap - 1] = 1;
2593 54652 : state.dataWindowManager->gwght[0][IGap - 1] = GasWght[0];
2594 218608 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2595 163956 : state.dataWindowManager->gcon[ICoeff - 1][0][IGap - 1] = GasCoeffsCon[ICoeff - 1][0];
2596 163956 : state.dataWindowManager->gvis[ICoeff - 1][0][IGap - 1] = GasCoeffsVis[ICoeff - 1][0];
2597 163956 : state.dataWindowManager->gcp[ICoeff - 1][0][IGap - 1] = GasCoeffsCp[ICoeff - 1][0];
2598 : }
2599 : }
2600 :
2601 : // Exterior convection coefficient, exterior air temperature and IR radiance
2602 : // of exterior surround. Depend on whether window is interzone (in an interzone
2603 : // wall or exterior (in an exterior wall).
2604 :
2605 22607285 : state.dataWindowManager->hcout = HextConvCoeff; // Exterior convection coefficient is passed in from outer routine
2606 : // tsky = SkyTemp + TKelvin
2607 :
2608 22607285 : if (SurfNumAdj > 0) { // Interzone window
2609 :
2610 27072 : ZoneNumAdj = state.dataSurface->Surface(SurfNumAdj).Zone;
2611 27072 : Real64 RefAirTemp = state.dataSurface->Surface(SurfNumAdj).getInsideAirTemperature(state, SurfNumAdj);
2612 27072 : state.dataHeatBal->SurfTempEffBulkAir(SurfNumAdj) = RefAirTemp;
2613 27072 : state.dataWindowManager->tout = RefAirTemp + state.dataWindowManager->TKelvin; // outside air temperature
2614 :
2615 : // Add long-wave radiation from adjacent zone absorbed by glass layer closest to the adjacent zone.
2616 27072 : state.dataWindowManager->AbsRadGlassFace[0] += state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNumAdj);
2617 :
2618 : // The IR radiance of this window's "exterior" surround is the IR radiance
2619 : // from surfaces and high-temp radiant sources in the adjacent zone
2620 :
2621 27072 : state.dataWindowManager->Outir =
2622 27072 : state.dataSurface->SurfWinIRfromParentZone(SurfNumAdj) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNumAdj);
2623 :
2624 : } else { // Exterior window (Ext BoundCond = 0)
2625 : // Calculate LWR from surrounding surfaces if defined for an exterior window
2626 22580213 : OutSrdIR = 0;
2627 22580213 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
2628 133056 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
2629 2688 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
2630 2688 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
2631 8064 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
2632 5376 : SrdSurfViewFac = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
2633 5376 : SrdSurfTempAbs = GetCurrentScheduleValue(state, SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).TempSchNum) +
2634 : DataGlobalConstants::KelvinConv;
2635 5376 : OutSrdIR += state.dataWindowManager->sigma * SrdSurfViewFac * pow_4(SrdSurfTempAbs);
2636 : }
2637 : }
2638 : }
2639 22580213 : if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
2640 22580213 : if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
2641 4686 : state.dataWindowManager->tout = state.dataSurface->SurfOutWetBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2642 : } else { // Dry
2643 22575527 : state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2644 : }
2645 : } else { // Window not exposed to wind
2646 0 : state.dataWindowManager->tout = state.dataSurface->SurfOutDryBulbTemp(SurfNum) + state.dataWindowManager->TKelvin;
2647 : }
2648 22580213 : state.dataWindowManager->Ebout = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tout);
2649 22580213 : state.dataWindowManager->Outir =
2650 45160426 : surface.ViewFactorSkyIR *
2651 67740639 : (state.dataSurface->SurfAirSkyRadSplit(SurfNum) * state.dataWindowManager->sigma * pow_4(state.dataEnvrn->SkyTempKelvin) +
2652 45160426 : (1.0 - state.dataSurface->SurfAirSkyRadSplit(SurfNum)) * state.dataWindowManager->Ebout) +
2653 45160426 : surface.ViewFactorGroundIR * state.dataWindowManager->Ebout + OutSrdIR;
2654 : }
2655 :
2656 : // Factors used in window layer temperature solution
2657 22607285 : if (state.dataWindowManager->ngllayer >= 2) {
2658 6460787 : state.dataWindowManager->A23P =
2659 6460787 : -state.dataWindowManager->emis[2] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
2660 6460787 : state.dataWindowManager->A32P =
2661 6460787 : state.dataWindowManager->emis[1] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
2662 6460787 : state.dataWindowManager->A23 = state.dataWindowManager->emis[1] * state.dataWindowManager->sigma * state.dataWindowManager->A23P;
2663 : }
2664 :
2665 22607285 : if (state.dataWindowManager->ngllayer >= 3) {
2666 92352 : state.dataWindowManager->A45P =
2667 92352 : -state.dataWindowManager->emis[4] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
2668 92352 : state.dataWindowManager->A54P =
2669 92352 : state.dataWindowManager->emis[3] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
2670 92352 : state.dataWindowManager->A45 = state.dataWindowManager->emis[3] * state.dataWindowManager->sigma * state.dataWindowManager->A45P;
2671 : }
2672 :
2673 22607285 : if (state.dataWindowManager->ngllayer == 4) {
2674 50688 : state.dataWindowManager->A67P =
2675 50688 : -state.dataWindowManager->emis[6] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
2676 50688 : state.dataWindowManager->A76P =
2677 50688 : state.dataWindowManager->emis[5] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
2678 50688 : state.dataWindowManager->A67 = state.dataWindowManager->emis[5] * state.dataWindowManager->sigma * state.dataWindowManager->A67P;
2679 : }
2680 :
2681 22607285 : state.dataWindowManager->thetas = {0.0};
2682 22607285 : state.dataWindowManager->thetasPrev = {0.0};
2683 22607285 : state.dataWindowManager->fvec = {0.0};
2684 :
2685 : // Calculate window face temperatures
2686 :
2687 22607285 : SolveForWindowTemperatures(state, SurfNum);
2688 :
2689 : // Temperature difference across glass layers (for debugging)
2690 :
2691 22607285 : dth1 = state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0];
2692 22607285 : dth2 = state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2];
2693 22607285 : dth3 = state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[4];
2694 22607285 : dth4 = state.dataWindowManager->thetas[7] - state.dataWindowManager->thetas[6];
2695 :
2696 22607285 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
2697 40940 : SurfInsideTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer + 1] - state.dataWindowManager->TKelvin;
2698 40940 : if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
2699 2569 : EffShBlEmiss =
2700 5138 : General::InterpGeneral(window.EffShBlindEmiss(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
2701 5138 : window.EffShBlindEmiss(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
2702 2569 : state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
2703 2569 : EffGlEmiss =
2704 5138 : General::InterpGeneral(window.EffGlassEmiss(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
2705 5138 : window.EffGlassEmiss(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
2706 2569 : state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
2707 : } else {
2708 38371 : EffShBlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1);
2709 38371 : EffGlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(1);
2710 : }
2711 40940 : state.dataSurface->SurfWinEffInsSurfTemp(SurfNum) =
2712 81880 : (EffShBlEmiss * SurfInsideTemp +
2713 122820 : EffGlEmiss * (state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin)) /
2714 40940 : (EffShBlEmiss + EffGlEmiss);
2715 : } else {
2716 22566345 : SurfInsideTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin;
2717 : }
2718 22607285 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
2719 13712 : SurfOutsideTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer] -
2720 13712 : state.dataWindowManager->TKelvin; // this index looks suspicious (CR 8202)
2721 : // SurfOutsideEmiss = emis(1) ! this index should be coordinated with previous line
2722 13712 : SurfOutsideEmiss = state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer]; // fix for CR 8202
2723 : } else {
2724 22593573 : SurfOutsideEmiss = state.dataWindowManager->emis[0];
2725 22593573 : SurfOutsideTemp = state.dataWindowManager->thetas[0] - state.dataWindowManager->TKelvin;
2726 : }
2727 :
2728 : // Save temperatures for use next time step
2729 :
2730 81172553 : for (k = 1; k <= state.dataWindowManager->nglfacep; ++k) {
2731 58565268 : window.ThetaFace(k) = state.dataWindowManager->thetas[k - 1];
2732 : }
2733 :
2734 : // Added TH 12/23/2008 for thermochromic windows to save the current TC layer temperature
2735 22607285 : if (state.dataWindowManager->locTCFlag) {
2736 4032 : state.dataSurface->SurfWinTCLayerTemp(SurfNum) =
2737 8064 : (state.dataWindowManager->thetas[2 * state.dataConstruction->Construct(ConstrNum).TCGlassID - 2] +
2738 8064 : state.dataWindowManager->thetas[2 * state.dataConstruction->Construct(ConstrNum).TCGlassID - 1]) /
2739 4032 : 2 -
2740 4032 : state.dataWindowManager->TKelvin; // degree C
2741 : }
2742 : } // regular window, not BSDF, not EQL
2743 :
2744 : // Set condensation flag to 1 if condensation expected to occur on the innermost glass face,
2745 : // or, for airflow windows, on either or the two glass faces in the airflow gap
2746 22653317 : if (!state.dataConstruction->Construct(surface.Construction).WindowTypeEQL) {
2747 22645253 : InsideGlassTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin;
2748 22645253 : RoomHumRat = thisZoneHB.ZoneAirHumRat;
2749 22645253 : RoomDewPoint = PsyTdpFnWPb(state, RoomHumRat, state.dataEnvrn->OutBaroPress);
2750 22645253 : state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0;
2751 22645253 : if (InsideGlassTemp < RoomDewPoint) state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1;
2752 : // If airflow window, is there condensation on either glass face of the airflow gap?
2753 22645253 : if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
2754 16128 : Tleft = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 3] - state.dataWindowManager->TKelvin;
2755 16128 : Tright = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 2] - state.dataWindowManager->TKelvin;
2756 16128 : if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
2757 16128 : if (Tleft < RoomDewPoint || Tright < RoomDewPoint) state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1;
2758 0 : } else if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Outdoor) {
2759 0 : if (Tleft < state.dataEnvrn->OutDewPointTemp || Tright < state.dataEnvrn->OutDewPointTemp)
2760 0 : state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1;
2761 : }
2762 : }
2763 :
2764 : // Do frame and divider calculation
2765 22645253 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0 || state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0)
2766 2948880 : CalcWinFrameAndDividerTemps(state,
2767 : SurfNum,
2768 589776 : state.dataWindowManager->tout,
2769 589776 : state.dataWindowManager->tin,
2770 589776 : state.dataWindowManager->hcout,
2771 589776 : state.dataWindowManager->hcin,
2772 589776 : state.dataWindowManager->Outir,
2773 : ConstrNum);
2774 22645253 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
2775 589776 : state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 0;
2776 589776 : if (state.dataSurface->SurfWinFrameTempIn(SurfNum) < RoomDewPoint) state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 1;
2777 : }
2778 22645253 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
2779 261168 : state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 0;
2780 261168 : if (state.dataSurface->SurfWinDividerTempIn(SurfNum) < RoomDewPoint)
2781 69781 : state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 1;
2782 : }
2783 : }
2784 : // update exterior environment surface heat loss reporting
2785 22653317 : Tsout = SurfOutsideTemp + state.dataWindowManager->TKelvin;
2786 22653317 : state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = -state.dataWindowManager->hcout * (Tsout - state.dataWindowManager->tout);
2787 :
2788 22653317 : Real64 const Tsout_4(pow_4(Tsout)); // Tuned To reduce pow calls and redundancies
2789 22653317 : Real64 const Tout_4(pow_4(state.dataWindowManager->tout));
2790 22653317 : Real64 const emiss_sigma_product(SurfOutsideEmiss * state.dataWindowManager->sigma);
2791 22653317 : Real64 rad_out_lw_srd_per_area = 0;
2792 :
2793 22653317 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
2794 133056 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
2795 2688 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
2796 8064 : for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface; SrdSurfNum++) {
2797 5376 : SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
2798 5376 : SrdSurfTempAbs = GetCurrentScheduleValue(
2799 5376 : state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).TempSchNum) +
2800 : DataGlobalConstants::KelvinConv;
2801 5376 : rad_out_lw_srd_per_area += -emiss_sigma_product * SrdSurfViewFac * (Tsout_4 - pow_4(SrdSurfTempAbs));
2802 : }
2803 : }
2804 : }
2805 :
2806 : Real64 const rad_out_air_per_area =
2807 22653317 : -emiss_sigma_product * (1.0 - state.dataSurface->SurfAirSkyRadSplit(SurfNum)) * surface.ViewFactorSkyIR * (Tsout_4 - Tout_4);
2808 22653317 : Real64 const rad_out_ground_per_area = -emiss_sigma_product * surface.ViewFactorGroundIR * (Tsout_4 - Tout_4);
2809 22653317 : Real64 const rad_out_sky_per_area = -emiss_sigma_product * state.dataSurface->SurfAirSkyRadSplit(SurfNum) * surface.ViewFactorSkyIR *
2810 22653317 : (Tsout_4 - pow_4(state.dataEnvrn->SkyTempKelvin));
2811 22653317 : Real64 const rad_out_per_area = rad_out_air_per_area + rad_out_sky_per_area + rad_out_ground_per_area + rad_out_lw_srd_per_area;
2812 :
2813 22653317 : state.dataHeatBalSurf->SurfHAirExt(SurfNum) = rad_out_air_per_area / (Tsout - state.dataWindowManager->tout);
2814 22653317 : state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = rad_out_lw_srd_per_area;
2815 22653317 : state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = rad_out_per_area;
2816 22653317 : }
2817 :
2818 : //****************************************************************************
2819 :
2820 0 : void WindowHeatBalanceEquations(EnergyPlusData &state, int const SurfNum) // Surface number
2821 : {
2822 :
2823 : // SUBROUTINE INFORMATION:
2824 : // AUTHOR F. Winkelmann
2825 : // DATE WRITTEN February 2000
2826 : // MODIFIED na
2827 : // RE-ENGINEERED na
2828 :
2829 : // PURPOSE OF THIS SUBROUTINE:
2830 : // Evaluates heat balance functions at each glass face.
2831 : // Also evaluates Jacobian.
2832 : // Currently limited to three glass layers.
2833 :
2834 0 : Array1D<Real64> hgap(5); // Gap gas conductance
2835 : Real64 gr; // Gap gas Grashof number
2836 : Real64 con; // Gap gas conductivity
2837 : Real64 pr; // Gap gas Prandtl number
2838 : Real64 nu; // Gap gas Nusselt number
2839 : Real64 thetas_2_3_4;
2840 : Real64 thetas_4_5_4;
2841 : Real64 thetas_6_7_4;
2842 :
2843 : // Have to zero fvec each time since LUdecompostion and LUsolution may
2844 : // add values to this array in unexpected places
2845 0 : state.dataWindowManager->fvec = {0.0};
2846 :
2847 0 : switch (state.dataWindowManager->ngllayer) {
2848 :
2849 0 : case 1: // single pane
2850 0 : state.dataWindowManager->fvec[0] =
2851 0 : state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
2852 0 : state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
2853 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
2854 0 : state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
2855 0 : state.dataWindowManager->AbsRadGlassFace[0];
2856 0 : state.dataWindowManager->fvec[1] =
2857 0 : state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] -
2858 0 : state.dataWindowManager->emis[1] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[1]) +
2859 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
2860 0 : state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[1]) +
2861 0 : state.dataWindowManager->AbsRadGlassFace[1];
2862 0 : break;
2863 0 : case 2: // double pane
2864 0 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
2865 0 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
2866 0 : hgap(1) = (con / state.dataWindowManager->gap[0] * nu) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
2867 :
2868 0 : state.dataWindowManager->fvec[0] =
2869 0 : state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
2870 0 : state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
2871 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
2872 0 : state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
2873 0 : state.dataWindowManager->AbsRadGlassFace[0];
2874 0 : thetas_2_3_4 = pow_4(state.dataWindowManager->thetas[1]) - pow_4(state.dataWindowManager->thetas[2]);
2875 0 : state.dataWindowManager->fvec[1] =
2876 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
2877 0 : hgap(1) * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[1]) + state.dataWindowManager->A23 * thetas_2_3_4 +
2878 0 : state.dataWindowManager->AbsRadGlassFace[1];
2879 0 : state.dataWindowManager->fvec[2] =
2880 0 : hgap(1) * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[2]) +
2881 0 : state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2]) -
2882 0 : state.dataWindowManager->A23 * thetas_2_3_4 + state.dataWindowManager->AbsRadGlassFace[2];
2883 0 : state.dataWindowManager->fvec[3] =
2884 0 : state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] -
2885 0 : state.dataWindowManager->emis[3] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[3]) +
2886 0 : state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[3]) +
2887 0 : state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[3]) +
2888 0 : state.dataWindowManager->AbsRadGlassFace[3];
2889 0 : break;
2890 0 : case 3: // Triple Pane
2891 0 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
2892 0 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
2893 0 : hgap(1) = con / state.dataWindowManager->gap[0] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
2894 :
2895 0 : WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
2896 0 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
2897 0 : hgap(2) = con / state.dataWindowManager->gap[1] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
2898 :
2899 0 : thetas_2_3_4 = pow_4(state.dataWindowManager->thetas[1]) - pow_4(state.dataWindowManager->thetas[2]);
2900 0 : thetas_4_5_4 = pow_4(state.dataWindowManager->thetas[3]) - pow_4(state.dataWindowManager->thetas[4]);
2901 0 : state.dataWindowManager->fvec[0] =
2902 0 : state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
2903 0 : state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
2904 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
2905 0 : state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
2906 0 : state.dataWindowManager->AbsRadGlassFace[0];
2907 0 : state.dataWindowManager->fvec[1] =
2908 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
2909 0 : hgap(1) * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[1]) + state.dataWindowManager->A23 * thetas_2_3_4 +
2910 0 : state.dataWindowManager->AbsRadGlassFace[1];
2911 0 : state.dataWindowManager->fvec[2] =
2912 0 : hgap(1) * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[2]) +
2913 0 : state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2]) -
2914 0 : state.dataWindowManager->A23 * thetas_2_3_4 + state.dataWindowManager->AbsRadGlassFace[2];
2915 0 : state.dataWindowManager->fvec[3] =
2916 0 : state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[3]) +
2917 0 : hgap(2) * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[3]) + state.dataWindowManager->A45 * thetas_4_5_4 +
2918 0 : state.dataWindowManager->AbsRadGlassFace[3];
2919 0 : state.dataWindowManager->fvec[4] =
2920 0 : hgap(2) * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[4]) +
2921 0 : state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[4]) -
2922 0 : state.dataWindowManager->A45 * thetas_4_5_4 + state.dataWindowManager->AbsRadGlassFace[4];
2923 0 : state.dataWindowManager->fvec[5] =
2924 0 : state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] -
2925 0 : state.dataWindowManager->emis[5] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[5]) +
2926 0 : state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[5]) +
2927 0 : state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[5]) +
2928 0 : state.dataWindowManager->AbsRadGlassFace[5];
2929 0 : break;
2930 0 : case 4: // Quad Pane
2931 0 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
2932 0 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
2933 0 : hgap(1) = con / state.dataWindowManager->gap[0] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
2934 :
2935 0 : WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
2936 0 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
2937 0 : hgap(2) = con / state.dataWindowManager->gap[1] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
2938 :
2939 0 : WindowGasConductance(state, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, con, pr, gr);
2940 0 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, gr, pr, nu);
2941 0 : hgap(3) = con / state.dataWindowManager->gap[2] * nu * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum);
2942 :
2943 0 : thetas_2_3_4 = pow_4(state.dataWindowManager->thetas[1]) - pow_4(state.dataWindowManager->thetas[2]);
2944 0 : thetas_4_5_4 = pow_4(state.dataWindowManager->thetas[3]) - pow_4(state.dataWindowManager->thetas[4]);
2945 0 : thetas_6_7_4 = pow_4(state.dataWindowManager->thetas[5]) - pow_4(state.dataWindowManager->thetas[6]);
2946 0 : state.dataWindowManager->fvec[0] =
2947 0 : state.dataWindowManager->Outir * state.dataWindowManager->emis[0] -
2948 0 : state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[0]) +
2949 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[0]) +
2950 0 : state.dataWindowManager->hcout * (state.dataWindowManager->tout - state.dataWindowManager->thetas[0]) +
2951 0 : state.dataWindowManager->AbsRadGlassFace[0];
2952 0 : state.dataWindowManager->fvec[1] =
2953 0 : state.dataWindowManager->scon[0] * (state.dataWindowManager->thetas[0] - state.dataWindowManager->thetas[1]) +
2954 0 : hgap(1) * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[1]) + state.dataWindowManager->A23 * thetas_2_3_4 +
2955 0 : state.dataWindowManager->AbsRadGlassFace[1];
2956 0 : state.dataWindowManager->fvec[2] =
2957 0 : hgap(1) * (state.dataWindowManager->thetas[1] - state.dataWindowManager->thetas[2]) +
2958 0 : state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[2]) -
2959 0 : state.dataWindowManager->A23 * thetas_2_3_4 + state.dataWindowManager->AbsRadGlassFace[2];
2960 0 : state.dataWindowManager->fvec[3] =
2961 0 : state.dataWindowManager->scon[1] * (state.dataWindowManager->thetas[2] - state.dataWindowManager->thetas[3]) +
2962 0 : hgap(2) * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[3]) + state.dataWindowManager->A45 * thetas_4_5_4 +
2963 0 : state.dataWindowManager->AbsRadGlassFace[3];
2964 0 : state.dataWindowManager->fvec[4] =
2965 0 : hgap(2) * (state.dataWindowManager->thetas[3] - state.dataWindowManager->thetas[4]) +
2966 0 : state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[4]) -
2967 0 : state.dataWindowManager->A45 * thetas_4_5_4 + state.dataWindowManager->AbsRadGlassFace[4];
2968 0 : state.dataWindowManager->fvec[5] =
2969 0 : state.dataWindowManager->scon[2] * (state.dataWindowManager->thetas[4] - state.dataWindowManager->thetas[5]) +
2970 0 : hgap(3) * (state.dataWindowManager->thetas[6] - state.dataWindowManager->thetas[5]) + state.dataWindowManager->A67 * thetas_6_7_4 +
2971 0 : state.dataWindowManager->AbsRadGlassFace[5];
2972 0 : state.dataWindowManager->fvec[6] =
2973 0 : hgap(3) * (state.dataWindowManager->thetas[5] - state.dataWindowManager->thetas[6]) +
2974 0 : state.dataWindowManager->scon[3] * (state.dataWindowManager->thetas[7] - state.dataWindowManager->thetas[6]) -
2975 0 : state.dataWindowManager->A67 * thetas_6_7_4 + state.dataWindowManager->AbsRadGlassFace[6];
2976 0 : state.dataWindowManager->fvec[7] =
2977 0 : state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] -
2978 0 : state.dataWindowManager->emis[7] * state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[7]) +
2979 0 : state.dataWindowManager->scon[3] * (state.dataWindowManager->thetas[6] - state.dataWindowManager->thetas[7]) +
2980 0 : state.dataWindowManager->hcin * (state.dataWindowManager->tin - state.dataWindowManager->thetas[7]) +
2981 0 : state.dataWindowManager->AbsRadGlassFace[7];
2982 0 : break;
2983 : }
2984 0 : }
2985 :
2986 : //****************************************************************************
2987 :
2988 14952 : void GetHeatBalanceEqCoefMatrixSimple(EnergyPlusData &state,
2989 : int const nglasslayer, // Number of glass layers
2990 : Array1D<Real64> const &hr, // Radiative conductance (W/m2-K)
2991 : Array1A<Real64> &hgap, // Gap gas conductive conductance (W/m2-K)
2992 : Array2D<Real64> &Aface, // Coefficient in equation Aface*thetas = Bface
2993 : Array1D<Real64> &Bface // Coefficient in equation Aface*thetas = Bface
2994 : )
2995 : {
2996 : Real64 gr; // Grashof number of gas in a gap
2997 : Real64 con; // Gap gas conductivity
2998 : Real64 pr; // Gap gas Prandtl number
2999 : Real64 nu; // Gap gas Nusselt number
3000 :
3001 14952 : if (nglasslayer == 1) {
3002 23781 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3003 15854 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3004 23781 : Bface(2) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] +
3005 15854 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[1];
3006 :
3007 7927 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3008 7927 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3009 7927 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3010 7927 : Aface(2, 2) = hr(2) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcin;
3011 :
3012 7025 : } else if (nglasslayer == 2) {
3013 5907 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
3014 5907 : NusseltNumber(state, 0, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
3015 5907 : hgap(1) = con / state.dataWindowManager->gap[0] * nu;
3016 :
3017 17721 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3018 11814 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3019 5907 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
3020 5907 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
3021 17721 : Bface(4) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] +
3022 11814 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[3];
3023 :
3024 5907 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3025 5907 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3026 :
3027 5907 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3028 5907 : Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
3029 5907 : Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
3030 :
3031 5907 : Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
3032 5907 : Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3033 5907 : Aface(4, 3) = -state.dataWindowManager->scon[1];
3034 :
3035 5907 : Aface(3, 4) = -state.dataWindowManager->scon[1];
3036 5907 : Aface(4, 4) = hr(4) + state.dataWindowManager->scon[1] + state.dataWindowManager->hcin;
3037 :
3038 1118 : } else if (nglasslayer == 3) {
3039 1037 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
3040 1037 : NusseltNumber(state, 0, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
3041 1037 : hgap(1) = con / state.dataWindowManager->gap[0] * nu;
3042 :
3043 1037 : WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
3044 1037 : NusseltNumber(state, 0, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
3045 1037 : hgap(2) = con / state.dataWindowManager->gap[1] * nu;
3046 :
3047 3111 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3048 2074 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3049 1037 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
3050 1037 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
3051 1037 : Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
3052 1037 : Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
3053 3111 : Bface(6) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] +
3054 2074 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[5];
3055 :
3056 1037 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3057 1037 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3058 :
3059 1037 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3060 1037 : Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
3061 1037 : Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
3062 :
3063 1037 : Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
3064 1037 : Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3065 1037 : Aface(4, 3) = -state.dataWindowManager->scon[1];
3066 :
3067 1037 : Aface(3, 4) = -state.dataWindowManager->scon[1];
3068 1037 : Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
3069 1037 : Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
3070 :
3071 1037 : Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
3072 1037 : Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
3073 1037 : Aface(6, 5) = -state.dataWindowManager->scon[2];
3074 :
3075 1037 : Aface(5, 6) = -state.dataWindowManager->scon[2];
3076 1037 : Aface(6, 6) = hr(6) + state.dataWindowManager->scon[2] + state.dataWindowManager->hcin;
3077 :
3078 81 : } else if (nglasslayer == 4) {
3079 81 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
3080 81 : NusseltNumber(state, 0, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
3081 81 : hgap(1) = con / state.dataWindowManager->gap[0] * nu;
3082 :
3083 81 : WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
3084 81 : NusseltNumber(state, 0, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
3085 81 : hgap(2) = con / state.dataWindowManager->gap[1] * nu;
3086 :
3087 81 : WindowGasConductance(state, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, con, pr, gr);
3088 81 : NusseltNumber(state, 0, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, gr, pr, nu);
3089 81 : hgap(3) = con / state.dataWindowManager->gap[2] * nu;
3090 :
3091 243 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3092 162 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3093 81 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
3094 81 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
3095 81 : Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
3096 81 : Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
3097 81 : Bface(6) = state.dataWindowManager->AbsRadGlassFace[5];
3098 81 : Bface(7) = state.dataWindowManager->AbsRadGlassFace[6];
3099 243 : Bface(8) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] +
3100 162 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[7];
3101 :
3102 81 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3103 81 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3104 :
3105 81 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3106 81 : Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
3107 81 : Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
3108 :
3109 81 : Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
3110 81 : Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3111 81 : Aface(4, 3) = -state.dataWindowManager->scon[1];
3112 :
3113 81 : Aface(3, 4) = -state.dataWindowManager->scon[1];
3114 81 : Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
3115 81 : Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
3116 :
3117 81 : Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
3118 81 : Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
3119 81 : Aface(6, 5) = -state.dataWindowManager->scon[2];
3120 :
3121 81 : Aface(5, 6) = -state.dataWindowManager->scon[2];
3122 81 : Aface(6, 6) = state.dataWindowManager->scon[2] + hgap(3) - state.dataWindowManager->A67P * hr(6);
3123 81 : Aface(7, 6) = -hgap(3) - state.dataWindowManager->A76P * hr(7);
3124 :
3125 81 : Aface(6, 7) = -hgap(3) + state.dataWindowManager->A67P * hr(6);
3126 81 : Aface(7, 7) = hgap(3) + state.dataWindowManager->scon[3] + state.dataWindowManager->A76P * hr(7);
3127 81 : Aface(8, 7) = -state.dataWindowManager->scon[3];
3128 :
3129 81 : Aface(7, 8) = -state.dataWindowManager->scon[3];
3130 81 : Aface(8, 8) = hr(8) + state.dataWindowManager->scon[3] + state.dataWindowManager->hcin;
3131 : }
3132 14952 : }
3133 :
3134 42038057 : void GetHeatBalanceEqCoefMatrix(EnergyPlusData &state,
3135 : int const SurfNum,
3136 : int const nglasslayer,
3137 : WinShadingType const ShadeFlag,
3138 : Real64 const sconsh,
3139 : Real64 const TauShIR,
3140 : Real64 const EpsShIR1,
3141 : Real64 const EpsShIR2,
3142 : Real64 const RhoShIR1,
3143 : Real64 const RhoShIR2,
3144 : Real64 const ShGlReflFacIR,
3145 : Real64 const RhoGlIR1,
3146 : Real64 const RhoGlIR2,
3147 : Real64 const hcv, // Convection coefficient from gap glass or shade/blind to gap air (W/m2-K)
3148 : Real64 const TGapNew, // Current-iteration average air temp in airflow gap (K)
3149 : Real64 const TAirflowGapNew, // Average air temp in airflow gap between glass panes (K)
3150 : Real64 const hcvAirflowGap, // Convection coefficient from airflow gap glass to airflow gap air (W/m2-K)
3151 : Array1A<Real64> const &hcvBG, // Convection coefficient from gap glass or shade to gap gas (W/m2-K)
3152 : Array1A<Real64> const &TGapNewBG,
3153 : Array1A<Real64> const &AbsRadShadeFace,
3154 : Array1D<Real64> const &hr,
3155 : Array2D<Real64> &Aface,
3156 : Array1D<Real64> &Bface)
3157 : {
3158 42038057 : auto &hgap = state.dataWindowManager->hgap;
3159 42038057 : auto &RhoIR = state.dataWindowManager->RhoIR;
3160 :
3161 : Real64 gr; // Grashof number of gas in a gap
3162 : Real64 con; // Gap gas conductivity
3163 : Real64 pr; // Gap gas Prandtl number
3164 : Real64 nu; // Gap gas Nusselt number
3165 :
3166 : Real64 FacRhoIR25; // Intermediate variable
3167 : Real64 FacRhoIR63; // Intermediate variable
3168 : Real64 RhoIRfp; // Intermediate variable
3169 : Real64 RhoIRbp; // Intermediate variable
3170 : Real64 FacRhoIR2fp; // Intermediate variable
3171 : Real64 FacRhoIR3bp; // Intermediate variable
3172 : Real64 FacRhoIR2fpRhoIR63; // Intermediate variable
3173 : Real64 FacRhoIR3bpRhoIR25; // Intermediate variable
3174 : Real64 FacRhoIR47; // Intermediate variable
3175 : Real64 FacRhoIR85; // Intermediate variable
3176 : Real64 FacRhoIR4fp; // Intermediate variable
3177 : Real64 FacRhoIR5bp; // Intermediate variable
3178 : Real64 FacRhoIR4fpRhoIR85; // Intermediate variable
3179 : Real64 FacRhoIR5bpRhoIR47; // Intermediate variable
3180 :
3181 : int i; // Counter
3182 :
3183 42038057 : if (nglasslayer == 1) {
3184 87014145 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3185 58009430 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3186 87014145 : Bface(2) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] +
3187 58009430 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[1];
3188 :
3189 29004715 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3190 29004715 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3191 29004715 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3192 29004715 : Aface(2, 2) = hr(2) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcin;
3193 :
3194 29004715 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3195 : // interior shade, single pane
3196 : // || ||
3197 : // outside 1||2 3||4
3198 : // || ||
3199 : // gl bl/sh/sc
3200 221096 : Bface(2) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[1] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3201 110548 : state.dataWindowManager->AbsRadGlassFace[1];
3202 110548 : Bface(3) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
3203 110548 : Bface(4) =
3204 110548 : state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
3205 :
3206 110548 : Aface(2, 2) = hr(2) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
3207 110548 : Aface(3, 2) = -state.dataWindowManager->emis[1] * hr(3) / ShGlReflFacIR;
3208 110548 : Aface(2, 3) = -hr(2) * EpsShIR1 / ShGlReflFacIR;
3209 110548 : Aface(3, 3) = hr(3) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
3210 110548 : Aface(4, 3) = -sconsh;
3211 110548 : Aface(3, 4) = -sconsh;
3212 110548 : Aface(4, 4) = hr(4) + sconsh + state.dataWindowManager->hcin;
3213 : }
3214 :
3215 29004715 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3216 : // exterior shade, single pane
3217 : // || ||
3218 : // outside 3||4 1||2
3219 : // || ||
3220 : // bl/sh/sc gl
3221 144502 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3222 72251 : state.dataWindowManager->AbsRadGlassFace[0];
3223 72251 : Bface(3) =
3224 72251 : state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
3225 72251 : Bface(4) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
3226 :
3227 72251 : Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
3228 72251 : Aface(4, 1) = -state.dataWindowManager->emis[0] * hr(4) / ShGlReflFacIR;
3229 72251 : Aface(3, 3) = hr(3) + sconsh + state.dataWindowManager->hcout;
3230 72251 : Aface(4, 3) = -sconsh;
3231 72251 : Aface(1, 4) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
3232 72251 : Aface(3, 4) = -sconsh;
3233 72251 : Aface(4, 4) = hr(4) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
3234 : }
3235 :
3236 13033342 : } else if (nglasslayer == 2) {
3237 12803273 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
3238 12803273 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
3239 12803273 : hgap(1) = con / state.dataWindowManager->gap[0] * nu;
3240 12803273 : if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
3241 1325129 : state.dataWindowManager->hrgap[0] =
3242 1325129 : 0.5 * std::abs(state.dataWindowManager->A23) * pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
3243 2650258 : hgap(1) = hgap(1) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
3244 1325129 : state.dataWindowManager->hrgap[0] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
3245 : }
3246 :
3247 38409819 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3248 25606546 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3249 12803273 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
3250 12803273 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
3251 38409819 : Bface(4) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] +
3252 25606546 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[3];
3253 :
3254 12803273 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3255 12803273 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3256 :
3257 12803273 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3258 12803273 : Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
3259 12803273 : Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
3260 :
3261 12803273 : Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
3262 12803273 : Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3263 12803273 : Aface(4, 3) = -state.dataWindowManager->scon[1];
3264 :
3265 12803273 : Aface(3, 4) = -state.dataWindowManager->scon[1];
3266 12803273 : Aface(4, 4) = hr(4) + state.dataWindowManager->scon[1] + state.dataWindowManager->hcin;
3267 :
3268 12803273 : if (!ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
3269 8045 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1] + hcvAirflowGap * TAirflowGapNew;
3270 8045 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2] + hcvAirflowGap * TAirflowGapNew;
3271 8045 : Aface(2, 2) = state.dataWindowManager->scon[0] + hcvAirflowGap - state.dataWindowManager->A23P * hr(2);
3272 8045 : Aface(3, 2) = -state.dataWindowManager->A32P * hr(3);
3273 8045 : Aface(2, 3) = state.dataWindowManager->A23P * hr(2);
3274 8045 : Aface(3, 3) = hcvAirflowGap + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3275 : }
3276 :
3277 12803273 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3278 180098 : Bface(4) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[3] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3279 90049 : state.dataWindowManager->AbsRadGlassFace[3];
3280 90049 : Bface(5) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
3281 90049 : Bface(6) =
3282 90049 : state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
3283 :
3284 90049 : Aface(4, 4) = hr(4) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[1] + hcv;
3285 90049 : Aface(5, 4) = -state.dataWindowManager->emis[3] * hr(5) / ShGlReflFacIR;
3286 90049 : Aface(4, 5) = -hr(4) * EpsShIR1 / ShGlReflFacIR;
3287 90049 : Aface(5, 5) = hr(5) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
3288 90049 : Aface(6, 5) = -sconsh;
3289 90049 : Aface(5, 6) = -sconsh;
3290 90049 : Aface(6, 6) = hr(6) + sconsh + state.dataWindowManager->hcin;
3291 : }
3292 :
3293 12803273 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3294 117896 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3295 58948 : state.dataWindowManager->AbsRadGlassFace[0];
3296 58948 : Bface(5) =
3297 58948 : state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
3298 58948 : Bface(6) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
3299 :
3300 58948 : Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
3301 58948 : Aface(6, 1) = -state.dataWindowManager->emis[0] * hr(6) / ShGlReflFacIR;
3302 58948 : Aface(5, 5) = hr(5) + sconsh + state.dataWindowManager->hcout;
3303 58948 : Aface(6, 5) = -sconsh;
3304 58948 : Aface(1, 6) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
3305 58948 : Aface(5, 6) = -sconsh;
3306 58948 : Aface(6, 6) = hr(6) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
3307 : }
3308 :
3309 12803273 : if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3310 427238 : for (i = 1; i <= 6; ++i) {
3311 366204 : RhoIR(i) = max(0.0, 1.0 - state.dataWindowManager->tir[i - 1] - state.dataWindowManager->emis[i - 1]);
3312 : }
3313 61034 : FacRhoIR25 = 1.0 - RhoIR(2) * RhoIR(5);
3314 61034 : FacRhoIR63 = 1.0 - RhoIR(6) * RhoIR(3);
3315 61034 : Real64 const tir_5_squared(pow_2(state.dataWindowManager->tir[4]));
3316 61034 : RhoIRfp = RhoIR(5) + tir_5_squared * RhoIR(3) / FacRhoIR63;
3317 61034 : RhoIRbp = RhoIR(6) + tir_5_squared * RhoIR(2) / FacRhoIR25;
3318 61034 : FacRhoIR2fp = 1.0 - RhoIRfp * RhoIR(2);
3319 61034 : FacRhoIR3bp = 1.0 - RhoIRbp * RhoIR(3);
3320 61034 : FacRhoIR2fpRhoIR63 = FacRhoIR2fp * FacRhoIR63;
3321 61034 : FacRhoIR3bpRhoIR25 = FacRhoIR3bp * FacRhoIR25;
3322 61034 : Aface(2, 2) =
3323 61034 : state.dataWindowManager->scon[0] + hcvBG(1) + hr(2) * (1 - RhoIRfp * (state.dataWindowManager->emis[1] + RhoIR(2))) / FacRhoIR2fp;
3324 61034 : Aface(3, 2) = -state.dataWindowManager->emis[1] * hr(3) * state.dataWindowManager->tir[4] / FacRhoIR2fpRhoIR63;
3325 61034 : Aface(5, 2) = -state.dataWindowManager->emis[1] * hr(5) / FacRhoIR2fp;
3326 61034 : Aface(6, 2) = -state.dataWindowManager->emis[1] * hr(6) * RhoIR(3) * state.dataWindowManager->tir[4] / FacRhoIR2fpRhoIR63;
3327 61034 : Bface(2) = hcvBG(1) * TGapNewBG(1) + state.dataWindowManager->AbsRadGlassFace[1];
3328 61034 : Aface(2, 3) = -state.dataWindowManager->emis[2] * hr(2) * state.dataWindowManager->tir[4] / FacRhoIR3bpRhoIR25;
3329 61034 : Aface(3, 3) =
3330 61034 : state.dataWindowManager->scon[1] + hcvBG(2) + hr(3) * (1 - RhoIRbp * (state.dataWindowManager->emis[2] + RhoIR(3))) / FacRhoIR3bp;
3331 61034 : Aface(5, 3) = -state.dataWindowManager->emis[2] * hr(5) * RhoIR(2) * state.dataWindowManager->tir[4] / FacRhoIR3bpRhoIR25;
3332 61034 : Aface(6, 3) = -state.dataWindowManager->emis[2] * hr(6) / FacRhoIR3bp;
3333 61034 : Bface(3) = hcvBG(2) * TGapNewBG(2) + state.dataWindowManager->AbsRadGlassFace[2];
3334 61034 : Aface(2, 5) = -state.dataWindowManager->emis[4] * hr(2) / FacRhoIR2fp;
3335 61034 : Aface(3, 5) = -hr(3) * state.dataWindowManager->tir[4] * RhoIR(2) * state.dataWindowManager->emis[4] / FacRhoIR2fpRhoIR63;
3336 61034 : Aface(5, 5) = sconsh + hcvBG(1) + hr(5) * (1 - RhoIR(2) * state.dataWindowManager->emis[4] / FacRhoIR2fp);
3337 61034 : Aface(6, 5) =
3338 61034 : -sconsh - hr(6) * RhoIR(2) * state.dataWindowManager->tir[4] * RhoIR(3) * state.dataWindowManager->emis[4] / FacRhoIR2fpRhoIR63;
3339 61034 : Bface(5) = hcvBG(1) * TGapNewBG(1) + AbsRadShadeFace(1);
3340 61034 : Aface(2, 6) = -hr(2) * state.dataWindowManager->tir[4] * RhoIR(3) * state.dataWindowManager->emis[5] / FacRhoIR3bpRhoIR25;
3341 61034 : Aface(3, 6) = -state.dataWindowManager->emis[5] * hr(3) / FacRhoIR3bp;
3342 61034 : Aface(5, 6) =
3343 61034 : -sconsh - hr(5) * RhoIR(3) * state.dataWindowManager->tir[4] * RhoIR(2) * state.dataWindowManager->emis[5] / FacRhoIR3bpRhoIR25;
3344 61034 : Aface(6, 6) = sconsh + hcvBG(2) + hr(6) * (1 - RhoIR(3) * state.dataWindowManager->emis[5] / FacRhoIR3bp);
3345 61034 : Bface(6) = hcvBG(2) * TGapNewBG(2) + AbsRadShadeFace(2);
3346 : }
3347 :
3348 230069 : } else if (nglasslayer == 3) {
3349 123781 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
3350 123781 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
3351 123781 : hgap(1) = con / state.dataWindowManager->gap[0] * nu;
3352 123781 : if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
3353 15026 : state.dataWindowManager->hrgap[0] =
3354 15026 : 0.5 * std::abs(state.dataWindowManager->A23) * pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
3355 30052 : hgap(1) = hgap(1) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
3356 15026 : state.dataWindowManager->hrgap[0] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
3357 : }
3358 :
3359 123781 : WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
3360 123781 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
3361 123781 : hgap(2) = con / state.dataWindowManager->gap[1] * nu;
3362 123781 : if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
3363 15026 : state.dataWindowManager->hrgap[1] =
3364 15026 : 0.5 * std::abs(state.dataWindowManager->A45) * pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
3365 30052 : hgap(2) = hgap(2) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
3366 15026 : state.dataWindowManager->hrgap[1] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
3367 : }
3368 :
3369 371343 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3370 247562 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3371 123781 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
3372 123781 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
3373 123781 : Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
3374 123781 : Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
3375 371343 : Bface(6) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] +
3376 247562 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[5];
3377 :
3378 123781 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3379 123781 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3380 :
3381 123781 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3382 123781 : Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
3383 123781 : Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
3384 :
3385 123781 : Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
3386 123781 : Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3387 123781 : Aface(4, 3) = -state.dataWindowManager->scon[1];
3388 :
3389 123781 : Aface(3, 4) = -state.dataWindowManager->scon[1];
3390 123781 : Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
3391 123781 : Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
3392 :
3393 123781 : Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
3394 123781 : Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
3395 123781 : Aface(6, 5) = -state.dataWindowManager->scon[2];
3396 :
3397 123781 : Aface(5, 6) = -state.dataWindowManager->scon[2];
3398 123781 : Aface(6, 6) = hr(6) + state.dataWindowManager->scon[2] + state.dataWindowManager->hcin;
3399 :
3400 123781 : if (!ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
3401 8377 : Bface(4) = state.dataWindowManager->AbsRadGlassFace[3] + hcvAirflowGap * TAirflowGapNew;
3402 8377 : Bface(5) = state.dataWindowManager->AbsRadGlassFace[4] + hcvAirflowGap * TAirflowGapNew;
3403 8377 : Aface(4, 4) = state.dataWindowManager->scon[1] + hcvAirflowGap - state.dataWindowManager->A45P * hr(4);
3404 8377 : Aface(5, 4) = -state.dataWindowManager->A54P * hr(5);
3405 8377 : Aface(4, 5) = state.dataWindowManager->A45P * hr(4);
3406 8377 : Aface(5, 5) = hcvAirflowGap + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
3407 : }
3408 :
3409 123781 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3410 13120 : Bface(6) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[5] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3411 6560 : state.dataWindowManager->AbsRadGlassFace[5];
3412 6560 : Bface(7) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
3413 6560 : Bface(8) =
3414 6560 : state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
3415 :
3416 6560 : Aface(6, 6) = hr(6) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[2] + hcv;
3417 6560 : Aface(7, 6) = -state.dataWindowManager->emis[5] * hr(7) / ShGlReflFacIR;
3418 6560 : Aface(6, 7) = -hr(6) * EpsShIR1 / ShGlReflFacIR;
3419 6560 : Aface(7, 7) = hr(7) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
3420 6560 : Aface(8, 7) = -sconsh;
3421 6560 : Aface(7, 8) = -sconsh;
3422 6560 : Aface(8, 8) = hr(8) + sconsh + state.dataWindowManager->hcin;
3423 117221 : } else if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3424 0 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3425 0 : state.dataWindowManager->AbsRadGlassFace[0];
3426 0 : Bface(7) =
3427 0 : state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
3428 0 : Bface(8) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
3429 :
3430 0 : Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
3431 0 : Aface(8, 1) = -state.dataWindowManager->emis[0] * hr(8) / ShGlReflFacIR;
3432 0 : Aface(7, 7) = hr(7) + sconsh + state.dataWindowManager->hcout;
3433 0 : Aface(8, 7) = -sconsh;
3434 0 : Aface(1, 8) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
3435 0 : Aface(7, 8) = -sconsh;
3436 0 : Aface(8, 8) = hr(8) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
3437 117221 : } else if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3438 426726 : for (i = 1; i <= 8; ++i) {
3439 379312 : RhoIR(i) = max(0.0, 1.0 - state.dataWindowManager->tir[i - 1] - state.dataWindowManager->emis[i - 1]);
3440 : }
3441 47414 : FacRhoIR47 = 1 - RhoIR(4) * RhoIR(7);
3442 47414 : FacRhoIR85 = 1 - RhoIR(8) * RhoIR(5);
3443 47414 : Real64 const tir_7_squared(pow_2(state.dataWindowManager->tir[6]));
3444 47414 : RhoIRfp = RhoIR(7) + tir_7_squared * RhoIR(5) / FacRhoIR85;
3445 47414 : RhoIRbp = RhoIR(8) + tir_7_squared * RhoIR(4) / FacRhoIR47;
3446 47414 : FacRhoIR4fp = 1 - RhoIRfp * RhoIR(4);
3447 47414 : FacRhoIR5bp = 1 - RhoIRbp * RhoIR(5);
3448 47414 : FacRhoIR4fpRhoIR85 = FacRhoIR4fp * FacRhoIR85;
3449 47414 : FacRhoIR5bpRhoIR47 = FacRhoIR5bp * FacRhoIR47;
3450 47414 : Aface(4, 4) =
3451 47414 : state.dataWindowManager->scon[1] + hcvBG(1) + hr(4) * (1 - RhoIRfp * (state.dataWindowManager->emis[3] + RhoIR(4))) / FacRhoIR4fp;
3452 47414 : Aface(5, 4) = -state.dataWindowManager->emis[3] * hr(5) * state.dataWindowManager->tir[6] / FacRhoIR4fpRhoIR85;
3453 47414 : Aface(7, 4) = -state.dataWindowManager->emis[3] * hr(7) / FacRhoIR4fp;
3454 47414 : Aface(8, 4) = -state.dataWindowManager->emis[3] * hr(8) * RhoIR(5) * state.dataWindowManager->tir[6] / FacRhoIR4fpRhoIR85;
3455 47414 : Bface(4) = hcvBG(1) * TGapNewBG(1) + state.dataWindowManager->AbsRadGlassFace[3];
3456 47414 : Aface(4, 5) = -state.dataWindowManager->emis[4] * hr(4) * state.dataWindowManager->tir[6] / FacRhoIR5bpRhoIR47;
3457 47414 : Aface(5, 5) =
3458 47414 : state.dataWindowManager->scon[2] + hcvBG(2) + hr(5) * (1 - RhoIRbp * (state.dataWindowManager->emis[4] + RhoIR(5))) / FacRhoIR5bp;
3459 47414 : Aface(7, 5) = -state.dataWindowManager->emis[4] * hr(7) * RhoIR(4) * state.dataWindowManager->tir[6] / FacRhoIR5bpRhoIR47;
3460 47414 : Aface(8, 5) = -state.dataWindowManager->emis[4] * hr(8) / FacRhoIR5bp;
3461 47414 : Bface(5) = hcvBG(2) * TGapNewBG(2) + state.dataWindowManager->AbsRadGlassFace[4];
3462 47414 : Aface(4, 7) = -state.dataWindowManager->emis[6] * hr(4) / FacRhoIR4fp;
3463 47414 : Aface(5, 7) = -hr(5) * state.dataWindowManager->tir[6] * RhoIR(4) * state.dataWindowManager->emis[6] / FacRhoIR4fpRhoIR85;
3464 47414 : Aface(7, 7) = sconsh + hcvBG(1) + hr(7) * (1 - RhoIR(4) * state.dataWindowManager->emis[6] / FacRhoIR4fp);
3465 47414 : Aface(8, 7) =
3466 47414 : -sconsh - hr(8) * RhoIR(4) * state.dataWindowManager->tir[6] * RhoIR(5) * state.dataWindowManager->emis[6] / FacRhoIR4fpRhoIR85;
3467 47414 : Bface(7) = hcvBG(1) * TGapNewBG(1) + AbsRadShadeFace(1);
3468 47414 : Aface(4, 8) = -hr(4) * state.dataWindowManager->tir[6] * RhoIR(5) * state.dataWindowManager->emis[7] / FacRhoIR5bpRhoIR47;
3469 47414 : Aface(5, 8) = -state.dataWindowManager->emis[7] * hr(5) / FacRhoIR5bp;
3470 47414 : Aface(7, 8) =
3471 47414 : -sconsh - hr(7) * RhoIR(5) * state.dataWindowManager->tir[6] * RhoIR(4) * state.dataWindowManager->emis[7] / FacRhoIR5bpRhoIR47;
3472 47414 : Aface(8, 8) = sconsh + hcvBG(2) + hr(8) * (1 - RhoIR(5) * state.dataWindowManager->emis[7] / FacRhoIR5bp);
3473 47414 : Bface(8) = hcvBG(2) * TGapNewBG(2) + AbsRadShadeFace(2);
3474 : }
3475 :
3476 106288 : } else if (nglasslayer == 4) {
3477 106288 : WindowGasConductance(state, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, con, pr, gr);
3478 106288 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[1], state.dataWindowManager->thetas[2], 1, gr, pr, nu);
3479 106288 : hgap(1) = con / state.dataWindowManager->gap[0] * nu;
3480 106288 : if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
3481 0 : state.dataWindowManager->hrgap[0] =
3482 0 : 0.5 * std::abs(state.dataWindowManager->A23) * pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
3483 0 : hgap(1) = hgap(1) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
3484 0 : state.dataWindowManager->hrgap[0] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
3485 : }
3486 :
3487 106288 : WindowGasConductance(state, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, con, pr, gr);
3488 106288 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[3], state.dataWindowManager->thetas[4], 2, gr, pr, nu);
3489 106288 : hgap(2) = con / state.dataWindowManager->gap[1] * nu;
3490 106288 : if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
3491 0 : state.dataWindowManager->hrgap[1] =
3492 0 : 0.5 * std::abs(state.dataWindowManager->A45) * pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
3493 0 : hgap(2) = hgap(2) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
3494 0 : state.dataWindowManager->hrgap[1] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
3495 : }
3496 :
3497 106288 : WindowGasConductance(state, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, con, pr, gr);
3498 106288 : NusseltNumber(state, SurfNum, state.dataWindowManager->thetas[5], state.dataWindowManager->thetas[6], 3, gr, pr, nu);
3499 106288 : hgap(3) = con / state.dataWindowManager->gap[2] * nu;
3500 106288 : if (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) > 1.0) { // Edge of glass correction
3501 0 : state.dataWindowManager->hrgap[2] =
3502 0 : 0.5 * std::abs(state.dataWindowManager->A67) * pow_3(state.dataWindowManager->thetas[5] + state.dataWindowManager->thetas[6]);
3503 0 : hgap(3) = hgap(3) * state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) +
3504 0 : state.dataWindowManager->hrgap[2] * (state.dataSurface->SurfWinEdgeGlCorrFac(SurfNum) - 1.0);
3505 : }
3506 318864 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] +
3507 212576 : state.dataWindowManager->hcout * state.dataWindowManager->tout + state.dataWindowManager->AbsRadGlassFace[0];
3508 106288 : Bface(2) = state.dataWindowManager->AbsRadGlassFace[1];
3509 106288 : Bface(3) = state.dataWindowManager->AbsRadGlassFace[2];
3510 106288 : Bface(4) = state.dataWindowManager->AbsRadGlassFace[3];
3511 106288 : Bface(5) = state.dataWindowManager->AbsRadGlassFace[4];
3512 106288 : Bface(6) = state.dataWindowManager->AbsRadGlassFace[5];
3513 106288 : Bface(7) = state.dataWindowManager->AbsRadGlassFace[6];
3514 318864 : Bface(8) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] +
3515 212576 : state.dataWindowManager->hcin * state.dataWindowManager->tin + state.dataWindowManager->AbsRadGlassFace[7];
3516 :
3517 106288 : Aface(1, 1) = hr(1) + state.dataWindowManager->scon[0] + state.dataWindowManager->hcout;
3518 106288 : Aface(2, 1) = -state.dataWindowManager->scon[0];
3519 :
3520 106288 : Aface(1, 2) = -state.dataWindowManager->scon[0];
3521 106288 : Aface(2, 2) = state.dataWindowManager->scon[0] + hgap(1) - state.dataWindowManager->A23P * hr(2);
3522 106288 : Aface(3, 2) = -hgap(1) - state.dataWindowManager->A32P * hr(3);
3523 :
3524 106288 : Aface(2, 3) = -hgap(1) + state.dataWindowManager->A23P * hr(2);
3525 106288 : Aface(3, 3) = hgap(1) + state.dataWindowManager->scon[1] + state.dataWindowManager->A32P * hr(3);
3526 106288 : Aface(4, 3) = -state.dataWindowManager->scon[1];
3527 :
3528 106288 : Aface(3, 4) = -state.dataWindowManager->scon[1];
3529 106288 : Aface(4, 4) = state.dataWindowManager->scon[1] + hgap(2) - state.dataWindowManager->A45P * hr(4);
3530 106288 : Aface(5, 4) = -hgap(2) - state.dataWindowManager->A54P * hr(5);
3531 :
3532 106288 : Aface(4, 5) = -hgap(2) + state.dataWindowManager->A45P * hr(4);
3533 106288 : Aface(5, 5) = hgap(2) + state.dataWindowManager->scon[2] + state.dataWindowManager->A54P * hr(5);
3534 106288 : Aface(6, 5) = -state.dataWindowManager->scon[2];
3535 :
3536 106288 : Aface(5, 6) = -state.dataWindowManager->scon[2];
3537 106288 : Aface(6, 6) = state.dataWindowManager->scon[2] + hgap(3) - state.dataWindowManager->A67P * hr(6);
3538 106288 : Aface(7, 6) = -hgap(3) - state.dataWindowManager->A76P * hr(7);
3539 :
3540 106288 : Aface(6, 7) = -hgap(3) + state.dataWindowManager->A67P * hr(6);
3541 106288 : Aface(7, 7) = hgap(3) + state.dataWindowManager->scon[3] + state.dataWindowManager->A76P * hr(7);
3542 106288 : Aface(8, 7) = -state.dataWindowManager->scon[3];
3543 :
3544 106288 : Aface(7, 8) = -state.dataWindowManager->scon[3];
3545 106288 : Aface(8, 8) = hr(8) + state.dataWindowManager->scon[3] + state.dataWindowManager->hcin;
3546 :
3547 106288 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3548 0 : Bface(8) = state.dataWindowManager->Rmir * state.dataWindowManager->emis[7] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3549 0 : state.dataWindowManager->AbsRadGlassFace[7];
3550 0 : Bface(9) = state.dataWindowManager->Rmir * TauShIR * RhoGlIR2 * EpsShIR1 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(1);
3551 0 : Bface(10) =
3552 0 : state.dataWindowManager->Rmir * EpsShIR2 + state.dataWindowManager->hcin * state.dataWindowManager->tin + AbsRadShadeFace(2);
3553 :
3554 0 : Aface(8, 8) = hr(8) * (1 - RhoShIR1) / ShGlReflFacIR + state.dataWindowManager->scon[3] + hcv;
3555 0 : Aface(9, 8) = -state.dataWindowManager->emis[7] * hr(9) / ShGlReflFacIR;
3556 0 : Aface(8, 9) = -hr(8) * EpsShIR1 / ShGlReflFacIR;
3557 0 : Aface(9, 9) = hr(9) * (1 - RhoGlIR2 * (EpsShIR1 + RhoShIR1)) / ShGlReflFacIR + sconsh + hcv;
3558 0 : Aface(10, 9) = -sconsh;
3559 0 : Aface(9, 10) = -sconsh;
3560 0 : Aface(10, 10) = hr(10) + sconsh + state.dataWindowManager->hcin;
3561 : }
3562 :
3563 106288 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3564 0 : Bface(1) = state.dataWindowManager->Outir * state.dataWindowManager->emis[0] * TauShIR / ShGlReflFacIR + hcv * TGapNew +
3565 0 : state.dataWindowManager->AbsRadGlassFace[0];
3566 0 : Bface(9) =
3567 0 : state.dataWindowManager->Outir * EpsShIR1 + state.dataWindowManager->hcout * state.dataWindowManager->tout + AbsRadShadeFace(1);
3568 0 : Bface(10) = state.dataWindowManager->Outir * TauShIR * RhoGlIR1 * EpsShIR2 / ShGlReflFacIR + hcv * TGapNew + AbsRadShadeFace(2);
3569 :
3570 0 : Aface(1, 1) = hr(1) * (1 - RhoShIR2) / ShGlReflFacIR + state.dataWindowManager->scon[0] + hcv;
3571 0 : Aface(10, 1) = -state.dataWindowManager->emis[0] * hr(10) / ShGlReflFacIR;
3572 0 : Aface(9, 9) = hr(9) + sconsh + state.dataWindowManager->hcout;
3573 0 : Aface(10, 9) = -sconsh;
3574 0 : Aface(1, 10) = -hr(1) * EpsShIR2 / ShGlReflFacIR;
3575 0 : Aface(9, 10) = -sconsh;
3576 0 : Aface(10, 10) = hr(10) * (1 - RhoGlIR1 * (EpsShIR2 + RhoShIR2)) / ShGlReflFacIR + sconsh + hcv;
3577 : }
3578 :
3579 : } else {
3580 0 : ShowFatalError(
3581 0 : state, format("SolveForWindowTemperatures: Invalid number of Glass Layers={}, up to 4 allowed.", state.dataWindowManager->ngllayer));
3582 : }
3583 42038057 : }
3584 :
3585 22607285 : void SolveForWindowTemperatures(EnergyPlusData &state, int const SurfNum) // Surface number
3586 : {
3587 :
3588 : // SUBROUTINE INFORMATION:
3589 : // AUTHOR F. Winkelmann
3590 : // DATE WRITTEN July 2000
3591 : // MODIFIED Oct 2000, FW: modify edge-of-glass correction to account
3592 : // for gap radiative conductance affects
3593 : // Feb 2001, FW: add interior or exterior shade to layer
3594 : // heat balance calculation.
3595 : // Mar 2001, FW: relax error tolerance if MaxIterations reached.
3596 : // Jun 2001, FW: add interior or exterior blind
3597 : // Nov 2002, FW: add relaxation on face temperatures
3598 : // to improve convergence for multipane cases where outer pane
3599 : // has high solar absorptance: temp --> 0.5*(temp + previous temp);
3600 : // also, increase MaxIterations from 50 to 100.
3601 : // Dec 2002, FW: add between-glass shade/blind for double and triple glazing.
3602 : // Mar 2003, FW: remove redundant relaxation on radiative conductances
3603 : // Mar 2003, FW: increase convergence tolerance from 0.01 to 0.02 to enhance
3604 : // convergence in difficult cases.
3605 : // June 2003, FW: correct the expression for convective gain to zone air
3606 : // from airflow windows with airflow destination = InsideAir. Previously
3607 : // convective gain of air as it passed through gap was used, which is correct
3608 : // for airflow source = InsideAir but incorrect for airflow source = OutsideAir.
3609 : // Save SurfaceWindow%TAirflowGapOutlet for use in calculating convective heat
3610 : // gain to return air when airflow source = InsideAir, destination = ReturnAir.
3611 : // Dec 2003, FW: enhance converge for difficult cases by increasing relaxation
3612 : // in layer surface temperatures for iterations > MaxIterations/4
3613 : // May 2006, RR: add exterior window screen
3614 : // January 2009, BG: inserted call to recalc inside face convection inside iteration loop
3615 : // per ISO 15099 Section 8.3.2.2
3616 : // RE-ENGINEERED na
3617 :
3618 : // PURPOSE OF THIS SUBROUTINE:
3619 : // Evaluates the coefficients Aface and Bface in the system of linear
3620 : // algebraic equations
3621 : // Sum [Aface(i,j)*thetas(j)] = Bface(i), i = 1,nglfacep, j=1,nglfacep
3622 : // where
3623 : // nglface = number of glass faces (= 2 * number of glass layers), or, if shade or blind is present,
3624 : // nglgacep = number of glass faces + 2
3625 : // thetas(j) = temperature of face j
3626 : // If an interior, exterior or between-glass shade or blind, or exterior screen is present
3627 : // the face numbering is as follows:
3628 : // 1 to 2*nglface are glass faces, from outside to inside;
3629 : // 2*nglface+1 and 2*nglface+2 are the shade or blind faces, from outside to inside
3630 : // For example, the following diagram shows the face number for an exterior shade, screen or blind
3631 : // on double glazing:
3632 : // || || ||
3633 : // 5||6 1||2 3||4
3634 : // || || ||
3635 : // bl/sh/sc gl gl
3636 :
3637 : // And for a between-glass shade/blind in triple glazing:
3638 : // || || || ||
3639 : // 1||2 3||4 7||8 5||6
3640 : // || || || ||
3641 : // gl gl bl/sh gl
3642 :
3643 : // METHODOLOGY EMPLOYED:
3644 : // The Aface and Bface coefficients are determined by the equations for
3645 : // heat balance at the glass and shade/blind faces. The system of linear equations is solved
3646 : // by LU decomposition.
3647 :
3648 : // Using/Aliasing
3649 : using ConvectionCoefficients::CalcISO15099WindowIntConvCoeff;
3650 : using General::InterpSw;
3651 : using Psychrometrics::PsyCpAirFnW;
3652 : using Psychrometrics::PsyHFnTdbW;
3653 : using Psychrometrics::PsyRhoAirFnPbTdbW;
3654 : using Psychrometrics::PsyTdbFnHW;
3655 :
3656 22607285 : constexpr int MaxIterations(100); // Maximum allowed number of iterations (increased 9/01 from 15 to 50,
3657 : // increased 11/02 from 50 to 100)
3658 22607285 : constexpr Real64 errtemptol(0.02); // Tolerance on errtemp for convergence (increased from 0.01, 3/4/03)
3659 :
3660 : int ZoneNum; // Zone number corresponding to SurfNum
3661 : int i; // Counter
3662 : Real64 d; // +1 if number of row interchanges is even,
3663 : // -1 if odd (in LU decomposition)
3664 :
3665 22607285 : auto &hr = state.dataWindowManager->hr;
3666 22607285 : auto &indx = state.dataWindowManager->indx;
3667 22607285 : auto &Aface = state.dataWindowManager->Aface;
3668 22607285 : auto &Bface = state.dataWindowManager->Bface;
3669 22607285 : auto &TGapNewBG = state.dataWindowManager->TGapNewBG;
3670 22607285 : auto &hcvBG = state.dataWindowManager->hcvBG;
3671 22607285 : auto &AbsRadShadeFace = state.dataWindowManager->AbsRadShadeFace;
3672 :
3673 22607285 : int iter = 0; // Iteration number
3674 22607285 : Real64 errtemp = 0.0; // Absolute value of sum of face temperature differences between iterations, divided by number of faces
3675 22607285 : Real64 VGap = 0.0; // Air velocity in gap between glass and shade/blind (m/s)
3676 22607285 : Real64 VAirflowGap = 0.0; // Air velocity in airflow gap between glass panes (m/s)
3677 22607285 : Real64 VGapPrev = 0.0; // Value of VGap from previous iteration
3678 22607285 : Real64 TGapNew = 0.0; // Average air temp in gap between glass and shade/blind (K)
3679 22607285 : Real64 TAirflowGapNew = 0.0; // Average air temp in airflow gap between glass panes (K)
3680 22607285 : Real64 TGapOutlet = 0.0; // Temperature of air leaving gap between glass and shade/blind (K)
3681 22607285 : Real64 TAirflowGapOutlet = 0.0; // Temperature of air leaving airflow gap between glass panes (K)
3682 22607285 : Real64 TAirflowGapOutletC = 0.0; // Temperature of air leaving airflow gap between glass panes (C)
3683 22607285 : Real64 hcv = 0.0; // Convection coefficient from gap glass or shade/blind to gap air (W/m2-K)
3684 22607285 : Real64 hcvAirflowGap = 0.0; // Convection coefficient from airflow gap glass to airflow gap air (W/m2-K)
3685 22607285 : Real64 hcvPrev = 0.0; // Value of hcv from previous iteration
3686 22607285 : Real64 ConvHeatFlowForced = 0.0; // Convective heat flow from forced airflow gap (W)
3687 22607285 : Real64 ShGlReflFacIR = 0.0; // Factor for long-wave inter-reflection between shade/blind and adjacent glass
3688 22607285 : Real64 RhoGlIR1 = 0.0; // Long-wave reflectance of glass surface facing shade/blind; 1=exterior shade/blind,
3689 22607285 : Real64 RhoGlIR2 = 0.0;
3690 : // 2=exterior shade/blind
3691 22607285 : Real64 EpsShIR1 = 0.0; // Long-wave emissivity of shade/blind surface facing glass; 1=interior shade/blind,
3692 22607285 : Real64 EpsShIR2 = 0.0;
3693 : // 2=interior shade/blind
3694 22607285 : Real64 RhoShIR1 = 0.0; // Long-wave reflectance of shade/blind surface facing glass; 1=interior shade/blind,
3695 22607285 : Real64 RhoShIR2 = 0.0;
3696 : // 2=exterior shade/blind
3697 22607285 : Real64 TauShIR = 0.0; // Long-wave transmittance of isolated shade/blind
3698 22607285 : Real64 sconsh = 0.0; // shade/blind conductance (W/m2-K)
3699 :
3700 22607285 : WinShadingType ShadeFlag = WinShadingType::NoShade; // Shading flag
3701 : // radiation from lights and zone equipment absorbed by faces of shade/blind (W/m2)
3702 22607285 : Real64 ShadeArea = 0.0; // shade/blind area (m2)
3703 : // Real64 CondHeatGainGlass = 0.0; // Conduction through inner glass layer, outside to inside (W)
3704 : // Real64 CondHeatGainShade = 0.0; // Conduction through shade/blind, outside to inside (W)
3705 : // shade/blind is present. Zero if shade/blind has zero IR transmittance (W)
3706 : // Real64 IncidentSolar = 0.0; // Solar incident on outside of window (W)
3707 22607285 : Real64 TransDiff = 0.0; // Diffuse shortwave transmittance
3708 22607285 : Real64 TotAirflowGap = 0.0; // Total volumetric airflow through window gap (m3/s)
3709 22607285 : Real64 CpAirOutlet = 0.0; // Heat capacity of air from window gap (J/kg-K)
3710 22607285 : Real64 CpAirZone = 0.0; // Heat capacity of zone air (J/kg-K)
3711 22607285 : Real64 InletAirHumRat = 0.0; // Humidity ratio of air from window gap entering fan
3712 22607285 : int InsideFaceIndex = 0; // intermediate variable for index of inside face in thetas
3713 :
3714 22607285 : state.dataWindowManager->nglfacep = state.dataWindowManager->nglface;
3715 22607285 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
3716 22607285 : ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
3717 22607285 : AbsRadShadeFace = 0.0;
3718 :
3719 22607285 : if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) {
3720 71522 : state.dataWindowManager->nglfacep = state.dataWindowManager->nglface + 2;
3721 71522 : AbsRadShadeFace(1) = DataSurfaces::AbsFrontSide(state, SurfNum);
3722 71522 : AbsRadShadeFace(2) = DataSurfaces::AbsBackSide(state, SurfNum);
3723 71522 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) AbsRadShadeFace(2) += state.dataSurface->SurfWinIntLWAbsByShade(SurfNum);
3724 71522 : sconsh = state.dataWindowManager->scon[state.dataWindowManager->ngllayer];
3725 71522 : TauShIR = state.dataWindowManager->tir[state.dataWindowManager->nglface];
3726 71522 : EpsShIR1 = state.dataWindowManager->emis[state.dataWindowManager->nglface];
3727 71522 : EpsShIR2 = state.dataWindowManager->emis[state.dataWindowManager->nglface + 1];
3728 71522 : RhoShIR1 = max(0.0, 1.0 - TauShIR - EpsShIR1);
3729 71522 : RhoShIR2 = max(0.0, 1.0 - TauShIR - EpsShIR2);
3730 71522 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3731 40940 : RhoGlIR2 = 1.0 - state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer - 1];
3732 40940 : ShGlReflFacIR = 1.0 - RhoGlIR2 * RhoShIR1;
3733 30582 : } else if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
3734 13712 : RhoGlIR1 = 1.0 - state.dataWindowManager->emis[0];
3735 13712 : ShGlReflFacIR = 1.0 - RhoGlIR1 * RhoShIR2;
3736 : }
3737 : } // End of check if shade or blind is on
3738 :
3739 : // Initialize face temperatures.
3740 :
3741 22607285 : StartingWindowTemps(state, SurfNum, AbsRadShadeFace);
3742 :
3743 22607285 : hcvPrev = 0.0;
3744 22607285 : VGapPrev = 0.0;
3745 :
3746 : // Calculate radiative conductances
3747 :
3748 22607285 : errtemp = errtemptol * 2.0;
3749 :
3750 106683399 : while (iter < MaxIterations && errtemp > errtemptol) {
3751 :
3752 153747177 : for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
3753 111709120 : hr(i) = state.dataWindowManager->emis[i - 1] * state.dataWindowManager->sigma * pow_3(state.dataWindowManager->thetas[i - 1]);
3754 : // Following line is redundant since thetas is being relaxed;
3755 : // removed by FCW, 3/4/03
3756 : //! fw if ( iter >= 1 ) hr(i) = 0.5*(hrprev(i)+hr(i))
3757 : }
3758 :
3759 : // call for new interior film coeff (since it is temperature dependent) if using Detailed inside coef model
3760 126114171 : if (((state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == 0) &&
3761 51652553 : (state.dataHeatBal->Zone(ZoneNum).InsideConvectionAlgo == ConvectionConstants::HcInt_ASHRAETARP)) ||
3762 9614496 : (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == -2)) {
3763 : // coef model is "detailed" and not prescribed by user
3764 : // need to find inside face index, varies with shade/blind etc.
3765 32423561 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3766 207157 : InsideFaceIndex = state.dataWindowManager->nglfacep;
3767 : } else {
3768 32216404 : InsideFaceIndex = state.dataWindowManager->nglface;
3769 : }
3770 64847122 : CalcISO15099WindowIntConvCoeff(state,
3771 : SurfNum,
3772 32423561 : state.dataWindowManager->thetas[InsideFaceIndex - 1] - DataGlobalConstants::KelvinConv,
3773 32423561 : state.dataWindowManager->tin - DataGlobalConstants::KelvinConv);
3774 32423561 : state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
3775 : }
3776 :
3777 42038057 : Aface = 0.0;
3778 42038057 : Bface = 0.0;
3779 :
3780 : // If interior or exterior shade or blind is present, get heat transfer
3781 : // coefficient from glass and shade/blind to gap between glass and shade/blind,
3782 : // effective gap air temperature, velocity of air in gap and gap outlet temperature.
3783 :
3784 42038057 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) || ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3785 338356 : ExtOrIntShadeNaturalFlow(
3786 338356 : state, SurfNum, iter, VGap, TGapNew, TGapOutlet, hcv, state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum));
3787 338356 : if (iter >= 1) {
3788 283704 : hcv = 0.5 * (hcvPrev + hcv);
3789 283704 : VGap = 0.5 * (VGapPrev + VGap);
3790 : }
3791 338356 : hcvPrev = hcv;
3792 338356 : VGapPrev = VGap;
3793 : }
3794 :
3795 42038057 : TAirflowGapOutlet = 0.0;
3796 : // If between-glass shade or blind is not present and this is an airflow window
3797 : // (i.e., with forced airflow in the gap for double glass or in the inner gap for triple glass)
3798 : // get glass-to-air forced convection heat transfer coefficient, average gap air temperature, and
3799 : // convective heat flow from gap.
3800 :
3801 42038057 : if (!ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
3802 16422 : BetweenGlassForcedFlow(state, SurfNum, iter, VAirflowGap, TAirflowGapNew, TAirflowGapOutlet, hcvAirflowGap, ConvHeatFlowForced);
3803 : }
3804 :
3805 : // If between-glass shade or blind is present, get convective heat transfer
3806 : // coefficients from glass and shade/blind to the two gaps on either side of the shade/blind.
3807 : // Also get average gas temperature in the two gaps, and, for airflow window, the sum of the
3808 : // convective heat flows from the gaps.
3809 :
3810 42038057 : if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
3811 108448 : if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) == 0.0) { // Natural convection in gaps
3812 88448 : BetweenGlassShadeNaturalFlow(state, SurfNum, iter, VGap, TGapNewBG, hcvBG);
3813 : } else { // Forced convection in gaps
3814 20000 : BetweenGlassShadeForcedFlow(state, SurfNum, iter, VGap, TGapNewBG, TAirflowGapOutlet, hcvBG, ConvHeatFlowForced);
3815 : }
3816 : }
3817 :
3818 42038057 : ++iter;
3819 :
3820 : // Calculations based on number of glass layers
3821 84076114 : GetHeatBalanceEqCoefMatrix(state,
3822 : SurfNum,
3823 42038057 : state.dataWindowManager->ngllayer,
3824 : ShadeFlag,
3825 : sconsh,
3826 : TauShIR,
3827 : EpsShIR1,
3828 : EpsShIR2,
3829 : RhoShIR1,
3830 : RhoShIR2,
3831 : ShGlReflFacIR,
3832 : RhoGlIR1,
3833 : RhoGlIR2,
3834 : hcv,
3835 : TGapNew,
3836 : TAirflowGapNew,
3837 : hcvAirflowGap,
3838 : hcvBG,
3839 : TGapNewBG,
3840 : AbsRadShadeFace,
3841 : hr,
3842 : Aface,
3843 : Bface);
3844 42038057 : LUdecomposition(state, Aface, state.dataWindowManager->nglfacep, indx,
3845 : d); // Note that these routines change Aface;
3846 42038057 : LUsolution(Aface, state.dataWindowManager->nglfacep, indx,
3847 : Bface); // face temperatures are returned in Bface
3848 :
3849 153747177 : for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
3850 111709120 : state.dataWindowManager->thetasPrev[i - 1] = state.dataWindowManager->thetas[i - 1];
3851 111709120 : if (iter < MaxIterations / 4) {
3852 111709088 : state.dataWindowManager->thetas[i - 1] = 0.5 * state.dataWindowManager->thetas[i - 1] + 0.5 * Bface(i);
3853 : } else {
3854 32 : state.dataWindowManager->thetas[i - 1] = 0.75 * state.dataWindowManager->thetas[i - 1] + 0.25 * Bface(i);
3855 : }
3856 : }
3857 :
3858 42038057 : errtemp = 0.0;
3859 153747177 : for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
3860 111709120 : errtemp += std::abs(state.dataWindowManager->thetas[i - 1] - state.dataWindowManager->thetasPrev[i - 1]);
3861 : }
3862 42038057 : errtemp /= state.dataWindowManager->nglfacep;
3863 : }
3864 :
3865 22607285 : state.dataSurface->SurfWinWindowCalcIterationsRep(SurfNum) = iter;
3866 :
3867 : // We have reached iteration limit or we have converged. If we have reached the
3868 : // iteration limit the following test relaxes the convergence tolerance.
3869 : // If we have converged (errtemp <= errtemptol) the following test has not effect.
3870 :
3871 22607285 : if (errtemp < 10 * errtemptol) {
3872 :
3873 : // Window heat balance solution has converged.
3874 :
3875 : // For interior shade, add convective gain from glass/shade gap air flow to zone convective gain;
3876 : // For all cases, get total window heat gain for reporting. See CalcWinFrameAndDividerTemps for
3877 : // contribution of frame and divider.
3878 : // IncidentSolar = state.dataSurface->Surface(SurfNum).Area * state.dataHeatBal->SurfQRadSWOutIncident(SurfNum);
3879 22607285 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
3880 : // Interior shade or blind
3881 : // Window heat gain from glazing and shade/blind to zone. Consists of transmitted solar, convection
3882 : // from air exiting gap, convection from zone-side of shade/blind, net IR to zone from shade and net IR to
3883 : // zone from the glass adjacent to the shade/blind (zero if shade/blind IR transmittance is zero).
3884 : // Following assumes glazed area = window area (i.e., dividers ignored) in calculating
3885 : // IR to zone from glass when interior shade/blind is present.
3886 40940 : ShadeArea = state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum);
3887 : // CondHeatGainShade = ShadeArea * sconsh *
3888 : // (state.dataWindowManager->thetas(state.dataWindowManager->nglfacep - 1) -
3889 : // state.dataWindowManager->thetas[state.dataWindowManager->nglfacep-1]);
3890 40940 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) =
3891 81880 : ShadeArea * EpsShIR2 *
3892 122820 : (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[state.dataWindowManager->nglfacep - 1]) -
3893 81880 : state.dataWindowManager->Rmir) +
3894 40940 : EpsShIR1 *
3895 122820 : (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[state.dataWindowManager->nglfacep - 2]) -
3896 81880 : state.dataWindowManager->Rmir) *
3897 40940 : RhoGlIR2 * TauShIR / ShGlReflFacIR;
3898 40940 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
3899 81880 : ShadeArea * (state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer - 1] * TauShIR / ShGlReflFacIR) *
3900 122820 : (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1]) -
3901 40940 : state.dataWindowManager->Rmir);
3902 40940 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) =
3903 81880 : ShadeArea * state.dataWindowManager->hcin *
3904 40940 : (state.dataWindowManager->thetas[state.dataWindowManager->nglfacep - 1] - state.dataWindowManager->tin);
3905 40940 : state.dataSurface->SurfWinHeatGain(SurfNum) =
3906 81880 : state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) +
3907 122820 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) + state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) +
3908 40940 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum);
3909 : } else {
3910 : // Interior shade or blind not present; innermost layer is glass
3911 : // CondHeatGainGlass = state.dataSurface->Surface(SurfNum).Area * state.dataWindowManager->scon(state.dataWindowManager->ngllayer) *
3912 : // (state.dataWindowManager->thetas(2 * state.dataWindowManager->ngllayer - 1) -
3913 : // state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1]);
3914 22566345 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
3915 45132690 : state.dataSurface->Surface(SurfNum).Area * state.dataWindowManager->emis[2 * state.dataWindowManager->ngllayer - 1] *
3916 67699035 : (state.dataWindowManager->sigma * pow_4(state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1]) -
3917 22566345 : state.dataWindowManager->Rmir);
3918 22566345 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
3919 45132690 : state.dataSurface->Surface(SurfNum).Area * state.dataWindowManager->hcin *
3920 22566345 : (state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->tin);
3921 67699035 : state.dataSurface->SurfWinHeatGain(SurfNum) = state.dataSurface->SurfWinTransSolar(SurfNum) +
3922 45132690 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
3923 22566345 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum);
3924 : }
3925 :
3926 : // Add convective heat gain from airflow window
3927 : // Note: effect of fan heat on gap outlet temperature is neglected since fan power (based
3928 : // on pressure drop through the gap) is extremely small
3929 :
3930 22607285 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
3931 22607285 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
3932 22607285 : TotAirflowGap = state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width;
3933 22607285 : TAirflowGapOutletC = TAirflowGapOutlet - state.dataWindowManager->TKelvin;
3934 22607285 : state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum) = TAirflowGapOutletC;
3935 22607285 : if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
3936 16128 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = ConvHeatFlowForced;
3937 16128 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) =
3938 16128 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3939 : // Add heat from gap airflow to zone air if destination is inside air; save the heat gain to return
3940 : // air in case it needs to be sent to the zone (due to no return air determined in HVAC simulation)
3941 32256 : if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor ||
3942 16128 : state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Return) {
3943 0 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
3944 0 : if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
3945 0 : InletAirHumRat = thisZoneHB.ZoneAirHumRat;
3946 : } else { // AirflowSource = outside air
3947 0 : InletAirHumRat = state.dataEnvrn->OutHumRat;
3948 : }
3949 0 : Real64 ZoneTemp = thisZoneHB.MAT; // this should be Tin (account for different reference temps)
3950 0 : CpAirOutlet = PsyCpAirFnW(InletAirHumRat);
3951 0 : CpAirZone = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat);
3952 0 : state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) =
3953 0 : TotAirflowGap * (CpAirOutlet * (TAirflowGapOutletC)-CpAirZone * ZoneTemp);
3954 0 : if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor) {
3955 0 : state.dataSurface->SurfWinHeatGain(SurfNum) += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum);
3956 : }
3957 : }
3958 : // For AirflowDestination = ReturnAir in a controlled (i.e., conditioned) zone with return air, see CalcZoneLeavingConditions
3959 : // for calculation of modification of return-air temperature due to airflow from window gaps into return air.
3960 : }
3961 :
3962 : // Correct WinHeatGain for interior diffuse shortwave (solar and shortwave from lights) transmitted
3963 : // back out window
3964 22607285 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3965 22607285 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
3966 :
3967 22607285 : TransDiff = state.dataConstruction->Construct(ConstrNum).TransDiff; // Default value for TransDiff here
3968 22607285 : if (NOT_SHADED(ShadeFlag)) {
3969 22464509 : TransDiff = state.dataConstruction->Construct(ConstrNum).TransDiff;
3970 142776 : } else if (ANY_SHADE_SCREEN(ShadeFlag)) {
3971 41718 : TransDiff = state.dataConstruction->Construct(ConstrNumSh).TransDiff;
3972 101058 : } else if (ANY_BLIND(ShadeFlag)) {
3973 29804 : if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
3974 9366 : TransDiff = General::InterpGeneral(
3975 3122 : state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)),
3976 3122 : state.dataConstruction->Construct(ConstrNumSh)
3977 6244 : .BlTransDiff(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)),
3978 3122 : state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum));
3979 : } else {
3980 26682 : TransDiff = state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(1);
3981 : }
3982 71254 : } else if (ShadeFlag == WinShadingType::SwitchableGlazing) {
3983 142508 : TransDiff = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
3984 71254 : state.dataConstruction->Construct(ConstrNum).TransDiff,
3985 71254 : state.dataConstruction->Construct(ConstrNumSh).TransDiff);
3986 : }
3987 : // shouldn't this be + outward flowing fraction of absorbed SW? -- do not know whose comment this is? LKL (9/2012)
3988 22607285 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
3989 22607285 : state.dataHeatBal->EnclSolQSWRad(state.dataSurface->Surface(SurfNum).SolarEnclIndex) * state.dataSurface->Surface(SurfNum).Area *
3990 : TransDiff;
3991 22607285 : state.dataSurface->SurfWinHeatGain(SurfNum) -= state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum);
3992 :
3993 22607285 : if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) {
3994 71522 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) =
3995 143044 : (state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum)) *
3996 71522 : (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum));
3997 71522 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) =
3998 71522 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
3999 : }
4000 22607285 : if (state.dataEnvrn->SunIsUp) {
4001 :
4002 11473140 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) =
4003 22946280 : state.dataSurface->SurfWinTransSolar(SurfNum) /
4004 22946280 : (state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) *
4005 22946280 : (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum)) +
4006 : 0.0001);
4007 11473140 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) =
4008 22946280 : (state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) + state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum)) /
4009 22946280 : (state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) *
4010 22946280 : (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum)) +
4011 : 0.0001);
4012 11473140 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) =
4013 11473140 : 1.0 - state.dataSurface->SurfWinSysSolTransmittance(SurfNum) - state.dataSurface->SurfWinSysSolAbsorptance(SurfNum);
4014 : } else {
4015 11134145 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
4016 11134145 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
4017 11134145 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
4018 : }
4019 :
4020 : // Save hcv for use in divider calc with interior or exterior shade (see CalcWinFrameAndDividerTemps)
4021 22607285 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) || ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag))
4022 54652 : state.dataSurface->SurfWinConvCoeffWithShade(SurfNum) = hcv;
4023 : } else {
4024 : // No convergence after MaxIterations even with relaxed error tolerance
4025 0 : ShowSevereError(state, "Convergence error in SolveForWindowTemperatures for window " + state.dataSurface->Surface(SurfNum).Name);
4026 0 : ShowContinueErrorTimeStamp(state, "");
4027 :
4028 0 : if (state.dataGlobal->DisplayExtraWarnings) {
4029 : // report out temperatures
4030 0 : for (i = 1; i <= state.dataWindowManager->nglfacep; ++i) {
4031 0 : ShowContinueError(state,
4032 0 : format("Glazing face index = {} ; new temperature ={:.4R}C ; previous temperature = {:.4R}C",
4033 : i,
4034 0 : state.dataWindowManager->thetas[i - 1] - DataGlobalConstants::KelvinConv,
4035 0 : state.dataWindowManager->thetasPrev[i - 1] - DataGlobalConstants::KelvinConv));
4036 : }
4037 : }
4038 :
4039 0 : ShowFatalError(state,
4040 0 : "Program halted because of convergence error in SolveForWindowTemperatures for window " +
4041 0 : state.dataSurface->Surface(SurfNum).Name);
4042 : }
4043 22607285 : }
4044 :
4045 : //****************************************************************************
4046 :
4047 338356 : void ExtOrIntShadeNaturalFlow(EnergyPlusData &state,
4048 : int const SurfNum, // Surface number
4049 : int const iter, // Iteration number for glass heat balance calculation
4050 : Real64 &VGap, // Air velocity in glass-shade/blind gap (m/s)
4051 : Real64 &TGapNew, // Current-iteration average air temp in glass-shade/blind gap (K)
4052 : Real64 &TGapOutlet, // Temperature of air leaving glass-shade/blind gap at top for upward
4053 : Real64 &hcv, // Convection coefficient from gap glass or shade to gap air (W/m2-K)
4054 : Real64 &QConvGap // Convective heat gain from glass-shade/blind gap for interior shade (W)
4055 : )
4056 : {
4057 :
4058 : // SUBROUTINE INFORMATION:
4059 : // AUTHOR F. Winkelmann
4060 : // DATE WRITTEN December 2000
4061 : // MODIFIED June 2001: add window blinds
4062 : // May 2006 (RR): add exterior window screens
4063 : // RE-ENGINEERED na
4064 :
4065 : // PURPOSE OF THIS SUBROUTINE:
4066 : // Called by SolveForWindowTemperatures for windows that have an interior
4067 : // or exterior blind or shade in place.
4068 : // Solves for air flow in gap between glass and shade/blind.
4069 : // Finds temperature of gap air and coefficient for convective heat transfer
4070 : // from glass to gap air and shade/blind to gap air.
4071 :
4072 : // METHODOLOGY EMPLOYED:
4073 : // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
4074 : // Detailed Calculations," 1/12/2000, Chapter 7, "Shading Devices."
4075 :
4076 : // SUBROUTINE ARGUMENT DEFINITIONS:
4077 : // air flow or bottom for downward air flow (K)
4078 :
4079 : int ConstrNumSh; // Shaded construction number
4080 : int MatNumSh; // Material number of shade/blind layer
4081 : int nglassfaces; // Number of glass faces in contruction
4082 : Real64 TGapInlet; // Temperature of air entering glass-shade/blind gap at bottom for upward
4083 : // air flow or top for downward air flow (K)
4084 : Real64 TGlassFace; // Temperature of glass surface facing glass-shade/blind gap (K)
4085 : Real64 TShadeFace; // Temperature of shade surface facing glass-shade/blind gap (K)
4086 : Real64 hGapStill; // Still-air glass-shade/blind gap conduction/convection coeff (W/m2-K)
4087 : Real64 TGapOld; // Previous-iteration average air temp in glass-shade/blind gap (K)
4088 : Real64 GapHeight; // Vertical length of glass-shade/blind gap (m)
4089 : Real64 GapDepth; // Distance from shade to glass (m)
4090 : Real64 RhoAir; // Density of glass-shade/blind gap air at a temperature of TGapOld (kg/m3)
4091 : Real64 RhoTRef; // Density of glass-shade/blind air at reference temp = KelvinConv (kg/m3)
4092 : Real64 ViscAir; // Viscosity of glass-shade/blind gap air at a temperature of TGapOld (kg/m3)
4093 : Real64 AGap; // Cross sectional area of glass-shade/blind gap (m2); for vertical window, this
4094 : // is in horizontal plane normal to window.
4095 : Real64 ATopGap; // Area of the top and bottom openings (m2)
4096 : Real64 ABotGap;
4097 : Real64 ALeftGap; // Area of the left and right openings (m2)
4098 : Real64 ARightGap;
4099 : Real64 AHolesGap; // Area of the holes in the shade (assumed homogeneously
4100 : // distributed) (m2)
4101 : Real64 ATopLRH; // Intermediate variables
4102 : Real64 ABotLRH;
4103 : Real64 AEqInlet; // Equivalent inlet and outlet opening areas (m2)
4104 : Real64 AEqOutlet;
4105 : Real64 Zinlet; // Inlet and outlet pressure loss factors
4106 : Real64 Zoutlet;
4107 : Real64 AVGap; // Coeff. of VGap**2 term in pressure balance equation
4108 : Real64 BVGap; // Coeff. of VGap term in pressure balance equation
4109 : Real64 CVGap; // VGap-independent term in pressure balance equation
4110 : Real64 GapHeightChar; // Characteristic height of the gap air temperature profile (m)
4111 : Real64 TAve; // Average of TGlass and TShade (K)
4112 : // REAL(r64) :: AirProps(8) ! Air properties
4113 : int TotGaps; // Glass/glass gaps + glass-shade/blind gap
4114 : Real64 con; // Gap conductivity and derivative
4115 : Real64 gr; // glass-shade/blind gap Grashof number
4116 : Real64 pr; // glass-shade/blind gap Prandtl number
4117 : Real64 nu; // glass-shade/blind gap Nusselt number
4118 : WinShadingType ShadeFlag; // Shading flag
4119 : int BlNum; // Blind number
4120 :
4121 : // Air properties
4122 : // Dens dDens/dT Con dCon/dT Vis dVis/dT Prandtl dPrandtl/dT
4123 : // DATA AirProps / 1.29, -0.4d-2, 2.41d-2, 7.6d-5, 1.73d-5, 1.0d-7, 0.72, 1.8d-3 /
4124 :
4125 338356 : ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
4126 338356 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4127 338356 : nglassfaces = 2 * state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers;
4128 338356 : TotGaps = state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers;
4129 :
4130 338356 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) { // Interior shade or blind
4131 207157 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(nglassfaces);
4132 207157 : TGapInlet = state.dataWindowManager->tin;
4133 207157 : TGlassFace = state.dataWindowManager->thetas[nglassfaces - 1];
4134 207157 : TShadeFace = state.dataWindowManager->thetas[nglassfaces];
4135 : } else { // Exterior shade, screen or blind
4136 131199 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1);
4137 131199 : TGapInlet = state.dataWindowManager->tout;
4138 131199 : TGlassFace = state.dataWindowManager->thetas[0];
4139 131199 : TShadeFace = state.dataWindowManager->thetas[nglassfaces + 1];
4140 : }
4141 338356 : TAve = 0.5 * (TGlassFace + TShadeFace);
4142 :
4143 338356 : if (iter == 0) {
4144 54652 : TGapOld = 0.5 * (TAve + TGapInlet);
4145 : } else {
4146 283704 : TGapOld = TGapNew;
4147 : }
4148 :
4149 : // Conductance of gap between glass and shade assuming gap is sealed
4150 338356 : WindowGasConductance(state, TGlassFace, TShadeFace, TotGaps, con, pr, gr);
4151 338356 : NusseltNumber(state, SurfNum, TGlassFace, TShadeFace, TotGaps, gr, pr, nu);
4152 338356 : hGapStill = con / state.dataWindowManager->gap[TotGaps - 1] * nu;
4153 :
4154 : // For near-horizontal windows (i.e., no more than 5 deg from horizontal) assume
4155 : // there is no air flow thru gap
4156 :
4157 338356 : if (std::abs(state.dataSurface->Surface(SurfNum).SinTilt) < 0.0872) {
4158 0 : VGap = 0.0;
4159 0 : hcv = 2.0 * hGapStill;
4160 0 : QConvGap = 0.0;
4161 0 : TGapNew = TAve;
4162 0 : TGapOutlet = TAve;
4163 0 : return;
4164 : }
4165 :
4166 338356 : GapHeight = state.dataSurface->Surface(SurfNum).Height;
4167 :
4168 338356 : if (ShadeFlag == WinShadingType::IntShade || ShadeFlag == WinShadingType::ExtShade || ShadeFlag == WinShadingType::ExtScreen) {
4169 : // Shade or Screen on
4170 246591 : GapDepth = state.dataMaterial->Material(MatNumSh).WinShadeToGlassDist;
4171 246591 : AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
4172 246591 : ATopGap = state.dataMaterial->Material(MatNumSh).WinShadeTopOpeningMult * AGap;
4173 246591 : ABotGap = state.dataMaterial->Material(MatNumSh).WinShadeBottomOpeningMult * AGap;
4174 246591 : ALeftGap = state.dataMaterial->Material(MatNumSh).WinShadeLeftOpeningMult * GapHeight * GapDepth;
4175 246591 : ARightGap = state.dataMaterial->Material(MatNumSh).WinShadeRightOpeningMult * GapHeight * GapDepth;
4176 246591 : AHolesGap = state.dataMaterial->Material(MatNumSh).WinShadeAirFlowPermeability * GapHeight * state.dataSurface->Surface(SurfNum).Width;
4177 : } else {
4178 : // Blind on
4179 91765 : BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
4180 91765 : GapDepth = state.dataHeatBal->Blind(BlNum).BlindToGlassDist;
4181 91765 : AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
4182 91765 : ATopGap = state.dataHeatBal->Blind(BlNum).BlindTopOpeningMult * AGap;
4183 91765 : ABotGap = state.dataHeatBal->Blind(BlNum).BlindBottomOpeningMult * AGap;
4184 91765 : ALeftGap = state.dataHeatBal->Blind(BlNum).BlindLeftOpeningMult * GapHeight * GapDepth;
4185 91765 : ARightGap = state.dataHeatBal->Blind(BlNum).BlindRightOpeningMult * GapHeight * GapDepth;
4186 91765 : AHolesGap = state.dataSurface->SurfWinBlindAirFlowPermeability(SurfNum) * GapHeight * state.dataSurface->Surface(SurfNum).Width;
4187 : }
4188 :
4189 338356 : RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapOld - state.dataWindowManager->TKelvin);
4190 338356 : ViscAir = state.dataWindowManager->AirProps[4] + state.dataWindowManager->AirProps[5] * (TGapOld - state.dataWindowManager->TKelvin);
4191 : // The factor 12 in the next line is based on the solution of steady laminar flow between fixed
4192 : // parallel plates given in Sec. 6.9.1 of Fundamentals of Fluid Mechanics, Munson/Young/Okishi, Third Edition
4193 : // Update, John Wiley & Sons, 1998; ISO 15099 has 8 for this factor, which is for flow through a tube.
4194 338356 : BVGap = 12.0 * ViscAir * GapHeight / pow_2(GapDepth);
4195 : // Adding 0.000001 and 0.000002 in the following gives ATopLRH = ABotLRH =
4196 : // 0.25*(ALeftGap + ARightGap + AHolesGap) when ABotGap = ATopGap = 0.0 (shade/blind sealed at
4197 : // bottom and top but possibly open at left side, right side and/or in-shade/blind)
4198 338356 : ATopLRH = 0.5 * ((ATopGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
4199 338356 : ABotLRH = 0.5 * ((ABotGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
4200 338356 : if (TGapOld > TGapInlet) {
4201 210412 : AEqInlet = ABotGap + ATopLRH;
4202 210412 : AEqOutlet = ATopGap + ABotLRH;
4203 : } else {
4204 127944 : AEqOutlet = ABotGap + ATopLRH;
4205 127944 : AEqInlet = ATopGap + ABotLRH;
4206 : }
4207 : // Adding 0.000001 in the following gives very large value of Zinlet for AEqInlet = 0 and
4208 : // very large value of Zoutlet for AEqInlet = 0; this gives VGap close to zero, as required
4209 : // when there is no inlet and/or outlet for air. This then reduces to the
4210 : // case of a completely sealed shade, in which hcv = 2*hGapStill and QConvGap = 0.
4211 338356 : Zinlet = pow_2(AGap / (0.6 * AEqInlet + 0.000001) - 1.0);
4212 338356 : Zoutlet = pow_2(AGap / (0.6 * AEqOutlet + 0.000001) - 1.0);
4213 338356 : AVGap = 0.5 * RhoAir * (1 + Zinlet + Zoutlet);
4214 338356 : RhoTRef = state.dataWindowManager->AirProps[0] * state.dataWindowManager->TKelvin;
4215 338356 : CVGap = RhoTRef * 9.81 * GapHeight * state.dataSurface->Surface(SurfNum).SinTilt * (TGapOld - TGapInlet) / (TGapOld * TGapInlet);
4216 :
4217 : // Solution of quadratic equation in VGap
4218 338356 : VGap = (std::sqrt(pow_2(BVGap) + std::abs(4.0 * AVGap * CVGap)) - BVGap) / (2.0 * AVGap);
4219 338356 : hcv = 2.0 * hGapStill + 4.0 * VGap;
4220 338356 : GapHeightChar = RhoAir * 1008.0 * GapDepth * VGap / (2.0 * hcv);
4221 : // The following avoids divide by zero and exponential underflow
4222 338356 : if (GapHeightChar == 0.0) {
4223 0 : TGapOutlet = TAve;
4224 338356 : } else if ((GapHeight / GapHeightChar) > 15.0) {
4225 66501 : TGapOutlet = TAve;
4226 : } else {
4227 271855 : TGapOutlet = TAve - (TAve - TGapInlet) * std::exp(-GapHeight / GapHeightChar);
4228 : }
4229 338356 : TGapNew = TAve - (GapHeightChar / GapHeight) * (TGapOutlet - TGapInlet);
4230 :
4231 : // Convective heat flow from gap to room air for interior shade or blind
4232 338356 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
4233 207157 : RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapNew - state.dataWindowManager->TKelvin);
4234 207157 : QConvGap = RhoAir * AGap * VGap * 1008.0 * (TGapOutlet - TGapInlet);
4235 : // Exclude convection to gap due to divider, if present; divider convection handled
4236 : // separately in CalcWinFrameAndDividerTemps
4237 414314 : QConvGap *= 0.5 * (1.0 + state.dataSurface->Surface(SurfNum).Area /
4238 207157 : (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum)));
4239 : }
4240 : }
4241 :
4242 : //****************************************************************************
4243 :
4244 88448 : void BetweenGlassShadeNaturalFlow(EnergyPlusData &state,
4245 : int const SurfNum, // Surface number
4246 : int const iter, // Iteration number for glass heat balance calculation
4247 : Real64 &VGap, // Gas velocity in gaps (m/s)
4248 : Array1A<Real64> TGapNew, // Current-iteration average gas temp in gaps (K)
4249 : Array1A<Real64> hcv // Convection coefficient from gap glass or shade to gap gas (W/m2-K)
4250 : )
4251 : {
4252 :
4253 : // SUBROUTINE INFORMATION:
4254 : // AUTHOR F. Winkelmann
4255 : // DATE WRITTEN December 2002
4256 : // MODIFIED na
4257 : // RE-ENGINEERED na
4258 :
4259 : // PURPOSE OF THIS SUBROUTINE:
4260 : // Called by SolveForWindowTemperatures for windows that have a
4261 : // between-glass shade or blind in place.
4262 : // Solves for gas flow in the two gaps on either side of shade/blind.
4263 : // Finds average temperature of gas in the two gaps, and the coefficient
4264 : // for convective heat transfer from glass to gap gas and shade/blind to gap gas
4265 : // for the two gaps. The two gaps are assumed to have the same depth so that the
4266 : // gas velocity due to natural convection is the same in the two gaps.
4267 : // The Between-glass shade/blind is between the two glass layers of double glazing
4268 : // or between the two inner glass layers of triple glazing. The quadruple glazing
4269 : // case is not considered.
4270 :
4271 : // METHODOLOGY EMPLOYED:
4272 : // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
4273 : // Detailed Calculations," 1/12/2000, Chapter 7, "Shading Devices."
4274 :
4275 : // Argument array dimensioning
4276 88448 : TGapNew.dim(2);
4277 88448 : hcv.dim(2);
4278 :
4279 : int ConstrNumSh; // Shaded construction number
4280 : int MatNumSh; // Material number of shade/blind layer
4281 : int nglassfaces; // Number of glass faces in contruction
4282 : // In the following, "gaps" refer to the gaps on either side of the shade/blind
4283 176896 : Array1D<Real64> TGlassFace(2); // Temperature of glass surfaces facing gaps (K)
4284 176896 : Array1D<Real64> TShadeFace(2); // Temperature of shade surfaces facing gaps (K)
4285 176896 : Array1D<Real64> hGapStill(2); // Still-air conduction/convection coeffs for the gaps (W/m2-K)
4286 176896 : Array1D<Real64> TGapOld(2); // Previous-iteration average gas temp in gaps (K)
4287 : Real64 GapHeight; // Vertical length of glass-shade/blind gap (m)
4288 : Real64 GapDepth; // Distance from shade/blind to glass; assumed same for both gaps (m)
4289 176896 : Array1D<Real64> RhoGas(2); // Density of gap gas at a temperature of TGapOld (kg/m3)
4290 : Real64 RhoTRef; // Density of gap gas at reference temp = KelvinConvK (kg/m3)
4291 176896 : Array1D<Real64> ViscGas(2); // Viscosity of gap gas at a temperature of TGapOld (kg/m3)
4292 : Real64 RhoGasZero; // Gas density at KelvinConvK
4293 : Real64 ViscGasZero; // Gas viscosity at KelvinConvK (not used)
4294 : Real64 AGap; // Cross sectional area of gaps (m2); for vertical window, this
4295 : // is in horizontal plane normal to window.
4296 : Real64 ATopGap; // Area of the top and bottom openings of shade/blind (m2)
4297 : Real64 ABotGap;
4298 : Real64 ALeftGap; // Area of the left and right openings of shade/blind (m2)
4299 : Real64 ARightGap;
4300 : Real64 AHolesGap; // Area of the holes in the shade/blind (assumed homogeneously
4301 : // distributed) (m2)
4302 : Real64 ATopLRH; // Intermediate variables
4303 : Real64 ABotLRH;
4304 : Real64 AEqInlet; // Equivalent inlet and outlet opening areas (m2)
4305 : Real64 AEqOutlet;
4306 : Real64 Zinlet; // Inlet and outlet pressure loss factors
4307 : Real64 Zoutlet;
4308 : Real64 AVGap; // Coeff. of VGap**2 term in pressure balance equation
4309 : Real64 BVGap; // Coeff. of VGap term in pressure balance equation
4310 : Real64 CVGap; // VGap-independent term in pressure balance equation
4311 176896 : Array1D<Real64> GapHeightChar(2); // Characteristic height of the gap gas temperature profile (m)
4312 176896 : Array1D<Real64> EpsChar(2); // EXP(-GapHeight/GapHeightChar(IGap))
4313 176896 : Array1D<Real64> TAve(2); // Average of TGlass and TShade for the gaps (K)
4314 : Real64 con; // Gap gas conductivity and derivative
4315 : Real64 gr; // Gap gas Grashof number
4316 : Real64 pr; // Gap gas Prandtl number
4317 : Real64 nu; // Gap gas Nusselt number
4318 : WinShadingType ShadeFlag; // Shading flag
4319 : int BlNum; // Blind number
4320 : int IGap; // Gap counter; 1 = gap on outer side of shade/blind, 2 = gap on inner side.
4321 : int IGapInc; // Gap increment (0 or 1)
4322 :
4323 88448 : ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
4324 88448 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4325 88448 : nglassfaces = 2 * state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers;
4326 :
4327 88448 : if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { // Double glazing
4328 51045 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3);
4329 51045 : IGapInc = 0;
4330 153135 : for (IGap = 1; IGap <= 2; ++IGap) {
4331 102090 : TGlassFace(IGap) = state.dataWindowManager->thetas[IGap];
4332 102090 : TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 3];
4333 : }
4334 : } else { // Triple glazing
4335 37403 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5);
4336 37403 : IGapInc = 1;
4337 112209 : for (IGap = 1; IGap <= 2; ++IGap) {
4338 74806 : TGlassFace(IGap) = state.dataWindowManager->thetas[IGap + 2];
4339 74806 : TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 5];
4340 : }
4341 : }
4342 :
4343 265344 : for (IGap = 1; IGap <= 2; ++IGap) {
4344 176896 : TAve(IGap) = 0.5 * (TGlassFace(IGap) + TShadeFace(IGap));
4345 176896 : if (iter == 0) {
4346 17612 : TGapOld(IGap) = TAve(IGap);
4347 : } else {
4348 159284 : TGapOld(IGap) = TGapNew(IGap);
4349 : }
4350 : // Conductance of gaps on either side of shade/blind assuming gaps are sealed
4351 176896 : WindowGasConductance(state, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, con, pr, gr);
4352 176896 : NusseltNumber(state, SurfNum, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, gr, pr, nu);
4353 176896 : hGapStill(IGap) = con / state.dataWindowManager->gap[IGap + IGapInc - 1] * nu;
4354 : }
4355 :
4356 : // For near-horizontal windows (i.e., no more than 5 deg from horizontal) assume
4357 : // there is no air flow thru gap
4358 :
4359 88448 : if (std::abs(state.dataSurface->Surface(SurfNum).SinTilt) < 0.0872) {
4360 0 : VGap = 0.0;
4361 0 : for (IGap = 1; IGap <= 2; ++IGap) {
4362 0 : hcv(IGap) = 2.0 * hGapStill(IGap);
4363 0 : TGapNew(IGap) = TAve(IGap);
4364 : }
4365 0 : return;
4366 : }
4367 :
4368 88448 : GapHeight = state.dataSurface->Surface(SurfNum).Height;
4369 88448 : GapDepth = state.dataWindowManager->gap[IGapInc];
4370 88448 : AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
4371 :
4372 88448 : if (ShadeFlag == WinShadingType::BGShade) {
4373 : // Shade on
4374 46150 : ATopGap = state.dataMaterial->Material(MatNumSh).WinShadeTopOpeningMult * AGap;
4375 46150 : ABotGap = state.dataMaterial->Material(MatNumSh).WinShadeBottomOpeningMult * AGap;
4376 46150 : ALeftGap = state.dataMaterial->Material(MatNumSh).WinShadeLeftOpeningMult * GapHeight * GapDepth;
4377 46150 : ARightGap = state.dataMaterial->Material(MatNumSh).WinShadeRightOpeningMult * GapHeight * GapDepth;
4378 46150 : AHolesGap = state.dataMaterial->Material(MatNumSh).WinShadeAirFlowPermeability * GapHeight * state.dataSurface->Surface(SurfNum).Width;
4379 : } else {
4380 : // Blind on
4381 42298 : BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
4382 42298 : ATopGap = state.dataHeatBal->Blind(BlNum).BlindTopOpeningMult * AGap;
4383 42298 : ABotGap = state.dataHeatBal->Blind(BlNum).BlindBottomOpeningMult * AGap;
4384 42298 : ALeftGap = state.dataHeatBal->Blind(BlNum).BlindLeftOpeningMult * GapHeight * GapDepth;
4385 42298 : ARightGap = state.dataHeatBal->Blind(BlNum).BlindRightOpeningMult * GapHeight * GapDepth;
4386 42298 : AHolesGap = state.dataSurface->SurfWinBlindAirFlowPermeability(SurfNum) * GapHeight * state.dataSurface->Surface(SurfNum).Width;
4387 : }
4388 :
4389 265344 : for (IGap = 1; IGap <= 2; ++IGap) {
4390 176896 : WindowGasPropertiesAtTemp(state, TGapOld(IGap), IGap + IGapInc, RhoGas(IGap), ViscGas(IGap));
4391 : }
4392 :
4393 88448 : BVGap = 12.0 * (ViscGas(1) + ViscGas(2)) * GapHeight / pow_2(GapDepth);
4394 : // Adding 0.000001 and 0.000002 in the following gives ATopLRH = ABotLRH =
4395 : // 0.25*(ALeftGap + ARightGap + AHolesGap) when ABotGap = ATopGap = 0.0 (shade/blind sealed at
4396 : // bottom and top but possibly open at left side, right side and/or in shade/blind)
4397 88448 : ATopLRH = 0.5 * ((ATopGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
4398 88448 : ABotLRH = 0.5 * ((ABotGap + 0.000001) / (ABotGap + ATopGap + 0.000002)) * (ALeftGap + ARightGap + AHolesGap);
4399 88448 : AEqInlet = ABotGap + ATopLRH;
4400 88448 : AEqOutlet = ATopGap + ABotLRH;
4401 :
4402 : // Adding 0.000001 in the following gives very large value of Zinlet for AEqInlet = 0 and
4403 : // very large value of Zoutlet for AEqInlet = 0; this gives VGap close to zero, as required
4404 : // when there is no inlet and/or outlet for air. This then reduces to the
4405 : // case of a completely sealed shade, in which hcv = 2*hGapStill and QConvGap = 0.
4406 88448 : Zinlet = pow_2(AGap / (0.6 * AEqInlet + 0.000001) - 1.0);
4407 88448 : Zoutlet = pow_2(AGap / (0.6 * AEqOutlet + 0.000001) - 1.0);
4408 88448 : AVGap = 0.5 * (RhoGas(1) + RhoGas(2)) * (1.0 + Zinlet + Zoutlet);
4409 88448 : WindowGasPropertiesAtTemp(state, state.dataWindowManager->TKelvin, 1 + IGapInc, RhoGasZero, ViscGasZero);
4410 88448 : RhoTRef = RhoGasZero * state.dataWindowManager->TKelvin;
4411 88448 : CVGap = RhoTRef * 9.81 * GapHeight * state.dataSurface->Surface(SurfNum).SinTilt * (TGapOld(1) - TGapOld(2)) / (TGapOld(1) * TGapOld(2));
4412 :
4413 : // Solution of quadratic equation in VGap
4414 :
4415 88448 : VGap = (std::sqrt(pow_2(BVGap) + std::abs(4 * AVGap * CVGap)) - BVGap) / (2 * AVGap);
4416 :
4417 265344 : for (IGap = 1; IGap <= 2; ++IGap) {
4418 176896 : hcv(IGap) = 2.0 * hGapStill(IGap) + 4.0 * VGap;
4419 176896 : GapHeightChar(IGap) = RhoGas(IGap) * 1008.0 * GapDepth * VGap / (2.0 * hcv(IGap));
4420 : // The following avoids divide by zero and exponential underflow
4421 176896 : if (GapHeightChar(IGap) == 0.0) {
4422 0 : EpsChar(IGap) = 0.0;
4423 176896 : } else if ((GapHeight / GapHeightChar(IGap)) > 15.0) {
4424 8936 : EpsChar(IGap) = 0.0;
4425 : } else {
4426 167960 : EpsChar(IGap) = std::exp(-GapHeight / GapHeightChar(IGap));
4427 : }
4428 : }
4429 :
4430 88448 : TGapNew(1) =
4431 88448 : TAve(1) - (TAve(1) - TAve(2)) * (GapHeightChar(1) / GapHeight) * (1 - EpsChar(1)) * (1 - EpsChar(2)) / (1 - EpsChar(1) * EpsChar(2));
4432 :
4433 88448 : TGapNew(2) =
4434 88448 : TAve(2) - (TAve(2) - TAve(1)) * (GapHeightChar(2) / GapHeight) * (1 - EpsChar(1)) * (1 - EpsChar(2)) / (1 - EpsChar(1) * EpsChar(2));
4435 : }
4436 :
4437 : //****************************************************************************
4438 :
4439 16422 : void BetweenGlassForcedFlow(EnergyPlusData &state,
4440 : int const SurfNum, // Surface number
4441 : int const iter, // Iteration number for glass heat balance calculation
4442 : Real64 &VGap, // Air velocity in airflow gap (m/s)
4443 : Real64 &TGapNew, // Current-iteration average air temp in airflow gap (K)
4444 : Real64 &TGapOutlet, // Temperature of air leaving glass-shade/blind gap at top for upward
4445 : Real64 &hcv, // Convection coefficient from gap glass faces to gap air (W/m2-K)
4446 : Real64 &QConvGap // Convective heat gain from air flow gap (W)
4447 : )
4448 : {
4449 :
4450 : // SUBROUTINE INFORMATION:
4451 : // AUTHOR F. Winkelmann
4452 : // DATE WRITTEN February 2003
4453 : // MODIFIED na
4454 : // RE-ENGINEERED na
4455 :
4456 : // PURPOSE OF THIS SUBROUTINE:
4457 : // Called by SolveForWindowTemperatures for "airflow windows",i.e., windows
4458 : // with forced airflow in one of the gaps between layers of glass. Based on
4459 : // the velocity of airflow through gap, finds effective temperature of gap air,
4460 : // convective heat transfer coefficient from glass to gap air,
4461 : // the gap outlet temperature, and the outlet convective heat flow.
4462 :
4463 : // Called only for double and triple glazing. For triple glazing the airflow
4464 : // is assumed to be between the inner two layers of glass (glass layers 2 and 3).
4465 :
4466 : // METHODOLOGY EMPLOYED:
4467 : // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
4468 : // Detailed Calculations"
4469 :
4470 : // Using/Aliasing
4471 : using ScheduleManager::GetCurrentScheduleValue;
4472 :
4473 : // Locals
4474 : // SUBROUTINE ARGUMENT DEFINITIONS:
4475 : // air flow or bottom for downward air flow (K)
4476 :
4477 : int ConstrNum; // Construction number of surface
4478 : int NGlass; // Number of glass layers in construction
4479 : int GapNum; // Number of airflow gap
4480 : Real64 TGapInlet; // Temperature of air entering glass-shade/blind gap at bottom for upward
4481 : // air flow or top for downward air flow (K)
4482 : Real64 TGlassFace1; // Temperature of left-hand glass surface facing airflow gap (K)
4483 : Real64 TGlassFace2; // Temperature of right-hand glass surface facing airflow gap (K)
4484 : Real64 hGapStill; // Still-air gap conduction/convection coeff (W/m2-K)
4485 : Real64 TGapOld; // Previous-iteration average air temp in airflow gap (K)
4486 : Real64 GapHeight; // Vertical length of airflow gap (m)
4487 : Real64 GapDepth; // Thickness of airflow gap (m)
4488 : Real64 RhoAir; // Density of airflow gap air at a temperature of TGapOld (kg/m3)
4489 : Real64 AGap; // Cross sectional area of airflow gap (m2); for vertical window, this
4490 : // is in horizontal plane normal to window.
4491 : Real64 GapHeightChar; // Characteristic height of the airflow gap air temperature profile (m)
4492 : Real64 TAve; // Average of TGlassFace1 and TGlassFace2 (K)
4493 : // REAL(r64) :: AirProps(8) ! Air properties
4494 : Real64 con; // Gap conductivity and derivative
4495 : Real64 gr; // Gap air Grashof number
4496 : Real64 pr; // Gap air Prandtl number
4497 : Real64 nu; // Gap air Nusselt number
4498 :
4499 : // Air properties
4500 : // Dens dDens/dT Con dCon/dT Vis dVis/dT Prandtl dPrandtl/dT
4501 : // DATA AirProps / 1.29, -0.4d-2, 2.41d-2, 7.6d-5, 1.73d-5, 1.0d-7, 0.72, 1.8d-3 /
4502 :
4503 16422 : ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
4504 16422 : NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
4505 16422 : TGlassFace1 = state.dataWindowManager->thetas[2 * NGlass - 3];
4506 16422 : TGlassFace2 = state.dataWindowManager->thetas[2 * NGlass - 2];
4507 16422 : GapNum = NGlass - 1;
4508 16422 : TAve = 0.5 * (TGlassFace1 + TGlassFace2);
4509 :
4510 16422 : if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
4511 16422 : TGapInlet = state.dataWindowManager->tin; // Source is inside air
4512 : } else {
4513 0 : TGapInlet = state.dataWindowManager->tout; // Source is outside air
4514 : }
4515 :
4516 16422 : if (iter == 0) {
4517 8064 : TGapOld = 0.5 * (TAve + TGapInlet);
4518 : } else {
4519 8358 : TGapOld = TGapNew;
4520 : }
4521 :
4522 : // Conductance of gap assuming it is sealed
4523 16422 : WindowGasConductance(state, TGlassFace1, TGlassFace2, GapNum, con, pr, gr);
4524 16422 : NusseltNumber(state, SurfNum, TGlassFace1, TGlassFace2, GapNum, gr, pr, nu);
4525 16422 : hGapStill = con / state.dataWindowManager->gap[GapNum - 1] * nu;
4526 16422 : GapHeight = state.dataSurface->Surface(SurfNum).Height;
4527 16422 : GapDepth = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(2 * NGlass - 2)).Thickness;
4528 16422 : AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
4529 16422 : VGap = state.dataSurface->SurfWinAirflowThisTS(SurfNum) / GapDepth;
4530 16422 : hcv = 2.0 * hGapStill + 4.0 * VGap;
4531 16422 : RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapOld - state.dataWindowManager->TKelvin);
4532 16422 : GapHeightChar = RhoAir * 1008.0 * GapDepth * VGap / (2.0 * hcv);
4533 : // The following avoids divide by zero and exponential underflow
4534 16422 : if (GapHeightChar == 0.0) {
4535 0 : TGapOutlet = TAve;
4536 16422 : } else if ((GapHeight / GapHeightChar) > 15.0) {
4537 0 : TGapOutlet = TAve;
4538 : } else {
4539 16422 : TGapOutlet = TAve - (TAve - TGapInlet) * std::exp(-GapHeight / GapHeightChar);
4540 : }
4541 16422 : TGapNew = TAve - (GapHeightChar / GapHeight) * (TGapOutlet - TGapInlet);
4542 : // Convective heat flow from gap [W]
4543 16422 : RhoAir = state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapNew - state.dataWindowManager->TKelvin);
4544 16422 : QConvGap = RhoAir * AGap * VGap * 1008.0 * (TGapOutlet - TGapInlet);
4545 16422 : }
4546 :
4547 : //****************************************************************************
4548 :
4549 20000 : void BetweenGlassShadeForcedFlow(EnergyPlusData &state,
4550 : int const SurfNum, // Surface number
4551 : int const iter, // Iteration number for glass heat balance calculation
4552 : Real64 &VGap, // Air velocity in each gap (m/s)
4553 : Array1A<Real64> TGapNew, // Current-iteration average gas temp in gaps (K)
4554 : Real64 &TGapOutletAve, // Average of TGapOutlet(1) and TGapOutlet(2) (K)
4555 : Array1A<Real64> hcv, // Convection coefficient from gap glass or shade to gap gas (W/m2-K)
4556 : Real64 &QConvTot // Sum of convective heat flow from gaps (W)
4557 : )
4558 : {
4559 :
4560 : // SUBROUTINE INFORMATION:
4561 : // AUTHOR F. Winkelmann
4562 : // DATE WRITTEN February 2003
4563 : // MODIFIED na
4564 : // RE-ENGINEERED na
4565 :
4566 : // PURPOSE OF THIS SUBROUTINE:
4567 : // Called by SolveForWindowTemperatures for airflow windows with a
4568 : // between-glass shade or blind over which fan-forced air flows.
4569 : // Based on the air flow velocity (which is assumed to be the same in the
4570 : // gaps on either side of the shade/blind), finds, for each gap: the average
4571 : // air temperature, the shade/blind or glass surface to air convective heat
4572 : // transfer coefficient, the gap outlet temperature, and the outlet convective heat flow.
4573 :
4574 : // Called only for double and triple glazing. For triple glazing the airflow
4575 : // is assumed to be between the inner two layers of glass (glass layers 2 and 3),
4576 : // between which the shade/blind is located.
4577 :
4578 : // METHODOLOGY EMPLOYED:
4579 : // Based on ISO/DIS 15099, "Thermal Performance of Windows, Doors and Shading Devices --
4580 : // Detailed Calculations," 1/12/2000, Chapter 7, "Shading Devices."
4581 :
4582 : // Argument array dimensioning
4583 20000 : TGapNew.dim(2);
4584 20000 : hcv.dim(2);
4585 :
4586 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4587 : int ConstrNumSh; // Shaded construction number
4588 : int MatNumSh; // Material number of shade/blind layer
4589 : // In the following, "gaps" refer to the gaps on either side of the shade/blind
4590 40000 : Array1D<Real64> TGlassFace(2); // Temperature of glass surfaces facing gaps (K)
4591 40000 : Array1D<Real64> TShadeFace(2); // Temperature of shade surfaces facing gaps (K)
4592 40000 : Array1D<Real64> hGapStill(2); // Still-air conduction/convection coeffs for the gaps (W/m2-K)
4593 40000 : Array1D<Real64> TGapOld(2); // Previous-iteration average gas temp in gaps (K)
4594 : Real64 GapHeight; // Vertical length of glass-shade/blind gap (m)
4595 : Real64 GapDepth; // Distance from shade/blind to glass; assumed same for both gaps (m)
4596 40000 : Array1D<Real64> RhoAir(2); // Density of gap air (kg/m3)
4597 : Real64 AGap; // Cross sectional area of each gap (m2); for vertical window, this
4598 : // is in horizontal plane normal to window.
4599 : Real64 TGapInlet; // Gap inlet air temperature (K)
4600 40000 : Array1D<Real64> TGapOutlet(2); // Gap outlet air temperature (K)
4601 40000 : Array1D<Real64> QConvGap(2); // Convective heat flow from each gap (W)
4602 40000 : Array1D<Real64> GapHeightChar(2); // Characteristic height of the gap air temperature profile (m)
4603 40000 : Array1D<Real64> TAve(2); // Average of TGlass and TShade for the gaps (K)
4604 : Real64 con; // Gap air conductivity and derivative
4605 : Real64 gr; // Gap air Grashof number
4606 : Real64 pr; // Gap air Prandtl number
4607 : Real64 nu; // Gap air Nusselt number
4608 : WinShadingType ShadeFlag; // Shading flag
4609 : int IGap; // Gap counter; 1 = gap on outer side of shade/blind, 2 = gap on inner side.
4610 : int IGapInc; // Gap increment; =0, double glass, =1, triple glass
4611 : // REAL(r64) :: AirProps(8) ! Air properties
4612 :
4613 : // Air properties
4614 : // Dens dDens/dT Con dCon/dT Vis dVis/dT Prandtl dPrandtl/dT
4615 : // DATA AirProps / 1.29, -0.4d-2, 2.41d-2, 7.6d-5, 1.73d-5, 1.0d-7, 0.72, 1.8d-3 /
4616 :
4617 20000 : ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
4618 20000 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
4619 :
4620 20000 : if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { // Double glazing
4621 9989 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3);
4622 9989 : IGapInc = 0;
4623 29967 : for (IGap = 1; IGap <= 2; ++IGap) {
4624 19978 : TGlassFace(IGap) = state.dataWindowManager->thetas[IGap];
4625 19978 : TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 3];
4626 : }
4627 : } else { // Triple glazing
4628 10011 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5);
4629 10011 : IGapInc = 1;
4630 30033 : for (IGap = 1; IGap <= 2; ++IGap) {
4631 20022 : TGlassFace(IGap) = state.dataWindowManager->thetas[IGap + 2];
4632 20022 : TShadeFace(IGap) = state.dataWindowManager->thetas[IGap + 5];
4633 : }
4634 : }
4635 :
4636 20000 : if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) {
4637 20000 : TGapInlet = state.dataWindowManager->tin;
4638 : } else {
4639 0 : TGapInlet = state.dataWindowManager->tout;
4640 : }
4641 :
4642 20000 : GapHeight = state.dataSurface->Surface(SurfNum).Height;
4643 20000 : GapDepth = state.dataWindowManager->gap[IGapInc];
4644 20000 : AGap = GapDepth * state.dataSurface->Surface(SurfNum).Width;
4645 : // Factor of 2 below assumes gaps on either side of shade/blind have same depth
4646 20000 : VGap = state.dataSurface->SurfWinAirflowThisTS(SurfNum) / (2.0 * GapDepth);
4647 :
4648 60000 : for (IGap = 1; IGap <= 2; ++IGap) {
4649 40000 : TAve(IGap) = 0.5 * (TGlassFace(IGap) + TShadeFace(IGap));
4650 40000 : if (iter == 0) {
4651 16128 : TGapOld(IGap) = TAve(IGap);
4652 : } else {
4653 23872 : TGapOld(IGap) = TGapNew(IGap);
4654 : }
4655 : // Conductance of gaps on either side of shade/blind assuming gaps are sealed
4656 40000 : WindowGasConductance(state, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, con, pr, gr);
4657 40000 : NusseltNumber(state, SurfNum, TGlassFace(IGap), TShadeFace(IGap), IGap + IGapInc, gr, pr, nu);
4658 40000 : hGapStill(IGap) = con / state.dataWindowManager->gap[IGap + IGapInc - 1] * nu;
4659 : // Shade/blind or glass surface to air convection coefficient
4660 40000 : hcv(IGap) = 2.0 * hGapStill(IGap) + 4.0 * VGap;
4661 40000 : RhoAir(IGap) =
4662 40000 : state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapOld(IGap) - state.dataWindowManager->TKelvin);
4663 40000 : hcv(IGap) = 2.0 * hGapStill(IGap) + 4.0 * VGap;
4664 40000 : GapHeightChar(IGap) = RhoAir(IGap) * 1008.0 * GapDepth * VGap / (2.0 * hcv(IGap));
4665 : // The following avoids divide by zero and exponential underflow
4666 40000 : if (GapHeightChar(IGap) == 0.0) {
4667 0 : TGapOutlet(IGap) = TAve(IGap);
4668 40000 : } else if ((GapHeight / GapHeightChar(IGap)) > 15.0) {
4669 0 : TGapOutlet(IGap) = TAve(IGap);
4670 : } else {
4671 40000 : TGapOutlet(IGap) = TAve(IGap) - (TAve(IGap) - TGapInlet) * std::exp(-GapHeight / GapHeightChar(IGap));
4672 : }
4673 40000 : TGapNew(IGap) = TAve(IGap) - (GapHeightChar(IGap) / GapHeight) * (TGapOutlet(IGap) - TGapInlet);
4674 : // Convective heat flow from gap [W]
4675 40000 : RhoAir(IGap) =
4676 40000 : state.dataWindowManager->AirProps[0] + state.dataWindowManager->AirProps[1] * (TGapNew(IGap) - state.dataWindowManager->TKelvin);
4677 40000 : QConvGap(IGap) = RhoAir(IGap) * AGap * VGap * 1008.0 * (TGapOutlet(IGap) - TGapInlet);
4678 : }
4679 :
4680 20000 : QConvTot = QConvGap(1) + QConvGap(2);
4681 20000 : TGapOutletAve = 0.5 * (TGapOutlet(1) + TGapOutlet(2));
4682 20000 : }
4683 :
4684 : //****************************************************************************
4685 :
4686 42053009 : void LUdecomposition(EnergyPlusData &state,
4687 : Array2<Real64> &ajac, // As input: matrix to be decomposed;
4688 : int const n, // Dimension of matrix
4689 : Array1D_int &indx, // Vector of row permutations
4690 : Real64 &d // +1 if even number of row interchange is even, -1
4691 : )
4692 : {
4693 :
4694 : // SUBROUTINE INFORMATION:
4695 : // AUTHOR F. Winkelmann, adapted from Numerical Recipes
4696 : // DATE WRITTEN February 2000
4697 : // MODIFIED na
4698 : // RE-ENGINEERED na
4699 :
4700 : // PURPOSE OF THIS SUBROUTINE:
4701 : // Performs LU decomposition of a matrix.
4702 :
4703 : // SUBROUTINE ARGUMENT DEFINITIONS:
4704 : // as output: decomposed matrix
4705 : // if odd
4706 :
4707 : int i; // Counters
4708 : int j;
4709 : int k;
4710 : int imax; // Temporary variable
4711 : // as output: decomposed matrix
4712 42053009 : auto &vv = state.dataWindowManager->vv;
4713 : Real64 aamax; // Absolute value of largest element of matrix
4714 : Real64 dum; // Temporary variable
4715 : Real64 sum; // Sum of products of matrix elements
4716 :
4717 42053009 : assert(n <= 10); // vv sizing
4718 :
4719 42053009 : d = 1.0;
4720 153808481 : for (i = 1; i <= n; ++i) {
4721 111755472 : aamax = 0.0;
4722 451959464 : for (j = 1; j <= n; ++j) {
4723 340203992 : if (std::abs(ajac(j, i)) > aamax) aamax = std::abs(ajac(j, i));
4724 : }
4725 111755472 : if (aamax == 0.0) ShowFatalError(state, "Singular matrix in LUdecomposition, window calculations");
4726 111755472 : vv[i - 1] = 1.0 / aamax;
4727 : }
4728 153808481 : for (j = 1; j <= n; ++j) {
4729 225979732 : for (i = 1; i <= j - 1; ++i) {
4730 114224260 : sum = ajac(j, i);
4731 179948760 : for (k = 1; k <= i - 1; ++k) {
4732 65724500 : sum -= ajac(k, i) * ajac(j, k);
4733 : }
4734 114224260 : ajac(j, i) = sum;
4735 : }
4736 111755472 : aamax = 0.0;
4737 337735204 : for (i = j; i <= n; ++i) {
4738 225979732 : sum = ajac(j, i);
4739 405928492 : for (k = 1; k <= j - 1; ++k) {
4740 179948760 : sum -= ajac(k, i) * ajac(j, k);
4741 : }
4742 225979732 : ajac(j, i) = sum;
4743 225979732 : dum = vv[i - 1] * std::abs(sum);
4744 225979732 : if (dum >= aamax) {
4745 112176327 : imax = i;
4746 112176327 : aamax = dum;
4747 : }
4748 : }
4749 111755472 : if (j != imax) {
4750 2450119 : for (k = 1; k <= n; ++k) {
4751 2029264 : dum = ajac(k, imax);
4752 2029264 : ajac(k, imax) = ajac(k, j);
4753 2029264 : ajac(k, j) = dum;
4754 : }
4755 420855 : d = -d;
4756 420855 : vv[imax - 1] = vv[j - 1];
4757 : }
4758 111755472 : indx(j) = imax;
4759 111755472 : if (ajac(j, j) == 0.0) ajac(j, j) = DataGlobalConstants::rTinyValue;
4760 111755472 : if (j != n) {
4761 69702463 : dum = 1.0 / ajac(j, j);
4762 183926723 : for (i = j + 1; i <= n; ++i) {
4763 114224260 : ajac(j, i) *= dum;
4764 : }
4765 : }
4766 : }
4767 42053009 : }
4768 :
4769 : //**************************************************************************
4770 :
4771 42053009 : void LUsolution(Array2<Real64> const &a, // Matrix and vector in a.x = b;
4772 : int const n, // Dimension of a and b
4773 : Array1D_int const &indx, // Vector of row permutations
4774 : Array1D<Real64> &b // Matrix and vector in a.x = b;
4775 : )
4776 : {
4777 :
4778 : // SUBROUTINE INFORMATION:
4779 : // AUTHOR F. Winkelmann, adapted from Numerical Recipes
4780 : // DATE WRITTEN February 2000
4781 : // MODIFIED na
4782 : // RE-ENGINEERED na
4783 :
4784 : // PURPOSE OF THIS SUBROUTINE:
4785 : // Solves set of linear equations a.x = b
4786 :
4787 : // Locals
4788 : // SUBROUTINE ARGUMENT DEFINITIONS:
4789 : // b is also output as the solution, x
4790 : // b is also output as the solution, x
4791 :
4792 : int i; // Counters
4793 : int j;
4794 : int ii; // Intermediate variables
4795 : int ll;
4796 : Real64 sum; // Summation variable
4797 :
4798 42053009 : ii = 0;
4799 153808481 : for (i = 1; i <= n; ++i) {
4800 111755472 : ll = indx(i);
4801 111755472 : sum = b(ll);
4802 111755472 : b(ll) = b(i);
4803 111755472 : if (ii != 0) {
4804 183926723 : for (j = ii; j <= i - 1; ++j) {
4805 114224260 : sum -= a(j, i) * b(j);
4806 : }
4807 42053009 : } else if (sum != 0.0) {
4808 42053009 : ii = i;
4809 : }
4810 111755472 : b(i) = sum;
4811 : }
4812 153808481 : for (i = n; i >= 1; --i) {
4813 111755472 : sum = b(i);
4814 225979732 : for (j = i + 1; j <= n; ++j) {
4815 114224260 : sum -= a(j, i) * b(j);
4816 : }
4817 111755472 : b(i) = sum / a(i, i);
4818 : }
4819 42053009 : }
4820 :
4821 : //******************************************************************************
4822 :
4823 13949597 : void WindowGasConductance(EnergyPlusData &state,
4824 : Real64 const tleft, // Temperature of gap surface closest to outside (K)
4825 : Real64 const tright, // Temperature of gap surface closest to zone (K)
4826 : int const IGap, // Gap number
4827 : Real64 &con, // Gap gas conductance (W/m2-K)
4828 : Real64 &pr, // Gap gas Prandtl number
4829 : Real64 &gr // Gap gas Grashof number
4830 : )
4831 : {
4832 :
4833 : // SUBROUTINE INFORMATION:
4834 : // AUTHOR Adapted by Fred Winkelmann from Window5 subroutine gasses
4835 : // DATE WRITTEN September 2001
4836 : // MODIFIED na
4837 : // RE-ENGINEERED na
4838 :
4839 : // PURPOSE OF THIS SUBROUTINE:
4840 : // Find the coefficient of convective/conductive heat transfer in the gas-filled gap
4841 : // between isothermal solid layers. The gap may be filled with a single gas or a gas mixture.
4842 :
4843 : // METHODOLOGY EMPLOYED:
4844 : // Based on methodology in Chapter 5 of the July 18, 2001 draft of ISO 15099,
4845 : // "Thermal Performance of Windows, Doors and Shading Devices--Detailed Calculations."
4846 : // The equation numbers below correspond to those in the standard.
4847 :
4848 : // REFERENCES:
4849 : // Window5 source code; ISO 15099
4850 :
4851 13949597 : constexpr Real64 pres(1.0e5); // Gap gas pressure (Pa)
4852 13949597 : constexpr Real64 gaslaw(8314.51); // Molar gas constant (J/kMol-K)
4853 13949597 : Real64 const two_sqrt_2(2.0 * std::sqrt(2.0));
4854 :
4855 : int IMix; // Counters of gases in a mixture
4856 : int i;
4857 : int j;
4858 : int NMix; // Number of gases in a mixture
4859 : Real64 molmix; // Molecular weight of mixture
4860 :
4861 13949597 : auto &kprime = state.dataWindowManager->kprime;
4862 13949597 : auto &kdblprm = state.dataWindowManager->kdblprm;
4863 13949597 : auto &mukpdwn = state.dataWindowManager->mukpdwn;
4864 13949597 : auto &kpdown = state.dataWindowManager->kpdown;
4865 13949597 : auto &kdpdown = state.dataWindowManager->kdpdown;
4866 13949597 : auto &frct = state.dataWindowManager->frct;
4867 13949597 : auto &fvis = state.dataWindowManager->fvis;
4868 13949597 : auto &fcon = state.dataWindowManager->fcon;
4869 13949597 : auto &fdens = state.dataWindowManager->fdens;
4870 13949597 : auto &fcp = state.dataWindowManager->fcp;
4871 :
4872 : Real64 kpmix; // Monotonic thermal conductivity of mixture
4873 : Real64 kdpmix;
4874 : Real64 kmix; // For accumulating conductance of gas mixture
4875 : Real64 mumix; // For accumulating viscosity of gas mixture
4876 13949597 : Real64 visc(0.0); // Dynamic viscosity of mixture at tmean (g/m-s)
4877 13949597 : Real64 cp(0.0); // Specific heat of mixture at tmean (J/m3-K)
4878 13949597 : Real64 dens(0.0); // Density of mixture at tmean (kg/m3)
4879 : Real64 cpmixm; // Gives cp when divided by molmix
4880 : Real64 phimup; // Numerator factor
4881 : Real64 downer; // Denominator factor
4882 : Real64 psiup; // Numerator factor
4883 : Real64 psiterm; // Factor
4884 : Real64 phikup; // Numerator factor
4885 : Real64 rhomix; // Density of gas mixture (kg/m3)
4886 :
4887 : // Autodesk:Logic Either assert NMix>0 or handle NMix<=0 in logic so that con and locals guar. initialized before use
4888 13949597 : NMix = state.dataWindowManager->gnmix[IGap - 1];
4889 :
4890 28026599 : for (IMix = 1; IMix <= NMix; ++IMix) {
4891 14077002 : frct[IMix - 1] = state.dataWindowManager->gfract[IMix - 1][IGap - 1];
4892 : }
4893 :
4894 13949597 : Real64 const tmean(0.5 * (tleft + tright)); // Average gap gas temperature (K)
4895 13949597 : Real64 const tmean_2(pow_2(tmean));
4896 :
4897 27899194 : fcon[0] = state.dataWindowManager->gcon[0][0][IGap - 1] + state.dataWindowManager->gcon[1][0][IGap - 1] * tmean +
4898 13949597 : state.dataWindowManager->gcon[2][0][IGap - 1] * tmean_2;
4899 27899194 : fvis[0] = state.dataWindowManager->gvis[0][0][IGap - 1] + state.dataWindowManager->gvis[1][0][IGap - 1] * tmean +
4900 13949597 : state.dataWindowManager->gvis[2][0][IGap - 1] * tmean_2;
4901 27899194 : fcp[0] = state.dataWindowManager->gcp[0][0][IGap - 1] + state.dataWindowManager->gcp[1][0][IGap - 1] * tmean +
4902 13949597 : state.dataWindowManager->gcp[2][0][IGap - 1] * tmean_2;
4903 13949597 : fdens[0] = pres * state.dataWindowManager->gwght[0][IGap - 1] / (gaslaw * tmean); // Density using ideal gas law:
4904 : // rho=(presure*molecweight)/(gasconst*tmean)
4905 :
4906 13949597 : if (NMix == 1) { // Single gas
4907 13822192 : con = fcon[0];
4908 13822192 : visc = fvis[0];
4909 13822192 : cp = fcp[0];
4910 13822192 : dens = fdens[0];
4911 127405 : } else if (NMix > 1) { // Multiple gases; calculate mixture properties
4912 127405 : molmix = frct[0] * state.dataWindowManager->gwght[0][IGap - 1]; // initialize eq. 56
4913 127405 : cpmixm = molmix * fcp[0]; // initialize eq. 58
4914 127405 : kprime[0] = 3.75 * (gaslaw / state.dataWindowManager->gwght[0][IGap - 1]) * fvis[0]; // eq. 67
4915 127405 : kdblprm[0] = fcon[0] - kprime[0]; // eq. 67
4916 :
4917 : // Initialize summations for eqns 60-66
4918 127405 : mumix = 0.0;
4919 127405 : kpmix = 0.0;
4920 127405 : kdpmix = 0.0;
4921 127405 : mukpdwn[0] = 1.0;
4922 127405 : kpdown[0] = 1.0;
4923 127405 : kdpdown[0] = 1.0;
4924 :
4925 : // Calculate properties of mixture constituents
4926 254810 : for (i = 2; i <= NMix; ++i) {
4927 254810 : fcon[i - 1] = state.dataWindowManager->gcon[0][i - 1][IGap - 1] + state.dataWindowManager->gcon[1][i - 1][IGap - 1] * tmean +
4928 127405 : state.dataWindowManager->gcon[2][i - 1][IGap - 1] * tmean_2;
4929 254810 : fvis[i - 1] = state.dataWindowManager->gvis[0][i - 1][IGap - 1] + state.dataWindowManager->gvis[1][i - 1][IGap - 1] * tmean +
4930 127405 : state.dataWindowManager->gvis[2][i - 1][IGap - 1] * tmean_2;
4931 254810 : fcp[i - 1] = state.dataWindowManager->gcp[0][i - 1][IGap - 1] + state.dataWindowManager->gcp[1][i - 1][IGap - 1] * tmean +
4932 127405 : state.dataWindowManager->gcp[2][i - 1][IGap - 1] * tmean_2;
4933 127405 : fdens[i - 1] = pres * state.dataWindowManager->gwght[i - 1][IGap - 1] / (gaslaw * tmean);
4934 127405 : molmix += frct[i - 1] * state.dataWindowManager->gwght[i - 1][IGap - 1]; // eq. 56
4935 127405 : cpmixm += frct[i - 1] * fcp[i - 1] * state.dataWindowManager->gwght[i - 1][IGap - 1]; // eq. 58-59
4936 127405 : kprime[i - 1] = 3.75 * gaslaw / state.dataWindowManager->gwght[i - 1][IGap - 1] * fvis[i - 1]; // eq. 67
4937 127405 : kdblprm[i - 1] = fcon[i - 1] - kprime[i - 1]; // eq. 68
4938 127405 : mukpdwn[i - 1] = 1.0; // initialize denomonator of eq. 60
4939 127405 : kpdown[i - 1] = 1.0; // initialize denomonator of eq. 63
4940 127405 : kdpdown[i - 1] = 1.0; // initialize denomonator of eq. 65
4941 : }
4942 :
4943 382215 : for (i = 1; i <= NMix; ++i) {
4944 764430 : for (j = 1; j <= NMix; ++j) {
4945 : // numerator of equation 61
4946 1019240 : phimup = pow_2(1.0 + std::sqrt(fvis[i - 1] / fvis[j - 1]) * root_4(state.dataWindowManager->gwght[j - 1][IGap - 1] /
4947 509620 : state.dataWindowManager->gwght[i - 1][IGap - 1]));
4948 : // denomonator of eq. 61, 64 and 66
4949 509620 : downer = two_sqrt_2 *
4950 509620 : std::sqrt(1 + (state.dataWindowManager->gwght[i - 1][IGap - 1] / state.dataWindowManager->gwght[j - 1][IGap - 1]));
4951 : // calculate the denominator of eq. 60
4952 509620 : if (i != j) mukpdwn[i - 1] += phimup / downer * frct[j - 1] / frct[i - 1];
4953 : // numerator of eq. 64; psiterm is the multiplied term in backets
4954 1019240 : psiup = pow_2(1.0 + std::sqrt(kprime[i - 1] / kprime[j - 1]) * root_4(state.dataWindowManager->gwght[i - 1][IGap - 1] /
4955 509620 : state.dataWindowManager->gwght[j - 1][IGap - 1]));
4956 1528860 : psiterm = 1.0 + 2.41 * (state.dataWindowManager->gwght[i - 1][IGap - 1] - state.dataWindowManager->gwght[j - 1][IGap - 1]) *
4957 1019240 : (state.dataWindowManager->gwght[i - 1][IGap - 1] - 0.142 * state.dataWindowManager->gwght[j - 1][IGap - 1]) /
4958 509620 : pow_2(state.dataWindowManager->gwght[i - 1][IGap - 1] + state.dataWindowManager->gwght[j - 1][IGap - 1]);
4959 : // using the common denominator, downer, calculate the denominator for eq. 63
4960 509620 : if (i != j) kpdown[i - 1] += psiup * (psiterm / downer) * (frct[j - 1] / frct[i - 1]);
4961 : // calculate the numerator of eq. 66
4962 1019240 : phikup = pow_2(1.0 + std::sqrt(kprime[i - 1] / kprime[j - 1]) * root_4(state.dataWindowManager->gwght[i - 1][IGap - 1] /
4963 509620 : state.dataWindowManager->gwght[j - 1][IGap - 1]));
4964 : // using the common denominator, downer, calculate the denomonator for eq. 65
4965 509620 : if (i != j) kdpdown[i - 1] += (phikup / downer) * (frct[j - 1] / frct[i - 1]);
4966 : }
4967 254810 : mumix += fvis[i - 1] / mukpdwn[i - 1]; // eq. 60
4968 254810 : kpmix += kprime[i - 1] / kpdown[i - 1]; // eq. 63
4969 254810 : kdpmix += kdblprm[i - 1] / kdpdown[i - 1]; // eq. 65
4970 : }
4971 :
4972 : // Calculate the density of the mixture assuming an ideal gas
4973 127405 : rhomix = pres * molmix / (gaslaw * tmean); // eq. 57
4974 127405 : kmix = kpmix + kdpmix; // eq. 68-a
4975 :
4976 : // Final mixture properties
4977 127405 : visc = mumix;
4978 127405 : con = kmix;
4979 127405 : dens = rhomix;
4980 127405 : cp = cpmixm / molmix;
4981 :
4982 : } else {
4983 0 : assert(false);
4984 : } // End of check if single or multiple gases in gap
4985 :
4986 13949597 : pr = cp * visc / con;
4987 13949597 : gr = 9.807 * pow_3(state.dataWindowManager->gap[IGap - 1]) * std::abs(tleft - tright) * pow_2(dens) / (tmean * pow_2(visc));
4988 13949597 : }
4989 :
4990 : //******************************************************************************
4991 :
4992 265344 : void WindowGasPropertiesAtTemp(EnergyPlusData &state,
4993 : Real64 const tmean, // Temperature of gas in gap (K)
4994 : int const IGap, // Gap number
4995 : Real64 &dens, // Gap gas density at tmean (kg/m3)
4996 : Real64 &visc // Gap gas dynamic viscosity at tmean (g/m-s)
4997 : )
4998 : {
4999 :
5000 : // SUBROUTINE INFORMATION:
5001 : // AUTHOR F. Winkelmann
5002 : // DATE WRITTEN December 2002
5003 : // MODIFIED na
5004 : // RE-ENGINEERED na
5005 :
5006 : // PURPOSE OF THIS SUBROUTINE:
5007 : // Finds the density and viscosity of the gas in a gap at a particular temperature.
5008 : // The gap may be filled with a single gas or a gas mixture.
5009 : // Based on Subroutine WindowGasConductance.
5010 :
5011 : // METHODOLOGY EMPLOYED:
5012 : // See Subr. WindowGasConductance
5013 :
5014 : // REFERENCES:
5015 : // See Subr. WindowGasConductance
5016 :
5017 265344 : Real64 constexpr pres(1.0e5); // Gap gas pressure (Pa)
5018 265344 : Real64 constexpr gaslaw(8314.51); // Molar gas constant (J/kMol-K)
5019 265344 : Real64 const two_sqrt_2(2.0 * std::sqrt(2.0));
5020 :
5021 : int IMix; // Counters of gases in a mixture
5022 : int i;
5023 : int j;
5024 : int NMix; // Number of gases in a mixture
5025 : Real64 molmix; // Molecular weight of mixture
5026 530688 : Array1D<Real64> mukpdwn(10); // Denominator term
5027 : Real64 mumix; // For accumulating viscosity of gas mixture
5028 : Real64 phimup; // Numerator factor
5029 : Real64 downer; // Denominator factor
5030 : Real64 rhomix; // Density of gas mixture (kg/m3)
5031 530688 : Array1D<Real64> frct(10); // Fraction of each gas in a mixture
5032 530688 : Array1D<Real64> fvis(10); // Viscosity of each gas in a mixture (g/m-s)
5033 530688 : Array1D<Real64> fdens(10); // Density of each gas in a mixture (kg/m3)
5034 :
5035 265344 : NMix = state.dataWindowManager->gnmix[IGap - 1];
5036 :
5037 530688 : for (IMix = 1; IMix <= NMix; ++IMix) {
5038 265344 : frct(IMix) = state.dataWindowManager->gfract[IMix - 1][IGap - 1];
5039 : }
5040 :
5041 265344 : Real64 const tmean_2(pow_2(tmean));
5042 530688 : fvis(1) = state.dataWindowManager->gvis[0][0][IGap - 1] + state.dataWindowManager->gvis[1][0][IGap - 1] * tmean +
5043 265344 : state.dataWindowManager->gvis[2][0][IGap - 1] * tmean_2;
5044 265344 : fdens(1) = pres * state.dataWindowManager->gwght[0][IGap - 1] / (gaslaw * tmean); // Density using ideal gas law:
5045 : // rho=(presure*molecweight)/(gasconst*tmean)
5046 265344 : if (NMix == 1) { // Single gas
5047 265344 : visc = fvis(1);
5048 265344 : dens = fdens(1);
5049 : } else { // Multiple gases; calculate mixture properties
5050 0 : molmix = frct(1) * state.dataWindowManager->gwght[0][IGap - 1]; // initialize eq. 56
5051 :
5052 : // Initialize summations for eqns 60-66
5053 0 : mumix = 0.0;
5054 0 : mukpdwn(1) = 1.0;
5055 :
5056 : // Calculate properties of mixture constituents
5057 0 : for (i = 2; i <= NMix; ++i) {
5058 0 : fvis(i) = state.dataWindowManager->gvis[0][i - 1][IGap - 1] + state.dataWindowManager->gvis[1][i - 1][IGap - 1] * tmean +
5059 0 : state.dataWindowManager->gvis[2][i - 1][IGap - 1] * tmean_2;
5060 0 : fdens(i) = pres * state.dataWindowManager->gwght[i - 1][IGap - 1] / (gaslaw * tmean);
5061 0 : molmix += frct(i) * state.dataWindowManager->gwght[i - 1][IGap - 1]; // eq. 56
5062 0 : mukpdwn(i) = 1.0; // initialize denomonator of eq. 60
5063 : }
5064 :
5065 0 : for (i = 1; i <= NMix; ++i) {
5066 0 : for (j = 1; j <= NMix; ++j) {
5067 : // numerator of equation 61
5068 0 : phimup = pow_2(1.0 + std::sqrt(fvis(i) / fvis(j)) * root_4(state.dataWindowManager->gwght[j - 1][IGap - 1] /
5069 0 : state.dataWindowManager->gwght[i - 1][IGap - 1]));
5070 : // denomonator of eq. 61, 64 and 66
5071 0 : downer = two_sqrt_2 *
5072 0 : std::sqrt(1 + (state.dataWindowManager->gwght[i - 1][IGap - 1] / state.dataWindowManager->gwght[j - 1][IGap - 1]));
5073 : // calculate the denominator of eq. 60
5074 0 : if (i != j) mukpdwn(i) += phimup / downer * frct(j) / frct(i);
5075 : }
5076 0 : mumix += fvis(i) / mukpdwn(i); // eq. 60
5077 : }
5078 :
5079 : // Calculate the density of the mixture assuming an ideal gas
5080 0 : rhomix = pres * molmix / (gaslaw * tmean); // eq. 57
5081 :
5082 : // Final mixture properties
5083 0 : visc = mumix;
5084 0 : dens = rhomix;
5085 :
5086 : } // End of check if single or multiple gases in gap
5087 265344 : }
5088 :
5089 : //********************************************************************************
5090 :
5091 22607285 : void StartingWindowTemps(EnergyPlusData &state,
5092 : int const SurfNum, // Surface number
5093 : Array1A<Real64> AbsRadShade // Short-wave radiation absorbed by shade/blind faces
5094 : )
5095 : {
5096 :
5097 : // SUBROUTINE INFORMATION:
5098 : // AUTHOR F. Winkelmann
5099 : // DATE WRITTEN January 2000
5100 : // MODIFIED March 2003, FW: add rough calc of increase above ambient of
5101 : // initial shade/blind temperature when shade/blind deployed
5102 : // after having been off.
5103 : // Jan 2004, FW: take into account whether storm window was added
5104 : // or removed in the current time step.
5105 : // RE-ENGINEERED na
5106 :
5107 : // PURPOSE OF THIS SUBROUTINE:
5108 : // Initializes face temperature distribution prior to iteration
5109 :
5110 : // Argument array dimensioning
5111 22607285 : AbsRadShade.dim(2);
5112 :
5113 22607285 : constexpr Real64 hrad(5.3); // Typical radiative conductance (W/m2-K)
5114 22607285 : constexpr Real64 resgap(0.21); // Typical gap resistance (m2-K/W)
5115 :
5116 : int i; // Face counter
5117 : WinShadingType ShadeFlag; // Shading flag
5118 45214570 : Array1D<Real64> rguess(11); // Combined radiative/convective resistance (m2-K/W) of
5119 : // inside or outside air film, or gap
5120 : Real64 restot; // Total window resistance including outside
5121 : // and inside air films (m2-K/W)
5122 : Real64 temdiff; // Inside/outside air temperature difference (K)
5123 : Real64 ressum; // Resistance sum (m2-K/W)
5124 : int StormWinFlagPrevDay; // Previous time step value (day) of storm window flag
5125 : int StormWinFlagThisDay; // Current time step value (day) of storm window flag
5126 : int nglfacePrevDay; // Previous time step value (dya) of number of glass faces (may differ
5127 : // current time step value, nglface, if storm window was
5128 : // added or removed during the current time step).
5129 :
5130 22607285 : StormWinFlagPrevDay = state.dataSurface->SurfWinStormWinFlagPrevDay(SurfNum);
5131 22607285 : StormWinFlagThisDay = state.dataSurface->SurfWinStormWinFlag(SurfNum);
5132 :
5133 22607285 : if (state.dataGlobal->BeginEnvrnFlag || (StormWinFlagThisDay != StormWinFlagPrevDay)) {
5134 :
5135 : // Guess values of glass face temperatures based on a simple resistance-network solution
5136 : // that (1) ignores short- and long-wave radiation (from lights and zone equipment) absorbed
5137 : // by the glass faces, and (2) assumes zero glass resistance. Absorbed solar is also ignored
5138 : // since the tests on BeginEnvrnFlag and storm window transition can be true only at midnight.
5139 : // Interaction with shade or blind, if one of these is present, is ignored. See below for
5140 : // separate calculation of shade/blind temperature.
5141 :
5142 25016 : rguess(1) = 1.0 / (state.dataWindowManager->hcout + hrad);
5143 25016 : rguess(state.dataWindowManager->nglface + 1) = 1.0 / (state.dataWindowManager->hcin + hrad);
5144 :
5145 58099 : for (i = 2; i <= state.dataWindowManager->nglface; i += 2) {
5146 33083 : rguess(i) = 1.0 / state.dataWindowManager->scon[i / 2 - 1];
5147 33083 : if (i < state.dataWindowManager->nglface) rguess(i + 1) = resgap;
5148 : }
5149 :
5150 25016 : restot = 0.0;
5151 116198 : for (i = 1; i <= state.dataWindowManager->nglface + 1; ++i) {
5152 91182 : restot += rguess(i);
5153 : }
5154 :
5155 25016 : temdiff = state.dataWindowManager->tin - state.dataWindowManager->tout;
5156 25016 : if (std::abs(temdiff) < 0.5) temdiff = 2.0;
5157 :
5158 25016 : ressum = 0.0;
5159 91182 : for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
5160 66166 : ressum += rguess(i);
5161 66166 : state.dataWindowManager->thetas[i - 1] = (ressum / restot) * temdiff + state.dataWindowManager->tout;
5162 : }
5163 :
5164 : } else {
5165 : // Use previous time step values
5166 80938327 : for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
5167 58356058 : state.dataWindowManager->thetas[i - 1] = state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(i);
5168 : }
5169 : }
5170 :
5171 : // Initialize face temperatures of shade or blind, if present
5172 :
5173 22607285 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
5174 67780919 : if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum)) ||
5175 45125468 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) == WinShadingType::ExtShade ||
5176 67724417 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) == WinShadingType::ExtBlind ||
5177 22558013 : ANY_BETWEENGLASS_SHADE_BLIND(state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum))) {
5178 : // Shade or blind is on during the previous TS; use previous-TS values of shade/blind face temps.
5179 : // Note that if shade or blind is NOT on in the current TS the following two
5180 : // temperature values, although calculated here, are not used. The shade/blind face numbers
5181 : // during the previous time step depend on whether a storm window glass layer was added to
5182 : // or removed from the window during the current time step.
5183 66126 : nglfacePrevDay = state.dataWindowManager->nglface;
5184 66126 : if (StormWinFlagPrevDay == 0 && StormWinFlagThisDay == 1) nglfacePrevDay = state.dataWindowManager->nglface - 2;
5185 66126 : if (StormWinFlagPrevDay == 1 && StormWinFlagThisDay == 0) nglfacePrevDay = state.dataWindowManager->nglface + 2;
5186 66126 : state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
5187 66126 : state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(nglfacePrevDay + 1);
5188 66126 : state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
5189 66126 : state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(nglfacePrevDay + 2);
5190 : } else {
5191 : // No shade or blind previous time step; guess starting values of shade/blind
5192 : // taking into account short- and long-wave radiation (from solar, lights and zone equipment)
5193 : // absorbed by shade/blind faces. Face temps are assumed to be the same and
5194 : // equal to shade/blind temp. For interior shade/blind, air temp on either side is
5195 : // assumed to be the same and equal to tin; for exterior blind it is assumed to be
5196 : // equal to tout. For between-glass shade/blind it is assumed to be equal to the
5197 : // average temperature of the adjacent glass faces.
5198 :
5199 22541159 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
5200 4475 : state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
5201 4475 : state.dataWindowManager->tin + (AbsRadShade(1) + AbsRadShade(2)) / (2 * (state.dataWindowManager->hcin + hrad));
5202 4475 : state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
5203 4475 : state.dataWindowManager->thetas[state.dataWindowManager->nglface];
5204 22536684 : } else if (ShadeFlag == WinShadingType::ExtShade || ShadeFlag == WinShadingType::ExtBlind) {
5205 180 : state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
5206 180 : state.dataWindowManager->tout + (AbsRadShade(1) + AbsRadShade(2)) / (2 * (state.dataWindowManager->hcout + hrad));
5207 180 : state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
5208 180 : state.dataWindowManager->thetas[state.dataWindowManager->nglface];
5209 22536504 : } else if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
5210 : // Between-glass shade/blind allowed only for double and triple glazing.
5211 : // The factor 16.0 below is based on a combined convective/radiative heat transfer
5212 : // coefficient on either side of the shade/blind of 8.0 W/m2-K -- about 1.4 Btu/h-ft2-F.
5213 30 : if (state.dataWindowManager->nglface == 4) { // double glazing
5214 22 : state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
5215 22 : 0.5 * (state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]) + (AbsRadShade(1) + AbsRadShade(2)) / 16.0;
5216 22 : state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
5217 22 : state.dataWindowManager->thetas[state.dataWindowManager->nglface];
5218 : } else { // triple glazing
5219 8 : state.dataWindowManager->thetas[state.dataWindowManager->nglface] =
5220 8 : 0.5 * (state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]) + (AbsRadShade(1) + AbsRadShade(2)) / 16.0;
5221 8 : state.dataWindowManager->thetas[state.dataWindowManager->nglface + 1] =
5222 8 : state.dataWindowManager->thetas[state.dataWindowManager->nglface];
5223 : }
5224 : }
5225 : }
5226 22607285 : }
5227 :
5228 : //****************************************************************************
5229 :
5230 13949597 : void NusseltNumber(EnergyPlusData &state,
5231 : int const SurfNum, // Surface number
5232 : Real64 const tso, // Temperature of gap surface closest to outside (K)
5233 : Real64 const tsi, // Temperature of gap surface closest to zone (K)
5234 : int const IGap, // Gap number
5235 : Real64 const gr, // Gap gas Grashof number
5236 : Real64 const pr, // Gap gas Prandtl number
5237 : Real64 &gnu // Gap gas Nusselt number
5238 : )
5239 : {
5240 :
5241 : // SUBROUTINE INFORMATION:
5242 : // AUTHOR Adapted by Fred Winkelmann from Window5 subroutine nusselt
5243 : // DATE WRITTEN September 2001
5244 : // MODIFIED na
5245 : // RE-ENGINEERED na
5246 :
5247 : // PURPOSE OF THIS SUBROUTINE:
5248 : // Finds the Nusselt number for gas-filled gaps between isothermal solid layers.
5249 : // The gap may be filled with a single gas or a gas mixture.
5250 :
5251 : // METHODOLOGY EMPLOYED:
5252 : // Based on methodology in Chapter 5 of the July 18, 2001 draft of ISO 15099,
5253 : // "Thermal Performance of Windows, Doors and Shading Devices--Detailed Calculations."
5254 : // The equation numbers below correspond to those in the standard.
5255 :
5256 : // REFERENCES:
5257 : // Window5 source code; ISO 15099
5258 :
5259 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5260 : Real64 asp; // Aspect ratio: window height to gap width
5261 : Real64 ra; // Rayleigh number
5262 : Real64 gnu901; // Nusselt number temporary variables for
5263 : Real64 gnu902;
5264 : Real64 gnu90;
5265 : Real64 gnu601;
5266 : Real64 gnu602; // different tilt and Ra ranges
5267 : Real64 gnu60;
5268 : Real64 gnu601a;
5269 : Real64 gnua;
5270 : Real64 gnub;
5271 : Real64 cra; // Temporary variables
5272 : Real64 a;
5273 : Real64 b;
5274 : Real64 g;
5275 : Real64 ang;
5276 :
5277 13949597 : if (SurfNum > 0) {
5278 13941373 : asp = state.dataSurface->Surface(SurfNum).Height / state.dataWindowManager->gap[IGap - 1];
5279 : } else { // SurfNum = 0 when NusseltNumber is called from CalcNominalWindowCond, which applies to a
5280 : // particular construction. So window height is not known and we assume 5 ft (1.524 m)
5281 8224 : asp = 1.524 / state.dataWindowManager->gap[IGap - 1];
5282 : }
5283 :
5284 13949597 : state.dataWindowManager->tiltr = state.dataWindowManager->tilt * DataGlobalConstants::DegToRadians;
5285 13949597 : ra = gr * pr;
5286 : //! fw if (ra > 2.0e6): error that outside range of Rayleigh number?
5287 :
5288 13949597 : if (ra <= 1.0e4) gnu901 = 1.0 + 1.7596678e-10 * std::pow(ra, 2.2984755); // eq. 51
5289 13949597 : if (ra > 1.0e4 && ra <= 5.0e4) gnu901 = 0.028154 * std::pow(ra, 0.4134); // eq. 50
5290 13949597 : if (ra > 5.0e4) gnu901 = 0.0673838 * std::pow(ra, 1.0 / 3.0); // eq. 49
5291 :
5292 13949597 : gnu902 = 0.242 * std::pow(ra / asp, 0.272); // eq. 52
5293 13949597 : gnu90 = max(gnu901, gnu902);
5294 :
5295 13949597 : if (tso > tsi) { // window heated from above
5296 4635528 : gnu = 1.0 + (gnu90 - 1.0) * std::sin(state.dataWindowManager->tiltr); // eq. 53
5297 : } else { // window heated from below
5298 9314069 : if (state.dataWindowManager->tilt >= 60.0) {
5299 8183659 : if (ra >= 0.001) {
5300 8160963 : g = 0.5 * std::pow(1.0 + std::pow(ra / 3160.0, 20.6), -0.1); // eq. 47
5301 : } else {
5302 22696 : g = 0.5;
5303 : }
5304 8183659 : gnu601a = 1.0 + pow_7(0.0936 * std::pow(ra, 0.314) / (1.0 + g)); // eq. 45
5305 8183659 : gnu601 = std::pow(gnu601a, 0.142857);
5306 :
5307 : // For any aspect ratio
5308 8183659 : gnu602 = (0.104 + 0.175 / asp) * std::pow(ra, 0.283); // eq. 46
5309 8183659 : gnu60 = max(gnu601, gnu602);
5310 :
5311 : // linear interpolation for layers inclined at angles between 60 and 90 deg
5312 8183659 : gnu = ((90.0 - state.dataWindowManager->tilt) * gnu60 + (state.dataWindowManager->tilt - 60.0) * gnu90) / 30.0;
5313 : }
5314 9314069 : if (state.dataWindowManager->tilt < 60.0) { // eq. 42
5315 1130410 : cra = ra * std::cos(state.dataWindowManager->tiltr);
5316 1130410 : a = 1.0 - 1708.0 / cra;
5317 1130410 : b = std::pow(cra / 5830.0, 0.33333) - 1.0;
5318 1130410 : gnua = (std::abs(a) + a) / 2.0;
5319 1130410 : gnub = (std::abs(b) + b) / 2.0;
5320 1130410 : ang = 1708.0 * std::pow(std::sin(1.8 * state.dataWindowManager->tiltr), 1.6);
5321 1130410 : gnu = 1.0 + 1.44 * gnua * (1.0 - ang / cra) + gnub;
5322 : }
5323 : }
5324 13949597 : }
5325 :
5326 : //*******************************************************************************************************
5327 :
5328 912020 : void TransAndReflAtPhi(Real64 const cs, // Cosine of incidence angle
5329 : Real64 const tf0, // Transmittance at zero incidence angle
5330 : Real64 const rf0, // Front reflectance at zero incidence angle
5331 : Real64 const rb0, // Back reflectance at zero incidence angle
5332 : Real64 &tfp, // Transmittance at cs
5333 : Real64 &rfp, // Front reflectance at cs
5334 : Real64 &rbp, // Back reflectance at cs
5335 : bool const SimpleGlazingSystem, // .TRUE. if simple block model being used
5336 : Real64 const SimpleGlazingSHGC, // SHGC value to use in alternate model for simple glazing system
5337 : Real64 const SimpleGlazingU // U-factor value to use in alternate model for simple glazing system
5338 : )
5339 : {
5340 :
5341 : // SUBROUTINE INFORMATION:
5342 : // AUTHOR F. Winkelmann
5343 : // DATE WRITTEN January 2000
5344 : // MODIFIED 5 June 2003, FCW: modify to correspond to WINDOW 4 and WINDOW 5.
5345 : // Original routine was based on the method in E.U. Finlayson et al,
5346 : // "WINDOW 4.0: Documentation of Calculation Procedures," LBL-33943,
5347 : // July 1993, which is not used in either WINDOW 4 or WINDOW 5.
5348 : // The current routine is based on ASHRAE Handbook of Fundamentals,
5349 : // 2001, pp. 30.20-23, "Optical Properties of Single Glazing Layers."
5350 : // Original routine underpredicted transmittance at angles of
5351 : // incidence > 60 degrees.
5352 : // June 2009. Brent Griffith. add simple window correlation
5353 : // newer model from LBNL windows group 5/15/2009
5354 : // RE-ENGINEERED na
5355 :
5356 : // PURPOSE OF THIS SUBROUTINE:
5357 : // For a single glazing layer, calculate transmittance and reflectance at an arbitrary
5358 : // angle of incidence given transmittance and reflectance at zero incidence angle.
5359 :
5360 : // REFERENCES:
5361 : // ASHRAE Handbook of Fundamentals, 2001, pp. 30.20-23,
5362 : // "Optical Properties of Single Glazing Layers."
5363 :
5364 : Real64 tfp1; // Transmittance at cs for each polarization
5365 : Real64 tfp2;
5366 : Real64 rfp1; // Front reflectance at cs for each polarization
5367 : Real64 rfp2;
5368 : Real64 rbp1; // Back reflectance at cs for each polarization
5369 : Real64 rbp2;
5370 : Real64 betaf; // Intermediate variables
5371 : Real64 betab;
5372 : Real64 r0f;
5373 : Real64 r0b;
5374 : Real64 abf;
5375 : Real64 abb;
5376 : Real64 ngf; // Front and back index of refraction
5377 : Real64 ngb;
5378 : Real64 cgf; // Intermediate variables
5379 : Real64 cgb;
5380 : Real64 rpf1; // Front and back air/glass interface reflectivity
5381 : Real64 rpb1;
5382 : Real64 tpf1;
5383 : Real64 tpb1;
5384 : // and transmittivity for first polarization
5385 : Real64 rpf2; // Front and back air/glass interface reflectivity
5386 : Real64 rpb2;
5387 : Real64 tpf2;
5388 : Real64 tpb2;
5389 : // and transmittivity for second polarization
5390 : Real64 tcl; // Transmittance and reflectance for clear glass
5391 : Real64 rcl;
5392 : Real64 tbnz; // Transmittance and reflectance for bronze glass
5393 : Real64 rbnz;
5394 : Real64 expmabfdivcgf;
5395 : Real64 expm2abfdivcgf;
5396 : Real64 expmabbdivcgb;
5397 :
5398 : Real64 testval; // temporary value for calculations
5399 : Real64 tmp1; // temporary value for calculations
5400 : Real64 tmp2; // temporary value for calculations
5401 : Real64 tmp3; // temporary value for calculations
5402 : Real64 tmp4; // temporary value for calculations
5403 : Real64 tmp5; // temporary value for calculations
5404 : Real64 tmp6; // temporary value for calculations
5405 : Real64 tmp7; // temporary value for calculations
5406 : Real64 tmp8; // temporary value for calculations
5407 : Real64 tmp9; // temporary value for calculations
5408 :
5409 912020 : if (SimpleGlazingSystem) { // use alternate angular dependence model for block model of simple glazing input
5410 :
5411 4880 : Real64 const cs_2(pow_2(cs));
5412 4880 : Real64 const cs_3(pow_3(cs));
5413 4880 : Real64 const cs_4(pow_4(cs));
5414 4880 : Real64 TransCurveA = 0.00 + 3.36 * cs - 3.85 * cs_2 + 1.49 * cs_3 + 0.01 * cs_4;
5415 4880 : Real64 TransCurveB = 0.00 + 2.83 * cs - 2.42 * cs_2 + 0.04 * cs_3 + 0.55 * cs_4;
5416 4880 : Real64 TransCurveC = 0.00 + 2.45 * cs - 1.58 * cs_2 - 0.64 * cs_3 + 0.77 * cs_4;
5417 4880 : Real64 TransCurveD = 0.00 + 2.85 * cs - 2.58 * cs_2 + 0.40 * cs_3 + 0.35 * cs_4;
5418 4880 : Real64 TransCurveE = 0.00 + 1.51 * cs + 2.49 * cs_2 - 5.87 * cs_3 + 2.88 * cs_4;
5419 4880 : Real64 TransCurveF = 0.00 + 1.21 * cs + 3.14 * cs_2 - 6.37 * cs_3 + 3.03 * cs_4;
5420 4880 : Real64 TransCurveG = 0.00 + 1.09 * cs + 3.54 * cs_2 - 6.84 * cs_3 + 3.23 * cs_4;
5421 4880 : Real64 TransCurveH = 0.00 + 0.98 * cs + 3.83 * cs_2 - 7.13 * cs_3 + 3.33 * cs_4;
5422 4880 : Real64 TransCurveI = 0.00 + 0.79 * cs + 3.93 * cs_2 - 6.86 * cs_3 + 3.15 * cs_4;
5423 4880 : Real64 TransCurveJ = 0.00 + 0.08 * cs + 6.02 * cs_2 - 8.84 * cs_3 + 3.74 * cs_4;
5424 4880 : Real64 TransCurveFGHI = (TransCurveF + TransCurveG + TransCurveH + TransCurveI) / 4.0;
5425 4880 : Real64 TransCurveFH = (TransCurveF + TransCurveH) / 2.0;
5426 4880 : Real64 TransCurveBDCD = (TransCurveB + TransCurveD + TransCurveC + TransCurveD) / 4.0;
5427 :
5428 4880 : Real64 ReflectCurveA = 1.00 - 0.70 * cs + 2.57 * cs_2 - 3.20 * cs_3 + 1.33 * cs_4 - TransCurveA;
5429 4880 : Real64 ReflectCurveB = 1.00 - 1.87 * cs + 6.50 * cs_2 - 7.86 * cs_3 + 3.23 * cs_4 - TransCurveB;
5430 4880 : Real64 ReflectCurveC = 1.00 - 2.52 * cs + 8.40 * cs_2 - 9.86 * cs_3 + 3.99 * cs_4 - TransCurveC;
5431 4880 : Real64 ReflectCurveD = 1.00 - 1.85 * cs + 6.40 * cs_2 - 7.64 * cs_3 + 3.11 * cs_4 - TransCurveD;
5432 4880 : Real64 ReflectCurveE = 1.00 - 1.57 * cs + 5.60 * cs_2 - 6.82 * cs_3 + 2.80 * cs_4 - TransCurveE;
5433 4880 : Real64 ReflectCurveF = 1.00 - 3.15 * cs + 10.98 * cs_2 - 13.14 * cs_3 + 5.32 * cs_4 - TransCurveF;
5434 4880 : Real64 ReflectCurveG = 1.00 - 3.25 * cs + 11.32 * cs_2 - 13.54 * cs_3 + 5.49 * cs_4 - TransCurveG;
5435 4880 : Real64 ReflectCurveH = 1.00 - 3.39 * cs + 11.70 * cs_2 - 13.94 * cs_3 + 5.64 * cs_4 - TransCurveH;
5436 4880 : Real64 ReflectCurveI = 1.00 - 4.06 * cs + 13.55 * cs_2 - 15.74 * cs_3 + 6.27 * cs_4 - TransCurveI;
5437 4880 : Real64 ReflectCurveJ = 1.00 - 4.35 * cs + 14.27 * cs_2 - 16.32 * cs_3 + 6.39 * cs_4 - TransCurveJ;
5438 :
5439 4880 : Real64 ReflectCurveFGHI = (ReflectCurveF + ReflectCurveG + ReflectCurveH + ReflectCurveI) / 4.0;
5440 4880 : Real64 ReflectCurveFH = (ReflectCurveF + ReflectCurveH) / 2.0;
5441 4880 : Real64 ReflectCurveBDCD = (ReflectCurveB + ReflectCurveD + ReflectCurveC + ReflectCurveD) / 4.0;
5442 :
5443 4880 : Real64 TransTmp(0.0);
5444 4880 : Real64 ReflectTmp(0.0);
5445 :
5446 4880 : if (SimpleGlazingU < 1.4195) { // cell 1, 2, or 3
5447 80 : if (SimpleGlazingSHGC > 0.45) {
5448 : // cell # 1
5449 : // Curve E
5450 80 : TransTmp = TransCurveE;
5451 80 : ReflectTmp = ReflectCurveE;
5452 :
5453 0 : } else if ((0.35 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
5454 : // cell # 2
5455 : // 2 way interpolation between Curve E and Curve J
5456 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.35, 0.45, TransCurveJ, TransCurveE);
5457 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.35, 0.45, ReflectCurveJ, ReflectCurveE);
5458 :
5459 0 : } else if (SimpleGlazingSHGC < 0.35) {
5460 : // cell # 3
5461 : // Curve J
5462 0 : TransTmp = TransCurveJ;
5463 0 : ReflectTmp = ReflectCurveJ;
5464 : }
5465 :
5466 4800 : } else if ((1.4195 <= SimpleGlazingU) && (SimpleGlazingU <= 1.7034)) { // cell 4, 5 , 6, 7, 8, 9, or 10
5467 0 : if (SimpleGlazingSHGC > 0.55) {
5468 : // cell # 4
5469 : // Curve E
5470 0 : TransTmp = TransCurveE;
5471 0 : ReflectTmp = ReflectCurveE;
5472 :
5473 0 : } else if ((0.5 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.55)) {
5474 : // cell # 5
5475 : // 4 way interpolation between Curve E , Curve E, Curve E and Curve FGHI
5476 :
5477 0 : TransTmp = InterpolateBetweenFourValues(
5478 : SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.50, 0.55, TransCurveE, TransCurveE, TransCurveFGHI, TransCurveE);
5479 0 : ReflectTmp = InterpolateBetweenFourValues(
5480 : SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.50, 0.55, ReflectCurveE, ReflectCurveE, ReflectCurveFGHI, ReflectCurveE);
5481 :
5482 0 : } else if ((0.45 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.5)) {
5483 : // cell # 6
5484 : // 2 way interpolation between Curve E and Curve FGHI
5485 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, TransCurveE, TransCurveFGHI);
5486 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, ReflectCurveE, ReflectCurveFGHI);
5487 :
5488 0 : } else if ((0.35 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
5489 : // cell # 7
5490 : // 4 way interpolation between Curve E , Curve FGHI, Curve J and Curve FGHI
5491 0 : TransTmp = InterpolateBetweenFourValues(
5492 : SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.35, 0.45, TransCurveJ, TransCurveE, TransCurveFGHI, TransCurveFGHI);
5493 0 : ReflectTmp = InterpolateBetweenFourValues(SimpleGlazingU,
5494 : SimpleGlazingSHGC,
5495 : 1.4195,
5496 : 1.7034,
5497 : 0.35,
5498 : 0.45,
5499 : ReflectCurveJ,
5500 : ReflectCurveE,
5501 : ReflectCurveFGHI,
5502 : ReflectCurveFGHI);
5503 :
5504 0 : } else if ((0.3 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.35)) {
5505 : // cell # 8
5506 : // 2 way interpolation between Curve J and Curve FGHI
5507 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, TransCurveJ, TransCurveFGHI);
5508 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, ReflectCurveJ, ReflectCurveFGHI);
5509 :
5510 0 : } else if ((0.25 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.3)) {
5511 : // cell # 9
5512 : // 4 way interpolation between Curve J, Curve FGHI, Curve J and Curve FH
5513 0 : TransTmp = InterpolateBetweenFourValues(
5514 : SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.25, 0.3, TransCurveJ, TransCurveJ, TransCurveFH, TransCurveFGHI);
5515 0 : ReflectTmp = InterpolateBetweenFourValues(
5516 : SimpleGlazingU, SimpleGlazingSHGC, 1.4195, 1.7034, 0.25, 0.3, ReflectCurveJ, ReflectCurveJ, ReflectCurveFH, ReflectCurveFGHI);
5517 :
5518 0 : } else if (SimpleGlazingSHGC <= 0.25) {
5519 : // cell # 10
5520 : // 2 way interpolation between Curve J and Curve FH
5521 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, TransCurveJ, TransCurveFH);
5522 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 1.4195, 1.7034, ReflectCurveJ, ReflectCurveFH);
5523 : }
5524 4800 : } else if ((1.7034 < SimpleGlazingU) && (SimpleGlazingU < 3.4068)) { // cell 11, 12, 13, 14, or 15
5525 9280 : if (SimpleGlazingSHGC > 0.55) {
5526 : // cell # 11
5527 : // Curve E
5528 400 : TransTmp = TransCurveE;
5529 400 : ReflectTmp = ReflectCurveE;
5530 :
5531 4240 : } else if ((0.5 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.55)) {
5532 : // cell # 12
5533 : // 2 way interpolation between Curve E and Curve FGHI
5534 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.5, 0.55, TransCurveFGHI, TransCurveE);
5535 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.5, 0.55, ReflectCurveFGHI, ReflectCurveE);
5536 :
5537 4240 : } else if ((0.3 < SimpleGlazingSHGC) && (SimpleGlazingSHGC < 0.5)) {
5538 : // cell # 13
5539 : // Curve FGHI
5540 4240 : TransTmp = TransCurveFGHI;
5541 4240 : ReflectTmp = ReflectCurveFGHI;
5542 :
5543 0 : } else if ((0.25 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.3)) {
5544 : // cell # 14
5545 : // 2 way interpolation between Curve FGHI and Curve FH
5546 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.25, 0.30, TransCurveFH, TransCurveFGHI);
5547 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.25, 0.30, ReflectCurveFH, ReflectCurveFGHI);
5548 :
5549 0 : } else if (SimpleGlazingSHGC < 0.25) {
5550 : // cell # 15
5551 : // Curve FH
5552 0 : TransTmp = TransCurveFH;
5553 0 : ReflectTmp = ReflectCurveFH;
5554 : }
5555 :
5556 160 : } else if ((3.4068 <= SimpleGlazingU) && (SimpleGlazingU <= 4.5424)) { // cell 16, 17, 18, 19, 20, 21, 22, or 23
5557 160 : if (SimpleGlazingSHGC > 0.65) {
5558 : // cell # 16
5559 : // 2 way interpolation between Curve E and Curve A
5560 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveE, TransCurveA);
5561 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveE, ReflectCurveA);
5562 :
5563 80 : } else if ((0.6 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.65)) {
5564 : // cell # 17
5565 : // 4 way interpolation between Curve E , Curve E, Curve A, and Curve BDCD
5566 0 : TransTmp = InterpolateBetweenFourValues(
5567 : SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.6, 0.65, TransCurveE, TransCurveE, TransCurveBDCD, TransCurveA);
5568 0 : ReflectTmp = InterpolateBetweenFourValues(
5569 : SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.6, 0.65, ReflectCurveE, ReflectCurveE, ReflectCurveBDCD, ReflectCurveA);
5570 :
5571 80 : } else if ((0.55 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.6)) {
5572 : // cell # 18
5573 : // 2 way interpolation between Curve E and Curve BDCD
5574 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveE, TransCurveBDCD);
5575 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveE, ReflectCurveBDCD);
5576 :
5577 80 : } else if ((0.5 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.55)) {
5578 : // cell # 19
5579 : // 4 way interpolation between Curve E , Curve FGHI, Curve BDCD and Curve BDCD
5580 40 : TransTmp = InterpolateBetweenFourValues(
5581 : SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.5, 0.55, TransCurveFGHI, TransCurveE, TransCurveBDCD, TransCurveBDCD);
5582 40 : ReflectTmp = InterpolateBetweenFourValues(SimpleGlazingU,
5583 : SimpleGlazingSHGC,
5584 : 3.4068,
5585 : 4.5424,
5586 : 0.5,
5587 : 0.55,
5588 : ReflectCurveFGHI,
5589 : ReflectCurveE,
5590 : ReflectCurveBDCD,
5591 : ReflectCurveBDCD);
5592 :
5593 40 : } else if ((0.45 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.5)) {
5594 : // cell # 20
5595 : // 2 way interpolation between Curve FGHI and Curve BDCD
5596 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveFGHI, TransCurveBDCD);
5597 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveFGHI, ReflectCurveBDCD);
5598 :
5599 40 : } else if ((0.3 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
5600 : // cell # 21
5601 : // 4 way interpolation between Curve FGHI, Curve FGHI, Curve BDCD, and Curve D
5602 40 : TransTmp = InterpolateBetweenFourValues(
5603 : SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.3, 0.45, TransCurveFGHI, TransCurveFGHI, TransCurveD, TransCurveBDCD);
5604 40 : ReflectTmp = InterpolateBetweenFourValues(SimpleGlazingU,
5605 : SimpleGlazingSHGC,
5606 : 3.4068,
5607 : 4.5424,
5608 : 0.3,
5609 : 0.45,
5610 : ReflectCurveFGHI,
5611 : ReflectCurveFGHI,
5612 : ReflectCurveD,
5613 : ReflectCurveBDCD);
5614 :
5615 0 : } else if ((0.25 < SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.3)) {
5616 : // cell # 22
5617 : // 4 way interpolation between Curve FGHI, Curve FH, Curve D, and Curve D
5618 0 : TransTmp = InterpolateBetweenFourValues(
5619 : SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.25, 0.3, TransCurveFH, TransCurveFGHI, TransCurveD, TransCurveD);
5620 0 : ReflectTmp = InterpolateBetweenFourValues(
5621 : SimpleGlazingU, SimpleGlazingSHGC, 3.4068, 4.5424, 0.25, 0.3, ReflectCurveFH, ReflectCurveFGHI, ReflectCurveD, ReflectCurveD);
5622 :
5623 0 : } else if (SimpleGlazingSHGC <= 0.25) {
5624 : // cell # 23
5625 : // 2 way interpolation between Curve FH and Curve D
5626 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, TransCurveFH, TransCurveD);
5627 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingU, 3.4068, 4.5424, ReflectCurveFH, ReflectCurveD);
5628 : }
5629 80 : } else if (SimpleGlazingU > 4.5424) { // cell 24, 25, 26, 27, or 28
5630 80 : if (SimpleGlazingSHGC > 0.65) {
5631 : // cell # 24
5632 : // Curve A
5633 80 : TransTmp = TransCurveA;
5634 80 : ReflectTmp = ReflectCurveA;
5635 0 : } else if ((0.6 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.65)) {
5636 : // cell # 25
5637 : // 2 way interpolation between Curve A and Curve BDCD
5638 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.6, 0.65, TransCurveBDCD, TransCurveA);
5639 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.6, 0.65, ReflectCurveBDCD, ReflectCurveA);
5640 :
5641 0 : } else if ((0.45 < SimpleGlazingSHGC) && (SimpleGlazingSHGC < 0.6)) {
5642 : // cell # 26
5643 : // Curve BDCD
5644 0 : TransTmp = TransCurveBDCD;
5645 0 : ReflectTmp = ReflectCurveBDCD;
5646 :
5647 0 : } else if ((0.3 <= SimpleGlazingSHGC) && (SimpleGlazingSHGC <= 0.45)) {
5648 : // cell # 27
5649 : // 2 way interpolation between Curve BDCD and Curve D
5650 0 : TransTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.3, 0.45, TransCurveD, TransCurveBDCD);
5651 0 : ReflectTmp = InterpolateBetweenTwoValues(SimpleGlazingSHGC, 0.3, 0.45, ReflectCurveD, ReflectCurveBDCD);
5652 :
5653 0 : } else if (SimpleGlazingSHGC < 0.3) {
5654 : // cell # 28
5655 : // Curve D
5656 0 : TransTmp = TransCurveD;
5657 0 : ReflectTmp = ReflectCurveD;
5658 :
5659 : } else {
5660 0 : assert(false);
5661 : }
5662 : } else {
5663 0 : assert(false);
5664 : }
5665 :
5666 4880 : if (cs == 1.0) { // at 0 deg incident, TransTmp and ReflectTmp should be 1.0
5667 488 : TransTmp = 1.0;
5668 488 : ReflectTmp = 0.0;
5669 : }
5670 :
5671 : // now apply normalization factors to zero incidence angle properties
5672 4880 : tfp = tf0 * TransTmp;
5673 4880 : tfp = max(min(1.0, tfp), 0.0);
5674 :
5675 4880 : rfp = rf0 * (1. - ReflectTmp) + ReflectTmp;
5676 4880 : rfp = max(min(0.9999 - tfp, rfp), 0.0);
5677 :
5678 4880 : rbp = rfp;
5679 :
5680 907140 : } else if (tf0 <= 0.0) {
5681 : // This is an opaque window. For all angles, set transmittance to 0; set reflectance to that at zero incidence angle.
5682 0 : tfp = 0.0;
5683 0 : rfp = rf0;
5684 0 : rbp = rb0;
5685 : } else {
5686 :
5687 907140 : betaf = pow_2(tf0) - pow_2(rf0) + 2.0 * rf0 + 1.0;
5688 907140 : betab = pow_2(tf0) - pow_2(rb0) + 2.0 * rb0 + 1.0;
5689 907140 : r0f = (betaf - std::sqrt(pow_2(betaf) - 4.0 * (2.0 - rf0) * rf0)) / (2.0 * (2.0 - rf0));
5690 907140 : r0b = (betab - std::sqrt(pow_2(betab) - 4.0 * (2.0 - rb0) * rb0)) / (2.0 * (2.0 - rb0));
5691 :
5692 907140 : tmp1 = std::abs(r0f - r0b);
5693 907140 : if (tmp1 != 0.0) {
5694 264420 : testval = std::abs(r0f - r0b) / (r0f + r0b);
5695 : } else {
5696 642720 : testval = 0.0;
5697 : }
5698 :
5699 907140 : if (testval < 0.001) { // CR8830, CR8942, implications of relaxation of glazing properties CR8413
5700 : // UNCOATED GLASS
5701 653220 : tmp1 = r0f * tf0;
5702 653220 : if (tmp1 != 0.0) {
5703 653220 : abf = std::log(tmp1 / (rf0 - r0f));
5704 : } else {
5705 0 : abf = 0.0;
5706 : }
5707 653220 : tmp2 = r0b * tf0;
5708 653220 : if (tmp2 != 0.0) {
5709 653220 : abb = std::log(tmp2 / (rb0 - r0b));
5710 : } else {
5711 0 : abb = 0.0;
5712 : }
5713 653220 : ngf = (1.0 + std::sqrt(r0f)) / (1.0 - std::sqrt(r0f));
5714 653220 : ngb = (1.0 + std::sqrt(r0b)) / (1.0 - std::sqrt(r0b));
5715 653220 : cgf = std::sqrt(1.0 - (1.0 - cs * cs) / pow_2(ngf));
5716 653220 : cgb = std::sqrt(1.0 - (1.0 - cs * cs) / pow_2(ngb));
5717 653220 : tmp3 = ngf * cs - cgf;
5718 653220 : if (tmp3 != 0.0) {
5719 653220 : rpf1 = pow_2(tmp3 / (ngf * cs + cgf));
5720 : } else {
5721 0 : rpf1 = 0.0;
5722 : }
5723 653220 : tmp4 = ngf * cgf - cs;
5724 653220 : if (tmp4 != 0.0) {
5725 653220 : rpf2 = pow_2(tmp4 / (ngf * cgf + cs));
5726 : } else {
5727 0 : rpf2 = 0.0;
5728 : }
5729 653220 : tpf1 = 1 - rpf1;
5730 653220 : tpf2 = 1 - rpf2;
5731 653220 : tmp5 = ngb * cs - cgb;
5732 653220 : if (tmp5 != 0.0) {
5733 653220 : rpb1 = pow_2(tmp5 / (ngb * cs + cgb));
5734 : } else {
5735 0 : rpb1 = 0.0;
5736 : }
5737 653220 : tmp6 = ngb * cgb - cs;
5738 653220 : if (tmp6 != 0.0) {
5739 653220 : rpb2 = pow_2(tmp6 / (ngb * cgb + cs));
5740 : } else {
5741 0 : rpb2 = 0.0;
5742 : }
5743 653220 : tpb1 = 1 - rpf1;
5744 653220 : tpb2 = 1 - rpf2;
5745 653220 : tmp7 = -abf;
5746 653220 : if (cgf != 0.0) {
5747 653220 : expmabfdivcgf = std::exp(tmp7 / cgf);
5748 : } else {
5749 0 : expmabfdivcgf = 0.0;
5750 : }
5751 653220 : tmp8 = -2.0 * abf;
5752 653220 : if (cgf != 0.0) {
5753 653220 : expm2abfdivcgf = std::exp(tmp8 / cgf);
5754 : } else {
5755 0 : expm2abfdivcgf = 0.0;
5756 : }
5757 653220 : if (tpf1 != 0.0) {
5758 587898 : tfp1 = pow_2(tpf1) * expmabfdivcgf / (1.0 - pow_2(rpf1) * expm2abfdivcgf);
5759 : } else {
5760 65322 : tfp1 = 0.0;
5761 : }
5762 653220 : rfp1 = rpf1 * (1.0 + tfp1 * expmabfdivcgf);
5763 653220 : if (tpf2 != 0.0) {
5764 587898 : tfp2 = pow_2(tpf2) * expmabfdivcgf / (1.0 - pow_2(rpf2) * expm2abfdivcgf);
5765 : } else {
5766 65322 : tfp2 = 0.0;
5767 : }
5768 653220 : rfp2 = rpf2 * (1.0 + tfp2 * expmabfdivcgf);
5769 653220 : tfp = 0.5 * (tfp1 + tfp2);
5770 653220 : rfp = 0.5 * (rfp1 + rfp2);
5771 653220 : tmp9 = -abb;
5772 653220 : if (tmp9 != 0.0) {
5773 653220 : expmabbdivcgb = std::exp(tmp9 / cgb);
5774 : } else {
5775 0 : expmabbdivcgb = 0.0;
5776 : }
5777 653220 : rbp1 = rpb1 * (1.0 + tfp1 * expmabbdivcgb);
5778 653220 : rbp2 = rpb2 * (1.0 + tfp2 * expmabbdivcgb);
5779 653220 : rbp = 0.5 * (rbp1 + rbp2);
5780 : } else {
5781 : // COATED GLASS
5782 253920 : if (tf0 > 0.645) {
5783 : // Use clear glass angular distribution.
5784 : // Normalized clear glass transmittance and reflectance distribution
5785 144900 : if (cs > 0.999) { // Angle of incidence = 0 deg
5786 14490 : tcl = 1.0;
5787 14490 : rcl = 0.0;
5788 130410 : } else if (cs < 0.001) { // Angle of incidence = 90 deg
5789 14490 : tcl = 0.0;
5790 14490 : rcl = 1.0;
5791 : } else {
5792 115920 : tcl = -0.0015 + (3.355 + (-3.840 + (1.460 + 0.0288 * cs) * cs) * cs) * cs;
5793 115920 : rcl = 0.999 + (-0.563 + (2.043 + (-2.532 + 1.054 * cs) * cs) * cs) * cs - tcl;
5794 : }
5795 144900 : tfp = tf0 * tcl;
5796 144900 : rfp = rf0 * (1.0 - rcl) + rcl;
5797 144900 : rbp = rb0 * (1.0 - rcl) + rcl;
5798 : } else {
5799 : // Use bronze glass angular distribution.
5800 : // Normalized bronze tinted glass transmittance and reflectance distribution
5801 109020 : if (cs > 0.999) { // Angle of incidence = 0 deg
5802 10902 : tbnz = 1.0;
5803 10902 : rbnz = 0.0;
5804 98118 : } else if (cs < 0.001) { // Angle of incidence = 90 deg
5805 10902 : tbnz = 0.0;
5806 10902 : rbnz = 1.0;
5807 : } else {
5808 87216 : tbnz = -0.002 + (2.813 + (-2.341 + (-0.05725 + 0.599 * cs) * cs) * cs) * cs;
5809 87216 : rbnz = 0.997 + (-1.868 + (6.513 + (-7.862 + 3.225 * cs) * cs) * cs) * cs - tbnz;
5810 : }
5811 109020 : tfp = tf0 * tbnz;
5812 109020 : rfp = rf0 * (1.0 - rbnz) + rbnz;
5813 109020 : rbp = rb0 * (1.0 - rbnz) + rbnz;
5814 : }
5815 : }
5816 : }
5817 :
5818 : // total absorptance cannot be negative
5819 912020 : assert(1.0 - rfp - tfp >= -1e6);
5820 912020 : assert(1.0 - rbp - tfp >= -1e6);
5821 912020 : }
5822 :
5823 0 : Real64 InterpolateBetweenTwoValues(Real64 const X, Real64 const X0, Real64 const X1, Real64 const F0, Real64 const F1)
5824 : {
5825 :
5826 : // FUNCTION INFORMATION:
5827 : // AUTHOR Brent Griffith
5828 : // DATE WRITTEN June 2009
5829 : // MODIFIED na
5830 : // RE-ENGINEERED na
5831 :
5832 : // PURPOSE OF THIS FUNCTION:
5833 : // Interpolate between two results
5834 :
5835 : // METHODOLOGY EMPLOYED:
5836 : // linear interpolation
5837 :
5838 : Real64 InterpResult;
5839 :
5840 0 : InterpResult = F0 + ((X - X0) / (X1 - X0)) * (F1 - F0);
5841 0 : return InterpResult;
5842 : }
5843 :
5844 160 : Real64 InterpolateBetweenFourValues(Real64 const X,
5845 : Real64 const Y,
5846 : Real64 const X1,
5847 : Real64 const X2,
5848 : Real64 const Y1,
5849 : Real64 const Y2,
5850 : Real64 const Fx1y1,
5851 : Real64 const Fx1y2,
5852 : Real64 const Fx2y1,
5853 : Real64 const Fx2y2)
5854 : {
5855 :
5856 : // FUNCTION INFORMATION:
5857 : // AUTHOR Brent Griffith
5858 : // DATE WRITTEN June 2009
5859 : // MODIFIED na
5860 : // RE-ENGINEERED na
5861 :
5862 : // PURPOSE OF THIS FUNCTION:
5863 : // Interpolate between four results.
5864 :
5865 : // METHODOLOGY EMPLOYED:
5866 : // bilinear interpolation (approximate)
5867 :
5868 : // REFERENCES:
5869 : // http://en.wikipedia.org/wiki/Bilinear_interpolation
5870 :
5871 : // Return value
5872 : Real64 InterpResult;
5873 :
5874 480 : InterpResult = (Fx1y1 / ((X2 - X1) * (Y2 - Y1))) * (X2 - X) * (Y2 - Y) + (Fx2y1 / ((X2 - X1) * (Y2 - Y1))) * (X - X1) * (Y2 - Y) +
5875 320 : (Fx1y2 / ((X2 - X1) * (Y2 - Y1))) * (X2 - X) * (Y - Y1) + (Fx2y2 / ((X2 - X1) * (Y2 - Y1))) * (X - X1) * (Y - Y1);
5876 160 : return InterpResult;
5877 : }
5878 :
5879 : //**************************************************************************
5880 :
5881 22832 : void W5LsqFit(Array1S<Real64> const IndepVar, // Independent variables
5882 : Array1S<Real64> const DepVar, // Dependent variables
5883 : int const N, // Order of polynomial
5884 : int const N1, // First and last data points used
5885 : int const N2,
5886 : Array1S<Real64> CoeffsCurve // Polynomial coeffients from fit
5887 : )
5888 : {
5889 :
5890 : // SUBROUTINE INFORMATION:
5891 : // AUTHOR George Walton
5892 : // DATE WRITTEN April 1976
5893 : // MODIFIED November 1999 F.Winkelmann
5894 : // RE-ENGINEERED na
5895 :
5896 : // PURPOSE OF THIS SUBROUTINE:
5897 : // Does least squares fit for coefficients of a polynomial
5898 : // that gives a window property, such as transmittance, as a function of
5899 : // the cosine of the angle of incidence. The polynomial is of the
5900 : // form C1*X + C2*X**2 + C3*X**3 + ... +CN*X**N, where N <= 6.
5901 : // Adapted from BLAST subroutine LSQFIT.
5902 :
5903 45664 : Array2D<Real64> A(6, 6); // Least squares derivative matrix
5904 45664 : Array1D<Real64> B(6); // Least squares derivative vector
5905 45664 : Array2D<Real64> D(6, 16); // Powers of independent variable
5906 : Real64 ACON; // Intermediate variables
5907 : Real64 SUM;
5908 : int i; // Loop parameters
5909 : int j;
5910 : int K;
5911 : int L;
5912 : int M;
5913 : int KP1;
5914 : int LP1;
5915 : int NM1;
5916 :
5917 : // Set up least squares matrix
5918 251152 : for (M = N1; M <= N2; ++M) {
5919 228320 : D(1, M) = IndepVar(M);
5920 : }
5921 :
5922 136992 : for (i = 2; i <= N; ++i) {
5923 1255760 : for (M = N1; M <= N2; ++M) {
5924 1141600 : D(i, M) = D(i - 1, M) * IndepVar(M);
5925 : }
5926 : }
5927 :
5928 159824 : for (i = 1; i <= N; ++i) {
5929 136992 : SUM = 0.0;
5930 1506912 : for (M = N1; M <= N2; ++M) {
5931 1369920 : SUM += DepVar(M) * D(i, M);
5932 : }
5933 136992 : B(i) = SUM;
5934 958944 : for (j = 1; j <= N; ++j) {
5935 821952 : SUM = 0.0;
5936 9041472 : for (M = N1; M <= N2; ++M) {
5937 8219520 : SUM += D(i, M) * D(j, M);
5938 : }
5939 821952 : A(j, i) = SUM;
5940 821952 : A(i, j) = SUM;
5941 : }
5942 : }
5943 :
5944 : // Solve the simultaneous equations using Gauss elimination
5945 22832 : NM1 = N - 1;
5946 136992 : for (K = 1; K <= NM1; ++K) {
5947 114160 : KP1 = K + 1;
5948 456640 : for (i = KP1; i <= N; ++i) {
5949 342480 : ACON = A(K, i) / A(K, K);
5950 342480 : B(i) -= B(K) * ACON;
5951 1940720 : for (j = K; j <= N; ++j) {
5952 1598240 : A(j, i) -= A(j, K) * ACON;
5953 : }
5954 : }
5955 : }
5956 :
5957 : // Perform back substituion
5958 22832 : CoeffsCurve(N) = B(N) / A(N, N);
5959 22832 : LP1 = N;
5960 22832 : L = N - 1;
5961 :
5962 251152 : while (L > 0) {
5963 114160 : SUM = 0.0;
5964 456640 : for (j = LP1; j <= N; ++j) {
5965 342480 : SUM += A(j, L) * CoeffsCurve(j);
5966 : }
5967 114160 : CoeffsCurve(L) = (B(L) - SUM) / A(L, L);
5968 114160 : LP1 = L;
5969 114160 : --L;
5970 : }
5971 22832 : }
5972 :
5973 : //********************************************************************************
5974 :
5975 0 : void W5LsqFit2(Array1A<Real64> const IndepVar, // Independent variables
5976 : Array1A<Real64> const DepVar, // Dependent variables
5977 : int const N, // Order of polynomial
5978 : int const N1, // First and last data points used
5979 : int const N2,
5980 : Array1A<Real64> CoeffsCurve // Polynomial coefficients from fit
5981 : )
5982 : {
5983 :
5984 : // SUBROUTINE INFORMATION:
5985 : // AUTHOR George Walton
5986 : // DATE WRITTEN April 1976
5987 : // MODIFIED November 1999 F.Winkelmann
5988 : // May 2001 F. Winkelmann, to do 19 indep. variables
5989 : // RE-ENGINEERED na
5990 :
5991 : // PURPOSE OF THIS SUBROUTINE:
5992 : // Does least squares fit for coefficients of a polynomial
5993 : // that gives a window property, such as transmittance, as a function of
5994 : // the cosine of the angle of incidence. The polynomial is of the
5995 : // form C1*X + C2*X**2 + C3*X**3 + ... +CN*X**N, where N <= 6.
5996 : // Adapted from BLAST subroutine LSQFIT.
5997 :
5998 : // Argument array dimensioning
5999 0 : IndepVar.dim(19);
6000 0 : DepVar.dim(19);
6001 0 : CoeffsCurve.dim(6);
6002 :
6003 0 : Array2D<Real64> A(6, 6); // Least squares derivative matrix
6004 0 : Array1D<Real64> B(6); // Least squares derivative vector
6005 0 : Array2D<Real64> D(6, 16); // Powers of independent variable
6006 : Real64 ACON; // Intermediate variables
6007 : Real64 SUM;
6008 : int i; // Loop parameters
6009 : int j;
6010 : int K;
6011 : int L;
6012 : int M;
6013 : int KP1;
6014 : int LP1;
6015 : int NM1;
6016 :
6017 : // Set up least squares matrix
6018 0 : for (M = N1; M <= N2; ++M) {
6019 0 : D(1, M) = IndepVar(M);
6020 : }
6021 :
6022 0 : for (i = 2; i <= N; ++i) {
6023 0 : for (M = N1; M <= N2; ++M) {
6024 0 : D(i, M) = D(i - 1, M) * IndepVar(M);
6025 : }
6026 : }
6027 :
6028 0 : for (i = 1; i <= N; ++i) {
6029 0 : SUM = 0.0;
6030 0 : for (M = N1; M <= N2; ++M) {
6031 0 : SUM += DepVar(M) * D(i, M);
6032 : }
6033 0 : B(i) = SUM;
6034 0 : for (j = 1; j <= N; ++j) {
6035 0 : SUM = 0.0;
6036 0 : for (M = N1; M <= N2; ++M) {
6037 0 : SUM += D(i, M) * D(j, M);
6038 : }
6039 0 : A(j, i) = SUM;
6040 0 : A(i, j) = SUM;
6041 : }
6042 : }
6043 :
6044 : // Solve the simultaneous equations using Gauss elimination
6045 0 : NM1 = N - 1;
6046 0 : for (K = 1; K <= NM1; ++K) {
6047 0 : KP1 = K + 1;
6048 0 : for (i = KP1; i <= N; ++i) {
6049 0 : ACON = A(K, i) / A(K, K);
6050 0 : B(i) -= B(K) * ACON;
6051 0 : for (j = K; j <= N; ++j) {
6052 0 : A(j, i) -= A(j, K) * ACON;
6053 : }
6054 : }
6055 : }
6056 :
6057 : // Perform back substituion
6058 0 : CoeffsCurve(N) = B(N) / A(N, N);
6059 0 : LP1 = N;
6060 0 : L = N - 1;
6061 :
6062 0 : while (L > 0) {
6063 0 : SUM = 0.0;
6064 0 : for (j = LP1; j <= N; ++j) {
6065 0 : SUM += A(j, L) * CoeffsCurve(j);
6066 : }
6067 0 : CoeffsCurve(L) = (B(L) - SUM) / A(L, L);
6068 0 : LP1 = L;
6069 0 : --L;
6070 : }
6071 0 : }
6072 :
6073 : //***********************************************************************
6074 :
6075 22384 : Real64 DiffuseAverage(Array1S<Real64> const PropertyValue) // Property value at angles of incidence
6076 : {
6077 :
6078 : // FUNCTION INFORMATION:
6079 : // AUTHOR Fred Winkelmann
6080 : // DATE WRITTEN November 1999
6081 : // MODIFIED na
6082 : // RE-ENGINEERED na
6083 :
6084 : // PURPOSE OF THIS FUNCTION:
6085 : // Calculate value of property, such as transmittance, for hemispherical
6086 : // diffuse radiation from property values at angles of incidence from
6087 : // 0 to 90 degrees in 10 degree increments.
6088 :
6089 : // METHODOLOGY EMPLOYED:
6090 : // By Simpson's rule, evaluates the integral from 0 to 90 deg of
6091 : // 2*PropertyValue(phi)*cos(phi)*sin(phi)*dphi (which is same as
6092 : // PropertyValue(phi)*sin(2*phi)*dphi)
6093 :
6094 : // Return value
6095 : Real64 DiffuseAverage;
6096 :
6097 : // Locals
6098 : // SUBROUTINE ARGUMENT DEFINITIONS:
6099 : // 0,10,20,...,80,90 degress
6100 :
6101 22384 : Real64 const DPhiR(10.0 * DataGlobalConstants::DegToRadians); // Half of 10-deg incidence angle increment (radians)
6102 : int IPhi; // Incidence angle counter
6103 :
6104 22384 : DiffuseAverage = 0.0;
6105 223840 : for (IPhi = 1; IPhi <= 9; ++IPhi) {
6106 201456 : DiffuseAverage +=
6107 201456 : 0.5 * DPhiR * (PropertyValue(IPhi) * std::sin(2.0 * (IPhi - 1) * DPhiR) + PropertyValue(IPhi + 1) * std::sin(2.0 * IPhi * DPhiR));
6108 : }
6109 22384 : if (DiffuseAverage < 0.0) DiffuseAverage = 0.0;
6110 :
6111 22384 : return DiffuseAverage;
6112 : }
6113 :
6114 : //*************************************************************************************
6115 :
6116 296 : Real64 DiffuseAverageProfAngGnd(Array1S<Real64> const Property) // Property value vs. profile angle
6117 : {
6118 :
6119 : // FUNCTION INFORMATION:
6120 : // AUTHOR Fred Winkelmann
6121 : // DATE WRITTEN January 2004
6122 : // MODIFIED na
6123 : // RE-ENGINEERED na
6124 :
6125 : // PURPOSE OF THIS FUNCTION:
6126 : // Calculates diffuse average of Property, such as blind transmittance, over profile angles
6127 : // corresponding to (upgoing) radiation from the ground.
6128 :
6129 : // METHODOLOGY EMPLOYED:
6130 : // Integration by Simpson's rule assuming uniform radiance distribution.
6131 :
6132 : // Using/Aliasing
6133 : using General::InterpProfAng;
6134 :
6135 : // Return value
6136 : Real64 DiffuseAverageProfAngGnd;
6137 :
6138 : Real64 Phi; // Profile angle (radians)
6139 : Real64 DPhi; // Phi increment
6140 : int IPhi; // Phi index
6141 : Real64 Sum; // Sums
6142 : Real64 SumDenom;
6143 :
6144 296 : Sum = 0.0;
6145 296 : SumDenom = 0.0;
6146 296 : DPhi = 5.0 * DataGlobalConstants::DegToRadians;
6147 :
6148 : // Integrate from -90 to 0 deg
6149 5624 : for (IPhi = 1; IPhi <= 18; ++IPhi) {
6150 5328 : Phi = -DataGlobalConstants::PiOvr2 + (IPhi - 0.5) * DPhi;
6151 5328 : Sum += std::cos(Phi) * DPhi * InterpProfAng(Phi, Property);
6152 5328 : SumDenom += std::cos(Phi) * DPhi;
6153 : }
6154 :
6155 296 : DiffuseAverageProfAngGnd = Sum / SumDenom;
6156 296 : if (DiffuseAverageProfAngGnd < 0.0) DiffuseAverageProfAngGnd = 0.0;
6157 :
6158 296 : return DiffuseAverageProfAngGnd;
6159 : }
6160 :
6161 : //*************************************************************************************
6162 :
6163 296 : Real64 DiffuseAverageProfAngSky(Array1S<Real64> const Property) // Property value vs. profile angle
6164 : {
6165 :
6166 : // FUNCTION INFORMATION:
6167 : // AUTHOR Fred Winkelmann
6168 : // DATE WRITTEN January 2004
6169 : // MODIFIED na
6170 : // RE-ENGINEERED na
6171 :
6172 : // PURPOSE OF THIS FUNCTION:
6173 : // Calculates diffuse average of Property, such as blind transmittance, over profile angles
6174 : // corresponding to (downgoing) radiation from the sky.
6175 :
6176 : // METHODOLOGY EMPLOYED:
6177 : // Integration by Simpson's rule assuming uniform radiance distribution.
6178 :
6179 : // Using/Aliasing
6180 : using General::InterpProfAng;
6181 :
6182 : // Return value
6183 : Real64 DiffuseAverageProfAngSky;
6184 :
6185 : Real64 Phi; // Profile angle (radians)
6186 : Real64 DPhi; // Phi increment
6187 : int IPhi; // Phi index
6188 : Real64 Sum; // Sums
6189 : Real64 SumDenom;
6190 :
6191 296 : Sum = 0.0;
6192 296 : SumDenom = 0.0;
6193 296 : DPhi = 5.0 * DataGlobalConstants::DegToRadians;
6194 :
6195 : // Integrate from 0 to 90 deg
6196 5624 : for (IPhi = 19; IPhi <= 36; ++IPhi) {
6197 5328 : Phi = -DataGlobalConstants::PiOvr2 + (IPhi - 0.5) * DPhi;
6198 5328 : Sum += std::cos(Phi) * DPhi * InterpProfAng(Phi, Property);
6199 5328 : SumDenom += std::cos(Phi) * DPhi;
6200 : }
6201 :
6202 296 : DiffuseAverageProfAngSky = Sum / SumDenom;
6203 296 : if (DiffuseAverageProfAngSky < 0.0) DiffuseAverageProfAngSky = 0.0;
6204 :
6205 296 : return DiffuseAverageProfAngSky;
6206 : }
6207 :
6208 : //*************************************************************************************
6209 :
6210 589776 : void CalcWinFrameAndDividerTemps(EnergyPlusData &state,
6211 : int const SurfNum, // Surface number
6212 : Real64 const tout, // Outside air temperature (K)
6213 : Real64 const tin, // Inside air temperature (K)
6214 : Real64 const HOutConv, // Outside convective air film conductance (W/m2-K)
6215 : Real64 const HInConv, // Inside convective air film conductance (W/m2-K)
6216 : Real64 const Outir, // Exterior IR irradiance from sky and ground
6217 : int const ConstrNum // Construction number of window
6218 : )
6219 : {
6220 :
6221 : // SUBROUTINE INFORMATION:
6222 : // AUTHOR F. Winkelmann
6223 : // DATE WRITTEN May 2000
6224 : // MODIFIED Aug 2000, FCW: Add effect of frame and divider projections
6225 : // Jun 2001, FCW: Add frame/divider contribution to WinHeatGain
6226 : // Aug 2003, FCW: Fix calculation of divider outside temp: frame
6227 : // inside temp was being used instead of divider inside temp
6228 : // RE-ENGINEERED na
6229 :
6230 : // PURPOSE OF THIS SUBROUTINE:
6231 : // Calculates window frame divider face temperatures from a linearized
6232 : // heat balance on the inside and outside faces
6233 :
6234 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6235 : Real64 HInRad; // Inside radiative conductance (W/m2-K)
6236 : Real64 HOutRad; // Outside radiative conductance (W/m2-K)
6237 : int FrDivNum; // Frame/divider number
6238 : Real64 TInRad; // Inside radiative temperature (K)
6239 : Real64 TInRadFr; // Effective inside radiative temperature for frame (K)
6240 : Real64 TInRadDiv; // Effective inside radiative temperature for divider (K)
6241 : Real64 TOutRad; // Outside radiative temperature (K)
6242 : Real64 TOutRadFr; // Effective outside radiative temperature for frame (K)
6243 : Real64 TOutRadDiv; // Effective outside radiative temperature for divider (K)
6244 : WinShadingType ShadeFlag; // Window shading flag
6245 : Real64 FrameCon; // Frame conductance (W/m2-K)
6246 :
6247 : Real64 Afac; // Intermediate calculation variables
6248 : Real64 Bfac;
6249 : Real64 Dfac;
6250 : Real64 Efac;
6251 : DataSurfaces::FrameDividerType DivType; // Divider type
6252 : Real64 DivCon; // Divider conductance (W/m2-K)
6253 : Real64 DivEmisIn; // Inside divider emissivity
6254 : Real64 DivEmisOut; // Outside divider emissivity
6255 :
6256 : Real64 ProjCorrFrOut; // Outside correction factor for absorbed radiation
6257 : // for frame with outside projection
6258 : Real64 ProjCorrFrIn; // Inside correction factor for absorbed radiation
6259 : // for frame with inside projection
6260 : Real64 HOutConvFr; // Effective outside convective coeff for frame
6261 : // with outside projection (W/m2-K)
6262 : Real64 HOutConvDiv; // Effective outside convective coeff for divider
6263 : // with outside projection (W/m2-K)
6264 : Real64 HInConvFr; // Effective inside convective coeff for frame
6265 : // with inside projection (W/m2-K)
6266 : Real64 HInConvDiv; // Effective inside convective coeff for divider
6267 : // with inside projection (W/m2-K)
6268 : Real64 EmisGlassOut; // Outside surface emissivity of window glazing
6269 : Real64 EmisGlassIn; // Inside surface emissivity of window glazing
6270 : int TotGlassLayers; // Total number of glass layers
6271 : int TotLayers; // Total number of layers in unshaded construction
6272 : // Real64 DivTempOut; // Outside surface divider temperature (K)
6273 : Real64 FrameHeatGain; // Heat gain to zone from frame (W)
6274 : // Real64 FrameHeatTransfer; // Heat tansfer through frame (W)
6275 : // Real64 ProjCorrWinHeatGain; // Inside projection correction to IR from divider to zone
6276 : // for window heat gain calculation
6277 : Real64 DividerHeatGain; // Heat gain to zone from divider (W)
6278 : // Real64 DividerHeatTransfer; // Heat transfer through divider (W)
6279 :
6280 589776 : TInRad = root_4(state.dataSurface->SurfWinIRfromParentZone(SurfNum) / state.dataWindowManager->sigma);
6281 589776 : TOutRad = root_4(Outir / state.dataWindowManager->sigma);
6282 589776 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
6283 589776 : FrDivNum = state.dataSurface->Surface(SurfNum).FrameDivider;
6284 589776 : TotLayers = state.dataConstruction->Construct(ConstrNum).TotLayers;
6285 589776 : TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
6286 589776 : EmisGlassOut = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermalFront;
6287 589776 : EmisGlassIn = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLayers)).AbsorpThermalBack;
6288 589776 : FrameHeatGain = 0.0;
6289 589776 : DividerHeatGain = 0.0;
6290 589776 : state.dataSurface->SurfWinFrameHeatGain(SurfNum) = 0.0;
6291 589776 : state.dataSurface->SurfWinFrameHeatLoss(SurfNum) = 0.0;
6292 589776 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
6293 589776 : state.dataSurface->SurfWinDividerHeatLoss(SurfNum) = 0.0;
6294 :
6295 589776 : if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
6296 : // Window has a frame. Note that if a shade, screen or blind is present it covers only the glazed part of the
6297 : // window and is assumed not to shadow long- or short-wave radiation incident on the frame elements.
6298 589776 : ProjCorrFrOut = state.dataSurface->SurfWinProjCorrFrOut(SurfNum);
6299 589776 : ProjCorrFrIn = state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
6300 589776 : TOutRadFr = TOutRad * root_4((1.0 + 0.5 * ProjCorrFrOut) / (1.0 + ProjCorrFrOut));
6301 589776 : TInRadFr = TInRad * root_4((1.0 + 0.5 * ProjCorrFrIn) / (1.0 + ProjCorrFrIn));
6302 589776 : FrameCon = state.dataSurface->SurfWinFrameConductance(SurfNum);
6303 1179552 : HInRad = 0.5 * state.dataSurface->SurfWinFrameEmis(SurfNum) * state.dataWindowManager->sigma *
6304 589776 : pow_3(TInRadFr + state.dataSurface->SurfWinFrameTempIn(SurfNum) + state.dataWindowManager->TKelvin);
6305 589776 : HInConvFr = HInConv;
6306 1179552 : HOutRad = 0.5 * state.dataSurface->SurfWinFrameEmis(SurfNum) * state.dataWindowManager->sigma *
6307 589776 : pow_3(TOutRadFr + state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) + state.dataWindowManager->TKelvin);
6308 589776 : HOutConvFr = HOutConv;
6309 589776 : if (state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut > 0.0) {
6310 522576 : HOutRad *= (1.0 + ProjCorrFrOut);
6311 522576 : HOutConvFr = HOutConv * (1.0 + ProjCorrFrOut);
6312 : // Add long-wave from outside window surface absorbed by frame outside projection
6313 522576 : state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) +=
6314 522576 : 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).FrameEmis * EmisGlassOut *
6315 1045152 : state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(1));
6316 : }
6317 589776 : if (state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn > 0.0) {
6318 522576 : HInRad *= (1.0 + ProjCorrFrIn);
6319 522576 : HInConvFr = HInConv * (1.0 + ProjCorrFrIn);
6320 : // Add long-wave from inside window surface absorbed by frame inside projection
6321 522576 : state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
6322 522576 : 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).FrameEmis * EmisGlassIn *
6323 1045152 : state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(2 * TotGlassLayers));
6324 : }
6325 589776 : Afac = (HOutRad * TOutRadFr + HOutConvFr * tout + state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum)) / (HOutRad + FrameCon + HOutConvFr);
6326 589776 : Bfac = FrameCon / (HOutRad + FrameCon + HOutConvFr);
6327 589776 : Dfac = (HInRad * TInRadFr + HInConvFr * tin + state.dataSurface->SurfWinFrameQRadInAbs(SurfNum)) / (HInRad + FrameCon + HInConvFr);
6328 589776 : Efac = FrameCon / (HInRad + FrameCon + HInConvFr);
6329 589776 : state.dataSurface->SurfWinFrameTempIn(SurfNum) = (Dfac + Efac * Afac) / (1.0 - Efac * Bfac) - state.dataWindowManager->TKelvin;
6330 589776 : state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) =
6331 589776 : Afac + Bfac * (state.dataSurface->SurfWinFrameTempIn(SurfNum) + state.dataWindowManager->TKelvin) - state.dataWindowManager->TKelvin;
6332 : // Heat gain to zone from frame
6333 :
6334 : // FrameHeatTransfer = state.dataSurface->SurfWinFrameArea(SurfNum) * FrameCon *
6335 : // (state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) - state.dataSurface->SurfWinFrameTempIn(SurfNum));
6336 1179552 : FrameHeatGain = state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
6337 1179552 : (HInConvFr * (state.dataSurface->SurfWinFrameTempIn(SurfNum) + state.dataWindowManager->TKelvin - tin));
6338 :
6339 589776 : if (FrameHeatGain > 0.0) {
6340 124385 : state.dataSurface->SurfWinFrameHeatGain(SurfNum) = FrameHeatGain;
6341 : } else {
6342 465391 : state.dataSurface->SurfWinFrameHeatLoss(SurfNum) = std::abs(FrameHeatGain);
6343 : }
6344 :
6345 589776 : state.dataSurface->SurfWinHeatGain(SurfNum) += FrameHeatGain;
6346 589776 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = FrameHeatGain;
6347 : } // End of check if window has a frame
6348 :
6349 589776 : if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && state.dataSurface->SurfWinStormWinFlag(SurfNum) < 1) {
6350 : // Window has divider. Note that if the window has a storm window layer in place (StormWinFlag = 1)
6351 : // the divider heat transfer calculation is not done.
6352 :
6353 261168 : DivType = state.dataSurface->SurfWinDividerType(SurfNum);
6354 261168 : DivCon = state.dataSurface->SurfWinDividerConductance(SurfNum);
6355 :
6356 261168 : if (DivType == DataSurfaces::FrameDividerType::DividedLite) { // Divided lite
6357 231696 : DivEmisIn = state.dataSurface->SurfWinDividerEmis(SurfNum);
6358 231696 : DivEmisOut = DivEmisIn;
6359 : } else { // Suspended (between-glass) divider
6360 29472 : DivEmisOut = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermalFront;
6361 29472 : DivEmisIn =
6362 : state.dataMaterial
6363 29472 : ->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataConstruction->Construct(ConstrNum).TotLayers))
6364 : .AbsorpThermalBack;
6365 : }
6366 :
6367 522336 : TOutRadDiv = TOutRad * root_4((1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)) /
6368 261168 : (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivOut(SurfNum)));
6369 522336 : TInRadDiv = TInRad * root_4((1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) /
6370 261168 : (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)));
6371 522336 : HInRad = 0.5 * DivEmisIn * state.dataWindowManager->sigma *
6372 261168 : pow_3(TInRadDiv + state.dataSurface->SurfWinDividerTempIn(SurfNum) + state.dataWindowManager->TKelvin);
6373 522336 : HOutRad = 0.5 * DivEmisOut * state.dataWindowManager->sigma *
6374 261168 : pow_3(TOutRadDiv + state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) + state.dataWindowManager->TKelvin);
6375 261168 : HOutConvDiv = HOutConv;
6376 :
6377 261168 : if (state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut > 0.0) {
6378 223632 : HOutRad *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
6379 223632 : if (state.dataSurface->SurfWinShadingFlag(SurfNum) == WinShadingType::ExtShade)
6380 0 : HOutConvDiv = state.dataSurface->SurfWinConvCoeffWithShade(SurfNum);
6381 223632 : HOutConvDiv *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
6382 : // Add long-wave from outside window surface absorbed by divider outside projection
6383 223632 : state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) +=
6384 223632 : state.dataSurface->SurfWinProjCorrDivOut(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).DividerEmis * EmisGlassOut *
6385 447264 : state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(1));
6386 : }
6387 :
6388 261168 : HInConvDiv = HInConv;
6389 :
6390 261168 : if (state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn > 0.0) {
6391 223632 : HInRad *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
6392 223632 : if (state.dataSurface->SurfWinShadingFlag(SurfNum) == WinShadingType::IntShade)
6393 0 : HInConvDiv = state.dataSurface->SurfWinConvCoeffWithShade(SurfNum);
6394 223632 : HInConvDiv *= (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
6395 : // Add long-wave from inside window surface absorbed by divider inside projection
6396 223632 : state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
6397 223632 : state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * state.dataSurface->FrameDivider(FrDivNum).DividerEmis * EmisGlassIn *
6398 447264 : state.dataWindowManager->sigma * pow_4(state.dataSurface->SurfaceWindow(SurfNum).ThetaFace(2 * TotGlassLayers));
6399 : }
6400 261168 : Afac =
6401 261168 : (HOutRad * TOutRadDiv + HOutConvDiv * tout + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum)) / (HOutRad + DivCon + HOutConvDiv);
6402 261168 : Bfac = DivCon / (HOutRad + DivCon + HOutConvDiv);
6403 261168 : Dfac = (HInRad * TInRadDiv + HInConvDiv * tin + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum)) / (HInRad + DivCon + HInConvDiv);
6404 261168 : Efac = DivCon / (HInRad + DivCon + HInConvDiv);
6405 261168 : state.dataSurface->SurfWinDividerTempIn(SurfNum) = (Dfac + Efac * Afac) / (1 - Efac * Bfac) - state.dataWindowManager->TKelvin;
6406 261168 : state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) =
6407 522336 : Afac + Bfac * (state.dataSurface->SurfWinDividerTempIn(SurfNum) + state.dataWindowManager->TKelvin) -
6408 261168 : state.dataWindowManager->TKelvin;
6409 : // Contribution of divider to window heat gain
6410 : // ProjCorrWinHeatGain = 1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
6411 :
6412 522336 : DividerHeatGain = state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
6413 522336 : (HInConvDiv * (state.dataSurface->SurfWinDividerTempIn(SurfNum) + state.dataWindowManager->TKelvin - tin));
6414 : // DividerHeatTransfer = state.dataSurface->SurfWinDividerArea(SurfNum) * DivCon *
6415 : // (state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) - state.dataSurface->SurfWinDividerTempIn(SurfNum));
6416 :
6417 261168 : if (DividerHeatGain > 0.0) {
6418 57853 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = DividerHeatGain;
6419 : } else {
6420 203315 : state.dataSurface->SurfWinDividerHeatLoss(SurfNum) = std::abs(DividerHeatGain);
6421 : }
6422 261168 : state.dataSurface->SurfWinHeatGain(SurfNum) += DividerHeatGain;
6423 261168 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) += DividerHeatGain;
6424 : // If interior shade is present it is assumed that both the convective and IR radiative gain
6425 : // from the inside surface of the divider goes directly into the zone air -- i.e., the IR radiative
6426 : // interaction between divider and shade is ignored due to the difficulty of calculating this interaction
6427 : // at the same time that the interaction between glass and shade is calculated.
6428 261168 : if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum)))
6429 742 : state.dataSurface->SurfWinDividerHeatGain(SurfNum) = DividerHeatGain;
6430 : // DivTempOut = state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) + state.dataWindowManager->TKelvin;
6431 : } // End of check if window has dividers
6432 589776 : }
6433 :
6434 : //************************************************************************************
6435 :
6436 2602 : void CalcNominalWindowCond(EnergyPlusData &state,
6437 : int const ConstrNum, // Construction number
6438 : int const WinterSummerFlag, // 1=winter, 2=summer
6439 : Real64 &NominalConductance, // Nominal center-of-glass conductance, including air films
6440 : Real64 &SHGC, // Nominal center-of-glass solar heat gain coefficient for
6441 : Real64 &TSolNorm, // Overall beam solar transmittance at normal incidence
6442 : Real64 &TVisNorm, // Overall beam visible transmittance at normal incidence
6443 : int &errFlag // Error flag
6444 : )
6445 : {
6446 :
6447 : // SUBROUTINE INFORMATION:
6448 : // AUTHOR F. Winkelmann
6449 : // DATE WRITTEN September 2000
6450 : // MODIFIED Oct 2000, FW: add solar heat gain coefficient
6451 : // June 2001, FW: account for blinds; change summer outside air
6452 : // temp from 35.0C to 31.7C to correspond to ASHRAE value
6453 : // Feb 2003, FW: add comments that this routine is not called for
6454 : // between-glass shade/blind constructions.
6455 : // May 2006, RR: account for screens
6456 : // Oct 2007, LKL: change temps to match Window 5 values
6457 : // Feb 2009, BG: Changes for CR7682 (SHGC)
6458 : // RE-ENGINEERED na
6459 :
6460 : // PURPOSE OF THIS SUBROUTINE:
6461 : // Calculates nominal center-of-glass U-value and solar heat gain coefficient
6462 : // (SHGC) of a window construction for ASHRAE winter and summer conditions.
6463 : // Winter:
6464 : // Inside air temperature = 21.C (69.80F)
6465 : // Outside air temperature = -18C (-.4F)
6466 : // Windspeed = 5.5 m/s (12.3 mph)
6467 : // No solar radiation
6468 : // Replaced Winter:
6469 : // Inside air temperature = 21.1C (70F)
6470 : // Outside air temperature = -17.8C (0F)
6471 : // Windspeed = 6.71 m/s (15 mph)
6472 : // No solar radiation
6473 : // Summer:
6474 : // Inside air temperature = 24C (75.2F)
6475 : // Outside air temperature = 32C (89.6F)
6476 : // Windspeed = 2.8 m/s (6.2 mph)
6477 : // 783 W/m2 (248 Btu/h-ft2) incident beam solar radiation normal to glazing
6478 : // Replaced Summer:
6479 : // Inside air temperature = 24C (75.2F) ! BG changed again Feb. 2009 by 0.1 (per Window5 team)
6480 : // Outside air temperature = 31.7C (89F)
6481 : // Windspeed = 3.35 m/s (7.5 mph)
6482 : // 783 W/m2 (248 Btu/h-ft2) incident beam solar radiation normal to glazing
6483 : // The window's inside surround is assumed to be a black body at the inside air temp.
6484 : // The window's outside surround is assumed t be a black body at the outside air temp.
6485 : // Note that in this routine we use a value of 26 W/m2 for the outside convective
6486 : // air film conductance for 5.5 m/s (12.3 mph) wind speed.
6487 : // This is the value used in Window 5 and is also the value for which the center-of-glass
6488 : // conductances in the EnergyPlus window construction reference data set were calculated.
6489 : // However, in the time step loop we will have different values of outside film
6490 : // conductance depending on that time step's wind speed, wind direction, surface-to-air temp difference,
6491 : // etc.(see subroutine InitExteriorConvectionCoeff).
6492 : // This routine will return an error and exit for window constructions with between-glass shade or blind
6493 : // until a method is worked out to determine the nominal conductance and SHGC in this case.
6494 : // If an interior or exterior shade or blind is present in the construction,
6495 : // the conductance calculation does not include the effect of the shade or blind.
6496 : // This is because in this case the conductance depends on the natural convective
6497 : // air flow in the shade/glass, screen/glass or blind/glass channel, which in turn is highly dependent
6498 : // on window height and other parameters that are not part of the construction definition.
6499 : // Therefore, the reported conductance value will be too high for windows with a tightly fitting
6500 : // shade, screen or blind with a relatively high thermal resistance.
6501 : // For SHGC calculation, all solar absorbed by interior blind or shade is assumed
6502 : // to go into zone air. (This is not true in general; the fraction of this absorbed solar that
6503 : // is conducted back out is accounted for in the time-step glazing calculation.)
6504 : // For CR 7682, the SHGC calculations were changed to model the absorbed solar arriving at the middle of the layer
6505 : // rather than at the outer face of the layer. The resistances changed by one half the glazing layer, or 0.5/scon(n).
6506 : // (CR 7682 also changed WindowTempsForNominalCond to include absorbed solar, a bigger change)
6507 :
6508 : // Using/Aliasing
6509 : using General::BlindBeamBeamTrans;
6510 : using General::InterpProfSlatAng;
6511 : using General::InterpSlatAng;
6512 : using General::POLYF;
6513 :
6514 : // Locals
6515 : // SUBROUTINE ARGUMENT DEFINITIONS:
6516 : // normal incidence beam solar radiation
6517 :
6518 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6519 : int TotLay; // Total number of layers in a construction
6520 : // (sum of solid layers and gap layers)
6521 : int TotGlassLay; // Total number of glass layers in a construction
6522 : int Lay; // Layer number
6523 : int LayPtr; // Material number for a layer
6524 : int IGlass; // glass layer number (1,2,3,...)
6525 : int IGap; // Gap layer number (1,2,...)
6526 : int IMix; // Gas component loop index for gap gas mixture
6527 : int ICoeff; // Gas property coefficient index
6528 :
6529 : Real64 BeamSolarInc; // Incident beam radiation at zero angle of incidence (W/m2)
6530 : // Real64 hOutRad; // Radiative conductance of outside and inside airfilm [W/m2-K]
6531 : // Real64 hInRad;
6532 : // Real64 rOut; // Combined radiative and conductive outside and inside film
6533 : // Real64 rIn;
6534 : // resistance [m2-K/W]
6535 5199 : Array1D<Real64> hgap(5); // Conductive gap conductance [W/m2-K]
6536 : // Array1D<Real64> hGapTot(5); // Combined radiative and conductive gap conductance [W/m2-K]
6537 : // Real64 Rbare; // Nominal center-of-glass resistance without air films [m2-K/W]
6538 : WinShadingType ShadeFlag; // Shading flag
6539 : Real64 ShadeRes; // Thermal resistance of shade
6540 : int MatOutside; // Material number of outside layer of construction
6541 : int MatInside; // Material number of inside layer of construction
6542 : int MatShade; // Material number of shade layer
6543 5199 : Array1D<Real64> AbsBeamNorm(5); // Beam absorptance at normal incidence for each glass layer
6544 : Real64 AbsBeamShadeNorm; // Shade solar absorptance at normal incidence
6545 : int ConstrNum1; // Construction counter
6546 : int ConstrNumBare; // Construction without shading device
6547 : int BlNum; // Blind number
6548 : int ScNum; // Screen number
6549 : bool VarSlats; // True if slats in blind are variable angle
6550 : Real64 SlatAng; // Slat angle (rad)
6551 : int LayPtrSh; // Layer pointer of blind
6552 : Real64 TBmBm; // Bare glass normal incidence beam-beam transmittance
6553 : Real64 TBmBmVis;
6554 : Real64 TBlBmBm; // Normal incidence blind beam-beam transmittance
6555 : Real64 TScBmBm; // Screen incident beam-beam transmittance
6556 : Real64 TScBmBmVis;
6557 : Real64 TBmBmBl; // TBmBm * TBlBmBm, TBmBmVis * TBlBmBm
6558 : Real64 TBmBmBlVis;
6559 : Real64 RGlDiffBack; // Bare glass back sol/vis reflectance
6560 : Real64 RGlDiffBackVis;
6561 : Real64 RGlDiffFront; // Bare glass front sol/vis reflectance
6562 : Real64 RGlDiffFrontVis;
6563 : Real64 RhoBlFront; // Blind normal front beam-diffuse sol/vis reflectance
6564 : Real64 RhoBlFrontVis;
6565 : Real64 RhoBlBack; // Blind normal back beam-diffuse sol/vis reflectance
6566 : Real64 RhoBlBackVis;
6567 : Real64 RScBack; // Screen back beam-diffuse sol/vis reflectance (same as front)
6568 : Real64 RScBackVis;
6569 : Real64 AbsBlFront; // Blind normal front beam solar absorptance
6570 : Real64 AbsBlBack; // Blind normal back beam solar absorptance
6571 : Real64 RhoBlDiffFront; // Blind front diffuse-diffuse sol/vis reflectance
6572 : Real64 RhoBlDiffFrontVis;
6573 : Real64 AbsBlDiffFront; // Blind front diffuse solar absorptance
6574 : Real64 AbsBlDiffBack; // Blind back diffuse solar absorptance
6575 : Real64 RGlFront; // Bare glass normal front beam sol/vis reflectance
6576 : Real64 RGlFrontVis;
6577 : Real64 RhoBlDiffBack; // Blind back diffuse-diffuse sol/vis reflectance
6578 : Real64 RhoBlDiffBackVis;
6579 : Real64 RScDifBack; // Screen back diffuse-diffuse sol/vis reflectance (doesn't change with sun angle)
6580 : Real64 RScDifBackVis;
6581 : Real64 TBlBmDif; // Blind front normal beam-diffuse sol/vis transmittance
6582 : Real64 TBlBmDifVis;
6583 : Real64 TBlDifDif; // Blind front diffuse-diffuse sol/vis transmittance
6584 : Real64 TBlDifDifVis;
6585 : Real64 TScBmDif; // Screen front beam-diffuse sol/vis transmittance
6586 : Real64 TScBmDifVis;
6587 : Real64 TDif; // Bare glass diffuse sol/vis transmittance
6588 : Real64 TDifVis;
6589 : Real64 AGlDiffBack; // Back diffuse solar absorptance of a glass layer
6590 :
6591 : // Autodesk:Uninit Initialize variables used uninitialized
6592 : // Rbare = 0.0; // Autodesk:Uninit Force default initialization
6593 2602 : NominalConductance = 0.0;
6594 2602 : errFlag = 0;
6595 2602 : TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers;
6596 2602 : TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
6597 2602 : state.dataWindowManager->ngllayer = TotGlassLay; // Autodesk:Uninit This routine needs to check/enforce 1<=ngllayer<=4
6598 : // EPTeam - believe that is done on input.
6599 2602 : state.dataWindowManager->nglface = 2 * state.dataWindowManager->ngllayer;
6600 2602 : state.dataWindowManager->tilt = 90.0; // Assume vertical window
6601 :
6602 2602 : if (WinterSummerFlag == 1) { // Winter
6603 : // LKL Oct 2007: According to Window5, Winter environmental conditions are:
6604 1313 : state.dataWindowManager->tin = 294.15; // Inside air temperature (69.8F, 21.C)
6605 1313 : state.dataWindowManager->tout = 255.15; // Outside air temperature (-.4F, -18C)
6606 1313 : state.dataWindowManager->hcout = 26.0; // Outside convective film conductance for 5.5 m/s (12.3 mph) wind speed
6607 : // (the value used in Window 5)
6608 : // tin = 294.26 ! Inside air temperature (70F, 21.1C)
6609 : // tout = 255.35 ! Outside air temperature (0F, -17.8C)
6610 : // hcout = 25.47 ! Outside convective film conductance for 6.71 m/s (15 mph) wind speed
6611 : // ! (the value used in Window 4)
6612 1313 : BeamSolarInc = 0.0;
6613 : } else { // Summer
6614 : // LKL Oct 2007: According to Window5, Summer environmental conditions are:
6615 : // tin = 297.05d0 ! Inside air temperature (75.2F, 24C)
6616 : // BG Feb. 2009: According to Window5 Expert Christian Kohler, it is exactly 24C or 297.15
6617 1289 : state.dataWindowManager->tin = 297.15;
6618 1289 : state.dataWindowManager->tout = 305.15; // Outside air temperature (89.6F, 32C)
6619 1289 : state.dataWindowManager->hcout = 15.0; // Outside convective film conductance for 2.8 m/s (6.2 mph) wind speed
6620 : // (the value used in Window 5)
6621 : // tin = 297.05 ! Inside air temperature (75F, 23.9C)
6622 : // !tout = 308.15 ! Outside air temperature (95F, 35.0C)
6623 : // ! Changed 6/20/01 by FCW to make consistent with Window 4 and 5.
6624 : // tout = 304.82 ! Outside air temperature (89F, 31.7C)
6625 : // hcout = 18.86 ! Outside convective film conductance for 3.35 m/s (7.5 mph) wind speed
6626 : // ! (average of Window 4 0 m/s and 6.71 m/s values)
6627 1289 : BeamSolarInc = 783.0;
6628 : }
6629 :
6630 : // IR incident on inside of glazing (inside surround assumed to be
6631 : // a black body at inside air temperature)
6632 2602 : state.dataWindowManager->Rmir = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tin);
6633 :
6634 : // IR incident on outside of glazing
6635 : // (outside surround is assumed to be a black body at outside air temperature)
6636 2602 : state.dataWindowManager->Outir = state.dataWindowManager->sigma * pow_4(state.dataWindowManager->tout);
6637 :
6638 : // Determine whether construction has an exterior or interior shade or blind
6639 2602 : ShadeFlag = WinShadingType::NoShade;
6640 2602 : ShadeRes = 0.0;
6641 2602 : MatOutside = state.dataConstruction->Construct(ConstrNum).LayerPoint(1);
6642 2602 : MatInside = state.dataConstruction->Construct(ConstrNum).LayerPoint(TotLay);
6643 2602 : if (state.dataMaterial->Material(MatOutside).Group == DataHeatBalance::MaterialGroup::Shade) { // Exterior shade present
6644 5 : MatShade = MatOutside;
6645 5 : ShadeFlag = WinShadingType::ExtShade;
6646 : // Set glazing outside convection coefficient to Window 4 still-air value
6647 5 : state.dataWindowManager->hcout = 12.25;
6648 2597 : } else if (state.dataMaterial->Material(MatOutside).Group == DataHeatBalance::MaterialGroup::Screen) { // Exterior screen present
6649 4 : MatShade = MatOutside;
6650 4 : ScNum = state.dataMaterial->Material(MatShade).ScreenDataPtr;
6651 : // Orphaned constructs with exterior screen are ignored
6652 4 : if (ScNum > 0) ShadeFlag = WinShadingType::ExtScreen;
6653 4 : state.dataWindowManager->hcout = 12.25;
6654 2593 : } else if (state.dataMaterial->Material(MatOutside).Group == DataHeatBalance::MaterialGroup::WindowBlind) { // Exterior blind present
6655 4 : MatShade = MatOutside;
6656 4 : ShadeFlag = WinShadingType::ExtBlind;
6657 4 : BlNum = state.dataMaterial->Material(MatShade).BlindDataPtr;
6658 4 : state.dataWindowManager->hcout = 12.25;
6659 2589 : } else if (state.dataMaterial->Material(MatInside).Group == DataHeatBalance::MaterialGroup::Shade) { // Interior shade present
6660 40 : MatShade = MatInside;
6661 40 : ShadeFlag = WinShadingType::IntShade;
6662 2549 : } else if (state.dataMaterial->Material(MatInside).Group == DataHeatBalance::MaterialGroup::WindowBlind) { // Interior blind present
6663 21 : MatShade = MatInside;
6664 21 : BlNum = state.dataMaterial->Material(MatShade).BlindDataPtr;
6665 21 : ShadeFlag = WinShadingType::IntBlind;
6666 2528 : } else if (TotGlassLay == 2) {
6667 962 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
6668 : DataHeatBalance::MaterialGroup::Shade)
6669 1 : ShadeFlag = WinShadingType::BGShade;
6670 962 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(3)).Group ==
6671 : DataHeatBalance::MaterialGroup::WindowBlind)
6672 2 : ShadeFlag = WinShadingType::BGBlind;
6673 1566 : } else if (TotGlassLay == 3) {
6674 132 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
6675 : DataHeatBalance::MaterialGroup::Shade)
6676 1 : ShadeFlag = WinShadingType::BGShade;
6677 132 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(5)).Group ==
6678 : DataHeatBalance::MaterialGroup::WindowBlind)
6679 1 : ShadeFlag = WinShadingType::BGBlind;
6680 : }
6681 :
6682 2602 : if (ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
6683 5 : errFlag = 2;
6684 5 : return;
6685 : }
6686 :
6687 2597 : TSolNorm = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
6688 2597 : TVisNorm = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
6689 2597 : AbsBeamShadeNorm = 0.0;
6690 2597 : if (ShadeFlag == WinShadingType::IntShade || ShadeFlag == WinShadingType::ExtShade) { // Exterior or interior shade on
6691 45 : AbsBeamShadeNorm = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef);
6692 : // Exterior blind or screen or interior blind on
6693 2552 : } else if (ShadeFlag == WinShadingType::IntBlind || ShadeFlag == WinShadingType::ExtBlind || ShadeFlag == WinShadingType::ExtScreen) {
6694 : // Find unshaded construction that goes with this construction w/blind or screen
6695 29 : ConstrNumBare = 0;
6696 173 : for (ConstrNum1 = 1; ConstrNum1 <= state.dataHeatBal->TotConstructs; ++ConstrNum1) {
6697 379 : if (ConstrNum1 != ConstrNum && state.dataConstruction->Construct(ConstrNum1).TypeIsWindow &&
6698 239 : state.dataConstruction->Construct(ConstrNum1).TotGlassLayers == state.dataConstruction->Construct(ConstrNum1).TotSolidLayers &&
6699 33 : state.dataConstruction->Construct(ConstrNum1).TotGlassLayers == state.dataConstruction->Construct(ConstrNum).TotGlassLayers) {
6700 : // We have an unshaded window construction with the same number of glass layers as ConstrNum;
6701 : // see if the glass and gas layers match
6702 31 : ConstrNumBare = ConstrNum1;
6703 66 : for (Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNum1).TotLayers; ++Lay) {
6704 35 : LayPtr = state.dataConstruction->Construct(ConstrNum1).LayerPoint(Lay);
6705 35 : if (ShadeFlag == WinShadingType::IntBlind) { // The shaded construction has an interior blind
6706 21 : LayPtrSh = state.dataConstruction->Construct(ConstrNum).LayerPoint(Lay);
6707 : } else { // The shaded construction has an exterior blind or screen
6708 14 : LayPtrSh = state.dataConstruction->Construct(ConstrNum).LayerPoint(Lay + 1);
6709 : }
6710 35 : if (LayPtrSh != LayPtr) ConstrNumBare = 0;
6711 : }
6712 31 : if (ConstrNumBare != 0) break;
6713 : }
6714 : }
6715 29 : if (ConstrNumBare == 0) {
6716 : // No matching bare construction found for this construction with blind or screen
6717 0 : errFlag = 1;
6718 0 : return;
6719 : }
6720 :
6721 29 : TBmBm = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).TransSolBeamCoef);
6722 29 : TBmBmVis = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).TransVisBeamCoef);
6723 29 : if (ShadeFlag == WinShadingType::ExtScreen) {
6724 : // Don't need to call subroutine, use normal incident properties (SUBROUTINE CalcNominalWindowCond)
6725 : // Last call to CalcScreenTransmittance(ISurf) was done at direct normal angle (0,0) in CalcWindowScreenProperties
6726 4 : TScBmBm = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTrans;
6727 4 : TScBmBmVis = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTransVis;
6728 4 : TScBmDif = state.dataHeatBal->SurfaceScreens(ScNum).BmDifTrans;
6729 4 : TScBmDifVis = state.dataHeatBal->SurfaceScreens(ScNum).BmDifTransVis;
6730 4 : TDif = state.dataConstruction->Construct(ConstrNumBare).TransDiff;
6731 4 : TDifVis = state.dataConstruction->Construct(ConstrNumBare).TransDiffVis;
6732 4 : RScBack = state.dataHeatBal->SurfaceScreens(ScNum).ReflectScreen;
6733 4 : RScBackVis = state.dataHeatBal->SurfaceScreens(ScNum).ReflectScreenVis;
6734 4 : RScDifBack = state.dataHeatBal->SurfaceScreens(ScNum).DifReflect;
6735 4 : RScDifBackVis = state.dataHeatBal->SurfaceScreens(ScNum).DifReflectVis;
6736 4 : RGlFront = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
6737 4 : RGlFrontVis = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
6738 4 : RGlDiffFront = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffFront;
6739 4 : RGlDiffFrontVis = state.dataConstruction->Construct(ConstrNumBare).ReflectVisDiffFront;
6740 8 : TSolNorm = TScBmBm * (TBmBm + TDif * RGlFront * RScBack / (1 - RGlDiffFront * RScDifBack)) +
6741 4 : TScBmDif * TDif / (1 - RGlDiffFront * RScDifBack);
6742 8 : TVisNorm = TScBmBmVis * (TBmBmVis + TDifVis * RGlFrontVis * RScBackVis / (1 - RGlDiffFrontVis * RScDifBackVis)) +
6743 4 : TScBmDifVis * TDifVis / (1 - RGlDiffFrontVis * RScDifBackVis);
6744 : } else {
6745 25 : VarSlats = false;
6746 25 : if (state.dataHeatBal->Blind(BlNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Variable) VarSlats = true;
6747 25 : SlatAng = state.dataHeatBal->Blind(BlNum).SlatAngle * DataGlobalConstants::DegToRadians;
6748 75 : TBlBmBm = BlindBeamBeamTrans(0.0,
6749 : SlatAng,
6750 25 : state.dataHeatBal->Blind(BlNum).SlatWidth,
6751 25 : state.dataHeatBal->Blind(BlNum).SlatSeparation,
6752 25 : state.dataHeatBal->Blind(BlNum).SlatThickness);
6753 25 : TBmBmBl = TBmBm * TBlBmBm;
6754 25 : TBmBmBlVis = TBmBmVis * TBlBmBm;
6755 25 : TBlBmDif = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans);
6756 25 : TBlBmDifVis = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontBeamDiffTrans);
6757 25 : TDif = state.dataConstruction->Construct(ConstrNumBare).TransDiff;
6758 25 : TDifVis = state.dataConstruction->Construct(ConstrNumBare).TransDiffVis;
6759 25 : if (ShadeFlag == WinShadingType::IntBlind) {
6760 21 : RGlDiffBack = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffBack;
6761 21 : RGlDiffBackVis = state.dataConstruction->Construct(ConstrNumBare).ReflectVisDiffBack;
6762 21 : RhoBlFront = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl);
6763 21 : RhoBlFrontVis = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontBeamDiffRefl);
6764 21 : AbsBlFront = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs);
6765 21 : RhoBlDiffFront = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl);
6766 21 : RhoBlDiffFrontVis = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffRefl);
6767 21 : AbsBlDiffFront = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs);
6768 21 : AbsBeamShadeNorm = TBmBm * (AbsBlFront + RhoBlFront * RGlDiffBack * AbsBlDiffFront / (1.0 - RhoBlDiffFront * RGlDiffBack));
6769 21 : TBlDifDif = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans);
6770 21 : TBlDifDifVis = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisFrontDiffDiffTrans);
6771 21 : TSolNorm = TBmBm * (TBlBmBm + TBlBmDif + TBlDifDif * RhoBlFront * RGlDiffBack / (1.0 - RhoBlDiffFront * RGlDiffBack));
6772 : // use of TBlBmBm here is correct, visible and IR transmittance are the same (reference deleted CR6925 on 3/20/2006)
6773 21 : TVisNorm = TBmBmVis *
6774 21 : (TBlBmBm + TBlBmDifVis + TBlDifDifVis * RhoBlFrontVis * RGlDiffBackVis / (1.0 - RhoBlDiffFrontVis * RGlDiffBackVis));
6775 : } // (IntBlind)
6776 25 : if (ShadeFlag == WinShadingType::ExtBlind) {
6777 12 : TBlBmBm = BlindBeamBeamTrans(0.0,
6778 : SlatAng,
6779 4 : state.dataHeatBal->Blind(BlNum).SlatWidth,
6780 4 : state.dataHeatBal->Blind(BlNum).SlatSeparation,
6781 4 : state.dataHeatBal->Blind(BlNum).SlatThickness);
6782 4 : RGlFront = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
6783 4 : RGlFrontVis = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).ReflSolBeamFrontCoef);
6784 4 : AbsBlFront = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs);
6785 4 : AbsBlBack = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackBeamAbs);
6786 4 : AbsBlDiffBack = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackDiffAbs);
6787 4 : RGlDiffFront = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffFront;
6788 4 : RGlDiffFrontVis = state.dataConstruction->Construct(ConstrNumBare).ReflectVisDiffFront;
6789 4 : RhoBlDiffBack = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl);
6790 4 : RhoBlDiffBackVis = InterpSlatAng(SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).VisBackDiffDiffRefl);
6791 4 : RhoBlBack = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl);
6792 4 : RhoBlBackVis = InterpProfSlatAng(0.0, SlatAng, VarSlats, state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl);
6793 4 : AbsBeamShadeNorm =
6794 4 : AbsBlFront + AbsBlBack * RGlFront * TBlBmBm +
6795 4 : (AbsBlDiffBack * RGlDiffFront / (1.0 - RhoBlDiffBack * RGlDiffFront)) * (RGlFront * TBlBmBm * RhoBlBack + TBlBmDif);
6796 4 : RGlDiffFront = state.dataConstruction->Construct(ConstrNumBare).ReflectSolDiffFront;
6797 8 : TSolNorm = TBlBmBm * (TBmBm + TDif * RGlFront * RhoBlBack / (1 - RGlDiffFront * RhoBlDiffBack)) +
6798 4 : TBlBmDif * TDif / (1.0 - RGlDiffFront * RhoBlDiffBack);
6799 8 : TVisNorm = TBlBmBm * (TBmBmVis + TDifVis * RGlFrontVis * RhoBlBackVis / (1 - RGlDiffFrontVis * RhoBlDiffBackVis)) +
6800 4 : TBlBmDifVis * TDifVis / (1.0 - RGlDiffFrontVis * RhoBlDiffBackVis);
6801 : } // (ExtBlind)
6802 : } // (Screen or Blind)
6803 : } // (Shade, Blind, or Screen)
6804 :
6805 : // Fill the layer properties needed for the thermal calculation.
6806 :
6807 : // The layer and face numbering are as follows (for the triple glazing case):
6808 : // Glass layers are 1,2 and 3, where 1 is the outside (outside environment facing)
6809 : // layer and 3 is the inside (room-facing) layer;
6810 : // Faces (also called surfaces) are 1,2,3,4,5 and 6, where face 1 is the
6811 : // outside (front) face of glass layer 1, face 2 is the inside (back)
6812 : // face of glass layer 1, face 3 is the outer face of glass layer 2, face 4 is the
6813 : // inner face of glass layer 2, etc.
6814 : // Gap layers are 1 and 2, where gap layer 1 is between glass layers 1 and 2
6815 : // and gap layer 2 is between glass layers 2 and 3.
6816 :
6817 2597 : IGlass = 0;
6818 2597 : IGap = 0;
6819 :
6820 7872 : for (Lay = 1; Lay <= TotLay; ++Lay) {
6821 5275 : LayPtr = state.dataConstruction->Construct(ConstrNum).LayerPoint(Lay);
6822 6903 : if ((state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGlass) ||
6823 1628 : (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowSimpleGlazing)) {
6824 3885 : ++IGlass;
6825 3885 : state.dataWindowManager->thick[IGlass - 1] = state.dataMaterial->Material(LayPtr).Thickness;
6826 3885 : state.dataWindowManager->scon[IGlass - 1] =
6827 3885 : state.dataMaterial->Material(LayPtr).Conductivity / state.dataMaterial->Material(LayPtr).Thickness;
6828 3885 : state.dataWindowManager->emis[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).AbsorpThermalFront;
6829 3885 : state.dataWindowManager->emis[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).AbsorpThermalBack;
6830 3885 : state.dataWindowManager->tir[2 * IGlass - 2] = state.dataMaterial->Material(LayPtr).TransThermal;
6831 3885 : state.dataWindowManager->tir[2 * IGlass - 1] = state.dataMaterial->Material(LayPtr).TransThermal;
6832 3885 : AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(IGlass));
6833 3885 : if (ShadeFlag == WinShadingType::IntBlind) { // Interior blind on
6834 21 : AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).AbsBeamCoef(IGlass));
6835 21 : AGlDiffBack = state.dataConstruction->Construct(ConstrNumBare).AbsDiffBack(IGlass);
6836 21 : AbsBeamNorm(IGlass) += TBmBm * AGlDiffBack * RhoBlFront / (1.0 - RhoBlFront * RGlDiffBack);
6837 3864 : } else if (ShadeFlag == WinShadingType::ExtBlind) { // Exterior blind on
6838 4 : AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).AbsBeamCoef(IGlass));
6839 12 : AbsBeamNorm(IGlass) = TBlBmBm * AbsBeamNorm(IGlass) + (TBlBmBm * RGlFront * RhoBlBack + TBlBmDif) *
6840 8 : state.dataConstruction->Construct(ConstrNumBare).AbsDiff(IGlass) /
6841 4 : (1.0 - RGlDiffFront * RhoBlDiffBack);
6842 3860 : } else if (ShadeFlag == WinShadingType::ExtScreen) { // Exterior screen on
6843 6 : AbsBeamNorm(IGlass) = POLYF(1.0, state.dataConstruction->Construct(ConstrNumBare).AbsBeamCoef(IGlass));
6844 18 : AbsBeamNorm(IGlass) = TScBmBm * AbsBeamNorm(IGlass) + (TScBmBm * RGlFront * RScBack + TScBmDif) *
6845 12 : state.dataConstruction->Construct(ConstrNumBare).AbsDiff(IGlass) /
6846 6 : (1.0 - RGlDiffFront * RScDifBack);
6847 : }
6848 3885 : state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 2] = 0.5 * BeamSolarInc * AbsBeamNorm(IGlass);
6849 3885 : state.dataWindowManager->AbsRadGlassFace[2 * IGlass - 1] = 0.5 * BeamSolarInc * AbsBeamNorm(IGlass);
6850 : }
6851 14588 : if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGas ||
6852 9277 : state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::WindowGasMixture ||
6853 4002 : state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::ComplexWindowGap) { // Gap layer
6854 1302 : ++IGap;
6855 : // Simon: Need to re-reference gas data in casee of complex fenestration gap
6856 1302 : if (state.dataMaterial->Material(LayPtr).Group == DataHeatBalance::MaterialGroup::ComplexWindowGap) {
6857 29 : LayPtr = state.dataMaterial->Material(LayPtr).GasPointer;
6858 : }
6859 1302 : state.dataWindowManager->gap[IGap - 1] = state.dataMaterial->Material(LayPtr).Thickness;
6860 1302 : state.dataWindowManager->gnmix[IGap - 1] = state.dataMaterial->Material(LayPtr).NumberOfGasesInMixture;
6861 2640 : for (IMix = 1; IMix <= state.dataWindowManager->gnmix[IGap - 1]; ++IMix) {
6862 1338 : state.dataWindowManager->gwght[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasWght(IMix);
6863 1338 : state.dataWindowManager->gfract[IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasFract(IMix);
6864 5352 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
6865 4014 : state.dataWindowManager->gcon[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCon(ICoeff, IMix);
6866 4014 : state.dataWindowManager->gvis[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasVis(ICoeff, IMix);
6867 4014 : state.dataWindowManager->gcp[ICoeff - 1][IMix - 1][IGap - 1] = state.dataMaterial->Material(LayPtr).GasCp(ICoeff, IMix);
6868 : }
6869 : }
6870 : }
6871 : }
6872 :
6873 : // Factors used in glass temperature solution
6874 2597 : if (state.dataWindowManager->ngllayer >= 2) {
6875 1132 : state.dataWindowManager->A23P =
6876 1132 : -state.dataWindowManager->emis[2] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
6877 1132 : state.dataWindowManager->A32P =
6878 1132 : state.dataWindowManager->emis[1] / (1.0 - (1.0 - state.dataWindowManager->emis[1]) * (1.0 - state.dataWindowManager->emis[2]));
6879 1132 : state.dataWindowManager->A23 = state.dataWindowManager->emis[1] * state.dataWindowManager->sigma * state.dataWindowManager->A23P;
6880 : }
6881 :
6882 2597 : if (state.dataWindowManager->ngllayer >= 3) {
6883 144 : state.dataWindowManager->A45P =
6884 144 : -state.dataWindowManager->emis[4] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
6885 144 : state.dataWindowManager->A54P =
6886 144 : state.dataWindowManager->emis[3] / (1.0 - (1.0 - state.dataWindowManager->emis[3]) * (1.0 - state.dataWindowManager->emis[4]));
6887 144 : state.dataWindowManager->A45 = state.dataWindowManager->emis[3] * state.dataWindowManager->sigma * state.dataWindowManager->A45P;
6888 : }
6889 :
6890 2597 : if (state.dataWindowManager->ngllayer == 4) {
6891 12 : state.dataWindowManager->A67P =
6892 12 : -state.dataWindowManager->emis[6] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
6893 12 : state.dataWindowManager->A76P =
6894 12 : state.dataWindowManager->emis[5] / (1.0 - (1.0 - state.dataWindowManager->emis[5]) * (1.0 - state.dataWindowManager->emis[6]));
6895 12 : state.dataWindowManager->A67 = state.dataWindowManager->emis[5] * state.dataWindowManager->sigma * state.dataWindowManager->A67P;
6896 : }
6897 :
6898 2597 : state.dataWindowManager->thetas = {0.0};
6899 :
6900 2597 : WindowTempsForNominalCond(state, ConstrNum, hgap, 1.0);
6901 :
6902 2597 : if (!ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) AbsBeamShadeNorm = 0.0;
6903 :
6904 : // Get center-of-glass conductance and solar heat gain coefficient
6905 : // including inside and outside air films
6906 2597 : Real64 inputU = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).SimpleWindowUfactor;
6907 :
6908 : // Calculate the NominalConductance glazing only (before adjusted)
6909 2597 : EvalNominalWindowCond(state, AbsBeamShadeNorm, AbsBeamNorm, hgap, NominalConductance, SHGC, TSolNorm);
6910 :
6911 2597 : if (WinterSummerFlag == 1) {
6912 1308 : state.dataHeatBal->NominalUBeforeAdjusted(ConstrNum) = NominalConductance;
6913 1308 : if (inputU > 0) { // only compute adjustment ratio when there is valid user input U
6914 122 : Real64 wettedAreaAdjRatio = 1; // Adjustment ratio for the wetted area
6915 122 : Real64 hcoutRated = state.dataWindowManager->hcout;
6916 : // Adjustment ratio applies to convective film coefficients when input U value is above the limit of the simple glazing nominal U
6917 : // Representing the nominal highly conductive frame effects. Solved iteratively.
6918 122 : Real64 adjLower = 1.0;
6919 122 : Real64 adjUpper = 2.0;
6920 122 : int MaxIter = 100;
6921 154 : while (std::abs(inputU - NominalConductance) > 0.01 && MaxIter > 0) {
6922 16 : wettedAreaAdjRatio = (adjLower + adjUpper) / 2;
6923 16 : WindowTempsForNominalCond(
6924 : state, ConstrNum, hgap, wettedAreaAdjRatio); // reeval hcout at each iteration, hcin is not linear to wetted area
6925 16 : state.dataWindowManager->hcout = hcoutRated * wettedAreaAdjRatio; // reeval hcout
6926 16 : EvalNominalWindowCond(state, AbsBeamShadeNorm, AbsBeamNorm, hgap, NominalConductance, SHGC, TSolNorm);
6927 16 : if (NominalConductance < inputU) {
6928 5 : adjLower = wettedAreaAdjRatio;
6929 : } else {
6930 11 : adjUpper = wettedAreaAdjRatio;
6931 : }
6932 16 : MaxIter -= 1;
6933 : }
6934 122 : state.dataHeatBal->CoeffAdjRatio(ConstrNum) = wettedAreaAdjRatio;
6935 : }
6936 : }
6937 :
6938 : // EPTeam - again -- believe that is enforced in input //Autodesk But this routine is not self-protecting: Add as an assert
6939 :
6940 : // init the surface convective and radiative adjustment ratio
6941 33215 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6942 61252 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6943 30634 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
6944 30634 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
6945 30634 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
6946 99303 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
6947 68669 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) {
6948 68637 : int ConstrNum2 = state.dataSurface->Surface(SurfNum).Construction;
6949 68637 : state.dataHeatBalSurf->SurfWinCoeffAdjRatio(SurfNum) = state.dataHeatBal->CoeffAdjRatio(ConstrNum2);
6950 : }
6951 : }
6952 : }
6953 : }
6954 :
6955 : // Need to add variables writing here since this routine will override previously calcualted values from WinCalc-Engine
6956 2597 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
6957 3 : TSolNorm = GetSolarTransDirectHemispherical(state, ConstrNum);
6958 3 : TVisNorm = GetVisibleTransDirectHemispherical(state, ConstrNum);
6959 : }
6960 : }
6961 :
6962 2613 : void EvalNominalWindowCond(EnergyPlusData &state,
6963 : Real64 const AbsBeamShadeNorm, // Shade solar absorptance at normal incidence
6964 : Array1D<Real64> const AbsBeamNorm, // Beam absorptance at normal incidence for each glass layer
6965 : Array1D<Real64> const hgap, // Conductive gap conductance [W/m2-K]
6966 : Real64 &NominalConductance, // Nominal center-of-glass conductance, including air films
6967 : Real64 &SHGC, // Nominal center-of-glass solar heat gain coefficient for
6968 : Real64 &TSolNorm // Overall beam solar transmittance at normal incidence
6969 : )
6970 : {
6971 5226 : Array1D<Real64> hGapTot(5); // Combined radiative and conductive gap conductance [W/m2-K]
6972 :
6973 2613 : Real64 hOutRad = state.dataWindowManager->emis[0] * state.dataWindowManager->sigma * 0.5 *
6974 2613 : pow_3(state.dataWindowManager->tout + state.dataWindowManager->thetas[0]);
6975 2613 : Real64 rOut = 1.0 / (hOutRad + state.dataWindowManager->hcout);
6976 2613 : Real64 hInRad = state.dataWindowManager->emis[state.dataWindowManager->nglface - 1] * state.dataWindowManager->sigma * 0.5 *
6977 2613 : pow_3(state.dataWindowManager->tin + state.dataWindowManager->thetas[state.dataWindowManager->nglface - 1]);
6978 2613 : Real64 rIn = 1.0 / (hInRad + state.dataWindowManager->hcin);
6979 2613 : Real64 Rbare = 0;
6980 :
6981 2613 : switch (state.dataWindowManager->ngllayer) {
6982 : // the switch cases here are just the integer number of layers, not exactly "magic" numbers 1, 2, 3. and 4.
6983 1481 : case 1:
6984 1481 : Rbare = 1.0 / state.dataWindowManager->scon[0];
6985 1481 : state.dataWindowManager->Rtot = rOut + Rbare + rIn;
6986 2962 : SHGC = AbsBeamNorm(1) * (rOut + (0.5 / state.dataWindowManager->scon[0])) /
6987 1481 : state.dataWindowManager->Rtot; // BG changed for CR7682 (solar absorbed in middle of layer)
6988 1481 : SHGC += AbsBeamShadeNorm;
6989 1481 : SHGC += TSolNorm;
6990 1481 : break;
6991 :
6992 988 : case 2:
6993 1976 : hGapTot(1) = hgap(1) + std::abs(state.dataWindowManager->A23) * 0.5 *
6994 988 : pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
6995 988 : Rbare = 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1];
6996 988 : state.dataWindowManager->Rtot = rOut + Rbare + rIn;
6997 1976 : SHGC = AbsBeamNorm(1) * (rOut + 0.5 / state.dataWindowManager->scon[0]) / state.dataWindowManager->Rtot +
6998 1976 : AbsBeamNorm(2) * (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 0.5 / state.dataWindowManager->scon[1]) /
6999 988 : state.dataWindowManager->Rtot; // CR7682
7000 988 : SHGC += AbsBeamShadeNorm;
7001 988 : SHGC += TSolNorm;
7002 988 : break;
7003 :
7004 132 : case 3:
7005 264 : hGapTot(1) = hgap(1) + std::abs(state.dataWindowManager->A23) * 0.5 *
7006 132 : pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
7007 264 : hGapTot(2) = hgap(2) + std::abs(state.dataWindowManager->A45) * 0.5 *
7008 132 : pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
7009 264 : Rbare = 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
7010 132 : 1.0 / state.dataWindowManager->scon[2];
7011 132 : state.dataWindowManager->Rtot = rOut + Rbare + rIn;
7012 396 : SHGC = AbsBeamNorm(1) * (rOut + 0.5 / state.dataWindowManager->scon[0]) / state.dataWindowManager->Rtot +
7013 264 : AbsBeamNorm(2) * (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 0.5 / state.dataWindowManager->scon[1]) /
7014 264 : state.dataWindowManager->Rtot +
7015 264 : AbsBeamNorm(3) *
7016 264 : (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
7017 264 : 0.5 / state.dataWindowManager->scon[2]) /
7018 132 : state.dataWindowManager->Rtot;
7019 132 : SHGC += AbsBeamShadeNorm;
7020 132 : SHGC += TSolNorm;
7021 132 : break;
7022 :
7023 12 : case 4:
7024 24 : hGapTot(1) = hgap(1) + std::abs(state.dataWindowManager->A23) * 0.5 *
7025 12 : pow_3(state.dataWindowManager->thetas[1] + state.dataWindowManager->thetas[2]);
7026 24 : hGapTot(2) = hgap(2) + std::abs(state.dataWindowManager->A45) * 0.5 *
7027 12 : pow_3(state.dataWindowManager->thetas[3] + state.dataWindowManager->thetas[4]);
7028 24 : hGapTot(3) = hgap(3) + std::abs(state.dataWindowManager->A67) * 0.5 *
7029 12 : pow_3(state.dataWindowManager->thetas[5] + state.dataWindowManager->thetas[6]);
7030 36 : Rbare = 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
7031 24 : 1.0 / state.dataWindowManager->scon[2] + 1.0 / hGapTot(3) + 1.0 / state.dataWindowManager->scon[3];
7032 12 : state.dataWindowManager->Rtot = rOut + Rbare + rIn;
7033 36 : SHGC = AbsBeamNorm(1) * (rOut + 0.5 / state.dataWindowManager->scon[0]) / state.dataWindowManager->Rtot +
7034 24 : AbsBeamNorm(2) * (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 0.5 / state.dataWindowManager->scon[1]) /
7035 24 : state.dataWindowManager->Rtot +
7036 24 : AbsBeamNorm(3) *
7037 24 : (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
7038 24 : 0.5 / state.dataWindowManager->scon[2]) /
7039 24 : state.dataWindowManager->Rtot +
7040 24 : AbsBeamNorm(4) *
7041 24 : (rOut + 1.0 / state.dataWindowManager->scon[0] + 1.0 / hGapTot(1) + 1.0 / state.dataWindowManager->scon[1] + 1.0 / hGapTot(2) +
7042 36 : 1.0 / state.dataWindowManager->scon[2] + 1.0 / hGapTot(3) + 0.5 / state.dataWindowManager->scon[3]) /
7043 12 : state.dataWindowManager->Rtot; // CR7682
7044 12 : SHGC += AbsBeamShadeNorm;
7045 12 : SHGC += TSolNorm;
7046 12 : break;
7047 0 : default:
7048 0 : break;
7049 : }
7050 2613 : NominalConductance = 1.0 / (rOut + Rbare + rIn);
7051 2613 : }
7052 : //****************************************************************************
7053 :
7054 2613 : void WindowTempsForNominalCond(EnergyPlusData &state,
7055 : int const ConstrNum, // Construction number
7056 : Array1A<Real64> hgap, // Gap gas conductive conductance (W/m2-K)
7057 : Real64 const adjRatio // adjusment Ratio to hcin
7058 : )
7059 : {
7060 :
7061 : // SUBROUTINE INFORMATION:
7062 : // AUTHOR F. Winkelmann
7063 : // DATE WRITTEN September 2000
7064 : // MODIFIED Nov 2002, FW: increase MaxIterations from 15 to 100, add face
7065 : // temperature relaxation, and increase convergence tolerance by
7066 : // a factor of 10 if no convergence after MaxIterations,
7067 : // all for consistency with SolveForWindowTemperatures.
7068 : // Mar 2003, FW: increase convergence tolerance from 0.01 to 0.02;
7069 : // remove redundant relaxation on radiative conductances (both of
7070 : // these were also done in SolveForWindowTemperatures).
7071 : // Jan 2009, BG: changed interior convection coefficient correlation to match
7072 : // ISO 15099.
7073 : // Feb 2009, BG: extended coefficient to include absorbed radiation
7074 : // to cover summer conditions for SHGC determination.
7075 : // RE-ENGINEERED na
7076 :
7077 : // PURPOSE OF THIS SUBROUTINE:
7078 : // This is a shortened form of SolveForWindowTemperatures tailored
7079 : // for calculation of the nominal center-of-glass U-value for a window
7080 : // construction at ASHRAE winter conditions and for determining conditions at
7081 : // summer conditions for calculationg SHGC.
7082 : // Evaluates the coefficients Aface and Bface in the system of linear
7083 : // algebraic equations
7084 : // Sum [Aface(i,j)*thetas(j)] = Bface(i), i = 1,nglface
7085 : // j=1,nglface
7086 : // where
7087 : // nglface = number of glass faces (= 2 * number of layers) and
7088 : // thetas(j) = temperature of face j
7089 :
7090 : // METHODOLOGY EMPLOYED:
7091 : // The Aface and Bface coefficients are determined by the equations for
7092 : // heat balance at the glass faces. The system of linear equations is solved
7093 : // by LU decomposition.
7094 :
7095 : using Psychrometrics::PsyRhoAirFnPbTdbW;
7096 :
7097 : // Argument array dimensioning
7098 2613 : hgap.dim(5);
7099 :
7100 2613 : int constexpr MaxIterations(100); // Maximum allowed number of iterations
7101 2613 : Real64 constexpr errtemptol(0.02); // Tolerance on errtemp for convergence
7102 : static constexpr std::string_view RoutineName("WindowTempsForNominalCond");
7103 :
7104 : int i; // Counter
7105 5226 : Array1D<Real64> hr(10); // Radiative conductance (W/m2-K)
7106 : Real64 hcinprev; // Value of hcin from previous iteration
7107 : Real64 d; // +1 if number of row interchanges is even,
7108 : // -1 if odd (in LU decomposition)
7109 5226 : Array1D_int indx(10); // Vector of row permutations in LU decomposition
7110 5226 : Array2D<Real64> Aface(10, 10); // Coefficient in equation Aface*thetas = Bface
7111 5226 : Array1D<Real64> Bface(10); // Coefficient in equation Aface*thetas = Bface
7112 : int iter; // Iteration number
7113 : Real64 errtemp; // Absolute value of sum of face temperature differences
7114 : // between iterations, divided by number of faces
7115 : Real64 TmeanFilm; // mean film temperature
7116 : Real64 TmeanFilmKelvin; // mean film temperature for property evaluation
7117 : Real64 rho; // density of (apparently dry) air [kg/m3]
7118 : Real64 g; // acceleration due to gravity [m/s2]
7119 : Real64 Height; // window cavity height [m]
7120 : Real64 Cp; // specific heat of air [J/kg-K]
7121 : Real64 lambda; // thermal conductivity of air [W/m-K]
7122 : Real64 mu; // dynamic viscosity of air [kg/m-s]
7123 : Real64 RaH; // Rayleigh number for cavity height [ Non dim]
7124 : Real64 TiltDeg; // glazing tilt in degrees
7125 : Real64 sineTilt; // sine of glazing tilt
7126 : Real64 Nuint; // Nusselt number for interior surface convection
7127 :
7128 2613 : iter = 0;
7129 :
7130 : // Initialize face temperatures
7131 2613 : StartingWinTempsForNominalCond(state);
7132 :
7133 : // Calculate radiative conductance
7134 2613 : errtemp = errtemptol * 2.0;
7135 :
7136 2613 : TiltDeg = 90.0;
7137 :
7138 2613 : sineTilt = std::sin(TiltDeg * DataGlobalConstants::DegToRadians); // degrees as arg
7139 :
7140 32517 : while (iter < MaxIterations && errtemp > errtemptol) {
7141 61304 : for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
7142 46352 : hr(i) = state.dataWindowManager->emis[i - 1] * state.dataWindowManager->sigma * pow_3(state.dataWindowManager->thetas[i - 1]);
7143 : //! fw 3/4/03 if ( iter >= 1 ) hr(i) = 0.5*(hrprev(i)+hr(i))
7144 : }
7145 :
7146 14952 : Aface = 0.0;
7147 14952 : Bface = 0.0;
7148 :
7149 : // Inside convective film conductance for vertical window
7150 14952 : if (iter >= 1) {
7151 12339 : hcinprev = state.dataWindowManager->hcin;
7152 : }
7153 : // CR7670 BG this next correlation was used for hcin but is not "standard" for windows
7154 : // hcin = 1.31d0*((ABS(thetas(nglface)-tin))**0.3333d0)
7155 : // Begin calculating for ISO 15099 method.
7156 : // mean film temperature
7157 29904 : TmeanFilmKelvin = state.dataWindowManager->tin + 0.25 * (state.dataWindowManager->thetas[state.dataWindowManager->nglface - 1] -
7158 14952 : state.dataWindowManager->tin); // eq. 133 in ISO 15099
7159 14952 : TmeanFilm = TmeanFilmKelvin - 273.15;
7160 : // the following properties are constants or linear relations for "standard" type reporting
7161 14952 : rho = PsyRhoAirFnPbTdbW(state, 101325.0, TmeanFilm, 0.0, RoutineName); // dry air assumption
7162 14952 : g = 9.81;
7163 14952 : Height = 1.0; // standard window rating practice is to use 1 meter (rather than actual)
7164 :
7165 14952 : lambda = 2.873E-3 + 7.76E-5 * TmeanFilmKelvin; // Table B.1 in ISO 15099
7166 14952 : mu = 3.723E-6 + 4.94E-8 * TmeanFilmKelvin; // Table B.2 in ISO 15099
7167 14952 : Cp = 1002.737 + 1.2324E-2 * TmeanFilmKelvin; // Table B.3 in ISO 15099
7168 :
7169 44856 : RaH = (pow_2(rho) * pow_3(Height) * g * Cp *
7170 14952 : (std::abs(state.dataWindowManager->thetas[state.dataWindowManager->nglface - 1] - state.dataWindowManager->tin))) /
7171 14952 : (TmeanFilmKelvin * mu * lambda); // eq 132 in ISO 15099
7172 :
7173 14952 : Nuint = 0.56 * root_4(RaH * sineTilt); // eq. 135 in ISO 15099 (only need this one because tilt is 90 deg
7174 :
7175 14952 : state.dataWindowManager->hcin = Nuint * lambda / Height;
7176 :
7177 : // End calculations for ISO 15099 method.
7178 :
7179 14952 : if (iter >= 1) state.dataWindowManager->hcin = 0.5 * (hcinprev + state.dataWindowManager->hcin);
7180 :
7181 14952 : state.dataWindowManager->hcin *= adjRatio;
7182 :
7183 14952 : ++iter;
7184 :
7185 14952 : GetHeatBalanceEqCoefMatrixSimple(state, state.dataWindowManager->ngllayer, hr, hgap, Aface, Bface);
7186 :
7187 14952 : LUdecomposition(state, Aface, state.dataWindowManager->nglface, indx,
7188 : d); // Note that these routines change Aface;
7189 14952 : LUsolution(Aface, state.dataWindowManager->nglface, indx,
7190 : Bface); // face temperatures are returned in Bface
7191 :
7192 14952 : errtemp = 0.0;
7193 61304 : for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
7194 46352 : errtemp += std::abs(state.dataWindowManager->thetas[i - 1] - Bface(i)) / state.dataWindowManager->nglface;
7195 : }
7196 :
7197 61304 : for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
7198 46352 : state.dataWindowManager->thetas[i - 1] = 0.5 * (state.dataWindowManager->thetas[i - 1] + Bface(i));
7199 : }
7200 : }
7201 :
7202 : // No convergence after MaxIterations; and/or error tolerance
7203 2613 : if (errtemp >= 10 * errtemptol) {
7204 : // Fatal error: didn't converge
7205 0 : ShowFatalError(state,
7206 0 : "Convergence error in WindowTempsForNominalCond for construction " + state.dataConstruction->Construct(ConstrNum).Name);
7207 : }
7208 2613 : }
7209 :
7210 : //****************************************************************************
7211 :
7212 2613 : void StartingWinTempsForNominalCond(EnergyPlusData &state)
7213 : {
7214 :
7215 : // SUBROUTINE INFORMATION:
7216 : // AUTHOR F. Winkelmann
7217 : // DATE WRITTEN September 2000
7218 : // MODIFIED na
7219 : // RE-ENGINEERED na
7220 :
7221 : // PURPOSE OF THIS SUBROUTINE:
7222 : // Initializes face temperature distribution prior to iteration.
7223 : // This is a shortened form of StartingWindowTemps for use in calculating
7224 : // the nominal center-of-glass U-value.
7225 :
7226 2613 : Real64 constexpr hrad(5.3); // Typical radiative conductance (W/m2-K)
7227 2613 : Real64 constexpr hcinStartValue(3.2); // Starting value for inside air film convective
7228 : // conductance (estimated for typical double glazing
7229 : // using 1.31(dT**0.333), where dT =
7230 : // room air temp - inside surface temp = 14.2K)
7231 2613 : Real64 constexpr resgap(0.21); // Typical gap resistance (m2-K/W)
7232 :
7233 : int i; // Face counter
7234 5226 : Array1D<Real64> rguess(11); // Combined radiative/convective resistance (m2-K/W) of
7235 : // inside or outside air film, or gap
7236 : Real64 restot; // Total window resistance including outside
7237 : // and inside air films (m2-K/W)
7238 : Real64 temdiff; // Inside/outside air temperature difference (K)
7239 : Real64 ressum; // Resistance sum (m2-K/W)
7240 :
7241 2613 : rguess(1) = 1.0 / (state.dataWindowManager->hcout + hrad);
7242 2613 : rguess(state.dataWindowManager->nglface + 1) = 1.0 / (hcinStartValue + hrad);
7243 :
7244 6514 : for (i = 2; i <= state.dataWindowManager->nglface; i += 2) {
7245 3901 : rguess(i) = 1.0 / state.dataWindowManager->scon[i / 2 - 1];
7246 3901 : if (i < state.dataWindowManager->nglface) rguess(i + 1) = resgap;
7247 : }
7248 2613 : restot = 0.0;
7249 :
7250 13028 : for (i = 1; i <= state.dataWindowManager->nglface + 1; ++i) {
7251 10415 : restot += rguess(i);
7252 : }
7253 :
7254 2613 : temdiff = state.dataWindowManager->tin - state.dataWindowManager->tout;
7255 2613 : if (std::abs(temdiff) < 0.5) temdiff = 2.0;
7256 2613 : ressum = 0.0;
7257 :
7258 10415 : for (i = 1; i <= state.dataWindowManager->nglface; ++i) {
7259 7802 : ressum += rguess(i);
7260 7802 : state.dataWindowManager->thetas[i - 1] = (ressum / restot) * temdiff + state.dataWindowManager->tout;
7261 : }
7262 2613 : }
7263 :
7264 : //****************************************************************************
7265 :
7266 768 : void ReportGlass(EnergyPlusData &state)
7267 : {
7268 :
7269 : // SUBROUTINE INFORMATION:
7270 : // AUTHOR Linda K. Lawrie
7271 : // DATE WRITTEN March 2000
7272 : // MODIFIED na
7273 : // RE-ENGINEERED na
7274 :
7275 : // PURPOSE OF THIS SUBROUTINE:
7276 : // This routine gives a detailed report to the user about
7277 : // the calculation parameters for windows and their associated
7278 : // materials.
7279 :
7280 : using General::POLYF;
7281 :
7282 : using General::ScanForReports;
7283 : using WindowComplexManager::CalcComplexWindowThermal;
7284 : using WindowComplexManager::UpdateComplexWindows;
7285 :
7286 768 : static Array1D_string const Roughness({0, 5}, {"VeryRough", "Rough", "MediumRough", "MediumSmooth", "Smooth", "VerySmooth"});
7287 768 : static Array1D_string const GasTypeName({0, 4}, {"Custom", "Air", "Argon", "Krypton", "Xenon"});
7288 :
7289 768 : Real64 TempVar(0.0); // just temporary usage for complex fenestration
7290 :
7291 : int ThisNum;
7292 : int Layer;
7293 : int BlNum; // Blind number
7294 : int i;
7295 : Real64 NominalConductanceWinter; // Nominal center-of-glass conductance of a window construction
7296 : // for ASHRAE winter conditions (W/m2-K):
7297 : // Inside air temperature = 21.1C (70F)
7298 : // Outside air temperature = -17.8C (0F)
7299 : // Windspeed = 6.71 m/s (15 mph)
7300 : // No solar radiation
7301 : Real64 NominalConductanceSummer; // Nominal center-of-glass conductance of a window construction
7302 : // for ASHRAE summer conditions (W/m2-K):
7303 : // Inside air temperature = 23.9C (75F)
7304 : // Outside air temperature = 35.0C (95F)
7305 : // Windspeed = 3.35 m/s (7.5 mph)
7306 : // 783 W/m2 (248 Btu/h-ft2) incident beam solar radiation normal to glazing
7307 768 : Real64 SHGCWinter(0.0); // Center-of-glass solar heat gain coefficient for ASHRAE
7308 768 : Real64 SHGCSummer(0.0);
7309 : // winter and summer conditions
7310 : Real64 TransSolNorm; // Window construction solar transmittance at normal incidence
7311 : Real64 TransVisNorm; // Window construction visible transmittance at normal incidence
7312 : int errFlag; // Error flag
7313 1536 : std::string SolarDiffusing; // 'Yes' if glass is solar diffusing; otherwise 'No' (clear glass)
7314 1536 : std::string SpectralDataName;
7315 1536 : std::string OpticalDataType;
7316 1536 : std::string SlateOrientation;
7317 1536 : std::string GapVentType;
7318 :
7319 768 : ScanForReports(state, "Constructions", state.dataWindowManager->DoReport, "Constructions");
7320 :
7321 768 : if (std::any_of(state.dataConstruction->Construct.begin(),
7322 768 : state.dataConstruction->Construct.end(),
7323 4383 : [](Construction::ConstructionProps const &e) { return e.TypeIsWindow; }))
7324 675 : state.dataWindowManager->HasWindows = true;
7325 768 : if (std::any_of(state.dataConstruction->Construct.begin(),
7326 768 : state.dataConstruction->Construct.end(),
7327 5844 : [](Construction::ConstructionProps const &e) { return e.WindowTypeBSDF; }))
7328 9 : state.dataWindowManager->HasComplexWindows = true; // Yes, this is a bit different than actually using them.
7329 768 : if (std::any_of(state.dataConstruction->Construct.begin(),
7330 768 : state.dataConstruction->Construct.end(),
7331 5846 : [](Construction::ConstructionProps const &e) { return e.WindowTypeEQL; }))
7332 1 : state.dataWindowManager->HasEQLWindows = true; // for reporting purpose only
7333 1327 : if (state.dataWindowManager->DoReport &&
7334 335 : (state.dataWindowManager->HasWindows || state.dataWindowManager->HasComplexWindows || state.dataWindowManager->HasEQLWindows)) {
7335 : // Write Descriptions
7336 261 : print(state.files.eio,
7337 : "{}\n",
7338 : "! <WindowConstruction>,Construction Name,Index,#Layers,Roughness,Conductance {W/m2-K},Conductance (Before Adjusted) {W/m2-K},"
7339 : "Convection Coefficient Adjustment Ratio,SHGC,"
7340 261 : "Solar Transmittance at Normal Incidence,Visible Transmittance at Normal Incidence");
7341 261 : if ((state.dataHeatBal->TotSimpleWindow > 0) || (state.dataHeatBal->W5GlsMat > 0) || (state.dataHeatBal->W5GlsMatAlt > 0))
7342 255 : print(state.files.eio,
7343 : "{}\n",
7344 : "! <WindowMaterial:Glazing>, Material Name, Optical Data Type, Spectral Data Set Name, "
7345 : "Thickness {m}, Solar Transmittance,Front Solar Reflectance, Back Solar Reflectance, Visible "
7346 : "Transmittance, Front Visible Reflectance,Back Visible Reflectance,Infrared Transmittance, "
7347 : "Front Thermal Emissivity, Back Thermal Emissivity,Conductivity {W/m-K},Dirt Factor,Solar "
7348 255 : "Diffusing");
7349 261 : if ((state.dataHeatBal->W5GasMat > 0) || (state.dataHeatBal->W5GasMatMixture > 0))
7350 87 : print(state.files.eio, "{}\n", "! <WindowMaterial:Gas>,Material Name,GasType,Thickness {m}");
7351 261 : if (state.dataHeatBal->TotShades > 0)
7352 7 : print(state.files.eio,
7353 : "{}\n",
7354 : "! <WindowMaterial:Shade>,Material Name,Thickness {m},Conductivity {W/m-K},Thermal "
7355 7 : "Absorptance,Transmittance,Visible Transmittance,Shade Reflectance");
7356 261 : if (state.dataHeatBal->TotScreens > 0)
7357 2 : print(state.files.eio,
7358 : "{}\n",
7359 : "! <WindowMaterial:Screen>,Material Name,Thickness {m},Conductivity {W/m-K},Thermal "
7360 : "Absorptance,Transmittance,Reflectance,Visible Reflectance,Diffuse Reflectance,Diffuse Visible "
7361 2 : "Reflectance,Screen Material Diameter To Spacing Ratio,Screen To GlassDistance {m}");
7362 261 : if (state.dataHeatBal->TotBlinds > 0)
7363 15 : print(state.files.eio,
7364 : "{}\n",
7365 : "! <WindowMaterial:Blind>,Material Name,Slat Width {m},Slat Separation {m},Slat Thickness "
7366 : "{m},Slat Angle {deg},Slat Beam Solar Transmittance,Slat Beam Solar Front Reflectance,Blind To "
7367 15 : "Glass Distance {m}");
7368 :
7369 261 : if (state.dataWindowManager->HasComplexWindows)
7370 8 : print(state.files.eio,
7371 : "{}\n",
7372 : "! <WindowConstruction:Complex>,Construction Name,Index,#Layers,U-factor {W/m2-K},SHGC"
7373 8 : "NFRC Product Type,Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
7374 :
7375 261 : if (state.dataWindowManager->HasEQLWindows)
7376 1 : print(state.files.eio,
7377 : "{}\n",
7378 : "! <Construction:WindowEquivalentLayer>,Construction Name,Index,#Layers,U-factor {W/m2-K},SHGC, "
7379 1 : "Solar Transmittance at Normal Incidence");
7380 261 : if (state.dataHeatBal->W5GlsMatEQL > 0)
7381 1 : print(state.files.eio,
7382 : "{}\n",
7383 : "! <WindowMaterial:Glazing:EquivalentLayer>, Material Name, Optical Data Type, Spectral Data "
7384 : "Set Name, Front Side Beam-Beam Solar Transmittance, Back Side Beam-Beam Solar Transmittance, "
7385 : "Front Side Beam-Beam Solar Reflectance, Back Side Beam-Beam Solar Reflectance, Front Side "
7386 : "Beam-Diffuse Solar Transmittance, Back Side Beam-Diffuse Solar Transmittance, , Front Side "
7387 : "Beam-Diffuse Solar Reflectance, Back Side Beam-Diffuse Solar Reflectance, Diffuse-Diffuse "
7388 : "Solar Transmittance, Front Side Diffuse-Diffuse Solar Reflectance, Back Side Diffuse-Diffuse "
7389 : "Solar Reflectance, Infrared Transmittance, Front Side Infrared Emissivity, Back Side Infrared "
7390 1 : "Emissivity");
7391 261 : if (state.dataHeatBal->TotShadesEQL > 0)
7392 1 : print(state.files.eio,
7393 : "{}\n",
7394 : "! <WindowMaterial:Shade:EquivalentLayer>, Material Name, Front Side Beam-Beam Solar "
7395 : "Transmittance, Back Side Beam-Beam Solar Transmittance, Front Side Beam-Diffuse Solar "
7396 : "Transmittance, Back Side Beam-Diffuse Solar Transmittance, , Front Side Beam-Diffuse Solar "
7397 : "Reflectance, Back Side Beam-Diffuse Solar Reflectance, Infrared Transmittance, Front Side "
7398 1 : "Infrared Emissivity, Back Side Infrared Emissivity");
7399 :
7400 261 : if (state.dataHeatBal->TotDrapesEQL > 0)
7401 0 : print(state.files.eio,
7402 : "{}\n",
7403 : "! <WindowMaterial:Drape:EquivalentLayer>, Material Name, Front Side Beam-Beam Solar "
7404 : "Transmittance, Back Side Beam-Beam Solar Transmittance, Front Side Beam-Diffuse Solar "
7405 : "Transmittance, Back Side Beam-Diffuse Solar Transmittance, , Front Side Beam-Diffuse Solar "
7406 : "Reflectance, Back Side Beam-Diffuse Solar Reflectance, Infrared Transmittance, Front Side "
7407 : "Infrared Emissivity, Back Side Infrared Emissivity, Width of Pleated Fabric, Length of Pleated "
7408 0 : "Fabric");
7409 :
7410 261 : if (state.dataHeatBal->TotBlindsEQL > 0)
7411 0 : print(state.files.eio,
7412 : "{}\n",
7413 : "! <WindowMaterial:Blind:EquivalentLayer>, Material Name, Slat Orientation, Slat Width, Slat "
7414 : "Separation, Slat Crown, Slat Angle, Front Side Slate Beam-Diffuse Solar Transmittance, Back "
7415 : "Side Slate Beam-Diffuse Solar Transmittance, Front Side Slate Beam-Diffuse Solar Reflectance, "
7416 : "Back Side Slate Beam-Diffuse Solar Reflectance, Slat Diffuse-Diffuse Solar Transmittance, "
7417 : "Front Side Slat Diffuse-Diffuse Solar Reflectance, Back Side Slat Diffuse-Diffuse Solar "
7418 : "Reflectance, Infrared Transmittance, Front Side Infrared Emissivity, Back Side Infrared "
7419 0 : "Emissivity, Slat Angle Control");
7420 261 : if (state.dataHeatBal->TotScreensEQL > 0)
7421 1 : print(state.files.eio,
7422 : "{}\n",
7423 : "! <WindowMaterial:Screen:EquivalentLayer>, Material Name, Screen Beam-Beam Solar "
7424 : "Transmittance, Screen Beam-Diffuse Solar Transmittance, Screen Beam-Diffuse Solar Reflectance, "
7425 : "Screen Infrared Transmittance, Screen Infrared Emissivity, Screen Wire Spacing, Screen Wire "
7426 1 : "Diameter");
7427 261 : if (state.dataHeatBal->W5GapMatEQL > 0)
7428 1 : print(state.files.eio, "{}\n", "! <WindowMaterial:Gap:EquivalentLayer>, Material Name, GasType, Gap Thickness {m}, Gap Vent Type");
7429 :
7430 3017 : for (ThisNum = 1; ThisNum <= state.dataHeatBal->TotConstructs; ++ThisNum) {
7431 :
7432 2756 : if (state.dataConstruction->Construct(ThisNum).WindowTypeBSDF) {
7433 :
7434 11 : i = ThisNum;
7435 11 : CalcComplexWindowThermal(state, 0, i, TempVar, TempVar, TempVar, TempVar, DataBSDFWindow::Condition::Winter);
7436 11 : CalcComplexWindowThermal(state, 0, i, TempVar, TempVar, TempVar, TempVar, DataBSDFWindow::Condition::Summer);
7437 :
7438 : static constexpr std::string_view Format_800(" WindowConstruction:Complex,{},{},{},{:.3R},{:.3R}\n");
7439 44 : print(state.files.eio,
7440 : Format_800,
7441 11 : state.dataConstruction->Construct(ThisNum).Name,
7442 : ThisNum,
7443 11 : state.dataConstruction->Construct(ThisNum).TotSolidLayers,
7444 11 : state.dataHeatBal->NominalU(ThisNum),
7445 11 : state.dataConstruction->Construct(ThisNum).SummerSHGC);
7446 :
7447 2745 : } else if (state.dataConstruction->Construct(ThisNum).TypeIsWindow) {
7448 : // Calculate for ASHRAE winter and summer conditions:
7449 : // (1) nominal center-of-glass conductance, including inside and outside air films,
7450 : // (2) solar heat gain coefficient (SHGC),
7451 : // (3) solar transmittance at normal incidence, and (4) visible transmittance at normal incidence.
7452 :
7453 663 : if (state.dataConstruction->Construct(ThisNum).WindowTypeEQL) {
7454 : // for equivalent layer Window already calculated
7455 : // NominalU(ThisNum)=NominalConductanceWinter
7456 : // Save the SHGC for later use in tabular report IVRS
7457 : // Construct(ThisNum)%SummerSHGC = SHGCSummer
7458 3 : state.dataConstruction->Construct(ThisNum).VisTransNorm = 0.0; // TODO list
7459 :
7460 : static constexpr std::string_view Format_799(" Construction:WindowEquivalentLayer,{},{},{},{:.3R},{:.3R},{:.3R}\n");
7461 15 : print(state.files.eio,
7462 : Format_799,
7463 3 : state.dataConstruction->Construct(ThisNum).Name,
7464 : ThisNum,
7465 3 : state.dataConstruction->Construct(ThisNum).TotSolidLayers,
7466 3 : state.dataHeatBal->NominalU(ThisNum),
7467 3 : state.dataConstruction->Construct(ThisNum).SummerSHGC,
7468 3 : state.dataConstruction->Construct(ThisNum).SolTransNorm);
7469 :
7470 : } else {
7471 :
7472 660 : CalcNominalWindowCond(state, ThisNum, 1, NominalConductanceWinter, SHGCWinter, TransSolNorm, TransVisNorm, errFlag);
7473 :
7474 660 : if (errFlag == 1) {
7475 0 : ShowWarningError(state,
7476 0 : "Window construction " + state.dataConstruction->Construct(ThisNum).Name +
7477 : " has an interior or exterior blind");
7478 0 : ShowContinueError(state, "but the corresponding construction without the blind cannot be found.");
7479 0 : ShowContinueError(state, "The ReportGlass entry for this construction will not be printed in eplusout.eio.");
7480 0 : continue;
7481 : }
7482 :
7483 : // Skip constructions with between-glass shade/blind until method is worked out to determine
7484 : // nominal conductance and SHGC.
7485 :
7486 665 : if (errFlag == 2) {
7487 15 : ShowWarningError(state,
7488 10 : "Window construction " + state.dataConstruction->Construct(ThisNum).Name +
7489 : " has a between-glass shade or blind");
7490 5 : ShowContinueError(state, "The ReportGlass entry for this construction will not be printed in eplusout.eio.");
7491 5 : continue;
7492 : }
7493 :
7494 655 : state.dataHeatBal->NominalU(ThisNum) = NominalConductanceWinter;
7495 655 : if (!state.dataConstruction->Construct(ThisNum).WindowTypeEQL) {
7496 655 : CalcNominalWindowCond(state, ThisNum, 2, NominalConductanceSummer, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
7497 : }
7498 : // Save the SHGC for later use in tabular report IVRS
7499 655 : state.dataConstruction->Construct(ThisNum).SummerSHGC = SHGCSummer;
7500 655 : state.dataConstruction->Construct(ThisNum).VisTransNorm = TransVisNorm;
7501 655 : state.dataConstruction->Construct(ThisNum).SolTransNorm = TransSolNorm;
7502 :
7503 : static constexpr std::string_view Format_700(" WindowConstruction,{},{},{},{},{:.3R},{:.3R},{:.3R},{:.3R}\n");
7504 3275 : print(state.files.eio,
7505 : Format_700,
7506 655 : state.dataConstruction->Construct(ThisNum).Name,
7507 : ThisNum,
7508 655 : state.dataConstruction->Construct(ThisNum).TotLayers,
7509 655 : Roughness(static_cast<int>(state.dataConstruction->Construct(ThisNum).OutsideRoughness)),
7510 : NominalConductanceWinter,
7511 655 : state.dataHeatBal->NominalUBeforeAdjusted(ThisNum),
7512 655 : state.dataHeatBal->CoeffAdjRatio(ThisNum),
7513 : SHGCSummer,
7514 : TransSolNorm,
7515 : TransVisNorm);
7516 : }
7517 : // Write(OutputFileConstrainParams, 705) TRIM(Construct(ThisNum)%Name), SHGCSummer ,TransVisNorm
7518 :
7519 2074 : for (i = 1; i <= state.dataConstruction->Construct(ThisNum).TotLayers; ++i) {
7520 1416 : Layer = state.dataConstruction->Construct(ThisNum).LayerPoint(i);
7521 1416 : switch (state.dataMaterial->Material(Layer).Group) {
7522 347 : case DataHeatBalance::MaterialGroup::WindowGas: {
7523 : static constexpr std::string_view Format_702(" WindowMaterial:Gas,{},{},{:.3R}\n");
7524 1041 : print(state.files.eio,
7525 : Format_702,
7526 347 : state.dataMaterial->Material(Layer).Name,
7527 347 : GasTypeName(state.dataMaterial->Material(Layer).GasType(1)),
7528 347 : state.dataMaterial->Material(Layer).Thickness);
7529 : //! fw CASE(WindowGasMixture)
7530 347 : } break;
7531 18 : case DataHeatBalance::MaterialGroup::Shade: {
7532 : static constexpr std::string_view Format_703(" WindowMaterial:Shade,,{},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
7533 126 : print(state.files.eio,
7534 : Format_703,
7535 18 : state.dataMaterial->Material(Layer).Name,
7536 18 : state.dataMaterial->Material(Layer).Thickness,
7537 18 : state.dataMaterial->Material(Layer).Conductivity,
7538 18 : state.dataMaterial->Material(Layer).AbsorpThermal,
7539 18 : state.dataMaterial->Material(Layer).Trans,
7540 18 : state.dataMaterial->Material(Layer).TransVis,
7541 18 : state.dataMaterial->Material(Layer).ReflectShade);
7542 18 : } break;
7543 12 : case DataHeatBalance::MaterialGroup::WindowBlind: {
7544 12 : BlNum = state.dataMaterial->Material(Layer).BlindDataPtr;
7545 : static constexpr std::string_view Format_704(
7546 : " WindowMaterial:Blind,{},{:.4R},{:.4R},{:.4R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
7547 96 : print(state.files.eio,
7548 : Format_704,
7549 12 : state.dataMaterial->Material(Layer).Name,
7550 12 : state.dataHeatBal->Blind(BlNum).SlatWidth,
7551 12 : state.dataHeatBal->Blind(BlNum).SlatSeparation,
7552 12 : state.dataHeatBal->Blind(BlNum).SlatThickness,
7553 12 : state.dataHeatBal->Blind(BlNum).SlatAngle,
7554 12 : state.dataHeatBal->Blind(BlNum).SlatTransSolBeamDiff,
7555 12 : state.dataHeatBal->Blind(BlNum).SlatFrontReflSolBeamDiff,
7556 12 : state.dataHeatBal->Blind(BlNum).BlindToGlassDist);
7557 12 : } break;
7558 2 : case DataHeatBalance::MaterialGroup::Screen: {
7559 2 : if (state.dataMaterial->Material(Layer).ScreenDataPtr > 0) {
7560 : static constexpr std::string_view Format_706(
7561 : " WindowMaterial:Screen,{},{:.5R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
7562 22 : print(
7563 : state.files.eio,
7564 : Format_706,
7565 2 : state.dataMaterial->Material(Layer).Name,
7566 2 : state.dataMaterial->Material(Layer).Thickness,
7567 2 : state.dataMaterial->Material(Layer).Conductivity,
7568 2 : state.dataMaterial->Material(Layer).AbsorpThermal,
7569 2 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).BmBmTrans,
7570 2 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).ReflectSolBeamFront,
7571 2 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).ReflectVisBeamFront,
7572 2 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).DifReflect,
7573 2 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).DifReflectVis,
7574 2 : state.dataHeatBal->SurfaceScreens(state.dataMaterial->Material(Layer).ScreenDataPtr).ScreenDiameterToSpacingRatio,
7575 2 : state.dataMaterial->Material(Layer).WinShadeToGlassDist);
7576 : }
7577 2 : } break;
7578 1010 : case DataHeatBalance::MaterialGroup::WindowGlass:
7579 : case DataHeatBalance::MaterialGroup::WindowSimpleGlazing: {
7580 1010 : SolarDiffusing = "No";
7581 1010 : if (state.dataMaterial->Material(Layer).SolarDiffusing) SolarDiffusing = "Yes";
7582 1010 : OpticalDataType = "SpectralAverage";
7583 1010 : SpectralDataName = "";
7584 1010 : if (state.dataMaterial->Material(Layer).GlassSpectralDataPtr > 0) {
7585 181 : OpticalDataType = "Spectral";
7586 181 : SpectralDataName = state.dataHeatBal->SpectralData(state.dataMaterial->Material(Layer).GlassSpectralDataPtr).Name;
7587 : }
7588 1010 : if (state.dataMaterial->Material(Layer).GlassSpectralAndAngle) {
7589 0 : OpticalDataType = "SpectralAndAngle";
7590 0 : SpectralDataName =
7591 0 : state.dataCurveManager->PerfCurve(state.dataMaterial->Material(Layer).GlassSpecAngTransDataPtr).Name + ", " +
7592 0 : state.dataCurveManager->PerfCurve(state.dataMaterial->Material(Layer).GlassSpecAngFRefleDataPtr).Name + ", " +
7593 0 : state.dataCurveManager->PerfCurve(state.dataMaterial->Material(Layer).GlassSpecAngBRefleDataPtr).Name;
7594 : }
7595 : static constexpr std::string_view Format_707(
7596 : " WindowMaterial:Glazing,{},{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{"
7597 : ":.5R},{:.5R},{:.5R},{:.5R},{:.5R},{}\n");
7598 13130 : print(state.files.eio,
7599 : Format_707,
7600 1010 : state.dataMaterial->Material(Layer).Name,
7601 : OpticalDataType,
7602 : SpectralDataName,
7603 1010 : state.dataMaterial->Material(Layer).Thickness,
7604 1010 : state.dataMaterial->Material(Layer).Trans,
7605 1010 : state.dataMaterial->Material(Layer).ReflectSolBeamFront,
7606 1010 : state.dataMaterial->Material(Layer).ReflectSolBeamBack,
7607 1010 : state.dataMaterial->Material(Layer).TransVis,
7608 1010 : state.dataMaterial->Material(Layer).ReflectVisBeamFront,
7609 1010 : state.dataMaterial->Material(Layer).ReflectVisBeamBack,
7610 1010 : state.dataMaterial->Material(Layer).TransThermal,
7611 1010 : state.dataMaterial->Material(Layer).AbsorpThermalFront,
7612 1010 : state.dataMaterial->Material(Layer).AbsorpThermalBack,
7613 1010 : state.dataMaterial->Material(Layer).Conductivity,
7614 1010 : state.dataMaterial->Material(Layer).GlassTransDirtFactor,
7615 : SolarDiffusing);
7616 1010 : } break;
7617 8 : case DataHeatBalance::MaterialGroup::GlassEquivalentLayer: {
7618 8 : OpticalDataType = "SpectralAverage";
7619 8 : SpectralDataName = "";
7620 : static constexpr std::string_view Format_708(
7621 : " WindowMaterial:Glazing:EquivalentLayer,{},{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}"
7622 : ",{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}\n");
7623 120 : print(state.files.eio,
7624 : Format_708,
7625 8 : state.dataMaterial->Material(Layer).Name,
7626 : OpticalDataType,
7627 : SpectralDataName,
7628 8 : state.dataMaterial->Material(Layer).TausFrontBeamBeam,
7629 8 : state.dataMaterial->Material(Layer).TausBackBeamBeam,
7630 8 : state.dataMaterial->Material(Layer).ReflFrontBeamBeam,
7631 8 : state.dataMaterial->Material(Layer).ReflBackBeamBeam,
7632 8 : state.dataMaterial->Material(Layer).TausFrontBeamDiff,
7633 8 : state.dataMaterial->Material(Layer).TausBackBeamDiff,
7634 8 : state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
7635 8 : state.dataMaterial->Material(Layer).ReflBackBeamDiff,
7636 8 : state.dataMaterial->Material(Layer).TausDiffDiff,
7637 8 : state.dataMaterial->Material(Layer).ReflFrontDiffDiff,
7638 8 : state.dataMaterial->Material(Layer).ReflBackDiffDiff,
7639 8 : state.dataMaterial->Material(Layer).TausThermal,
7640 8 : state.dataMaterial->Material(Layer).EmissThermalFront,
7641 8 : state.dataMaterial->Material(Layer).EmissThermalBack);
7642 8 : } break;
7643 2 : case DataHeatBalance::MaterialGroup::ShadeEquivalentLayer: {
7644 : static constexpr std::string_view Format_709(
7645 : " WindowMaterial:Shade:EquivalentLayer,{},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R}\n");
7646 20 : print(state.files.eio,
7647 : Format_709,
7648 2 : state.dataMaterial->Material(Layer).Name,
7649 2 : state.dataMaterial->Material(Layer).TausFrontBeamBeam,
7650 2 : state.dataMaterial->Material(Layer).TausBackBeamBeam,
7651 2 : state.dataMaterial->Material(Layer).TausFrontBeamDiff,
7652 2 : state.dataMaterial->Material(Layer).TausBackBeamDiff,
7653 2 : state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
7654 2 : state.dataMaterial->Material(Layer).ReflBackBeamDiff,
7655 2 : state.dataMaterial->Material(Layer).TausThermal,
7656 2 : state.dataMaterial->Material(Layer).EmissThermalFront,
7657 2 : state.dataMaterial->Material(Layer).EmissThermalBack);
7658 2 : } break;
7659 0 : case DataHeatBalance::MaterialGroup::DrapeEquivalentLayer: {
7660 : static constexpr std::string_view Format_710(
7661 : " WindowMaterial:Drape:EquivalentLayer,{},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},"
7662 : "{:.4R},{:.4R},{:.5R},{:.5R}\n");
7663 0 : print(state.files.eio,
7664 : Format_710,
7665 0 : state.dataMaterial->Material(Layer).Name,
7666 0 : state.dataMaterial->Material(Layer).TausFrontBeamBeam,
7667 0 : state.dataMaterial->Material(Layer).TausFrontBeamDiff,
7668 0 : state.dataMaterial->Material(Layer).TausBackBeamDiff,
7669 0 : state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
7670 0 : state.dataMaterial->Material(Layer).ReflBackBeamDiff,
7671 0 : state.dataMaterial->Material(Layer).TausThermal,
7672 0 : state.dataMaterial->Material(Layer).EmissThermalFront,
7673 0 : state.dataMaterial->Material(Layer).EmissThermalBack,
7674 0 : state.dataMaterial->Material(Layer).PleatedDrapeWidth,
7675 0 : state.dataMaterial->Material(Layer).PleatedDrapeLength);
7676 0 : } break;
7677 1 : case DataHeatBalance::MaterialGroup::ScreenEquivalentLayer: {
7678 : static constexpr std::string_view Format_711(
7679 : " WindowMaterial:Screen:EquivalentLayer,{},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R},{:.4R}"
7680 : ",{:.4R},{:.4R},{:.5R},{:.5R}\n");
7681 11 : print(state.files.eio,
7682 : Format_711,
7683 1 : state.dataMaterial->Material(Layer).Name,
7684 1 : state.dataMaterial->Material(Layer).TausFrontBeamBeam,
7685 1 : state.dataMaterial->Material(Layer).TausFrontBeamDiff,
7686 1 : state.dataMaterial->Material(Layer).TausBackBeamDiff,
7687 1 : state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
7688 1 : state.dataMaterial->Material(Layer).ReflBackBeamDiff,
7689 1 : state.dataMaterial->Material(Layer).TausThermal,
7690 1 : state.dataMaterial->Material(Layer).EmissThermalFront,
7691 1 : state.dataMaterial->Material(Layer).EmissThermalBack,
7692 1 : state.dataMaterial->Material(Layer).ScreenWireSpacing,
7693 1 : state.dataMaterial->Material(Layer).ScreenWireDiameter);
7694 1 : } break;
7695 0 : case DataHeatBalance::MaterialGroup::BlindEquivalentLayer: {
7696 0 : SlateOrientation = "Horizontal";
7697 0 : if (state.dataMaterial->Material(Layer).SlatOrientation == DataWindowEquivalentLayer::Orientation::Vertical) {
7698 0 : SlateOrientation = "Vertical";
7699 : }
7700 : // Formats
7701 : static constexpr std::string_view Format_712(
7702 : " WindowMaterial:Blind:EquivalentLayer,{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:."
7703 : "5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}");
7704 0 : print(state.files.eio,
7705 : Format_712,
7706 0 : state.dataMaterial->Material(Layer).Name,
7707 : SlateOrientation,
7708 0 : state.dataMaterial->Material(Layer).SlatWidth,
7709 0 : state.dataMaterial->Material(Layer).SlatSeparation,
7710 0 : state.dataMaterial->Material(Layer).SlatCrown,
7711 0 : state.dataMaterial->Material(Layer).SlatAngle,
7712 0 : state.dataMaterial->Material(Layer).TausFrontBeamDiff,
7713 0 : state.dataMaterial->Material(Layer).TausBackBeamDiff,
7714 0 : state.dataMaterial->Material(Layer).ReflFrontBeamDiff,
7715 0 : state.dataMaterial->Material(Layer).ReflBackBeamDiff,
7716 0 : state.dataMaterial->Material(Layer).TausDiffDiff,
7717 0 : state.dataMaterial->Material(Layer).ReflFrontDiffDiff,
7718 0 : state.dataMaterial->Material(Layer).ReflBackDiffDiff,
7719 0 : state.dataMaterial->Material(Layer).TausThermal,
7720 0 : state.dataMaterial->Material(Layer).EmissThermalFront,
7721 0 : state.dataMaterial->Material(Layer).EmissThermalBack);
7722 0 : } break;
7723 8 : case DataHeatBalance::MaterialGroup::GapEquivalentLayer: {
7724 8 : GapVentType = "Sealed";
7725 8 : if (state.dataMaterial->Material(Layer).GapVentType == 2) {
7726 0 : GapVentType = "VentedIndoor";
7727 8 : } else if (state.dataMaterial->Material(Layer).GapVentType == 3) {
7728 0 : GapVentType = "VentedOutdoor";
7729 : }
7730 : static constexpr std::string_view Format_713(" WindowMaterial:Gap:EquivalentLayer,{},{},{:.3R},{}\n");
7731 24 : print(state.files.eio,
7732 : Format_713,
7733 8 : state.dataMaterial->Material(Layer).Name,
7734 8 : GasTypeName(state.dataMaterial->Material(Layer).GasType(1)),
7735 8 : state.dataMaterial->Material(Layer).Thickness,
7736 : GapVentType);
7737 8 : } break;
7738 8 : default:
7739 8 : break;
7740 : }
7741 : }
7742 : }
7743 : }
7744 :
7745 507 : } else if (state.dataWindowManager->HasWindows) {
7746 :
7747 3293 : for (ThisNum = 1; ThisNum <= state.dataHeatBal->TotConstructs; ++ThisNum) {
7748 :
7749 2879 : if (!state.dataConstruction->Construct(ThisNum).TypeIsWindow) continue;
7750 653 : if (state.dataConstruction->Construct(ThisNum).WindowTypeEQL) continue; // skip if equivalent layer window
7751 :
7752 : // Calculate for ASHRAE winter and summer conditions: (1)nominal center-of-glass conductance,
7753 : // (2) solar heat gain coefficient (SHGC), including inside and outside air films,
7754 : // (3) solar transmittance at normal incidence, and (4) visible transmittance at normal incidence.
7755 :
7756 653 : CalcNominalWindowCond(state, ThisNum, 1, NominalConductanceWinter, SHGCWinter, TransSolNorm, TransVisNorm, errFlag);
7757 653 : if (errFlag == 1 || errFlag == 2) continue;
7758 653 : state.dataHeatBal->NominalU(ThisNum) = NominalConductanceWinter;
7759 : // Need to have this because of window assembly reports (Simon)
7760 653 : state.dataConstruction->Construct(ThisNum).SummerSHGC = SHGCSummer;
7761 653 : state.dataConstruction->Construct(ThisNum).VisTransNorm = TransVisNorm;
7762 : }
7763 : }
7764 768 : }
7765 :
7766 : //*************************************************************************************
7767 :
7768 17 : void CalcWindowBlindProperties(EnergyPlusData &state)
7769 : {
7770 :
7771 : // SUBROUTINE INFORMATION:
7772 : // AUTHOR Hans Simmler
7773 : // DATE WRITTEN July-Aug 1995
7774 : // MODIFIED Aug 2001 (FCW): adapt to EnergyPlus
7775 : // Dec 2001 (FCW): add variable slat angle
7776 : // RE-ENGINEERED na
7777 :
7778 : // PURPOSE OF THIS SUBROUTINE:
7779 : // Calculates solar-optical properties of a window blind
7780 : // from slat properties and solar profile angle. Assumes flat slats.
7781 :
7782 : // METHODOLOGY EMPLOYED:
7783 : // The solar profile angle is varied from -90 to +90 deg and slat angle is varied from 0 to 180deg,
7784 : // covering the full range of possible profile angles and slat angles.
7785 : // (The profile angle is defined as the angle of incidence when the radiation
7786 : // source is located in a plane that (1)is perpendicular to the plane of the blinds [which is
7787 : // the same as the window plane] and (2) contains the slat normal vector.)
7788 :
7789 : // In the time-step calculation,the blind properties vs. profile angle and slat angle
7790 : // that are calculated here will be applicable to windows and slats
7791 : // of arbitrary orientation, and to arbitrary sun positions, as long as the appropiate
7792 : // profile angle is used. The slat angle for a particular window with blinds is determined
7793 : // each time step in subroutine WindowShadingManager on the basis of user-specified
7794 : // slat control options.
7795 :
7796 : // REFERENCES:
7797 : // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
7798 : // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
7799 :
7800 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7801 :
7802 34 : Array1D<Real64> bld_pr(15); // Slat properties
7803 34 : Array1D<Real64> st_lay(16); // Solar-optical blind/glazing system properties
7804 : Real64 sun_el; // Solar profile angle (radians)
7805 34 : Array1D<Real64> sun_el_deg(37); // Solar profile angle (deg) corresponding to sun_el values
7806 : Real64 bld_el; // Slat angle (elevation of slat normal vector in plane
7807 : // perpendicular to window and containing the slat normal vector) (radians)
7808 : int ISolVis; // 1 = do solar and IR calculation; 2 = do visible calculation
7809 : int IProfAng; // Profile angle index
7810 : int BlindNum; // Blind number
7811 : int ISlatAng; // Slat angle index
7812 :
7813 37 : for (BlindNum = 1; BlindNum <= state.dataHeatBal->TotBlinds; ++BlindNum) {
7814 :
7815 20 : bld_pr(2) = state.dataHeatBal->Blind(BlindNum).SlatWidth;
7816 20 : bld_pr(3) = state.dataHeatBal->Blind(BlindNum).SlatSeparation;
7817 :
7818 60 : for (ISolVis = 1; ISolVis <= 2; ++ISolVis) {
7819 40 : if (ISolVis == 1) { // For solar calculation
7820 20 : bld_pr(4) = 0.0;
7821 20 : bld_pr(5) = 0.0;
7822 20 : bld_pr(6) = 0.0;
7823 20 : bld_pr(7) = state.dataHeatBal->Blind(BlindNum).SlatTransSolBeamDiff;
7824 20 : bld_pr(8) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflSolBeamDiff;
7825 20 : bld_pr(9) = state.dataHeatBal->Blind(BlindNum).SlatBackReflSolBeamDiff;
7826 20 : bld_pr(10) = state.dataHeatBal->Blind(BlindNum).SlatTransSolDiffDiff;
7827 20 : bld_pr(11) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflSolDiffDiff;
7828 20 : bld_pr(12) = state.dataHeatBal->Blind(BlindNum).SlatBackReflSolDiffDiff;
7829 : } else { // For visible calculation
7830 20 : bld_pr(4) = 0.0;
7831 20 : bld_pr(5) = 0.0;
7832 20 : bld_pr(6) = 0.0;
7833 20 : bld_pr(7) = state.dataHeatBal->Blind(BlindNum).SlatTransVisBeamDiff;
7834 20 : bld_pr(8) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflVisBeamDiff;
7835 20 : bld_pr(9) = state.dataHeatBal->Blind(BlindNum).SlatBackReflVisBeamDiff;
7836 20 : bld_pr(10) = state.dataHeatBal->Blind(BlindNum).SlatTransVisDiffDiff;
7837 20 : bld_pr(11) = state.dataHeatBal->Blind(BlindNum).SlatFrontReflVisDiffDiff;
7838 20 : bld_pr(12) = state.dataHeatBal->Blind(BlindNum).SlatBackReflVisDiffDiff;
7839 : }
7840 : // For IR calculation
7841 40 : bld_pr(13) = state.dataHeatBal->Blind(BlindNum).SlatTransIR;
7842 40 : bld_pr(14) = state.dataHeatBal->Blind(BlindNum).SlatFrontEmissIR;
7843 40 : bld_pr(15) = state.dataHeatBal->Blind(BlindNum).SlatBackEmissIR;
7844 :
7845 : // Calculate diffuse properties of blind. If blind has variable slat angle, &
7846 : // vary slat angle from 0 to 180 deg in 10-deg steps (for MaxSlatAngs = 19).
7847 : // If blind has fixed slat angle, calculate properties at that angle only.
7848 :
7849 154 : for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
7850 :
7851 148 : st_lay = 0.0;
7852 148 : if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) {
7853 34 : bld_el = state.dataHeatBal->Blind(BlindNum).SlatAngle * DataGlobalConstants::DegToRadians;
7854 : } else { // Variable slat angle
7855 114 : bld_el = (DataGlobalConstants::Pi / (MaxSlatAngs - 1)) * (ISlatAng - 1); // 0 <= bld_el <= 180 deg
7856 : }
7857 148 : BlindOpticsDiffuse(state, BlindNum, ISolVis, bld_pr, bld_el, st_lay);
7858 :
7859 148 : if (ISolVis == 1) { // Fill blind diffuse solar and IR properties
7860 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffTrans(ISlatAng) = st_lay(9);
7861 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffRefl(ISlatAng) = st_lay(10);
7862 74 : state.dataHeatBal->Blind(BlindNum).SolBackDiffDiffTrans(ISlatAng) = st_lay(11);
7863 74 : state.dataHeatBal->Blind(BlindNum).SolBackDiffDiffRefl(ISlatAng) = st_lay(12);
7864 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffAbs(ISlatAng) = max(0.0, 1.0 - st_lay(9) - st_lay(10));
7865 74 : state.dataHeatBal->Blind(BlindNum).SolBackDiffAbs(ISlatAng) = max(0.0, 1.0 - st_lay(11) - st_lay(12));
7866 74 : state.dataHeatBal->Blind(BlindNum).IRFrontTrans(ISlatAng) = st_lay(13);
7867 74 : state.dataHeatBal->Blind(BlindNum).IRFrontEmiss(ISlatAng) = st_lay(14);
7868 74 : state.dataHeatBal->Blind(BlindNum).IRBackTrans(ISlatAng) = st_lay(13);
7869 74 : state.dataHeatBal->Blind(BlindNum).IRBackEmiss(ISlatAng) = st_lay(15);
7870 : } else { // Fill blind diffuse visible properties
7871 74 : state.dataHeatBal->Blind(BlindNum).VisFrontDiffDiffTrans(ISlatAng) = st_lay(9);
7872 74 : state.dataHeatBal->Blind(BlindNum).VisFrontDiffDiffRefl(ISlatAng) = st_lay(10);
7873 74 : state.dataHeatBal->Blind(BlindNum).VisBackDiffDiffTrans(ISlatAng) = st_lay(11);
7874 74 : state.dataHeatBal->Blind(BlindNum).VisBackDiffDiffRefl(ISlatAng) = st_lay(12);
7875 : }
7876 :
7877 148 : if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
7878 : } // End of slat angle loop
7879 :
7880 : // Calculate beam properties of blind. Vary profile angle from -90 to +90 deg in 5-deg steps.
7881 : // If blind has variable slat angle, vary slat angle from 0 to 180 deg in 10-deg steps
7882 : // (for MaxSlatAngs = 19). If blind has fixed slat angle, calculate properties at that angle only.
7883 :
7884 1520 : for (IProfAng = 1; IProfAng <= 37; ++IProfAng) {
7885 1480 : sun_el = -DataGlobalConstants::Pi / 2.0 + (DataGlobalConstants::Pi / 36.0) * (IProfAng - 1);
7886 1480 : sun_el_deg(IProfAng) = 57.2958 * sun_el;
7887 :
7888 5698 : for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
7889 5476 : st_lay = 0.0;
7890 5476 : if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) {
7891 1258 : bld_el = state.dataHeatBal->Blind(BlindNum).SlatAngle * DataGlobalConstants::DegToRadians;
7892 : } else { // Variable slat angle
7893 4218 : bld_el = (DataGlobalConstants::Pi / (MaxSlatAngs - 1)) * (ISlatAng - 1); // 0 <= bld_el <= 180 deg
7894 : }
7895 :
7896 : // Beam solar-optical properties of blind for given profile angle and slat angle
7897 :
7898 5476 : BlindOpticsBeam(state, BlindNum, bld_pr, bld_el, sun_el, st_lay);
7899 :
7900 5476 : if (ISolVis == 1) { // Fill blind beam solar properties
7901 2738 : state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamTrans(ISlatAng, IProfAng) = st_lay(1);
7902 2738 : state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamRefl(ISlatAng, IProfAng) = st_lay(2);
7903 2738 : state.dataHeatBal->Blind(BlindNum).SolBackBeamBeamTrans(ISlatAng, IProfAng) = st_lay(3);
7904 2738 : state.dataHeatBal->Blind(BlindNum).SolBackBeamBeamRefl(ISlatAng, IProfAng) = st_lay(4);
7905 2738 : state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffTrans(ISlatAng, IProfAng) = st_lay(5);
7906 2738 : state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffRefl(ISlatAng, IProfAng) = st_lay(6);
7907 2738 : state.dataHeatBal->Blind(BlindNum).SolBackBeamDiffTrans(ISlatAng, IProfAng) = st_lay(7);
7908 2738 : state.dataHeatBal->Blind(BlindNum).SolBackBeamDiffRefl(ISlatAng, IProfAng) = st_lay(8);
7909 2738 : state.dataHeatBal->Blind(BlindNum).SolFrontBeamAbs(ISlatAng, IProfAng) =
7910 2738 : max(0.0, 1.0 - st_lay(6) - st_lay(1) - st_lay(5));
7911 2738 : state.dataHeatBal->Blind(BlindNum).SolBackBeamAbs(ISlatAng, IProfAng) = max(0.0, 1.0 - st_lay(7) - st_lay(3) - st_lay(8));
7912 :
7913 : } else { // Fill blind beam visible properties
7914 2738 : state.dataHeatBal->Blind(BlindNum).VisFrontBeamBeamTrans(ISlatAng, IProfAng) = st_lay(1);
7915 2738 : state.dataHeatBal->Blind(BlindNum).VisFrontBeamBeamRefl(ISlatAng, IProfAng) = st_lay(2);
7916 2738 : state.dataHeatBal->Blind(BlindNum).VisBackBeamBeamTrans(ISlatAng, IProfAng) = st_lay(3);
7917 2738 : state.dataHeatBal->Blind(BlindNum).VisBackBeamBeamRefl(ISlatAng, IProfAng) = st_lay(4);
7918 2738 : state.dataHeatBal->Blind(BlindNum).VisFrontBeamDiffTrans(ISlatAng, IProfAng) = st_lay(5);
7919 2738 : state.dataHeatBal->Blind(BlindNum).VisFrontBeamDiffRefl(ISlatAng, IProfAng) = st_lay(6);
7920 2738 : state.dataHeatBal->Blind(BlindNum).VisBackBeamDiffTrans(ISlatAng, IProfAng) = st_lay(7);
7921 2738 : state.dataHeatBal->Blind(BlindNum).VisBackBeamDiffRefl(ISlatAng, IProfAng) = st_lay(8);
7922 : }
7923 :
7924 5476 : if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
7925 : } // End of loop over slat angles
7926 : } // End of loop over profile angles
7927 :
7928 40 : if (ISolVis == 1) {
7929 77 : for (ISlatAng = 1; ISlatAng <= MaxSlatAngs; ++ISlatAng) {
7930 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffTransGnd(ISlatAng) =
7931 222 : DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamTrans(ISlatAng, {1, 37})) +
7932 148 : DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffTrans(ISlatAng, {1, 37}));
7933 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffTransSky(ISlatAng) =
7934 222 : DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamBeamTrans(ISlatAng, {1, 37})) +
7935 148 : DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffTrans(ISlatAng, {1, 37}));
7936 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffAbsGnd(ISlatAng) =
7937 148 : DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamAbs(ISlatAng, {1, 37}));
7938 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffAbsSky(ISlatAng) =
7939 148 : DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamAbs(ISlatAng, {1, 37}));
7940 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffReflGnd(ISlatAng) =
7941 148 : DiffuseAverageProfAngGnd(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffRefl(ISlatAng, {1, 37}));
7942 74 : state.dataHeatBal->Blind(BlindNum).SolFrontDiffDiffReflSky(ISlatAng) =
7943 148 : DiffuseAverageProfAngSky(state.dataHeatBal->Blind(BlindNum).SolFrontBeamDiffRefl(ISlatAng, {1, 37}));
7944 :
7945 : // TH 2/17/2010. Added. Loop only for movable slat blinds
7946 74 : if (state.dataHeatBal->Blind(BlindNum).SlatAngleType == DataWindowEquivalentLayer::AngleType::Fixed) break;
7947 : }
7948 : }
7949 :
7950 : } // End of loop over solar vs. visible properties
7951 :
7952 : } // End of loop over blinds
7953 17 : }
7954 :
7955 : //*************************************************************************************
7956 :
7957 2 : void CalcWindowScreenProperties(EnergyPlusData &state)
7958 : {
7959 :
7960 : // SUBROUTINE INFORMATION:
7961 : // AUTHOR Richard Raustad
7962 : // DATE WRITTEN April 2006
7963 : // MODIFIED na
7964 : // RE-ENGINEERED na
7965 :
7966 : // PURPOSE OF THIS SUBROUTINE:
7967 : // Initialize static properties of window screens.
7968 :
7969 : // METHODOLOGY EMPLOYED:
7970 : // Loop through all surfaces to determine which window has an exterior screen. Static
7971 : // variables are defined here, dynamic variables are calculated in CalcScreenTransmittance.
7972 :
7973 : // Locals
7974 : // SUBROUTINE PARAMETER DEFINITIONS:
7975 2 : int constexpr M(18);
7976 2 : int constexpr N(18);
7977 :
7978 : int SurfNum; // Index to surface number
7979 : int ScreenNum; // Index to each screen used on exterior of window
7980 : int ConstrNumSh; // Index to shaded construction
7981 : int MatNum; // Index to material number
7982 : int i; // Integration loop counters
7983 : int j;
7984 : Real64 SumTrans; // Integration variable for transmittance
7985 : Real64 SumTransVis; // Integration variable for visible transmittance
7986 : Real64 SumReflect; // Integration variable for reflectance
7987 : Real64 SumReflectVis; // Integration variable for visible reflectance
7988 : Real64 SumArea; // Integration variable for area of quarter hemisphere
7989 : bool FoundMaterial; // Flag to avoid printing screen transmittance data multiple times when Material:WindowScreen
7990 : // is used on multiple surfaces
7991 : bool PrintTransMap; // Flag used to print transmittance map
7992 :
7993 2 : constexpr std::array<std::string_view, static_cast<int>(ScreenBeamReflectanceModel::Num)> ScreenBeamReflectanceModelNamesUC{
7994 : "DONOTMODEL", "MODELASDIRECTBEAM", "MODELASDIFFUSE"};
7995 :
7996 2 : state.dataHeatBal->SurfaceScreens.allocate(state.dataHeatBal->NumSurfaceScreens);
7997 2 : state.dataHeatBal->ScreenTrans.allocate(state.dataHeatBal->NumSurfaceScreens);
7998 2 : ScreenNum = 0;
7999 :
8000 : // Pre-calculate these constants
8001 4 : std::vector<Real64> sunAzimuth;
8002 4 : std::vector<Real64> sin_sunAzimuth;
8003 4 : std::vector<Real64> cos_sunAzimuth;
8004 4 : std::vector<Real64> sunAltitude;
8005 4 : std::vector<Real64> sin_sunAltitude;
8006 4 : std::vector<Real64> cos_sunAltitude;
8007 4 : std::vector<Real64> skyArea; // Area of integration
8008 4 : Array2D<Real64> relativeAzimuth; // Relative azimuth angle of sun with respect to surface outward normal
8009 4 : Array2D<Real64> relativeAltitude; // Relative altitude angle of sun with respect to surface outward normal
8010 :
8011 2 : relativeAzimuth.allocate(N, M);
8012 2 : relativeAltitude.allocate(N, M);
8013 :
8014 38 : for (j = 0; j <= N - 1; ++j) {
8015 36 : Real64 currAzimuth = (90.0 / N) * j * DataGlobalConstants::DegToRadians;
8016 36 : sunAzimuth.push_back(currAzimuth); // Azimuth angle of sun during integration
8017 36 : sin_sunAzimuth.push_back(std::sin(currAzimuth));
8018 36 : cos_sunAzimuth.push_back(std::cos(currAzimuth));
8019 : }
8020 :
8021 38 : for (i = 0; i <= M - 1; ++i) {
8022 36 : Real64 currAltitude = (90.0 / M) * i * DataGlobalConstants::DegToRadians;
8023 36 : sunAltitude.push_back(currAltitude); // Altitude angle of sun during integration
8024 36 : sin_sunAltitude.push_back(std::sin(currAltitude));
8025 36 : cos_sunAltitude.push_back(std::cos(currAltitude));
8026 36 : skyArea.push_back(sin_sunAltitude[i] * cos_sunAltitude[i]);
8027 : }
8028 :
8029 38 : for (j = 1; j <= N; ++j) {
8030 684 : for (i = 1; i <= M; ++i) {
8031 : // Integrate transmittance using coordinate transform
8032 648 : relativeAzimuth(i, j) = std::asin(sin_sunAltitude[i - 1] * cos_sunAzimuth[j - 1]); // phi prime
8033 648 : relativeAltitude(i, j) = std::atan(std::tan(sunAltitude[i - 1]) * sin_sunAzimuth[j - 1]); // alpha
8034 : }
8035 : }
8036 :
8037 2 : PrintTransMap = false;
8038 192 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
8039 :
8040 190 : if (state.dataSurface->Surface(SurfNum).HasShadeControl) {
8041 28 : ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction;
8042 28 : MatNum = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1);
8043 : WinShadingType ShadingType =
8044 28 : state.dataSurface->WindowShadingControl(state.dataSurface->Surface(SurfNum).activeWindowShadingControl).ShadingType;
8045 28 : if (ShadingType == WinShadingType::ExtScreen) {
8046 :
8047 8 : if (state.dataMaterial->Material(MatNum).ScreenMapResolution > 0) PrintTransMap = true;
8048 8 : ++ScreenNum;
8049 8 : state.dataSurface->SurfWinScreenNumber(SurfNum) = ScreenNum;
8050 : // If a screen material is used more than once, the Material structure's screen data pointer holds the screen number
8051 : // of the last window surface. Use this method to access the screen parameter's only for static variables such as
8052 : // diffuse properties (InitGlassOpticalCalculations). For all cases where the screen properties are a function of
8053 : // sun azimuth and altitude angles, use the SurfaceScreens structure.
8054 8 : state.dataMaterial->Material(MatNum).ScreenDataPtr = ScreenNum;
8055 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber = MatNum;
8056 : // Invert calculation done in GetMaterialInput to find Diameter to Spacing ratio (Props(7)/Props(6))
8057 : // dataMaterial.Material(MaterNum)%Trans = (1 - MaterialProps(7)/MaterialProps(6))**2.0
8058 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).ScreenDiameterToSpacingRatio =
8059 8 : 1.0 - std::sqrt(state.dataMaterial->Material(MatNum).Trans);
8060 :
8061 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).screenBeamReflectanceModel = static_cast<DataSurfaces::ScreenBeamReflectanceModel>(
8062 24 : getEnumerationValue(ScreenBeamReflectanceModelNamesUC,
8063 24 : UtilityRoutines::MakeUPPERCase(state.dataMaterial->Material(MatNum).ReflectanceModeling)));
8064 :
8065 : // Reflectance of screen material only
8066 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinder =
8067 8 : state.dataMaterial->Material(MatNum).ReflectShade / (1 - state.dataMaterial->Material(MatNum).Trans);
8068 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinderVis =
8069 8 : state.dataMaterial->Material(MatNum).ReflectShadeVis / (1 - state.dataMaterial->Material(MatNum).Trans);
8070 :
8071 : // Integrate the transmittance over a quarter hemisphere for use in diffuse calculations
8072 8 : SumTrans = 0.0;
8073 8 : SumTransVis = 0.0;
8074 8 : SumReflect = 0.0;
8075 8 : SumReflectVis = 0.0;
8076 8 : SumArea = 0.0;
8077 : // Integration over quarter hemisphere in polar coordinates and converting to rectangular to call screen model.
8078 : // Proceed in reverse order such that the last calculation yields zero sun angle to window screen normal (angles=0,0).
8079 : // The properties calculated at zero sun angle are then used elsewhere prior to the start of the actual simulation.
8080 :
8081 152 : for (j = N; j >= 1; --j) {
8082 2736 : for (i = M; i >= 1; --i) {
8083 : // Integrate transmittance using coordinate transform
8084 2592 : CalcScreenTransmittance(state, 0, relativeAltitude(i, j), relativeAzimuth(i, j), ScreenNum);
8085 2592 : SumTrans +=
8086 5184 : (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTrans + state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTrans) *
8087 2592 : skyArea[i - 1];
8088 7776 : SumTransVis += (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTransVis +
8089 5184 : state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTransVis) *
8090 2592 : skyArea[i - 1];
8091 2592 : SumReflect += state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectSolBeamFront * skyArea[i - 1];
8092 2592 : SumReflectVis += state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectVisBeamFront * skyArea[i - 1];
8093 2592 : SumArea += skyArea[i - 1];
8094 : }
8095 : }
8096 :
8097 : // Reflectance of overall screen including openings and scattered transmittance
8098 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectScreen =
8099 16 : state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinder *
8100 8 : (1.0 - (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTrans + state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTrans));
8101 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectScreenVis =
8102 16 : state.dataHeatBal->SurfaceScreens(ScreenNum).ReflectCylinderVis *
8103 8 : (1.0 -
8104 8 : (state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTransVis + state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTransVis));
8105 :
8106 8 : if (SumArea != 0) {
8107 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).DifDifTrans = SumTrans / SumArea;
8108 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).DifDifTransVis = SumTransVis / SumArea;
8109 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect = SumReflect / SumArea;
8110 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflectVis = SumReflectVis / SumArea;
8111 : }
8112 8 : state.dataHeatBal->SurfaceScreens(ScreenNum).DifScreenAbsorp = max(
8113 : 0.0,
8114 8 : (1.0 - state.dataHeatBal->SurfaceScreens(ScreenNum).DifDifTrans - state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect));
8115 :
8116 8 : state.dataMaterial->Material(MatNum).AbsorpThermalBack = state.dataHeatBal->SurfaceScreens(ScreenNum).DifScreenAbsorp;
8117 8 : state.dataMaterial->Material(MatNum).AbsorpThermalFront = state.dataHeatBal->SurfaceScreens(ScreenNum).DifScreenAbsorp;
8118 8 : state.dataMaterial->Material(MatNum).ReflectSolBeamFront = state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect;
8119 8 : state.dataMaterial->Material(MatNum).ReflectSolBeamBack = state.dataHeatBal->SurfaceScreens(ScreenNum).DifReflect;
8120 :
8121 : } // (ShadingType == 'EXTERIORSCREEN')
8122 : }
8123 : } // End of screen surface initialization
8124 :
8125 : // Write transmittance versus direct normal angle to csv file
8126 :
8127 2 : if (PrintTransMap) {
8128 : // Fortran version did not have error handling in case of file open failure. This one does.
8129 : // Which is correct?
8130 4 : auto screenCsvFile = state.files.screenCsv.open(state, "CalcWindowScreenComponents", state.files.outputControl.screen);
8131 :
8132 : // WRITE(ScreenTransUnitNo,*)' '
8133 10 : for (ScreenNum = 1; ScreenNum <= state.dataHeatBal->NumSurfaceScreens; ++ScreenNum) {
8134 8 : MatNum = state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber;
8135 : // Do not print transmittance map if angle increment is equal to 0
8136 8 : if (state.dataMaterial->Material(MatNum).ScreenMapResolution == 0) continue;
8137 8 : FoundMaterial = false;
8138 20 : for (i = ScreenNum + 1; i <= state.dataHeatBal->NumSurfaceScreens; ++i) {
8139 : // Write out transmittance data once for each Material:WindowScreen object
8140 12 : if (MatNum == state.dataHeatBal->SurfaceScreens(i).MaterialNumber) FoundMaterial = true;
8141 : }
8142 8 : if (FoundMaterial) continue;
8143 : // Store transmittance at direct normal angle
8144 2 : if (state.dataMaterial->Material(MatNum).ScreenMapResolution != 0) {
8145 6 : state.dataHeatBal->ScreenTrans(ScreenNum).Trans.allocate(90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1,
8146 6 : 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1);
8147 6 : state.dataHeatBal->ScreenTrans(ScreenNum).Scatt.allocate(90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1,
8148 6 : 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1);
8149 2 : state.dataHeatBal->ScreenTrans(ScreenNum).Trans = 0.0;
8150 2 : state.dataHeatBal->ScreenTrans(ScreenNum).Scatt = 0.0;
8151 40 : for (j = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; j >= 1; --j) {
8152 760 : for (i = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; i >= 1; --i) {
8153 : Real64 SunAzimuth =
8154 722 : state.dataMaterial->Material(MatNum).ScreenMapResolution * (j - 1) * DataGlobalConstants::DegToRadians;
8155 : Real64 SunAltitude =
8156 722 : state.dataMaterial->Material(MatNum).ScreenMapResolution * (i - 1) * DataGlobalConstants::DegToRadians;
8157 722 : CalcScreenTransmittance(state, 0, SunAltitude, SunAzimuth, ScreenNum);
8158 722 : state.dataHeatBal->ScreenTrans(ScreenNum).Trans(i, j) = state.dataHeatBal->SurfaceScreens(ScreenNum).BmBmTrans;
8159 722 : state.dataHeatBal->ScreenTrans(ScreenNum).Scatt(i, j) = state.dataHeatBal->SurfaceScreens(ScreenNum).BmDifTrans;
8160 : }
8161 : }
8162 :
8163 4 : print(screenCsvFile,
8164 : "MATERIAL:WINDOWSCREEN:{}\n",
8165 4 : state.dataMaterial->Material(state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber).Name);
8166 2 : print(screenCsvFile,
8167 : "Tabular data for beam solar transmittance at varying \"relative\" azimuth (row) and "
8168 2 : "altitude (column) angles (deg) [relative to surface normal].\n");
8169 2 : print(screenCsvFile, ",90");
8170 36 : for (i = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution; i >= 2; --i) {
8171 34 : print(screenCsvFile, ",{}", (i - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
8172 : }
8173 2 : print(screenCsvFile, ",0\n");
8174 :
8175 40 : for (j = 1; j <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; ++j) {
8176 38 : print(screenCsvFile, "{}", (j - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
8177 722 : for (i = 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; i >= 2; --i) {
8178 684 : print(screenCsvFile, ",{:.6R}", state.dataHeatBal->ScreenTrans(ScreenNum).Trans(i, j));
8179 : }
8180 38 : print(screenCsvFile, ",{:.6R}\n", state.dataHeatBal->ScreenTrans(ScreenNum).Trans(i, j));
8181 : }
8182 2 : print(screenCsvFile, "\n\n");
8183 :
8184 4 : print(screenCsvFile,
8185 : "MATERIAL:WINDOWSCREEN:{}\n",
8186 4 : state.dataMaterial->Material(state.dataHeatBal->SurfaceScreens(ScreenNum).MaterialNumber).Name);
8187 2 : print(screenCsvFile,
8188 : "Tabular data for scattered solar transmittance at varying \"relative\" azimuth (row) and "
8189 2 : "altitude (column) angles (deg) [relative to surface normal].\n");
8190 :
8191 38 : for (i = 1; i <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution; ++i) {
8192 36 : print(screenCsvFile, ",{}", (i - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
8193 : }
8194 2 : print(screenCsvFile, ",{}\n", (i - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
8195 :
8196 40 : for (j = 1; j <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution + 1; ++j) {
8197 38 : print(screenCsvFile, "{}", (j - 1) * state.dataMaterial->Material(MatNum).ScreenMapResolution);
8198 722 : for (i = 1; i <= 90 / state.dataMaterial->Material(MatNum).ScreenMapResolution; ++i) {
8199 684 : print(screenCsvFile, ",{:.6R}", state.dataHeatBal->ScreenTrans(ScreenNum).Scatt(i, j));
8200 : }
8201 38 : print(screenCsvFile, ",{:.6R}\n", state.dataHeatBal->ScreenTrans(ScreenNum).Scatt(i, j));
8202 : }
8203 2 : print(screenCsvFile, "\n\n");
8204 : }
8205 : }
8206 : }
8207 2 : state.dataHeatBal->ScreenTrans.deallocate();
8208 2 : }
8209 :
8210 148 : void BlindOpticsDiffuse(EnergyPlusData &state,
8211 : int const BlindNum, // Blind number
8212 : int const ISolVis, // 1 = solar and IR calculation; 2 = visible calculation
8213 : Array1A<Real64> const c, // Slat properties
8214 : Real64 const b_el, // Slat elevation (radians)
8215 : Array1A<Real64> p // Blind properties
8216 : )
8217 : {
8218 :
8219 : // SUBROUTINE INFORMATION:
8220 : // AUTHOR Hans Simmler
8221 : // DATE WRITTEN July-Aug 1995
8222 : // MODIFIED Aug 2001 (FCW): adapt to EnergyPlus
8223 : // Aug 2002 (FCW): make corrections so that calculations are consistent with
8224 : // G(i) = Sum over j of J(j)*F(j,i). Previously, i,j was
8225 : // interchanged in F, so that
8226 : // G(i) = Sum over j of J(j)*F(i,j), which is wrong.
8227 : // This change was made to resolve discrepancies between EnergyPlus results
8228 : // and blind transmittance measurements made at Oklahoma State Univ.
8229 : // Feb 2004 (FCW): modify slat edge correction calc to avoid possible divide by zero
8230 : // RE-ENGINEERED na
8231 :
8232 : // PURPOSE OF THIS SUBROUTINE:
8233 : // From the slat properties, calculates the diffuse solar, diffuse visible and IR
8234 : // transmission and reflection properties of a window blind.
8235 :
8236 : // METHODOLOGY EMPLOYED:
8237 : // na
8238 :
8239 : // REFERENCES:
8240 : // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
8241 : // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
8242 :
8243 : // Argument array dimensioning
8244 148 : c.dim(15);
8245 148 : p.dim(16);
8246 :
8247 : Real64 ri; // Front and back IR slat reflectance
8248 : Real64 rib;
8249 : Real64 phib; // Elevation of slat normal vector (radians)
8250 : Real64 phis; // Source elevation (radians)
8251 : Real64 delphis; // Angle increment for integration over source distribution (radians)
8252 296 : Array1D<Real64> fEdgeSource(10); // Slat edge correction factor vs source elevation
8253 296 : Array1D<Real64> fEdgeA(2); // Average slat edge correction factor for upper and lower quadrants
8254 : // seen by window blind
8255 : Real64 gamma; // phib - phis
8256 : int Iphis; // Source elevation counter
8257 : int IUpDown; // =1 for source in upper quadrant, =2 for source in lower quadrant
8258 : Real64 fEdge; // Slat edge correction factor
8259 : Real64 fEdge1;
8260 296 : Array1D<Real64> j(6); // Slat section radiosity vector
8261 296 : Array1D<Real64> G(6); // Slat section irradiance vector
8262 296 : Array1D<Real64> Q(6); // Slat section radiance vector
8263 296 : Array2D<Real64> F(6, 6); // View factor array
8264 296 : Array2D<Real64> X(4, 4); // Exchange matrix
8265 296 : Array2D<Real64> Xinv(4, 4); // Inverse of exchange matrix
8266 : int k; // Array indices
8267 : int m;
8268 296 : Array1D_int indx(4); // LU decomposition indices
8269 : Real64 BlindIRreflFront; // Blind front IR reflectance
8270 : Real64 BlindIRreflBack; // Blind back IR reflectance
8271 :
8272 : // The slat input properties are:
8273 : // c(1) 0. (unused)
8274 : // c(2) Slat width (m)
8275 : // c(3) Slat separation (m)
8276 : // c(4) 0. (unused)
8277 : // c(5) 0. (unused)
8278 : // c(6) 0. (unused)
8279 : // The following are solar or visible properties
8280 : // c(7) trans beam-diff
8281 : // c(8) refl front beam-diff
8282 : // c(9) refl back beam-diff
8283 : // c(10) trans diff-diff
8284 : // c(11) refl front diff-diff
8285 : // c(12) refl back diff-diff
8286 : // The following are hemispherical thermal IR properties
8287 : // c(13) trans diff-diff
8288 : // c(14) emiss front diff
8289 : // c(15) emiss back diff
8290 :
8291 : // The calculated blind properties are:
8292 : // The following are solar or visible properties
8293 : // p(1) trans front beam-beam
8294 : // p(2) refl front beam-beam
8295 : // p(3) trans back beam-beam
8296 : // p(4) refl back beam-beam
8297 : // p(5) trans front beam-diff
8298 : // p(6) refl front beam-diff
8299 : // p(7) trans back beam-diff
8300 : // p(8) refl back beam-diff
8301 : // p(9) trans front diff-diff
8302 : // p(10) refl front diff-diff
8303 : // p(11) trans back diff-diff
8304 : // p(12) refl back diff-diff
8305 : // The following are IR properties
8306 : // p(13) IR trans front (same as IR trans back)
8307 : // p(14) IR emissivity front
8308 : // p(15) IR emissivity back
8309 : // p(16) 0.0 (unused)
8310 :
8311 : // Calculate view factors between slat sections (slat is divided longitudinally into two equal parts)
8312 :
8313 148 : ViewFac(c(2), c(3), b_el, DataGlobalConstants::PiOvr2, F);
8314 :
8315 : // Set up exchange matrix X for diffuse properties
8316 :
8317 444 : for (k = 3; k <= 5; k += 2) {
8318 1480 : for (m = 3; m <= 6; ++m) {
8319 1184 : X(m - 2, k - 2) = -c(12) * F(k, m) - c(10) * F(k + 1, m);
8320 1184 : X(m - 2, k - 1) = -c(10) * F(k, m) - c(11) * F(k + 1, m);
8321 : }
8322 : }
8323 :
8324 740 : for (k = 1; k <= 4; ++k) {
8325 592 : ++X(k, k);
8326 : }
8327 :
8328 148 : indx = 0;
8329 148 : InvertMatrix(state, X, Xinv, indx, 4, 4); // Autodesk:Note X modified by this call
8330 :
8331 : //---------Calculate diffuse short-wave properties for the front side of the blind
8332 :
8333 : // Sources
8334 :
8335 148 : Q(3) = c(12) * F(3, 1) + c(10) * F(4, 1);
8336 148 : Q(4) = c(10) * F(3, 1) + c(11) * F(4, 1);
8337 148 : Q(5) = c(12) * F(5, 1) + c(10) * F(6, 1);
8338 148 : Q(6) = c(10) * F(5, 1) + c(11) * F(6, 1);
8339 :
8340 : // Radiosities
8341 :
8342 148 : j(1) = 1.0;
8343 148 : j(2) = 0.0;
8344 740 : for (k = 3; k <= 6; ++k) {
8345 592 : j(k) = 0.0;
8346 2960 : for (m = 3; m <= 6; ++m) {
8347 2368 : j(k) += Xinv(m - 2, k - 2) * Q(m);
8348 : }
8349 : }
8350 :
8351 : // Irradiances
8352 :
8353 1036 : for (k = 1; k <= 6; ++k) {
8354 888 : G(k) = 0.0;
8355 6216 : for (m = 1; m <= 6; ++m) {
8356 : // G(k)=G(k)+F(k,m)*J(m)
8357 5328 : G(k) += j(m) * F(k, m);
8358 : }
8359 : }
8360 :
8361 : // Slat edge correction factor
8362 148 : phib = b_el;
8363 148 : delphis = DataGlobalConstants::PiOvr2 / 10.0;
8364 444 : for (IUpDown = 1; IUpDown <= 2; ++IUpDown) {
8365 3256 : for (Iphis = 1; Iphis <= 10; ++Iphis) {
8366 2960 : phis = -(Iphis - 0.5) * delphis;
8367 2960 : if (IUpDown == 2) phis = (Iphis - 0.5) * delphis;
8368 2960 : fEdgeSource(Iphis) = 0.0;
8369 2960 : fEdge1 = 0.0;
8370 2960 : gamma = phib - phis;
8371 2960 : if (std::abs(std::sin(gamma)) > 0.01) {
8372 2936 : if ((phib > 0.0 && phib <= DataGlobalConstants::PiOvr2 && phis <= phib) ||
8373 1108 : (phib > DataGlobalConstants::PiOvr2 && phib <= DataGlobalConstants::Pi && phis > -(DataGlobalConstants::Pi - phib))) {
8374 4236 : fEdge1 = state.dataHeatBal->Blind(BlindNum).SlatThickness * std::abs(std::sin(gamma)) /
8375 4236 : ((state.dataHeatBal->Blind(BlindNum).SlatSeparation +
8376 4236 : state.dataHeatBal->Blind(BlindNum).SlatThickness / std::abs(std::sin(phib))) *
8377 2118 : std::cos(phis));
8378 : }
8379 2936 : fEdgeSource(Iphis) = min(1.0, std::abs(fEdge1));
8380 : }
8381 : }
8382 296 : fEdgeA(IUpDown) = DiffuseAverage(fEdgeSource);
8383 : }
8384 148 : fEdge = 0.5 * (fEdgeA(1) + fEdgeA(2));
8385 :
8386 : // Front diffuse-diffuse transmittance (transmittance of slat edge assumed zero)
8387 148 : p(9) = G(2) * (1.0 - fEdge);
8388 :
8389 : // Front diffuse-diffuse reflectance (edge of slat is assumed to have same diffuse
8390 : // reflectance as front side of slat, c(11))
8391 148 : p(10) = G(1) * (1.0 - fEdge) + fEdge * c(11);
8392 :
8393 : //-----------Calculate diffuse short-wave properties for the back side of the blind
8394 :
8395 : // Sources
8396 :
8397 148 : Q(3) = c(12) * F(3, 2) + c(10) * F(4, 2);
8398 148 : Q(4) = c(10) * F(3, 2) + c(11) * F(4, 2);
8399 148 : Q(5) = c(12) * F(5, 2) + c(10) * F(6, 2);
8400 148 : Q(6) = c(10) * F(5, 2) + c(11) * F(6, 2);
8401 :
8402 : // Radiosities
8403 :
8404 148 : j(1) = 0.0;
8405 148 : j(2) = 1.0;
8406 740 : for (k = 3; k <= 6; ++k) {
8407 592 : j(k) = 0.0;
8408 2960 : for (m = 3; m <= 6; ++m) {
8409 2368 : j(k) += Xinv(m - 2, k - 2) * Q(m);
8410 : }
8411 : }
8412 :
8413 : // Irradiances
8414 :
8415 1036 : for (k = 1; k <= 6; ++k) {
8416 888 : G(k) = 0.0;
8417 6216 : for (m = 1; m <= 6; ++m) {
8418 : // G(k)=G(k)+F(k,m)*J(m)
8419 5328 : G(k) += j(m) * F(k, m);
8420 : }
8421 : }
8422 :
8423 : // Back diffuse-diffuse transmittance
8424 148 : p(11) = G(1) * (1.0 - fEdge);
8425 :
8426 : // Back hemi-hemi reflectance
8427 148 : p(12) = G(2) * (1.0 - fEdge) + fEdge * c(11);
8428 :
8429 148 : if (ISolVis == 1) {
8430 :
8431 : //-----------Calculate IR properties of the blind
8432 : // (use same set of view factors as for diffuse short-wave properties)
8433 :
8434 : // Front and back slat IR reflectances
8435 74 : ri = 1 - c(13) - c(14);
8436 74 : rib = 1 - c(13) - c(15);
8437 :
8438 : // Set up exchange matrix X for diffuse properties
8439 :
8440 222 : for (k = 3; k <= 5; k += 2) {
8441 740 : for (m = 3; m <= 6; ++m) {
8442 592 : X(m - 2, k - 2) = -rib * F(k, m) - c(13) * F(k + 1, m);
8443 592 : X(m - 2, k - 1) = -c(13) * F(k, m) - ri * F(k + 1, m);
8444 : }
8445 : }
8446 :
8447 370 : for (k = 1; k <= 4; ++k) {
8448 296 : ++X(k, k);
8449 : }
8450 :
8451 74 : indx = 0;
8452 74 : InvertMatrix(state, X, Xinv, indx, 4, 4); // Autodesk:Note X modified by this call
8453 :
8454 : //---------Calculate diffuse IR properties for the FRONT side of the blind
8455 :
8456 : // Sources
8457 :
8458 74 : Q(3) = rib * F(3, 1) + c(13) * F(4, 1);
8459 74 : Q(4) = c(13) * F(3, 1) + ri * F(4, 1);
8460 74 : Q(5) = rib * F(5, 1) + c(13) * F(6, 1);
8461 74 : Q(6) = c(13) * F(5, 1) + ri * F(6, 1);
8462 :
8463 : // Radiosities
8464 :
8465 74 : j(1) = 1.0;
8466 74 : j(2) = 0.0;
8467 370 : for (k = 3; k <= 6; ++k) {
8468 296 : j(k) = 0.0;
8469 1480 : for (m = 3; m <= 6; ++m) {
8470 1184 : j(k) += Xinv(m - 2, k - 2) * Q(m);
8471 : }
8472 : }
8473 :
8474 : // Irradiances
8475 518 : for (k = 1; k <= 6; ++k) {
8476 444 : G(k) = 0.0;
8477 3108 : for (m = 1; m <= 6; ++m) {
8478 : // G(k)=G(k)+F(k,m)*J(m)
8479 2664 : G(k) += j(m) * F(k, m);
8480 : }
8481 : }
8482 :
8483 : // Front diffuse-diffuse IR transmittance (transmittance of slat edge assumed zero)
8484 74 : p(13) = G(2) * (1.0 - fEdge);
8485 :
8486 : // Front diffuse-diffuse IR reflectance (edge of slat is assumed to have same IR
8487 : // reflectance as front side of slat, ri)
8488 74 : BlindIRreflFront = G(1) * (1.0 - fEdge) + fEdge * ri;
8489 :
8490 : // Front IR emissivity
8491 74 : p(14) = max(0.0001, 1.0 - p(13) - BlindIRreflFront);
8492 :
8493 : //-----------Calculate diffuse IR properties for the BACK side of the blind
8494 :
8495 : // Sources
8496 :
8497 74 : Q(3) = rib * F(3, 2) + c(13) * F(4, 2);
8498 74 : Q(4) = c(13) * F(3, 2) + ri * F(4, 2);
8499 74 : Q(5) = rib * F(5, 2) + c(13) * F(6, 2);
8500 74 : Q(6) = c(13) * F(5, 2) + ri * F(6, 2);
8501 :
8502 : // Radiosities
8503 :
8504 74 : j(1) = 0.0;
8505 74 : j(2) = 1.0;
8506 370 : for (k = 3; k <= 6; ++k) {
8507 296 : j(k) = 0.0;
8508 1480 : for (m = 3; m <= 6; ++m) {
8509 1184 : j(k) += Xinv(m - 2, k - 2) * Q(m);
8510 : }
8511 : }
8512 :
8513 : // Irradiances
8514 :
8515 518 : for (k = 1; k <= 6; ++k) {
8516 444 : G(k) = 0.0;
8517 3108 : for (m = 1; m <= 6; ++m) {
8518 : // G(k)=G(k)+F(k,m)*J(m)
8519 2664 : G(k) += j(m) * F(k, m);
8520 : }
8521 : }
8522 :
8523 : // Back diffuse-diffuse IR reflectance
8524 74 : BlindIRreflBack = G(2) * (1.0 - fEdge) + fEdge * ri;
8525 :
8526 : // Back IR emissivity
8527 74 : p(15) = max(0.0001, 1.0 - p(13) - BlindIRreflBack);
8528 :
8529 : } // End of IR properties calculation
8530 148 : }
8531 :
8532 : //**********************************************************************************************
8533 :
8534 5476 : void BlindOpticsBeam(EnergyPlusData &state,
8535 : int const BlindNum, // Blind number
8536 : Array1A<Real64> const c, // Slat properties (equivalent to BLD_PR)
8537 : Real64 const b_el, // Slat elevation (radians)
8538 : Real64 const s_el, // Solar profile angle (radians)
8539 : Array1A<Real64> p // Blind properties (equivalent to ST_LAY)
8540 : )
8541 : {
8542 :
8543 : // SUBROUTINE INFORMATION:
8544 : // AUTHOR Hans Simmler
8545 : // DATE WRITTEN July-Aug 1995
8546 : // MODIFIED Aug 2001 (FCW): adapt to EnergyPlus
8547 : // Aug 2002 (FCW): make corrections so that calculations are consistent with
8548 : // G(i) = Sum over j of J(j)*F(j,i). Previously, i,j was
8549 : // interchanged in F, so that
8550 : // G(i) = Sum over j of J(j)*F(i,j), which is wrong.
8551 : // This change was made to resolve discrepancies between EnergyPlus results
8552 : // and blind transmittance measurements made at Oklahoma State Univ.
8553 : // RE-ENGINEERED na
8554 :
8555 : // PURPOSE OF THIS SUBROUTINE:
8556 : // Calculates the beam radiation properties of a
8557 : // window blind consisting of flat slats with known material properties.
8558 : // The calculation for the reverse direction is done with the radiation source
8559 : // reflected at the window plane.
8560 :
8561 : // REFERENCES:
8562 : // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
8563 : // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
8564 :
8565 : using General::BlindBeamBeamTrans; // Blind beam-to-beam transmittance function
8566 :
8567 : // Argument array dimensioning
8568 5476 : c.dim(15);
8569 5476 : p.dim(16);
8570 :
8571 : // The slat input properties are:
8572 : // c(1) 0. (unused)
8573 : // c(2) Slat width (m)
8574 : // c(3) Slat separation (m)
8575 : // c(4) 0. (unused)
8576 : // c(5) 0. (unused)
8577 : // c(6) 0. (unused)
8578 : // The following are solar or visible properties
8579 : // c(7) trans beam-diff
8580 : // c(8) refl front beam-diff
8581 : // c(9) refl back beam-diff
8582 : // c(10) trans diff-diff
8583 : // c(11) refl front diff-diff
8584 : // c(12) refl back diff-diff
8585 : // The following are hemispherical thermal IR properties
8586 : // c(13) trans diff-diff
8587 : // c(14) emiss front diff
8588 : // c(15) emiss back diff
8589 :
8590 : // The calculated blind properties are:
8591 : // The following are solar or visible properties
8592 : // p(1) trans front beam-beam
8593 : // p(2) refl front beam-beam
8594 : // p(3) trans back beam-beam
8595 : // p(4) refl back beam-beam
8596 : // p(5) trans front beam-diff
8597 : // p(6) refl front beam-diff
8598 : // p(7) trans back beam-diff
8599 : // p(8) refl back beam-diff
8600 : // p(9) trans front diff-diff
8601 : // p(10) refl front diff-diff
8602 : // p(11) trans back diff-diff
8603 : // p(12) refl back diff-diff
8604 : // The following are IR properties
8605 : // p(13) IR trans front (same as IR trans back)
8606 : // p(14) IR emissivity front
8607 : // p(15) IR emissivity back
8608 : // p(16) 0.0 (unused)
8609 :
8610 : Real64 phib; // Elevation angle of normal vector to front of slat (0 to pi radians)
8611 : Real64 phis; // Elevation angle of source vector; same as "profile angle" (-pi/2 to pi/2 radians)
8612 : Real64 gamma; // phib - phis (radians)
8613 10952 : Array1D<Real64> j(6); // Slat surface section radiosity vector
8614 10952 : Array1D<Real64> G(6); // Slat surface section irradiance vector
8615 10952 : Array1D<Real64> Q(6); // Slat surface section source vector
8616 10952 : Array2D<Real64> F(6, 6); // View factor array
8617 10952 : Array2D<Real64> X(4, 4); // X*J = Q
8618 10952 : Array2D<Real64> Xinv(4, 4); // J = Xinv*Q
8619 : Real64 fEdge; // Slat edge correction factor
8620 : Real64 fEdge1;
8621 : int i; // Array indices
8622 : int k;
8623 : int m;
8624 10952 : Array1D_int indx(4); // Indices for LU decomposition
8625 :
8626 5476 : p = 0.0;
8627 :
8628 : // Elevation of radiation source; source is assumed to be in a plane that
8629 : // (1) contains the slat outward normal and (2) is perpendicular to plane of the blinds.
8630 5476 : phis = s_el;
8631 :
8632 : // Elevation of slat outward normal
8633 5476 : phib = b_el;
8634 :
8635 : // Loop twice for front and back side properties of blind
8636 16428 : for (i = 0; i <= 2; i += 2) {
8637 :
8638 : // For back-side properties, reflect the source position so that it is the mirror
8639 : // image of the original source position, where the "mirror" is in the plane of the
8640 : // blinds. This is equivalent to keeping the original source position but rotating
8641 : // the slats so that the original slat angle (e.g., 45 deg) becomes 180 - original slat
8642 : // angle (135 deg).
8643 :
8644 10952 : if (i == 2) {
8645 5476 : phib = DataGlobalConstants::Pi - phib;
8646 : }
8647 :
8648 : // Correction factor that accounts for finite thickness of slats. It is used to modify the
8649 : // blind transmittance and reflectance to account for reflection and absorption by the
8650 : // edge of the slat. fEdge is ratio of area subtended by edge of slat
8651 : // to area between tops of adjacent slats.
8652 :
8653 10952 : fEdge = 0.0;
8654 10952 : fEdge1 = 0.0;
8655 10952 : gamma = phib - phis;
8656 10952 : if (std::abs(std::sin(gamma)) > 0.01) {
8657 10644 : if ((phib > 0.0 && phib <= DataGlobalConstants::PiOvr2 && phis <= phib) ||
8658 5112 : (phib > DataGlobalConstants::PiOvr2 && phib <= DataGlobalConstants::Pi && phis > -(DataGlobalConstants::Pi - phib))) {
8659 15312 : fEdge1 = state.dataHeatBal->Blind(BlindNum).SlatThickness * std::abs(std::sin(gamma)) /
8660 15312 : ((state.dataHeatBal->Blind(BlindNum).SlatSeparation +
8661 15312 : state.dataHeatBal->Blind(BlindNum).SlatThickness / std::abs(std::sin(phib))) *
8662 7656 : std::cos(phis));
8663 : }
8664 10644 : fEdge = min(1.0, std::abs(fEdge1));
8665 : }
8666 :
8667 : // Direct-to-direct transmittance (portion of beam that passes between slats without
8668 : // without touching them
8669 :
8670 32856 : p(1 + i) = BlindBeamBeamTrans(phis,
8671 : phib,
8672 10952 : state.dataHeatBal->Blind(BlindNum).SlatWidth,
8673 10952 : state.dataHeatBal->Blind(BlindNum).SlatSeparation,
8674 10952 : state.dataHeatBal->Blind(BlindNum).SlatThickness);
8675 : // Direct-to-direct reflectance; this is zero for now since all reflection is assumed to be diffuse.
8676 10952 : p(2 + i) = 0.0;
8677 :
8678 : // View factors between slat sections for calculating direct-to-diffuse transmittance and reflectance
8679 10952 : ViewFac(c(2), c(3), phib, phis, F);
8680 :
8681 : // Set up exchange matrix X for calculating direct-to-diffuse properties
8682 :
8683 32856 : for (k = 3; k <= 5; k += 2) {
8684 109520 : for (m = 3; m <= 6; ++m) {
8685 87616 : X(m - 2, k - 2) = -c(12) * F(k, m) - c(10) * F(k + 1, m);
8686 87616 : X(m - 2, k - 1) = -c(10) * F(k, m) - c(11) * F(k + 1, m);
8687 : }
8688 : }
8689 :
8690 54760 : for (k = 1; k <= 4; ++k) {
8691 43808 : ++X(k, k);
8692 : }
8693 :
8694 10952 : indx = 0;
8695 : // In the following, note that InvertMatrix changes X
8696 10952 : InvertMatrix(state, X, Xinv, indx, 4, 4);
8697 :
8698 : // Set up sources for direct-diffuse slat properties
8699 10952 : if (std::abs(phis - phib) <= DataGlobalConstants::PiOvr2) { // Beam hits front of slat
8700 5600 : Q(3) = c(4) + c(7); // beam-beam trans of slat + beam-diff trans of slat
8701 5600 : Q(4) = c(5) + c(8); // front beam-beam refl of slat + front beam-diff refl of slat
8702 : } else { // Beam hits back of slat
8703 5352 : Q(3) = c(6) + c(9); // back beam-beam refl of slat + back beam-diff refl of slat
8704 5352 : Q(4) = c(4) + c(7); // beam-beam trans of slat + beam-diff trans of slat
8705 : }
8706 :
8707 : // Correct for fraction of beam that is not directly transmitted; 1 - this fraction is
8708 : // the fraction of the incoming beam that is incident on the front or back surfaces of the slats.
8709 10952 : Q(3) *= (1.0 - p(1 + i));
8710 10952 : Q(4) *= (1.0 - p(1 + i));
8711 :
8712 : // Radiosities (radiance of slat sections)
8713 10952 : j(1) = 0.0;
8714 10952 : j(2) = 0.0;
8715 54760 : for (k = 3; k <= 6; ++k) {
8716 43808 : j(k) = 0.0;
8717 131424 : for (m = 3; m <= 4; ++m) {
8718 87616 : j(k) += Xinv(m - 2, k - 2) * Q(m);
8719 : }
8720 : }
8721 :
8722 : // Irradiance on slat sections
8723 76664 : for (k = 1; k <= 6; ++k) {
8724 65712 : G(k) = 0.0;
8725 328560 : for (m = 3; m <= 6; ++m) {
8726 262848 : G(k) += j(m) * F(k, m);
8727 : }
8728 : }
8729 :
8730 : // Direct-to-diffuse transmittance
8731 10952 : p(5 + i) = G(2) * (1.0 - fEdge);
8732 :
8733 : // Direct-to-diffuse reflectance (assuming the edge reflectance is the same as the
8734 : // reflectance of the front side of the slat, C(8))
8735 10952 : p(6 + i) = G(1) * (1.0 - fEdge) + fEdge * c(8);
8736 :
8737 : } // End of loop over front and back side properties of blind
8738 5476 : }
8739 :
8740 : //********************************************************************************************
8741 :
8742 11100 : void ViewFac(Real64 const s, // Slat width (m)
8743 : Real64 const h, // Distance between faces of adjacent slats (m)
8744 : Real64 const phib, // Elevation angle of normal to slat (radians)
8745 : Real64 const phis, // Profile angle of radiation source (radians)
8746 : Array2A<Real64> F // View factor array
8747 : )
8748 : {
8749 :
8750 : // SUBROUTINE INFORMATION:
8751 : // AUTHOR Hans Simmler
8752 : // DATE WRITTEN July-Aug 1995
8753 : // MODIFIED Aug 2001 (FCW): adapt to EnergyPlus
8754 : // Apr 2002 (FCW): prevent sqrt of small negative argument
8755 : // RE-ENGINEERED na
8756 :
8757 : // PURPOSE OF THIS SUBROUTINE:
8758 : // Calculates the view factors between sections of adjacent slats,
8759 : // where each slat is divided longitudinally into two equal sections whose
8760 : // dimensions depend on source profile angle and slat geometry. The view
8761 : // factors are used in BlindOpticsBeam and BlindOpticsDiffuse to determine blind
8762 : // transmittance and reflectance for short-wave and long-wave radiation.
8763 :
8764 : // METHODOLOGY EMPLOYED:
8765 : // Uses expressions for view factor between flat strips with a common edge
8766 : // and flat strips displaced from one another. See engineering documentation.
8767 :
8768 : // REFERENCES:
8769 : // "Solar-Thermal Window Blind Model for DOE-2," H. Simmler, U. Fischer and
8770 : // F. Winkelmann, Lawrence Berkeley National Laboratory, Jan. 1996.
8771 :
8772 : // Argument array dimensioning
8773 11100 : F.dim(6, 6);
8774 :
8775 22200 : Array1D<Real64> L(6); // Length of slat sections: L1 = L2 = h; L3, L5 = length
8776 : Real64 L3;
8777 : Real64 L5;
8778 : // of upper slat sections; L4, L6 = length of lower slat
8779 : // slat sections (m)
8780 : Real64 d1; // Slat geometry variables (m)
8781 : Real64 d2;
8782 : Real64 d3;
8783 : Real64 d4;
8784 : Real64 d5;
8785 : Real64 d6;
8786 : Real64 h2; // h**2
8787 : Real64 ht; // 2*h
8788 : Real64 w; // Slat geometry variable (m)
8789 : Real64 a; // Intermediate variable (m)
8790 : Real64 co; // Cosine of source profile angle
8791 : int i; // View factor array indices
8792 : int j;
8793 :
8794 11100 : h2 = pow_2(h);
8795 11100 : ht = 2.0 * h;
8796 11100 : co = std::cos(phis);
8797 11100 : if (std::abs(co) < 0.001) co = 0.0;
8798 11100 : w = ht;
8799 11100 : if (co != 0.0) w = s * std::cos(phib - phis) / co;
8800 11100 : L3 = s * h / std::abs(w);
8801 11100 : if (L3 > s) L3 = s;
8802 11100 : L5 = s - L3;
8803 11100 : a = ht * std::cos(phib);
8804 : // MAX(0.,...) in the following prevents small negative argument for sqrt
8805 11100 : d1 = std::sqrt(max(0.0, s * s + h2 + a * s));
8806 11100 : d2 = std::sqrt(max(0.0, s * s + h2 - a * s));
8807 11100 : d3 = std::sqrt(max(0.0, L3 * L3 + h2 + a * L3));
8808 11100 : d4 = std::sqrt(max(0.0, L3 * L3 + h2 - a * L3));
8809 11100 : d5 = std::sqrt(max(0.0, L5 * L5 + h2 - a * L5));
8810 11100 : d6 = std::sqrt(max(0.0, L5 * L5 + h2 + a * L5));
8811 77700 : for (i = 1; i <= 6; ++i) {
8812 66600 : F(i, i) = 0.0;
8813 : }
8814 11100 : F(1, 1) = 0.0;
8815 11100 : F(2, 1) = (d1 + d2 - 2.0 * s) / ht;
8816 11100 : F(3, 1) = (h + L3 - d3) / ht;
8817 11100 : F(4, 1) = (h + L3 - d4) / ht;
8818 11100 : F(5, 1) = (L5 + d3 - d1) / ht;
8819 11100 : F(6, 1) = (L5 + d4 - d2) / ht;
8820 11100 : F(3, 2) = (L3 + d5 - d2) / ht;
8821 11100 : F(4, 2) = (L3 + d6 - d1) / ht;
8822 11100 : F(5, 2) = (h + L5 - d5) / ht;
8823 11100 : F(6, 2) = (h + L5 - d6) / ht;
8824 11100 : F(4, 3) = (d3 + d4 - ht) / (2.0 * L3);
8825 11100 : F(5, 3) = 0.0;
8826 11100 : F(6, 3) = (d2 + h - d4 - d5) / (2.0 * L3);
8827 11100 : F(5, 4) = (d1 + h - d3 - d6) / (2.0 * L3);
8828 11100 : F(6, 4) = 0.0;
8829 11100 : F(6, 5) = 0.0;
8830 11100 : if (L5 > 0.0) F(6, 5) = (d5 + d6 - ht) / (2.0 * L5);
8831 11100 : L(1) = h;
8832 11100 : L(2) = h;
8833 11100 : L(3) = L3;
8834 11100 : L(4) = L3;
8835 11100 : L(5) = L5;
8836 11100 : L(6) = L5;
8837 66600 : for (i = 2; i <= 6; ++i) {
8838 222000 : for (j = 1; j <= i - 1; ++j) {
8839 166500 : F(j, i) = 0.0;
8840 166500 : if (L(i) > 0.0) F(j, i) = F(i, j) * L(j) / L(i);
8841 : }
8842 : }
8843 11100 : }
8844 :
8845 : //*****************************************************************************************
8846 :
8847 11174 : void InvertMatrix(EnergyPlusData &state,
8848 : Array2A<Real64> a, // Matrix to be inverted
8849 : Array2A<Real64> y, // Inverse of matrix a
8850 : Array1A_int indx, // Index vector for LU decomposition
8851 : int const np, // Dimension of matrix
8852 : int const n)
8853 : {
8854 :
8855 : // SUBROUTINE INFORMATION:
8856 : // AUTHOR Hans Simmler
8857 : // DATE WRITTEN July-Aug 1995
8858 : // MODIFIED Aug 2001 (FCW): adapt to EnergyPlus
8859 : // RE-ENGINEERED na
8860 :
8861 : // PURPOSE OF THIS SUBROUTINE:
8862 : // Inverts a matrix.
8863 :
8864 : // METHODOLOGY EMPLOYED:
8865 : // Uses LU decomposition.
8866 :
8867 : // Argument array dimensioning
8868 11174 : a.dim(np, np);
8869 11174 : y.dim(np, np);
8870 11174 : indx.dim(np);
8871 :
8872 : int i; // Array indices
8873 : int j;
8874 : int d;
8875 :
8876 11174 : y = 0.0;
8877 55870 : for (i = 1; i <= n; ++i) {
8878 44696 : y(i, i) = 1.0;
8879 : }
8880 11174 : indx = 0;
8881 :
8882 11174 : LUDCMP(state, a, n, np, indx, d);
8883 :
8884 55870 : for (j = 1; j <= n; ++j) {
8885 44696 : LUBKSB(a, n, np, indx, y(j, 1));
8886 : }
8887 11174 : }
8888 :
8889 : //*****************************************************************************************
8890 :
8891 11174 : void LUDCMP(EnergyPlusData &state,
8892 : Array2A<Real64> A, // matrix
8893 : int const N,
8894 : int const NP,
8895 : Array1A_int INDX,
8896 : int &D)
8897 : {
8898 :
8899 : // SUBROUTINE INFORMATION:
8900 : // AUTHOR Fred Winkelmann?
8901 : // DATE WRITTEN <date_written>
8902 : // MODIFIED na
8903 : // RE-ENGINEERED na
8904 :
8905 : // PURPOSE OF THIS SUBROUTINE:
8906 : // This subroutine performs a LU decompostion of given matrix.
8907 :
8908 : // Argument array dimensioning
8909 11174 : A.dim(NP, NP);
8910 11174 : INDX.dim(N);
8911 :
8912 22348 : Array1D<Real64> VV(100);
8913 : Real64 sum;
8914 : Real64 aamax;
8915 : Real64 dum;
8916 : int i;
8917 : int j;
8918 : int K;
8919 : int imax;
8920 :
8921 11174 : D = 1;
8922 55870 : for (i = 1; i <= N; ++i) {
8923 44696 : aamax = 0.0;
8924 223480 : for (j = 1; j <= N; ++j) {
8925 178784 : if (std::abs(A(j, i)) > aamax) aamax = std::abs(A(j, i));
8926 : }
8927 :
8928 44696 : if (aamax == 0.0) {
8929 0 : ShowFatalError(state, "Singular matrix in LUDCMP, window calculations");
8930 : }
8931 44696 : VV(i) = 1.0 / aamax; // Was commented out prior to 10/5/01, which caused overflows
8932 : // in this routine in rare cases
8933 : }
8934 :
8935 55870 : for (j = 1; j <= N; ++j) {
8936 44696 : if (j > 1) {
8937 100566 : for (i = 1; i <= j - 1; ++i) {
8938 67044 : sum = A(j, i);
8939 67044 : if (i > 1) {
8940 78218 : for (K = 1; K <= i - 1; ++K) {
8941 44696 : sum -= A(K, i) * A(j, K);
8942 : }
8943 :
8944 33522 : A(j, i) = sum;
8945 : }
8946 : }
8947 : }
8948 44696 : aamax = 0.0;
8949 156436 : for (i = j; i <= N; ++i) {
8950 111740 : sum = A(j, i);
8951 111740 : if (j > 1) {
8952 178784 : for (K = 1; K <= j - 1; ++K) {
8953 111740 : sum -= A(K, i) * A(j, K);
8954 : }
8955 67044 : A(j, i) = sum;
8956 : }
8957 :
8958 111740 : dum = VV(i) * std::abs(sum);
8959 111740 : if (dum >= aamax) {
8960 44696 : imax = i;
8961 44696 : aamax = dum;
8962 : }
8963 : }
8964 :
8965 44696 : if (j != imax) {
8966 0 : for (K = 1; K <= N; ++K) {
8967 0 : dum = A(K, imax);
8968 0 : A(K, imax) = A(K, j);
8969 0 : A(K, j) = dum;
8970 : }
8971 :
8972 0 : D = -D;
8973 0 : VV(imax) = VV(j);
8974 : }
8975 :
8976 44696 : INDX(j) = imax;
8977 44696 : if (j != N) {
8978 33522 : if (A(j, j) == 0.0) A(j, j) = DataGlobalConstants::rTinyValue;
8979 :
8980 33522 : dum = 1.0 / A(j, j);
8981 100566 : for (i = j + 1; i <= N; ++i) {
8982 67044 : A(j, i) *= dum;
8983 : }
8984 : }
8985 : }
8986 :
8987 11174 : if (A(N, N) == 0.0) A(N, N) = DataGlobalConstants::rTinyValue;
8988 11174 : }
8989 :
8990 : //*****************************************************************************************
8991 :
8992 44696 : void LUBKSB(Array2A<Real64> A, int const N, int const NP, Array1A_int INDX, Array1A<Real64> B)
8993 : {
8994 :
8995 : // SUBROUTINE INFORMATION:
8996 : // AUTHOR <author>
8997 : // DATE WRITTEN <date_written>
8998 : // MODIFIED na
8999 : // RE-ENGINEERED na
9000 :
9001 : // PURPOSE OF THIS SUBROUTINE:
9002 : // This subroutine performs back substitution of a LU matrix.
9003 :
9004 : // Argument array dimensioning
9005 44696 : A.dim(NP, NP);
9006 44696 : INDX.dim(N);
9007 44696 : B.dim(N);
9008 :
9009 : int j;
9010 : int i;
9011 : int ii;
9012 : int LL;
9013 : Real64 sum;
9014 :
9015 44696 : ii = 0;
9016 :
9017 223480 : for (i = 1; i <= N; ++i) {
9018 178784 : LL = INDX(i);
9019 178784 : sum = B(LL);
9020 178784 : B(LL) = B(i);
9021 178784 : if (ii != 0) {
9022 178784 : for (j = ii; j <= i - 1; ++j) {
9023 111740 : sum -= A(j, i) * B(j);
9024 : }
9025 111740 : } else if (sum != 0.0) {
9026 44696 : ii = i;
9027 : }
9028 :
9029 178784 : B(i) = sum;
9030 : }
9031 :
9032 223480 : for (i = N; i >= 1; --i) {
9033 178784 : sum = B(i);
9034 178784 : if (i < N) {
9035 402264 : for (j = i + 1; j <= N; ++j) {
9036 268176 : sum -= A(j, i) * B(j);
9037 : }
9038 : }
9039 :
9040 178784 : B(i) = sum / A(i, i);
9041 : }
9042 44696 : }
9043 :
9044 : // added for custom solar or visible spectrum
9045 :
9046 771 : void CheckAndReadCustomSprectrumData(EnergyPlusData &state)
9047 : {
9048 :
9049 : // SUBROUTINE INFORMATION:
9050 : // AUTHOR T. Hong
9051 : // DATE WRITTEN August 2013
9052 : // MODIFIED
9053 : // RE-ENGINEERED na
9054 :
9055 : // PURPOSE OF THIS SUBROUTINE:
9056 : // Check, read, and assign the custom solar or visible spectrum to:
9057 : // solar: nume, wle(nume), e(nume). nume = 107
9058 : // visible: numt3, wlt3(numt3), y30(numt3). numt3 = 81
9059 : // Three related IDD objects:
9060 : // EnergyManagementSystem:ConstructionIndexVariable
9061 : // Site:SolarAndVisibleSpectrum, Site:SpectrumData
9062 :
9063 : // METHODOLOGY EMPLOYED:
9064 : // Overwriting the default values
9065 :
9066 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9067 771 : bool ErrorsFound(false); // If errors detected in input
9068 : int NumAlphas; // Number of Alphas for each GetobjectItem call
9069 : int NumNumbers; // Number of Numbers for each GetobjectItem call
9070 : int NumArgs;
9071 : int IOStatus;
9072 772 : Array1D_string cAlphaArgs; // Alpha input items for object
9073 772 : Array1D<Real64> rNumericArgs; // Numeric input items for object
9074 :
9075 772 : std::string cCurrentModuleObject;
9076 772 : std::string cSolarSpectrum;
9077 772 : std::string cVisibleSpectrum;
9078 771 : int iSolarSpectrum(0);
9079 771 : int iVisibleSpectrum(0);
9080 771 : int NumSiteSpectrum(0);
9081 : int Loop;
9082 : int iTmp;
9083 :
9084 771 : if (state.dataWindowManager->RunMeOnceFlag) return;
9085 :
9086 : // Step 1 - check whether there is custom solar or visible spectrum
9087 771 : cCurrentModuleObject = "Site:SolarAndVisibleSpectrum";
9088 771 : NumSiteSpectrum = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
9089 :
9090 : // no custom spectrum data, done!
9091 771 : if (NumSiteSpectrum == 0) {
9092 770 : state.dataWindowManager->RunMeOnceFlag = true;
9093 770 : return;
9094 : }
9095 :
9096 : // read custom spectrum data from Site:SolarAndVisibleSpectrum
9097 1 : if (NumSiteSpectrum > 1) { // throw error
9098 0 : ShowSevereError(state, "Only one " + cCurrentModuleObject + " object is allowed");
9099 0 : ErrorsFound = true;
9100 : }
9101 :
9102 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
9103 1 : cAlphaArgs.allocate(NumAlphas);
9104 1 : rNumericArgs.dimension(NumNumbers, 0.0);
9105 :
9106 1 : if (NumSiteSpectrum == 1) {
9107 3 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
9108 : cCurrentModuleObject,
9109 : 1,
9110 1 : state.dataIPShortCut->cAlphaArgs,
9111 : NumAlphas,
9112 1 : state.dataIPShortCut->rNumericArgs,
9113 : NumNumbers,
9114 : IOStatus);
9115 :
9116 : // use default spectrum data, done!
9117 1 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(2), "Default")) {
9118 0 : state.dataWindowManager->RunMeOnceFlag = true;
9119 0 : return;
9120 : }
9121 :
9122 : // now read custom solar and visible spectrum data
9123 1 : cSolarSpectrum = state.dataIPShortCut->cAlphaArgs(3);
9124 1 : cVisibleSpectrum = state.dataIPShortCut->cAlphaArgs(4);
9125 :
9126 1 : cCurrentModuleObject = "Site:SpectrumData";
9127 1 : NumSiteSpectrum = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
9128 1 : if (NumSiteSpectrum == 0) { // throw error
9129 0 : ShowSevereError(state, "No " + cCurrentModuleObject + " object is found");
9130 0 : ErrorsFound = true;
9131 : }
9132 :
9133 1 : cAlphaArgs.deallocate();
9134 1 : rNumericArgs.deallocate();
9135 :
9136 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
9137 1 : cAlphaArgs.allocate(NumAlphas);
9138 1 : rNumericArgs.dimension(NumNumbers, 0.0);
9139 :
9140 1 : iSolarSpectrum = 0;
9141 1 : iVisibleSpectrum = 0;
9142 2 : for (Loop = 1; Loop <= NumSiteSpectrum; ++Loop) {
9143 : // Step 2 - read user-defined spectrum data
9144 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
9145 : cCurrentModuleObject,
9146 : Loop,
9147 2 : state.dataIPShortCut->cAlphaArgs,
9148 : NumAlphas,
9149 2 : state.dataIPShortCut->rNumericArgs,
9150 : NumNumbers,
9151 : IOStatus);
9152 2 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(1), cSolarSpectrum)) {
9153 1 : iSolarSpectrum = Loop;
9154 : // overwrite the default solar spectrum
9155 1 : if (NumNumbers > 2 * state.dataWindowManager->nume) {
9156 0 : ShowSevereError(state,
9157 0 : "Solar spectrum data pair is more than 107 - " + cCurrentModuleObject + " - " +
9158 0 : state.dataIPShortCut->cAlphaArgs(1));
9159 0 : ErrorsFound = true;
9160 : } else {
9161 : // Step 3 - overwrite default solar spectrum data
9162 108 : for (iTmp = 1; iTmp <= state.dataWindowManager->nume; ++iTmp) {
9163 107 : if (iTmp <= NumNumbers / 2) {
9164 107 : state.dataWindowManager->wle[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp - 1);
9165 107 : state.dataWindowManager->e[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp);
9166 : } else {
9167 0 : state.dataWindowManager->wle[iTmp - 1] = 0.0;
9168 0 : state.dataWindowManager->e[iTmp - 1] = 0.0;
9169 : }
9170 : }
9171 : }
9172 : }
9173 2 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(1), cVisibleSpectrum)) {
9174 1 : iVisibleSpectrum = Loop;
9175 : // overwrite the default solar spectrum
9176 1 : if (NumNumbers > 2 * state.dataWindowManager->numt3) {
9177 0 : ShowSevereError(state,
9178 0 : "Visible spectrum data pair is more than 81 - " + cCurrentModuleObject + " - " +
9179 0 : state.dataIPShortCut->cAlphaArgs(1));
9180 0 : ErrorsFound = true;
9181 : } else {
9182 : // Step 3 - overwrite default visible spectrum data
9183 82 : for (iTmp = 1; iTmp <= state.dataWindowManager->numt3; ++iTmp) {
9184 81 : if (iTmp <= NumNumbers / 2) {
9185 81 : state.dataWindowManager->wlt3[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp - 1);
9186 81 : state.dataWindowManager->y30[iTmp - 1] = state.dataIPShortCut->rNumericArgs(2 * iTmp);
9187 : } else {
9188 0 : state.dataWindowManager->wlt3[iTmp - 1] = 0.0;
9189 0 : state.dataWindowManager->y30[iTmp - 1] = 0.0;
9190 : }
9191 : }
9192 : }
9193 : }
9194 2 : if ((iSolarSpectrum > 0) && (iVisibleSpectrum > 0)) break;
9195 : }
9196 : }
9197 :
9198 1 : cAlphaArgs.deallocate();
9199 1 : rNumericArgs.deallocate();
9200 :
9201 1 : if (ErrorsFound) {
9202 0 : ShowFatalError(state, "Errors found in processing input for user-defined solar/visible spectrum");
9203 : }
9204 :
9205 1 : state.dataWindowManager->RunMeOnceFlag = true;
9206 : }
9207 :
9208 : //*****************************************************************************************
9209 :
9210 771 : void initWindowModel(EnergyPlusData &state)
9211 : {
9212 1542 : const std::string objectName = "WindowsCalculationEngine";
9213 771 : state.dataWindowManager->inExtWindowModel = CWindowModel::WindowModelFactory(state, objectName);
9214 771 : state.dataWindowManager->winOpticalModel = CWindowOpticalModel::WindowOpticalModelFactory(state);
9215 771 : }
9216 :
9217 : //*****************************************************************************************
9218 :
9219 : } // namespace WindowManager
9220 :
9221 2313 : } // namespace EnergyPlus
|