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 <cassert>
50 : #include <cmath>
51 : #include <memory>
52 :
53 : // ObjexxFCL Headers
54 : #include <ObjexxFCL/Array.functions.hh>
55 : #include <ObjexxFCL/Fmath.hh>
56 : #include <ObjexxFCL/Vector3.hh>
57 : #include <ObjexxFCL/member.functions.hh>
58 :
59 : // EnergyPlus Headers
60 : #include <EnergyPlus/CommandLineInterface.hh>
61 : #include <EnergyPlus/Construction.hh>
62 : #include <EnergyPlus/Data/EnergyPlusData.hh>
63 : #include <EnergyPlus/DataDaylightingDevices.hh>
64 : #include <EnergyPlus/DataEnvironment.hh>
65 : #include <EnergyPlus/DataErrorTracking.hh>
66 : #include <EnergyPlus/DataHeatBalSurface.hh>
67 : #include <EnergyPlus/DataHeatBalance.hh>
68 : #include <EnergyPlus/DataIPShortCuts.hh>
69 : #include <EnergyPlus/DataReportingFlags.hh>
70 : #include <EnergyPlus/DataShadowingCombinations.hh>
71 : #include <EnergyPlus/DataStringGlobals.hh>
72 : #include <EnergyPlus/DataSurfaces.hh>
73 : #include <EnergyPlus/DataSystemVariables.hh>
74 : #include <EnergyPlus/DataViewFactorInformation.hh>
75 : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
76 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
77 : #include <EnergyPlus/DaylightingDevices.hh>
78 : #include <EnergyPlus/DaylightingManager.hh>
79 : #include <EnergyPlus/DisplayRoutines.hh>
80 : #include <EnergyPlus/General.hh>
81 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
82 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
83 : #include <EnergyPlus/OutputProcessor.hh>
84 : #include <EnergyPlus/OutputReportPredefined.hh>
85 : #include <EnergyPlus/ScheduleManager.hh>
86 : #include <EnergyPlus/SolarReflectionManager.hh>
87 : #include <EnergyPlus/SolarShading.hh>
88 : #include <EnergyPlus/UtilityRoutines.hh>
89 : #include <EnergyPlus/Vectors.hh>
90 : #include <EnergyPlus/WindowComplexManager.hh>
91 : #include <EnergyPlus/WindowEquivalentLayer.hh>
92 : #include <EnergyPlus/WindowManager.hh>
93 : #include <EnergyPlus/WindowManagerExteriorData.hh>
94 : #include <EnergyPlus/WindowModel.hh>
95 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
96 : #include <WCEMultiLayerOptics.hpp>
97 :
98 : namespace EnergyPlus::SolarShading {
99 :
100 : // MODULE INFORMATION:
101 : // AUTHOR Rick Strand
102 : // DATE WRITTEN March 1997
103 : // MODIFIED December 1998, FCW
104 : // MODIFIED July 1999, Linda Lawrie, eliminate shadefl.scr,
105 : // do shadowing calculations during simulation
106 : // MODIFIED June 2001, FCW, handle window blinds
107 : // MODIFIED May 2004, LKL, Polygons > 4 sides (not subsurfaces)
108 : // MODIFIED January 2007, LKL, Taking parameters back to original integer (HC)
109 : // MODIFIED August 2011, JHK, Including Complex Fenestration optical calculations
110 : // MODIFIED November 2012, BG, Timestep solar and daylighting calculations
111 : // RE-ENGINEERED na
112 :
113 : // PURPOSE OF THIS MODULE:
114 : // The purpose of this module is to encompass the routines and data
115 : // which are need to perform the solar calculations in EnergyPlus.
116 : // This also requires that shading and geometry routines and data
117 : // which are used by the solar calculations be included in this module.
118 :
119 : // METHODOLOGY EMPLOYED:
120 : // Many of the methods used in this module have been carried over from the
121 : // (I)BLAST program. As such, there is not much documentation on the
122 : // methodology used. The original code was written mainly by George
123 : // Walton and requires coordinate transformations. It calculates
124 : // shading using an overlapping polygon approach.
125 :
126 : // REFERENCES:
127 : // TARP Manual, NIST Publication.
128 : // Passive Solar Extension of the BLAST Program, CERL/UIUC Publication.
129 :
130 : using namespace DataEnvironment;
131 : using namespace DataHeatBalance;
132 : using namespace DataSurfaces;
133 : using namespace DataShadowingCombinations;
134 : using namespace SolarReflectionManager;
135 : using namespace DataVectorTypes;
136 : using namespace WindowManager;
137 : using namespace FenestrationCommon;
138 : using namespace SingleLayerOptics;
139 :
140 : int constexpr NPhi = 6; // Number of altitude angle steps for sky integration
141 : int constexpr NTheta = 24; // Number of azimuth angle steps for sky integration
142 : Real64 constexpr Eps = 1.e-10; // Small number
143 : Real64 constexpr DPhi = DataGlobalConstants::PiOvr2 / NPhi; // Altitude step size
144 : Real64 constexpr DTheta = 2.0 * DataGlobalConstants::Pi / NTheta; // Azimuth step size
145 : Real64 constexpr DThetaDPhi = DTheta * DPhi; // Product of DTheta and DPhi
146 : Real64 constexpr PhiMin = 0.5 * DPhi; // Minimum altitude
147 :
148 : Real64 constexpr HCMULT = 100000.0; // Multiplier used to change meters to .01 millimeters for homogeneous coordinates.
149 : // Homogeneous Coordinates are represented in integers (64 bit). This changes the surface coordinates from meters
150 : // to .01 millimeters -- making that the resolution for shadowing, polygon clipping, etc.
151 : Real64 const sqHCMULT = (HCMULT * HCMULT); // Square of HCMult used in Homogeneous coordinates
152 : Real64 const sqHCMULT_fac = (0.5 / sqHCMULT); // ( 0.5 / sqHCMULT ) factor
153 :
154 : // Parameters for use with the variable OverlapStatus...
155 : int constexpr NoOverlap = 1;
156 : int constexpr FirstSurfWithinSecond = 2;
157 : int constexpr SecondSurfWithinFirst = 3;
158 : int constexpr PartialOverlap = 4;
159 : int constexpr TooManyVertices = 5;
160 : int constexpr TooManyFigures = 6;
161 :
162 771 : void InitSolarCalculations(EnergyPlusData &state)
163 : {
164 :
165 : // SUBROUTINE INFORMATION:
166 : // AUTHOR George Walton
167 : // DATE WRITTEN September 1977
168 : // MODIFIED na
169 : // RE-ENGINEERED Mar97, RKS, Initial EnergyPlus Version
170 :
171 : // PURPOSE OF THIS SUBROUTINE:
172 : // This routine controls the computation of the solar flux multipliers.
173 :
174 : // METHODOLOGY EMPLOYED:
175 : // All shadowing calculations have been grouped under this routine to
176 : // allow segmentation separating it from the hourly loads calculation.
177 :
178 : #ifdef EP_Count_Calls
179 : ++state.dataTimingsData->NumInitSolar_Calls;
180 : #endif
181 771 : if (state.dataGlobal->BeginSimFlag) {
182 771 : if (state.files.outputControl.shd) {
183 1540 : state.dataSolarShading->shd_stream =
184 2310 : std::make_unique<std::fstream>(state.dataStrGlobals->outputShdFilePath, std::ios_base::out | std::ios_base::trunc);
185 770 : if (!state.dataSolarShading->shd_stream) {
186 0 : ShowFatalError(state,
187 0 : "InitSolarCalculations: Could not open file \"" + state.dataStrGlobals->outputShdFilePath.string() +
188 : "\" for output (write).");
189 : }
190 : } else {
191 1 : state.dataSolarShading->shd_stream = std::make_unique<std::iostream>(nullptr);
192 : }
193 :
194 771 : if (state.dataSolarShading->GetInputFlag) {
195 771 : GetShadowingInput(state);
196 771 : state.dataSolarShading->GetInputFlag = false;
197 771 : state.dataSolarShading->MaxHCV =
198 771 : (((max(15, state.dataSurface->MaxVerticesPerSurface) + 16) / 16) * 16) - 1; // Assure MaxHCV+1 is multiple of 16 for 128 B alignment
199 771 : assert((state.dataSolarShading->MaxHCV + 1) % 16 == 0);
200 : }
201 :
202 771 : if (state.dataSolarShading->firstTime) DisplayString(state, "Allocate Solar Module Arrays");
203 771 : AllocateModuleArrays(state);
204 :
205 771 : if (state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::FullInteriorExterior) {
206 331 : if (state.dataSolarShading->firstTime) DisplayString(state, "Computing Interior Solar Absorption Factors");
207 331 : ComputeIntSolarAbsorpFactors(state);
208 : }
209 :
210 771 : if (state.dataSolarShading->firstTime) DisplayString(state, "Determining Shadowing Combinations");
211 771 : DetermineShadowingCombinations(state);
212 771 : state.dataSolarShading->shd_stream.reset(); // Done writing to shd file
213 :
214 771 : if (state.dataSolarShading->firstTime) DisplayString(state, "Computing Window Shade Absorption Factors");
215 771 : ComputeWinShadeAbsorpFactors(state);
216 :
217 771 : if (state.dataSurface->CalcSolRefl) {
218 9 : DisplayString(state, "Initializing Solar Reflection Factors");
219 9 : InitSolReflRecSurf(state);
220 : }
221 :
222 771 : if (state.dataSolarShading->firstTime) DisplayString(state, "Proceeding with Initializing Solar Calculations");
223 : }
224 :
225 771 : if (state.dataGlobal->BeginEnvrnFlag) {
226 771 : state.dataSolarShading->SurfSunCosTheta = 0.0;
227 771 : state.dataSolarShading->SurfSunlitArea = 0.0;
228 771 : state.dataSurface->SurfSunlitArea = 0.0;
229 771 : state.dataSurface->SurfSunlitFrac = 0.0;
230 771 : state.dataHeatBal->SurfSunlitFracHR = 0.0;
231 771 : state.dataHeatBal->SurfSunlitFrac = 0.0;
232 771 : state.dataHeatBal->SurfSunlitFracWithoutReveal = 0.0;
233 771 : state.dataHeatBal->SurfWinBackSurfaces = 0;
234 771 : state.dataHeatBal->SurfWinOverlapAreas = 0.0;
235 771 : state.dataHeatBal->SurfCosIncAngHR = 0.0;
236 771 : state.dataHeatBal->SurfCosIncAng = 0.0;
237 771 : state.dataSolarShading->SurfAnisoSkyMult = 1.0; // For isotropic sky; recalculated in AnisoSkyViewFactors if anisotropic radiance
238 : // WithShdgIsoSky=0.0
239 : // WoShdgIsoSky=0.0
240 : // WithShdgHoriz=0.0
241 : // WoShdgHoriz=0.0
242 : // DifShdgRatioIsoSky=0.0
243 : // DifShdgRatioHoriz=0.0
244 771 : state.dataSolarShading->SurfMultIsoSky = 0.0;
245 771 : state.dataSolarShading->SurfMultCircumSolar = 0.0;
246 771 : state.dataSolarShading->SurfMultHorizonZenith = 0.0;
247 771 : state.dataSolarShading->SurfWinRevealStatus = 0;
248 :
249 5585 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
250 4814 : state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
251 4814 : state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
252 4814 : state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
253 4814 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
254 4814 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
255 4814 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
256 4814 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
257 4814 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
258 4814 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
259 4814 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
260 : }
261 5582 : for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
262 4811 : state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
263 4811 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
264 4811 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
265 4811 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
266 4811 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
267 4811 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
268 4811 : state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
269 4811 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
270 4811 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
271 4811 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
272 4811 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
273 : }
274 44533 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
275 43762 : state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
276 43762 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
277 43762 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
278 43762 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
279 43762 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
280 43762 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
281 43762 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
282 43762 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
283 43762 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
284 43762 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
285 43762 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
286 43762 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
287 43762 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
288 43762 : state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
289 43762 : state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
290 43762 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
291 43762 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
292 43762 : state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
293 : }
294 5585 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
295 9632 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
296 4818 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
297 4818 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
298 4818 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
299 10792 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
300 :
301 5974 : state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
302 5974 : state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
303 5974 : state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
304 5974 : state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
305 5974 : state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
306 :
307 5974 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
308 5974 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
309 5974 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
310 5974 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
311 :
312 5974 : state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
313 5974 : state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
314 5974 : state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
315 : }
316 10792 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
317 5974 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
318 5974 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
319 5974 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
320 5974 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
321 5974 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
322 5974 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
323 5974 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
324 5974 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
325 :
326 5974 : state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
327 5974 : state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
328 5974 : state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
329 : }
330 10792 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
331 5974 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
332 5974 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
333 5974 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
334 5974 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
335 5974 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
336 :
337 5974 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
338 5974 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
339 5974 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
340 5974 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
341 :
342 5974 : state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0;
343 5974 : state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 0;
344 5974 : state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 0;
345 : }
346 : }
347 : }
348 : }
349 :
350 : // Initialize these once
351 5397 : for (int IPhi = 1; IPhi <= NPhi; ++IPhi) { // Loop over patch altitude values
352 4626 : Real64 Phi = PhiMin + (IPhi - 1) * DPhi; // 7.5,22.5,37.5,52.5,67.5,82.5 for NPhi = 6
353 4626 : state.dataSolarShading->sin_Phi.push_back(std::sin(Phi));
354 4626 : state.dataSolarShading->cos_Phi.push_back(std::cos(Phi));
355 : }
356 :
357 19275 : for (int ITheta = 1; ITheta <= NTheta; ++ITheta) { // Loop over patch azimuth values
358 18504 : Real64 Theta = (ITheta - 1) * DTheta; // 0,15,30,....,330,345 for NTheta = 24
359 18504 : state.dataSolarShading->sin_Theta.push_back(std::sin(Theta));
360 18504 : state.dataSolarShading->cos_Theta.push_back(std::cos(Theta));
361 : }
362 :
363 771 : state.dataSolarShading->firstTime = false;
364 771 : }
365 :
366 771 : void GetShadowingInput(EnergyPlusData &state)
367 : {
368 : // SUBROUTINE INFORMATION:
369 : // AUTHOR Linda K. Lawrie
370 : // DATE WRITTEN July 1999
371 : // MODIFIED B. Griffith, Nov 2012, add calculation method
372 :
373 : // PURPOSE OF THIS SUBROUTINE:
374 : // This subroutine gets the Shadowing Calculation object.
375 :
376 : // Using/Aliasing
377 : using DataSystemVariables::ShadingMethod;
378 :
379 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
380 : int NumItems;
381 : int NumNumbers;
382 : int NumAlphas;
383 : int IOStat;
384 771 : int Found = 0;
385 771 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
386 771 : state.dataIPShortCut->rNumericArgs({1, 4}) = 0.0; // so if nothing gotten, defaults will be maintained.
387 771 : state.dataIPShortCut->cAlphaArgs(1) = "";
388 771 : state.dataIPShortCut->cAlphaArgs(2) = "";
389 771 : cCurrentModuleObject = "ShadowCalculation";
390 771 : NumItems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
391 771 : NumAlphas = 0;
392 771 : NumNumbers = 0;
393 771 : if (NumItems > 1) {
394 0 : ShowWarningError(state, cCurrentModuleObject + ": More than 1 occurrence of this object found, only first will be used.");
395 : }
396 :
397 771 : if (NumItems != 0) {
398 1036 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
399 : cCurrentModuleObject,
400 : 1,
401 148 : state.dataIPShortCut->cAlphaArgs,
402 : NumAlphas,
403 148 : state.dataIPShortCut->rNumericArgs,
404 : NumNumbers,
405 : IOStat,
406 148 : state.dataIPShortCut->lNumericFieldBlanks,
407 148 : state.dataIPShortCut->lAlphaFieldBlanks,
408 148 : state.dataIPShortCut->cAlphaFieldNames,
409 148 : state.dataIPShortCut->cNumericFieldNames);
410 148 : state.dataSolarShading->ShadowingCalcFrequency = state.dataIPShortCut->rNumericArgs(1);
411 : }
412 :
413 771 : if (state.dataSolarShading->ShadowingCalcFrequency <= 0) {
414 : // Set to default value
415 623 : state.dataSolarShading->ShadowingCalcFrequency = 20;
416 : }
417 771 : if (state.dataSolarShading->ShadowingCalcFrequency > 31) {
418 0 : ShowWarningError(state, cCurrentModuleObject + ": suspect " + state.dataIPShortCut->cNumericFieldNames(1));
419 0 : ShowContinueError(state, format("Value entered=[{:.0R}], Shadowing Calculations will be inaccurate.", state.dataIPShortCut->rNumericArgs(1)));
420 : }
421 :
422 771 : if (state.dataIPShortCut->rNumericArgs(2) > 199.0) {
423 104 : state.dataSolarShading->MaxHCS = state.dataIPShortCut->rNumericArgs(2);
424 : } else {
425 667 : state.dataSolarShading->MaxHCS = 15000;
426 : }
427 :
428 771 : int aNum = 1;
429 771 : unsigned pixelRes = 512u;
430 771 : if (NumAlphas >= aNum) {
431 148 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Scheduled")) {
432 1 : state.dataSysVars->shadingMethod = ShadingMethod::Scheduled;
433 1 : state.dataIPShortCut->cAlphaArgs(aNum) = "Scheduled";
434 147 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Imported")) {
435 1 : if (state.dataScheduleMgr->ScheduleFileShadingProcessed) {
436 1 : state.dataSysVars->shadingMethod = ShadingMethod::Imported;
437 1 : state.dataIPShortCut->cAlphaArgs(aNum) = "Imported";
438 : } else {
439 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
440 0 : ShowContinueError(state,
441 0 : "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) +
442 : "\" while no Schedule:File:Shading object is defined, InternalCalculation will be used.");
443 : }
444 146 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "PolygonClipping")) {
445 145 : state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
446 145 : state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
447 1 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "PixelCounting")) {
448 1 : state.dataSysVars->shadingMethod = ShadingMethod::PixelCounting;
449 1 : state.dataIPShortCut->cAlphaArgs(aNum) = "PixelCounting";
450 1 : if (NumNumbers >= 3) {
451 1 : pixelRes = (unsigned)state.dataIPShortCut->rNumericArgs(3);
452 : }
453 : #ifdef EP_NO_OPENGL
454 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
455 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\"");
456 : ShowContinueError(state, "This version of EnergyPlus was not compiled to use OpenGL (required for PixelCounting)");
457 : ShowContinueError(state, "PolygonClipping will be used instead");
458 : state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
459 : state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
460 : #else
461 1 : auto error_callback = [](const int messageType, const std::string &message, void *contextPtr) {
462 0 : auto *state = (EnergyPlusData *)contextPtr;
463 0 : if (messageType == Pumbra::MSG_ERR) {
464 0 : ShowSevereError(*state, message);
465 0 : } else if (messageType == Pumbra::MSG_WARN) {
466 0 : ShowWarningError(*state, message);
467 : } else { // if (messageType == MSG_INFO)
468 0 : ShowMessage(*state, message);
469 : }
470 1 : };
471 1 : if (Pumbra::Penumbra::isValidContext()) {
472 1 : state.dataSolarShading->penumbra = std::make_unique<Pumbra::Penumbra>(error_callback, &state, pixelRes);
473 : } else {
474 0 : ShowWarningError(state, "No GPU found (required for PixelCounting)");
475 0 : ShowContinueError(state, "PolygonClipping will be used instead");
476 0 : state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
477 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
478 : }
479 : #endif
480 : } else {
481 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
482 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", PolygonClipping will be used.");
483 : }
484 : } else {
485 623 : state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
486 623 : state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
487 : }
488 :
489 772 : if ((state.dataSysVars->shadingMethod == DataSystemVariables::ShadingMethod::PixelCounting) &&
490 1 : state.dataSolarShading->anyScheduledShadingSurface) {
491 1 : ShowSevereError(state, "The Shading Calculation Method of choice is \"PixelCounting\"; ");
492 1 : ShowContinueError(state, "and there is at least one shading surface of type ");
493 1 : ShowContinueError(state, "Shading:Site:Detailed, Shading:Building:Detailed, or Shading:Zone:Detailed, ");
494 1 : ShowContinueError(state, "that has an active transmittance schedule value greater than zero.");
495 1 : ShowContinueError(state, "With \"PixelCounting\" Shading Calculation Method, the shading surfaces will be treated as ");
496 1 : ShowContinueError(state, "completely opaque (transmittance = 0) during the shading calculation, ");
497 1 : ShowContinueError(state, "which may result in inaccurate or unexpected results.");
498 1 : ShowContinueError(state, "It is suggested switching to another Shading Calculation Method, such as \"PolygonClipping\".");
499 : }
500 :
501 771 : aNum++;
502 771 : if (NumAlphas >= aNum) {
503 148 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Periodic")) {
504 146 : state.dataSysVars->DetailedSolarTimestepIntegration = false;
505 146 : state.dataIPShortCut->cAlphaArgs(aNum) = "Periodic";
506 2 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Timestep")) {
507 2 : state.dataSysVars->DetailedSolarTimestepIntegration = true;
508 2 : state.dataIPShortCut->cAlphaArgs(aNum) = "Timestep";
509 : } else {
510 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
511 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", Periodic will be used.");
512 0 : state.dataSysVars->DetailedSolarTimestepIntegration = false;
513 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "Periodic";
514 : }
515 : } else {
516 623 : state.dataSysVars->DetailedSolarTimestepIntegration = false;
517 623 : state.dataIPShortCut->cAlphaArgs(aNum) = "Periodic";
518 : }
519 :
520 771 : aNum++;
521 771 : if (NumAlphas >= aNum) {
522 7 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "SutherlandHodgman")) {
523 7 : state.dataSysVars->SutherlandHodgman = true;
524 7 : state.dataIPShortCut->cAlphaArgs(aNum) = "SutherlandHodgman";
525 0 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "ConvexWeilerAtherton")) {
526 0 : state.dataSysVars->SutherlandHodgman = false;
527 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "ConvexWeilerAtherton";
528 0 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "SlaterBarskyandSutherlandHodgman")) {
529 0 : state.dataSysVars->SutherlandHodgman = true;
530 0 : state.dataSysVars->SlaterBarsky = true;
531 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "SlaterBarskyandSutherlandHodgman";
532 0 : } else if (state.dataIPShortCut->lAlphaFieldBlanks(aNum)) {
533 0 : if (!state.dataSysVars->SutherlandHodgman) { // if already set.
534 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "ConvexWeilerAtherton";
535 : } else {
536 0 : if (!state.dataSysVars->SlaterBarsky) {
537 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "SutherlandHodgman";
538 : } else {
539 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "SlaterBarskyandSutherlandHodgman";
540 : }
541 : }
542 : } else {
543 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
544 0 : if (!state.dataSysVars->SutherlandHodgman) {
545 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", ConvexWeilerAtherton will be used.");
546 : } else {
547 0 : if (!state.dataSysVars->SlaterBarsky) {
548 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", SutherlandHodgman will be used.");
549 : } else {
550 0 : ShowContinueError(
551 0 : state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", SlaterBarskyandSutherlandHodgman will be used.");
552 : }
553 : }
554 : }
555 : } else {
556 764 : if (!state.dataSysVars->SutherlandHodgman) {
557 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "ConvexWeilerAtherton";
558 : } else {
559 764 : if (!state.dataSysVars->SlaterBarsky) {
560 764 : state.dataIPShortCut->cAlphaArgs(aNum) = "SutherlandHodgman";
561 : } else {
562 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "SlaterBarskyandSutherlandHodgman";
563 : }
564 : }
565 : }
566 :
567 771 : aNum++;
568 771 : if (NumAlphas >= aNum) {
569 5 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "SimpleSkyDiffuseModeling")) {
570 5 : state.dataSysVars->DetailedSkyDiffuseAlgorithm = false;
571 5 : state.dataIPShortCut->cAlphaArgs(aNum) = "SimpleSkyDiffuseModeling";
572 0 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "DetailedSkyDiffuseModeling")) {
573 0 : state.dataSysVars->DetailedSkyDiffuseAlgorithm = true;
574 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "DetailedSkyDiffuseModeling";
575 0 : } else if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
576 0 : state.dataSysVars->DetailedSkyDiffuseAlgorithm = false;
577 0 : state.dataIPShortCut->cAlphaArgs(aNum) = "SimpleSkyDiffuseModeling";
578 : } else {
579 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
580 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", SimpleSkyDiffuseModeling will be used.");
581 : }
582 : } else {
583 766 : state.dataIPShortCut->cAlphaArgs(aNum) = "SimpleSkyDiffuseModeling";
584 766 : state.dataSysVars->DetailedSkyDiffuseAlgorithm = false;
585 : }
586 :
587 771 : aNum++;
588 771 : if (NumAlphas >= aNum) {
589 5 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Yes")) {
590 1 : state.dataSysVars->ReportExtShadingSunlitFrac = true;
591 1 : state.dataIPShortCut->cAlphaArgs(aNum) = "Yes";
592 4 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "No")) {
593 4 : state.dataSysVars->ReportExtShadingSunlitFrac = false;
594 4 : state.dataIPShortCut->cAlphaArgs(aNum) = "No";
595 : } else {
596 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
597 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", InternalCalculation will be used.");
598 : }
599 : } else {
600 766 : state.dataIPShortCut->cAlphaArgs(aNum) = "No";
601 766 : state.dataSysVars->ReportExtShadingSunlitFrac = false;
602 : }
603 771 : if (state.dataSysVars->shadingMethod == ShadingMethod::Imported) {
604 : int ExtShadingSchedNum;
605 114 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
606 113 : ExtShadingSchedNum = ScheduleManager::GetScheduleIndex(state, state.dataSurface->Surface(SurfNum).Name + "_shading");
607 113 : if (ExtShadingSchedNum != 0) {
608 113 : state.dataSurface->Surface(SurfNum).SurfSchedExternalShadingFrac = true;
609 113 : state.dataSurface->Surface(SurfNum).SurfExternalShadingSchInd = ExtShadingSchedNum;
610 : } else {
611 0 : ShowWarningError(state,
612 0 : cCurrentModuleObject + ": sunlit fraction schedule not found for " + state.dataSurface->Surface(SurfNum).Name +
613 : " when using ImportedShading.");
614 0 : ShowContinueError(state, "These values are set to 1.0.");
615 : }
616 : }
617 : }
618 :
619 771 : bool DisableSelfShadingWithinGroup = false;
620 771 : bool DisableSelfShadingBetweenGroup = false;
621 :
622 771 : aNum++;
623 771 : if (NumAlphas >= aNum) {
624 3 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Yes")) {
625 2 : DisableSelfShadingWithinGroup = true;
626 2 : state.dataIPShortCut->cAlphaArgs(aNum) = "Yes";
627 1 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "No")) {
628 1 : state.dataIPShortCut->cAlphaArgs(aNum) = "No";
629 : } else {
630 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
631 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", all shading effects would be considered.");
632 : }
633 : } else {
634 768 : state.dataIPShortCut->cAlphaArgs(aNum) = "No";
635 : }
636 :
637 771 : aNum++;
638 771 : if (NumAlphas >= aNum) {
639 3 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "Yes")) {
640 1 : DisableSelfShadingBetweenGroup = true;
641 1 : state.dataIPShortCut->cAlphaArgs(aNum) = "Yes";
642 2 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "No")) {
643 2 : state.dataIPShortCut->cAlphaArgs(aNum) = "No";
644 : } else {
645 0 : ShowWarningError(state, cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(aNum));
646 0 : ShowContinueError(state, "Value entered=\"" + state.dataIPShortCut->cAlphaArgs(aNum) + "\", all shading effects would be considered.");
647 : }
648 : } else {
649 768 : state.dataIPShortCut->cAlphaArgs(aNum) = "No";
650 : }
651 :
652 771 : if (DisableSelfShadingBetweenGroup && DisableSelfShadingWithinGroup) {
653 1 : state.dataSysVars->DisableAllSelfShading = true;
654 770 : } else if (DisableSelfShadingBetweenGroup || DisableSelfShadingWithinGroup) {
655 1 : state.dataSysVars->DisableGroupSelfShading = true;
656 : }
657 :
658 771 : aNum++;
659 : int SurfZoneGroup, CurZoneGroup;
660 771 : if (state.dataSysVars->DisableGroupSelfShading) {
661 2 : Array1D_int DisableSelfShadingGroups;
662 : int NumOfShadingGroups;
663 1 : if (NumAlphas >= aNum) {
664 : // Read all shading groups
665 1 : NumOfShadingGroups = NumAlphas - (aNum - 1);
666 1 : DisableSelfShadingGroups.allocate(NumOfShadingGroups);
667 2 : for (int i = 1; i <= NumOfShadingGroups; i++) {
668 3 : Found = UtilityRoutines::FindItemInList(
669 3 : state.dataIPShortCut->cAlphaArgs(i + (aNum - 1)), state.dataHeatBal->ZoneList, state.dataHeatBal->NumOfZoneLists);
670 1 : if (Found != 0) DisableSelfShadingGroups(i) = Found;
671 : }
672 :
673 114 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
674 113 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond == 0) { // Loop through all exterior surfaces
675 89 : SurfZoneGroup = 0;
676 : // Check the shading zone group of each exterior surface
677 178 : for (int ZoneGroupLoop = 1; ZoneGroupLoop <= NumOfShadingGroups; ZoneGroupLoop++) { // Loop through all defined shading groups
678 89 : CurZoneGroup = DisableSelfShadingGroups(ZoneGroupLoop);
679 425 : for (int ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(CurZoneGroup).NumOfZones;
680 : ZoneNum++) { // Loop through all zones in the zone list
681 375 : if (state.dataSurface->Surface(SurfNum).Zone == state.dataHeatBal->ZoneList(CurZoneGroup).Zone(ZoneNum)) {
682 39 : SurfZoneGroup = CurZoneGroup;
683 39 : break;
684 : }
685 : }
686 : }
687 : // if a surface is not in any zone group, no self shading is disabled for this surface
688 89 : if (SurfZoneGroup != 0) {
689 : // if DisableSelfShadingWithinGroup, add all zones in the same zone group to the surface's disabled zone list
690 : // if DisableSelfShadingBetweenGroups, add all zones in all other zone groups to the surface's disabled zone list
691 78 : for (int ZoneGroupLoop = 1; ZoneGroupLoop <= NumOfShadingGroups; ZoneGroupLoop++) { // Loop through all defined shading groups
692 39 : CurZoneGroup = DisableSelfShadingGroups(ZoneGroupLoop);
693 39 : if (SurfZoneGroup == CurZoneGroup && DisableSelfShadingWithinGroup) {
694 234 : for (int ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(CurZoneGroup).NumOfZones;
695 : ZoneNum++) { // Loop through all zones in the zone list
696 390 : state.dataSurface->SurfShadowDisabledZoneList(SurfNum).push_back(
697 195 : state.dataHeatBal->ZoneList(CurZoneGroup).Zone(ZoneNum));
698 39 : }
699 0 : } else if (SurfZoneGroup != CurZoneGroup && DisableSelfShadingBetweenGroup) {
700 0 : for (int ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(CurZoneGroup).NumOfZones; ZoneNum++) {
701 0 : state.dataSurface->SurfShadowDisabledZoneList(SurfNum).push_back(
702 0 : state.dataHeatBal->ZoneList(CurZoneGroup).Zone(ZoneNum));
703 : }
704 : }
705 : }
706 : }
707 : }
708 : }
709 : } else {
710 0 : ShowFatalError(state, "No Shading groups are defined when disabling grouped self shading.");
711 : }
712 : }
713 :
714 771 : if (!state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
715 0 : state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) {
716 :
717 0 : ShowWarningError(state,
718 : "GetShadowingInput: The shading transmittance for shading devices changes throughout the year. Choose "
719 0 : "DetailedSkyDiffuseModeling in the " +
720 0 : cCurrentModuleObject + " object to remove this warning.");
721 0 : ShowContinueError(state, "Simulation has been reset to use DetailedSkyDiffuseModeling. Simulation continues.");
722 0 : state.dataSysVars->DetailedSkyDiffuseAlgorithm = true;
723 0 : state.dataIPShortCut->cAlphaArgs(2) = "DetailedSkyDiffuseModeling";
724 0 : if (state.dataSolarShading->ShadowingCalcFrequency > 1) {
725 0 : ShowContinueError(state,
726 0 : "Better accuracy may be gained by setting the " + state.dataIPShortCut->cNumericFieldNames(1) + " to 1 in the " +
727 0 : cCurrentModuleObject + " object.");
728 : }
729 771 : } else if (state.dataSysVars->DetailedSkyDiffuseAlgorithm) {
730 0 : if (!state.dataSurface->ShadingTransmittanceVaries || state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
731 0 : ShowWarningError(state,
732 : "GetShadowingInput: DetailedSkyDiffuseModeling is chosen but not needed as either the shading transmittance for "
733 : "shading devices does not change throughout the year");
734 0 : ShowContinueError(state, " or MinimalShadowing has been chosen.");
735 0 : ShowContinueError(state, "Simulation should be set to use SimpleSkyDiffuseModeling, but is left at Detailed for simulation.");
736 0 : ShowContinueError(state, "Choose SimpleSkyDiffuseModeling in the " + cCurrentModuleObject + " object to reduce computation time.");
737 : }
738 : }
739 :
740 771 : print(state.files.eio,
741 : "{}",
742 : "! <Shadowing/Sun Position Calculations Annual Simulations>, Shading Calculation Method, "
743 : "Shading Calculation Update Frequency Method, Shading Calculation Update Frequency {days}, "
744 : "Maximum Figures in Shadow Overlap Calculations {}, Polygon Clipping Algorithm, Pixel Counting Resolution, Sky Diffuse Modeling "
745 : "Algorithm, Output External Shading Calculation Results, Disable "
746 771 : "Self-Shading Within Shading Zone Groups, Disable Self-Shading From Shading Zone Groups to Other Zones\n");
747 7710 : print(state.files.eio,
748 : "Shadowing/Sun Position Calculations Annual Simulations,{},{},{},{},{},{},{},{},{},{}\n",
749 771 : state.dataIPShortCut->cAlphaArgs(1),
750 771 : state.dataIPShortCut->cAlphaArgs(2),
751 771 : state.dataSolarShading->ShadowingCalcFrequency,
752 771 : state.dataSolarShading->MaxHCS,
753 771 : state.dataIPShortCut->cAlphaArgs(3),
754 : pixelRes,
755 771 : state.dataIPShortCut->cAlphaArgs(4),
756 771 : state.dataIPShortCut->cAlphaArgs(5),
757 771 : state.dataIPShortCut->cAlphaArgs(6),
758 1542 : state.dataIPShortCut->cAlphaArgs(7));
759 771 : }
760 :
761 771 : void AllocateModuleArrays(EnergyPlusData &state)
762 : {
763 :
764 : // SUBROUTINE INFORMATION:
765 : // AUTHOR Rick Strand
766 : // DATE WRITTEN February 1998
767 : // MODIFIED August 2005 JG - Added output variables for energy in J
768 :
769 : // PURPOSE OF THIS SUBROUTINE:
770 : // This routine allocates all of the arrays at the module level which
771 : // require allocation.
772 :
773 : // METHODOLOGY EMPLOYED:
774 : // Allocation is dependent on the user input file.
775 :
776 : int SurfLoop;
777 : int I;
778 : int NumOfLayers;
779 771 : int constexpr HoursInDay(24);
780 :
781 771 : state.dataSolarShading->SurfSunCosTheta.dimension(state.dataSurface->TotSurfaces, 0.0);
782 771 : state.dataSolarShading->SurfSunlitArea.dimension(state.dataSurface->TotSurfaces, 0.0);
783 771 : if (!state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() || !state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
784 769 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac.allocate(state.dataSurface->TotSurfaces);
785 769 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac.allocate(state.dataSurface->TotSurfaces);
786 769 : state.dataSolarShading->SurfWinTransBmSolar.allocate(state.dataSurface->TotSurfaces);
787 769 : state.dataSolarShading->SurfWinTransDifSolar.allocate(state.dataSurface->TotSurfaces);
788 769 : state.dataSolarShading->SurfWinTransDifSolarGnd.allocate(state.dataSurface->TotSurfaces);
789 769 : state.dataSolarShading->SurfWinTransDifSolarSky.allocate(state.dataSurface->TotSurfaces);
790 769 : state.dataSolarShading->SurfWinTransBmBmSolar.allocate(state.dataSurface->TotSurfaces);
791 769 : state.dataSolarShading->SurfWinTransBmDifSolar.allocate(state.dataSurface->TotSurfaces);
792 : }
793 771 : state.dataSolarShading->SurfAnisoSkyMult.dimension(state.dataSurface->TotSurfaces, 1.0);
794 771 : state.dataSolarShading->SurfIntAbsFac.dimension(state.dataSurface->TotSurfaces, 0.0);
795 : // For isotropic sky: recalculated in AnisoSkyViewFactors if anisotropic radiance
796 : // ALLOCATE(WithShdgIsoSky(TotSurfaces))
797 : // WithShdgIsoSky=0.0
798 : // ALLOCATE(WoShdgIsoSky(TotSurfaces))
799 : // WoShdgIsoSky=0.0
800 : // ALLOCATE(WithShdgHoriz(TotSurfaces))
801 : // WithShdgHoriz=0.0
802 : // ALLOCATE(WoShdgHoriz(TotSurfaces))
803 : // WoShdgHoriz=0.0
804 : // ALLOCATE(DifShdgRatioIsoSky(TotSurfaces))
805 : // DifShdgRatioIsoSky=0.0
806 : // ALLOCATE(DifShdgRatioHoriz(TotSurfaces))
807 : // DifShdgRatioHoriz=0.0
808 771 : state.dataSolarShading->SurfMultIsoSky.dimension(state.dataSurface->TotSurfaces, 0.0);
809 771 : state.dataSolarShading->SurfMultCircumSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
810 771 : state.dataSolarShading->SurfMultHorizonZenith.dimension(state.dataSurface->TotSurfaces, 0.0);
811 771 : state.dataSolarShading->SurfWinRevealStatus.dimension(24, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0);
812 :
813 : // Weiler-Atherton
814 771 : state.dataSolarShading->MAXHCArrayBounds = 2 * (state.dataSurface->MaxVerticesPerSurface + 1);
815 771 : state.dataSolarShading->MAXHCArrayIncrement = state.dataSurface->MaxVerticesPerSurface + 1;
816 771 : state.dataSolarShading->XTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
817 771 : state.dataSolarShading->YTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
818 771 : state.dataSolarShading->XVC.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
819 771 : state.dataSolarShading->XVS.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
820 771 : state.dataSolarShading->YVC.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
821 771 : state.dataSolarShading->YVS.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
822 771 : state.dataSolarShading->ZVC.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
823 :
824 : // Sutherland-Hodgman
825 771 : state.dataSolarShading->ATEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
826 771 : state.dataSolarShading->BTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
827 771 : state.dataSolarShading->CTEMP.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
828 771 : state.dataSolarShading->XTEMP1.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
829 771 : state.dataSolarShading->YTEMP1.dimension(2 * (state.dataSurface->MaxVerticesPerSurface + 1), 0.0);
830 :
831 771 : state.dataSurface->SurfSunCosHourly.allocate(HoursInDay);
832 19275 : for (int hour = 1; hour <= HoursInDay; hour++) {
833 18504 : state.dataSurface->SurfSunCosHourly(hour) = 0.0;
834 : }
835 771 : state.dataSurface->SurfSunlitArea.dimension(state.dataSurface->TotSurfaces, 0.0);
836 771 : state.dataSurface->SurfSunlitFrac.dimension(state.dataSurface->TotSurfaces, 0.0);
837 771 : state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
838 771 : state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
839 771 : state.dataSurface->SurfBmToBmReflFacObs.dimension(state.dataSurface->TotSurfaces, 0.0);
840 771 : state.dataSurface->SurfBmToDiffReflFacObs.dimension(state.dataSurface->TotSurfaces, 0.0);
841 771 : state.dataSurface->SurfBmToDiffReflFacGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
842 771 : state.dataSurface->SurfSkyDiffReflFacGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
843 771 : state.dataSurface->SurfOpaqAI.dimension(state.dataSurface->TotSurfaces, 0.0);
844 771 : state.dataSurface->SurfOpaqAO.dimension(state.dataSurface->TotSurfaces, 0.0);
845 771 : state.dataSurface->SurfWinTransSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
846 771 : state.dataSurface->SurfWinBmSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
847 771 : state.dataSurface->SurfWinBmBmSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
848 771 : state.dataSurface->SurfWinBmDifSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
849 771 : state.dataSurface->SurfWinDifSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
850 771 : state.dataSurface->SurfWinHeatGain.dimension(state.dataSurface->TotSurfaces, 0.0);
851 771 : state.dataSurface->SurfWinHeatGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
852 771 : state.dataSurface->SurfWinHeatLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
853 771 : state.dataSurface->SurfWinGainConvGlazToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
854 771 : state.dataSurface->SurfWinGainIRGlazToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
855 771 : state.dataSurface->SurfWinLossSWZoneToOutWinRep.dimension(state.dataSurface->TotSurfaces, 0.0);
856 771 : state.dataSurface->SurfWinGainFrameDividerToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
857 771 : state.dataSurface->SurfWinGainConvShadeToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
858 771 : state.dataSurface->SurfWinGainIRShadeToZoneRep.dimension(state.dataSurface->TotSurfaces, 0.0);
859 771 : state.dataSurface->SurfWinGapConvHtFlowRep.dimension(state.dataSurface->TotSurfaces, 0.0);
860 771 : state.dataSurface->SurfWinShadingAbsorbedSolar.dimension(state.dataSurface->TotSurfaces, 0.0);
861 771 : state.dataSurface->SurfWinSysSolTransmittance.dimension(state.dataSurface->TotSurfaces, 0.0);
862 771 : state.dataSurface->SurfWinSysSolReflectance.dimension(state.dataSurface->TotSurfaces, 0.0);
863 771 : state.dataSurface->SurfWinSysSolAbsorptance.dimension(state.dataSurface->TotSurfaces, 0.0);
864 771 : state.dataSurface->SurfWinInsideGlassCondensationFlag.dimension(state.dataSurface->TotSurfaces, 0);
865 771 : state.dataSurface->SurfWinInsideFrameCondensationFlag.dimension(state.dataSurface->TotSurfaces, 0);
866 771 : state.dataSurface->SurfWinInsideDividerCondensationFlag.dimension(state.dataSurface->TotSurfaces, 0);
867 :
868 771 : state.dataHeatBal->SurfSunlitFracHR.dimension(HoursInDay, state.dataSurface->TotSurfaces, 0.0);
869 771 : state.dataHeatBal->SurfSunlitFrac.dimension(HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0.0);
870 771 : state.dataHeatBal->SurfSunlitFracWithoutReveal.dimension(HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0.0);
871 1542 : state.dataHeatBal->SurfWinBackSurfaces.dimension(
872 1542 : HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataBSDFWindow->MaxBkSurf, state.dataSurface->TotSurfaces, 0);
873 1542 : state.dataHeatBal->SurfWinOverlapAreas.dimension(
874 1542 : HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataBSDFWindow->MaxBkSurf, state.dataSurface->TotSurfaces, 0.0);
875 771 : state.dataHeatBal->SurfCosIncAngHR.dimension(HoursInDay, state.dataSurface->TotSurfaces, 0.0);
876 771 : state.dataHeatBal->SurfCosIncAng.dimension(HoursInDay, state.dataGlobal->NumOfTimeStepInHour, state.dataSurface->TotSurfaces, 0.0);
877 :
878 771 : state.dataHeatBal->ZoneTransSolar.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
879 771 : state.dataHeatBal->ZoneBmSolFrExtWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
880 771 : state.dataHeatBal->ZoneBmSolFrIntWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
881 771 : state.dataHeatBal->EnclSolInitialDifSolReflW.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
882 771 : state.dataHeatBal->ZoneDifSolFrExtWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
883 771 : state.dataHeatBal->ZoneDifSolFrIntWinsRep.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
884 771 : state.dataHeatBal->ZoneWinHeatGain.dimension(state.dataGlobal->NumOfZones, 0.0);
885 771 : state.dataHeatBal->ZoneWinHeatGainRep.dimension(state.dataGlobal->NumOfZones, 0.0);
886 771 : state.dataHeatBal->ZoneWinHeatLossRep.dimension(state.dataGlobal->NumOfZones, 0.0);
887 771 : state.dataHeatBal->ZoneOpaqSurfInsFaceCond.dimension(state.dataGlobal->NumOfZones, 0.0);
888 771 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep.dimension(state.dataGlobal->NumOfZones, 0.0);
889 771 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep.dimension(state.dataGlobal->NumOfZones, 0.0);
890 771 : state.dataHeatBal->ZoneOpaqSurfExtFaceCond.dimension(state.dataGlobal->NumOfZones, 0.0);
891 771 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep.dimension(state.dataGlobal->NumOfZones, 0.0);
892 771 : state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep.dimension(state.dataGlobal->NumOfZones, 0.0);
893 :
894 771 : state.dataHeatBal->SurfQRadSWOutIncident.dimension(state.dataSurface->TotSurfaces, 0.0);
895 771 : state.dataHeatBal->SurfQRadSWOutIncidentBeam.dimension(state.dataSurface->TotSurfaces, 0.0);
896 771 : state.dataHeatBal->SurfBmIncInsSurfIntensRep.dimension(state.dataSurface->TotSurfaces, 0.0);
897 771 : state.dataHeatBal->SurfBmIncInsSurfAmountRep.dimension(state.dataSurface->TotSurfaces, 0.0);
898 : // ALLOCATE(DifIncInsSurfIntensRep(TotSurfaces))
899 : // DifIncInsSurfIntensRep=0.0
900 : // ALLOCATE(DifIncInsSurfAmountRep(TotSurfaces))
901 : // DifIncInsSurfAmountRep=0.0
902 771 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep.dimension(state.dataSurface->TotSurfaces, 0.0);
903 771 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep.dimension(state.dataSurface->TotSurfaces, 0.0);
904 : // ALLOCATE(IntDifIncInsSurfIntensRep(TotSurfaces))
905 : // IntDifIncInsSurfIntensRep=0.0
906 : // ALLOCATE(IntDifIncInsSurfAmountRep(TotSurfaces))
907 : // IntDifIncInsSurfAmountRep=0.0
908 771 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse.dimension(state.dataSurface->TotSurfaces, 0.0);
909 771 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse.dimension(state.dataSurface->TotSurfaces, 0.0);
910 771 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
911 771 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd.dimension(state.dataSurface->TotSurfaces, 0.0);
912 771 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs.dimension(state.dataSurface->TotSurfaces, 0.0);
913 771 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs.dimension(state.dataSurface->TotSurfaces, 0.0);
914 771 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs.dimension(state.dataSurface->TotSurfaces, 0.0);
915 771 : state.dataHeatBal->SurfCosIncidenceAngle.dimension(state.dataSurface->TotSurfaces, 0.0);
916 :
917 771 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep.dimension(state.dataSurface->TotSurfaces, 0);
918 771 : state.dataHeatBal->SurfWinBSDFBeamThetaRep.dimension(state.dataSurface->TotSurfaces, 0.0);
919 771 : state.dataHeatBal->SurfWinBSDFBeamPhiRep.dimension(state.dataSurface->TotSurfaces, 0.0);
920 771 : state.dataHeatBal->SurfWinQRadSWwinAbsTot.dimension(state.dataSurface->TotSurfaces, 0.0);
921 771 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer.dimension(state.dataSurface->TotSurfaces, state.dataHeatBal->MaxSolidWinLayers, 0.0);
922 771 : state.dataHeatBal->SurfWinFenLaySurfTempFront.dimension(state.dataSurface->TotSurfaces, state.dataHeatBal->MaxSolidWinLayers, 0.0);
923 771 : state.dataHeatBal->SurfWinFenLaySurfTempBack.dimension(state.dataSurface->TotSurfaces, state.dataHeatBal->MaxSolidWinLayers, 0.0);
924 :
925 771 : state.dataHeatBal->SurfWinSWwinAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
926 771 : state.dataHeatBal->SurfInitialDifSolInAbsReport.dimension(state.dataSurface->TotSurfaces, 0.0);
927 771 : state.dataHeatBal->SurfWinInitialDifSolInTransReport.dimension(state.dataSurface->TotSurfaces, 0.0);
928 771 : state.dataHeatBal->SurfSWInAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
929 :
930 : // energy
931 771 : state.dataSurface->SurfWinTransSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
932 771 : state.dataSurface->SurfWinBmSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
933 771 : state.dataSurface->SurfWinBmBmSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
934 771 : state.dataSurface->SurfWinBmDifSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
935 :
936 771 : state.dataSurface->SurfWinDifSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
937 771 : state.dataSurface->SurfWinHeatGainRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
938 771 : state.dataSurface->SurfWinHeatLossRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
939 771 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
940 771 : state.dataSurface->SurfWinHeatTransferRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
941 771 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
942 :
943 771 : state.dataHeatBal->ZoneTransSolarEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
944 771 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
945 771 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
946 771 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
947 771 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy.dimension(state.dataViewFactor->NumOfSolarEnclosures, 0.0);
948 771 : state.dataHeatBal->ZoneWinHeatGainRepEnergy.dimension(state.dataGlobal->NumOfZones, 0.0);
949 771 : state.dataHeatBal->ZoneWinHeatLossRepEnergy.dimension(state.dataGlobal->NumOfZones, 0.0);
950 :
951 771 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
952 771 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
953 771 : state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
954 771 : state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg.dimension(state.dataGlobal->NumOfZones, 0.0);
955 : // ALLOCATE(DifIncInsSurfAmountRepEnergy(TotSurfaces))
956 : // DifIncInsSurfAmountRepEnergy=0.0
957 771 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
958 771 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
959 : // ALLOCATE(IntDifIncInsSurfAmountRepEnergy(TotSurfaces))
960 : // IntDifIncInsSurfAmountRepEnergy=0.0
961 771 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
962 :
963 44533 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
964 43762 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
965 43762 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
966 43762 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
967 43762 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
968 43762 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
969 43762 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
970 43762 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
971 43762 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
972 43762 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
973 43762 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
974 : }
975 :
976 : // Added report variables for inside reveal to debug CR 7596. TH 5/26/2009
977 44533 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
978 43762 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
979 43762 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
980 43762 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
981 43762 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
982 : }
983 :
984 771 : DisplayString(state, "Initializing Zone and Enclosure Report Variables");
985 5582 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
986 4811 : auto &thisEnclosureName = state.dataViewFactor->EnclSolInfo(enclosureNum).Name;
987 9622 : SetupOutputVariable(state,
988 : "Zone Windows Total Transmitted Solar Radiation Rate",
989 : OutputProcessor::Unit::W,
990 4811 : state.dataHeatBal->ZoneTransSolar(enclosureNum),
991 : OutputProcessor::SOVTimeStepType::Zone,
992 : OutputProcessor::SOVStoreType::Average,
993 4811 : thisEnclosureName);
994 9622 : SetupOutputVariable(state,
995 : "Zone Exterior Windows Total Transmitted Beam Solar Radiation Rate",
996 : OutputProcessor::Unit::W,
997 4811 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum),
998 : OutputProcessor::SOVTimeStepType::Zone,
999 : OutputProcessor::SOVStoreType::Average,
1000 4811 : thisEnclosureName);
1001 9622 : SetupOutputVariable(state,
1002 : "Zone Interior Windows Total Transmitted Beam Solar Radiation Rate",
1003 : OutputProcessor::Unit::W,
1004 4811 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum),
1005 : OutputProcessor::SOVTimeStepType::Zone,
1006 : OutputProcessor::SOVStoreType::Average,
1007 4811 : thisEnclosureName);
1008 9622 : SetupOutputVariable(state,
1009 : "Zone Exterior Windows Total Transmitted Diffuse Solar Radiation Rate",
1010 : OutputProcessor::Unit::W,
1011 4811 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum),
1012 : OutputProcessor::SOVTimeStepType::Zone,
1013 : OutputProcessor::SOVStoreType::Average,
1014 4811 : thisEnclosureName);
1015 9622 : SetupOutputVariable(state,
1016 : "Zone Interior Windows Total Transmitted Diffuse Solar Radiation Rate",
1017 : OutputProcessor::Unit::W,
1018 4811 : state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum),
1019 : OutputProcessor::SOVTimeStepType::Zone,
1020 : OutputProcessor::SOVStoreType::Average,
1021 4811 : thisEnclosureName);
1022 : // Energy variables
1023 9622 : SetupOutputVariable(state,
1024 : "Zone Windows Total Transmitted Solar Radiation Energy",
1025 : OutputProcessor::Unit::J,
1026 4811 : state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum),
1027 : OutputProcessor::SOVTimeStepType::Zone,
1028 : OutputProcessor::SOVStoreType::Summed,
1029 4811 : thisEnclosureName);
1030 9622 : SetupOutputVariable(state,
1031 : "Zone Exterior Windows Total Transmitted Beam Solar Radiation Energy",
1032 : OutputProcessor::Unit::J,
1033 4811 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum),
1034 : OutputProcessor::SOVTimeStepType::Zone,
1035 : OutputProcessor::SOVStoreType::Summed,
1036 4811 : thisEnclosureName);
1037 9622 : SetupOutputVariable(state,
1038 : "Zone Interior Windows Total Transmitted Beam Solar Radiation Energy",
1039 : OutputProcessor::Unit::J,
1040 4811 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclosureNum),
1041 : OutputProcessor::SOVTimeStepType::Zone,
1042 : OutputProcessor::SOVStoreType::Summed,
1043 4811 : thisEnclosureName);
1044 9622 : SetupOutputVariable(state,
1045 : "Zone Exterior Windows Total Transmitted Diffuse Solar Radiation Energy",
1046 : OutputProcessor::Unit::J,
1047 4811 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum),
1048 : OutputProcessor::SOVTimeStepType::Zone,
1049 : OutputProcessor::SOVStoreType::Summed,
1050 4811 : thisEnclosureName);
1051 9622 : SetupOutputVariable(state,
1052 : "Zone Interior Windows Total Transmitted Diffuse Solar Radiation Energy",
1053 : OutputProcessor::Unit::J,
1054 4811 : state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum),
1055 : OutputProcessor::SOVTimeStepType::Zone,
1056 : OutputProcessor::SOVStoreType::Summed,
1057 4811 : thisEnclosureName);
1058 : }
1059 5585 : for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) {
1060 14442 : SetupOutputVariable(state,
1061 : "Zone Windows Total Heat Gain Rate",
1062 : OutputProcessor::Unit::W,
1063 4814 : state.dataHeatBal->ZoneWinHeatGainRep(ZoneLoop),
1064 : OutputProcessor::SOVTimeStepType::Zone,
1065 : OutputProcessor::SOVStoreType::Average,
1066 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
1067 14442 : SetupOutputVariable(state,
1068 : "Zone Windows Total Heat Loss Rate",
1069 : OutputProcessor::Unit::W,
1070 4814 : state.dataHeatBal->ZoneWinHeatLossRep(ZoneLoop),
1071 : OutputProcessor::SOVTimeStepType::Zone,
1072 : OutputProcessor::SOVStoreType::Average,
1073 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
1074 14442 : SetupOutputVariable(state,
1075 : "Zone Windows Total Heat Gain Energy",
1076 : OutputProcessor::Unit::J,
1077 4814 : state.dataHeatBal->ZoneWinHeatGainRepEnergy(ZoneLoop),
1078 : OutputProcessor::SOVTimeStepType::Zone,
1079 : OutputProcessor::SOVStoreType::Summed,
1080 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
1081 14442 : SetupOutputVariable(state,
1082 : "Zone Windows Total Heat Loss Energy",
1083 : OutputProcessor::Unit::J,
1084 4814 : state.dataHeatBal->ZoneWinHeatLossRepEnergy(ZoneLoop),
1085 : OutputProcessor::SOVTimeStepType::Zone,
1086 : OutputProcessor::SOVStoreType::Summed,
1087 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
1088 4814 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
1089 : // CurrentModuleObject='Zone(Advanced)'
1090 171 : SetupOutputVariable(state,
1091 : "Zone Opaque Surface Inside Faces Total Conduction Heat Gain Rate",
1092 : OutputProcessor::Unit::W,
1093 57 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(ZoneLoop),
1094 : OutputProcessor::SOVTimeStepType::Zone,
1095 : OutputProcessor::SOVStoreType::Average,
1096 114 : state.dataHeatBal->Zone(ZoneLoop).Name);
1097 171 : SetupOutputVariable(state,
1098 : "Zone Opaque Surface Inside Faces Total Conduction Heat Loss Rate",
1099 : OutputProcessor::Unit::W,
1100 57 : state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(ZoneLoop),
1101 : OutputProcessor::SOVTimeStepType::Zone,
1102 : OutputProcessor::SOVStoreType::Average,
1103 114 : state.dataHeatBal->Zone(ZoneLoop).Name);
1104 : // Energy variables
1105 171 : SetupOutputVariable(state,
1106 : "Zone Opaque Surface Inside Faces Total Conduction Heat Gain Energy",
1107 : OutputProcessor::Unit::J,
1108 57 : state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(ZoneLoop),
1109 : OutputProcessor::SOVTimeStepType::Zone,
1110 : OutputProcessor::SOVStoreType::Summed,
1111 114 : state.dataHeatBal->Zone(ZoneLoop).Name);
1112 171 : SetupOutputVariable(state,
1113 : "Zone Opaque Surface Inside Faces Total Conduction Heat Loss Energy",
1114 : OutputProcessor::Unit::J,
1115 57 : state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(ZoneLoop),
1116 : OutputProcessor::SOVTimeStepType::Zone,
1117 : OutputProcessor::SOVStoreType::Summed,
1118 114 : state.dataHeatBal->Zone(ZoneLoop).Name);
1119 : }
1120 : }
1121 :
1122 771 : DisplayString(state, "Initializing Surface (Shading) Report Variables");
1123 : // CurrentModuleObject='Surfaces'
1124 44533 : for (SurfLoop = 1; SurfLoop <= state.dataSurface->TotSurfaces; ++SurfLoop) {
1125 175048 : SetupOutputVariable(state,
1126 : "Surface Outside Normal Azimuth Angle",
1127 : OutputProcessor::Unit::deg,
1128 43762 : state.dataSurface->Surface(SurfLoop).Azimuth,
1129 : OutputProcessor::SOVTimeStepType::Zone,
1130 : OutputProcessor::SOVStoreType::Average,
1131 87524 : state.dataSurface->Surface(SurfLoop).Name);
1132 43762 : if (state.dataSurface->Surface(SurfLoop).ExtSolar) {
1133 55143 : SetupOutputVariable(state,
1134 : "Surface Outside Face Sunlit Area",
1135 : OutputProcessor::Unit::m2,
1136 18381 : state.dataSurface->SurfSunlitArea(SurfLoop),
1137 : OutputProcessor::SOVTimeStepType::Zone,
1138 : OutputProcessor::SOVStoreType::State,
1139 36762 : state.dataSurface->Surface(SurfLoop).Name);
1140 55143 : SetupOutputVariable(state,
1141 : "Surface Outside Face Sunlit Fraction",
1142 : OutputProcessor::Unit::None,
1143 18381 : state.dataSurface->SurfSunlitFrac(SurfLoop),
1144 : OutputProcessor::SOVTimeStepType::Zone,
1145 : OutputProcessor::SOVStoreType::State,
1146 36762 : state.dataSurface->Surface(SurfLoop).Name);
1147 55143 : SetupOutputVariable(state,
1148 : "Surface Outside Face Incident Solar Radiation Rate per Area",
1149 : OutputProcessor::Unit::W_m2,
1150 18381 : state.dataHeatBal->SurfQRadSWOutIncident(SurfLoop),
1151 : OutputProcessor::SOVTimeStepType::Zone,
1152 : OutputProcessor::SOVStoreType::Average,
1153 36762 : state.dataSurface->Surface(SurfLoop).Name);
1154 55143 : SetupOutputVariable(state,
1155 : "Surface Outside Face Incident Beam Solar Radiation Rate per Area",
1156 : OutputProcessor::Unit::W_m2,
1157 18381 : state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfLoop),
1158 : OutputProcessor::SOVTimeStepType::Zone,
1159 : OutputProcessor::SOVStoreType::Average,
1160 36762 : state.dataSurface->Surface(SurfLoop).Name);
1161 55143 : SetupOutputVariable(state,
1162 : "Surface Outside Face Incident Sky Diffuse Solar Radiation Rate per Area",
1163 : OutputProcessor::Unit::W_m2,
1164 18381 : state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfLoop),
1165 : OutputProcessor::SOVTimeStepType::Zone,
1166 : OutputProcessor::SOVStoreType::Average,
1167 36762 : state.dataSurface->Surface(SurfLoop).Name);
1168 55143 : SetupOutputVariable(state,
1169 : "Surface Outside Face Incident Ground Diffuse Solar Radiation Rate per Area",
1170 : OutputProcessor::Unit::W_m2,
1171 18381 : state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfLoop),
1172 : OutputProcessor::SOVTimeStepType::Zone,
1173 : OutputProcessor::SOVStoreType::Average,
1174 36762 : state.dataSurface->Surface(SurfLoop).Name);
1175 55143 : SetupOutputVariable(state,
1176 : "Surface Outside Face Beam Solar Incident Angle Cosine Value",
1177 : OutputProcessor::Unit::None,
1178 18381 : state.dataHeatBal->SurfCosIncidenceAngle(SurfLoop),
1179 : OutputProcessor::SOVTimeStepType::Zone,
1180 : OutputProcessor::SOVStoreType::Average,
1181 36762 : state.dataSurface->Surface(SurfLoop).Name);
1182 55143 : SetupOutputVariable(state,
1183 : "Surface Outside Face Incident Sky Diffuse Ground Reflected Solar Radiation Rate per Area",
1184 : OutputProcessor::Unit::W_m2,
1185 18381 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfLoop),
1186 : OutputProcessor::SOVTimeStepType::Zone,
1187 : OutputProcessor::SOVStoreType::Average,
1188 36762 : state.dataSurface->Surface(SurfLoop).Name);
1189 55143 : SetupOutputVariable(state,
1190 : "Surface Outside Face Incident Sky Diffuse Surface Reflected Solar Radiation Rate per Area",
1191 : OutputProcessor::Unit::W_m2,
1192 18381 : state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfLoop),
1193 : OutputProcessor::SOVTimeStepType::Zone,
1194 : OutputProcessor::SOVStoreType::Average,
1195 36762 : state.dataSurface->Surface(SurfLoop).Name);
1196 55143 : SetupOutputVariable(state,
1197 : "Surface Outside Face Incident Beam To Beam Surface Reflected Solar Radiation Rate per Area",
1198 : OutputProcessor::Unit::W_m2,
1199 18381 : state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfLoop),
1200 : OutputProcessor::SOVTimeStepType::Zone,
1201 : OutputProcessor::SOVStoreType::Average,
1202 36762 : state.dataSurface->Surface(SurfLoop).Name);
1203 55143 : SetupOutputVariable(state,
1204 : "Surface Outside Face Incident Beam To Diffuse Surface Reflected Solar Radiation Rate per Area",
1205 : OutputProcessor::Unit::W_m2,
1206 18381 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfLoop),
1207 : OutputProcessor::SOVTimeStepType::Zone,
1208 : OutputProcessor::SOVStoreType::Average,
1209 36762 : state.dataSurface->Surface(SurfLoop).Name);
1210 55143 : SetupOutputVariable(state,
1211 : "Surface Outside Face Incident Beam To Diffuse Ground Reflected Solar Radiation Rate per Area",
1212 : OutputProcessor::Unit::W_m2,
1213 18381 : state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfLoop),
1214 : OutputProcessor::SOVTimeStepType::Zone,
1215 : OutputProcessor::SOVStoreType::Average,
1216 36762 : state.dataSurface->Surface(SurfLoop).Name);
1217 55143 : SetupOutputVariable(state,
1218 : "Surface Anisotropic Sky Multiplier",
1219 : OutputProcessor::Unit::None,
1220 18381 : state.dataSolarShading->SurfAnisoSkyMult(SurfLoop),
1221 : OutputProcessor::SOVTimeStepType::Zone,
1222 : OutputProcessor::SOVStoreType::Average,
1223 36762 : state.dataSurface->Surface(SurfLoop).Name);
1224 73524 : SetupOutputVariable(state,
1225 : "Surface Window BSDF Beam Direction Number",
1226 : OutputProcessor::Unit::None,
1227 18381 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfLoop),
1228 : OutputProcessor::SOVTimeStepType::Zone,
1229 : OutputProcessor::SOVStoreType::Average,
1230 36762 : state.dataSurface->Surface(SurfLoop).Name);
1231 55143 : SetupOutputVariable(state,
1232 : "Surface Window BSDF Beam Theta Angle",
1233 : OutputProcessor::Unit::rad,
1234 18381 : state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfLoop),
1235 : OutputProcessor::SOVTimeStepType::Zone,
1236 : OutputProcessor::SOVStoreType::Average,
1237 36762 : state.dataSurface->Surface(SurfLoop).Name);
1238 55143 : SetupOutputVariable(state,
1239 : "Surface Window BSDF Beam Phi Angle",
1240 : OutputProcessor::Unit::rad,
1241 18381 : state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfLoop),
1242 : OutputProcessor::SOVTimeStepType::Zone,
1243 : OutputProcessor::SOVStoreType::Average,
1244 36762 : state.dataSurface->Surface(SurfLoop).Name);
1245 : }
1246 43762 : if (!state.dataSurface->Surface(SurfLoop).HeatTransSurf) continue;
1247 :
1248 42207 : if (state.dataSurface->Surface(SurfLoop).Class == SurfaceClass::Window) {
1249 : // CurrentModuleObject='Windows/GlassDoors'
1250 5974 : if (state.dataSurface->Surface(SurfLoop).ExtSolar) {
1251 17874 : SetupOutputVariable(state,
1252 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
1253 : OutputProcessor::Unit::W,
1254 5958 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
1255 : OutputProcessor::SOVTimeStepType::Zone,
1256 : OutputProcessor::SOVStoreType::Average,
1257 11916 : state.dataSurface->Surface(SurfLoop).Name);
1258 17874 : SetupOutputVariable(state,
1259 : "Surface Window Total Glazing Layers Absorbed Shortwave Radiation Rate",
1260 : OutputProcessor::Unit::W,
1261 5958 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfLoop),
1262 : OutputProcessor::SOVTimeStepType::Zone,
1263 : OutputProcessor::SOVStoreType::Average,
1264 11916 : state.dataSurface->Surface(SurfLoop).Name);
1265 :
1266 5958 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF) {
1267 24 : NumOfLayers = state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).TotSolidLayers;
1268 : } else {
1269 5934 : NumOfLayers = state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).TotLayers;
1270 : }
1271 15910 : for (I = 1; I <= NumOfLayers; ++I) {
1272 9952 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF) {
1273 340 : SetupOutputVariable(state,
1274 136 : format("Surface Window Total Absorbed Shortwave Radiation Rate Layer {}", I),
1275 : OutputProcessor::Unit::W,
1276 136 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfLoop, I),
1277 : OutputProcessor::SOVTimeStepType::Zone,
1278 : OutputProcessor::SOVStoreType::Average,
1279 68 : state.dataSurface->Surface(SurfLoop).Name);
1280 : }
1281 9952 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF || (I == 1)) {
1282 30010 : SetupOutputVariable(state,
1283 12004 : format("Surface Window Front Face Temperature Layer {}", I),
1284 : OutputProcessor::Unit::C,
1285 12004 : state.dataHeatBal->SurfWinFenLaySurfTempFront(SurfLoop, I),
1286 : OutputProcessor::SOVTimeStepType::Zone,
1287 : OutputProcessor::SOVStoreType::Average,
1288 6002 : state.dataSurface->Surface(SurfLoop).Name);
1289 : }
1290 9952 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeBSDF || (I == NumOfLayers)) {
1291 30010 : SetupOutputVariable(state,
1292 12004 : format("Surface Window Back Face Temperature Layer {}", I),
1293 : OutputProcessor::Unit::C,
1294 12004 : state.dataHeatBal->SurfWinFenLaySurfTempBack(SurfLoop, I),
1295 : OutputProcessor::SOVTimeStepType::Zone,
1296 : OutputProcessor::SOVStoreType::Average,
1297 6002 : state.dataSurface->Surface(SurfLoop).Name);
1298 : }
1299 : }
1300 :
1301 17874 : SetupOutputVariable(state,
1302 : "Surface Window Transmitted Solar Radiation Rate",
1303 : OutputProcessor::Unit::W,
1304 5958 : state.dataSurface->SurfWinTransSolar(SurfLoop),
1305 : OutputProcessor::SOVTimeStepType::Zone,
1306 : OutputProcessor::SOVStoreType::Average,
1307 11916 : state.dataSurface->Surface(SurfLoop).Name);
1308 17874 : SetupOutputVariable(state,
1309 : "Surface Window Transmitted Beam Solar Radiation Rate",
1310 : OutputProcessor::Unit::W,
1311 5958 : state.dataSurface->SurfWinBmSolar(SurfLoop),
1312 : OutputProcessor::SOVTimeStepType::Zone,
1313 : OutputProcessor::SOVStoreType::Average,
1314 11916 : state.dataSurface->Surface(SurfLoop).Name);
1315 :
1316 : // added TH 12/9/2009
1317 17874 : SetupOutputVariable(state,
1318 : "Surface Window Transmitted Beam To Beam Solar Radiation Rate",
1319 : OutputProcessor::Unit::W,
1320 5958 : state.dataSurface->SurfWinBmBmSolar(SurfLoop),
1321 : OutputProcessor::SOVTimeStepType::Zone,
1322 : OutputProcessor::SOVStoreType::Average,
1323 11916 : state.dataSurface->Surface(SurfLoop).Name);
1324 17874 : SetupOutputVariable(state,
1325 : "Surface Window Transmitted Beam To Diffuse Solar Radiation Rate",
1326 : OutputProcessor::Unit::W,
1327 5958 : state.dataSurface->SurfWinBmDifSolar(SurfLoop),
1328 : OutputProcessor::SOVTimeStepType::Zone,
1329 : OutputProcessor::SOVStoreType::Average,
1330 11916 : state.dataSurface->Surface(SurfLoop).Name);
1331 :
1332 17874 : SetupOutputVariable(state,
1333 : "Surface Window Transmitted Diffuse Solar Radiation Rate",
1334 : OutputProcessor::Unit::W,
1335 5958 : state.dataSurface->SurfWinDifSolar(SurfLoop),
1336 : OutputProcessor::SOVTimeStepType::Zone,
1337 : OutputProcessor::SOVStoreType::Average,
1338 11916 : state.dataSurface->Surface(SurfLoop).Name);
1339 17874 : SetupOutputVariable(state,
1340 : "Surface Window Heat Gain Rate",
1341 : OutputProcessor::Unit::W,
1342 5958 : state.dataSurface->SurfWinHeatGainRep(SurfLoop),
1343 : OutputProcessor::SOVTimeStepType::Zone,
1344 : OutputProcessor::SOVStoreType::Average,
1345 11916 : state.dataSurface->Surface(SurfLoop).Name);
1346 17874 : SetupOutputVariable(state,
1347 : "Surface Window Heat Loss Rate",
1348 : OutputProcessor::Unit::W,
1349 5958 : state.dataSurface->SurfWinHeatLossRep(SurfLoop),
1350 : OutputProcessor::SOVTimeStepType::Zone,
1351 : OutputProcessor::SOVStoreType::Average,
1352 11916 : state.dataSurface->Surface(SurfLoop).Name);
1353 17874 : SetupOutputVariable(state,
1354 : "Surface Window Gap Convective Heat Transfer Rate",
1355 : OutputProcessor::Unit::W,
1356 5958 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfLoop),
1357 : OutputProcessor::SOVTimeStepType::Zone,
1358 : OutputProcessor::SOVStoreType::Average,
1359 11916 : state.dataSurface->Surface(SurfLoop).Name);
1360 17874 : SetupOutputVariable(state,
1361 : "Surface Window Shading Device Absorbed Solar Radiation Rate",
1362 : OutputProcessor::Unit::W,
1363 5958 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfLoop),
1364 : OutputProcessor::SOVTimeStepType::Zone,
1365 : OutputProcessor::SOVStoreType::Average,
1366 11916 : state.dataSurface->Surface(SurfLoop).Name);
1367 17874 : SetupOutputVariable(state,
1368 : "Surface Window Net Heat Transfer Rate",
1369 : OutputProcessor::Unit::W,
1370 5958 : state.dataSurface->SurfWinHeatGain(SurfLoop),
1371 : OutputProcessor::SOVTimeStepType::Zone,
1372 : OutputProcessor::SOVStoreType::Average,
1373 11916 : state.dataSurface->Surface(SurfLoop).Name);
1374 :
1375 5958 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
1376 : // CurrentModuleObject='Windows/GlassDoors(Advanced)'
1377 378 : SetupOutputVariable(state,
1378 : "Surface Window Inside Face Glazing Zone Convection Heat Gain Rate",
1379 : OutputProcessor::Unit::W,
1380 126 : state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfLoop),
1381 : OutputProcessor::SOVTimeStepType::Zone,
1382 : OutputProcessor::SOVStoreType::Average,
1383 252 : state.dataSurface->Surface(SurfLoop).Name);
1384 378 : SetupOutputVariable(state,
1385 : "Surface Window Inside Face Glazing Net Infrared Heat Transfer Rate",
1386 : OutputProcessor::Unit::W,
1387 126 : state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfLoop),
1388 : OutputProcessor::SOVTimeStepType::Zone,
1389 : OutputProcessor::SOVStoreType::Average,
1390 252 : state.dataSurface->Surface(SurfLoop).Name);
1391 378 : SetupOutputVariable(state,
1392 : "Surface Window Shortwave from Zone Back Out Window Heat Transfer Rate",
1393 : OutputProcessor::Unit::W,
1394 126 : state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfLoop),
1395 : OutputProcessor::SOVTimeStepType::Zone,
1396 : OutputProcessor::SOVStoreType::Average,
1397 252 : state.dataSurface->Surface(SurfLoop).Name);
1398 378 : SetupOutputVariable(state,
1399 : "Surface Window Inside Face Frame and Divider Zone Heat Gain Rate",
1400 : OutputProcessor::Unit::W,
1401 126 : state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfLoop),
1402 : OutputProcessor::SOVTimeStepType::Zone,
1403 : OutputProcessor::SOVStoreType::Average,
1404 252 : state.dataSurface->Surface(SurfLoop).Name);
1405 378 : SetupOutputVariable(state,
1406 : "Surface Window Inside Face Gap between Shade and Glazing Zone Convection Heat Gain Rate",
1407 : OutputProcessor::Unit::W,
1408 126 : state.dataSurface->SurfWinConvHeatFlowNatural(SurfLoop),
1409 : OutputProcessor::SOVTimeStepType::Zone,
1410 : OutputProcessor::SOVStoreType::Average,
1411 252 : state.dataSurface->Surface(SurfLoop).Name);
1412 378 : SetupOutputVariable(state,
1413 : "Surface Window Inside Face Shade Zone Convection Heat Gain Rate",
1414 : OutputProcessor::Unit::W,
1415 126 : state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfLoop),
1416 : OutputProcessor::SOVTimeStepType::Zone,
1417 : OutputProcessor::SOVStoreType::Average,
1418 252 : state.dataSurface->Surface(SurfLoop).Name);
1419 378 : SetupOutputVariable(state,
1420 : "Surface Window Inside Face Shade Net Infrared Heat Transfer Rate",
1421 : OutputProcessor::Unit::W,
1422 126 : state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfLoop),
1423 : OutputProcessor::SOVTimeStepType::Zone,
1424 : OutputProcessor::SOVStoreType::Average,
1425 252 : state.dataSurface->Surface(SurfLoop).Name);
1426 126 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).WindowTypeEQL) {
1427 0 : SetupOutputVariable(state,
1428 : "Surface Window Inside Face Other Convection Heat Gain Rate",
1429 : OutputProcessor::Unit::W,
1430 0 : state.dataSurface->SurfWinOtherConvHeatGain(SurfLoop),
1431 : OutputProcessor::SOVTimeStepType::Zone,
1432 : OutputProcessor::SOVStoreType::Average,
1433 0 : state.dataSurface->Surface(SurfLoop).Name);
1434 : }
1435 : }
1436 :
1437 : // Added TH 12/23/2008 for thermochromic windows
1438 : // CurrentModuleObject='Thermochromic Windows'
1439 5958 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfLoop).Construction).TCFlag == 1) {
1440 3 : SetupOutputVariable(state,
1441 : "Surface Window Thermochromic Layer Temperature",
1442 : OutputProcessor::Unit::C,
1443 1 : state.dataSurface->SurfWinTCLayerTemp(SurfLoop),
1444 : OutputProcessor::SOVTimeStepType::Zone,
1445 : OutputProcessor::SOVStoreType::Average,
1446 2 : state.dataSurface->Surface(SurfLoop).Name);
1447 3 : SetupOutputVariable(state,
1448 : "Surface Window Thermochromic Layer Property Specification Temperature",
1449 : OutputProcessor::Unit::C,
1450 1 : state.dataSurface->SurfWinSpecTemp(SurfLoop),
1451 : OutputProcessor::SOVTimeStepType::Zone,
1452 : OutputProcessor::SOVStoreType::Average,
1453 2 : state.dataSurface->Surface(SurfLoop).Name);
1454 : }
1455 :
1456 : // Added TH 5/26/2009 for switchable windows to report switching factor (tinted level)
1457 : // CurrentModuleObject='Switchable Windows'
1458 5958 : if (state.dataSurface->Surface(SurfLoop).HasShadeControl) {
1459 143 : if (state.dataSurface->WindowShadingControl(state.dataSurface->Surface(SurfLoop).activeWindowShadingControl).ShadingType ==
1460 : WinShadingType::SwitchableGlazing) {
1461 : // IF (SurfaceWindow(SurfLoop)%ShadingFlag == WinShadingType::SwitchableGlazing) THEN !ShadingFlag is not set to
1462 : // WinShadingType::SwitchableGlazing yet!
1463 90 : SetupOutputVariable(state,
1464 : "Surface Window Switchable Glazing Switching Factor",
1465 : OutputProcessor::Unit::None,
1466 30 : state.dataSurface->SurfWinSwitchingFactor(SurfLoop),
1467 : OutputProcessor::SOVTimeStepType::Zone,
1468 : OutputProcessor::SOVStoreType::Average,
1469 60 : state.dataSurface->Surface(SurfLoop).Name);
1470 90 : SetupOutputVariable(state,
1471 : "Surface Window Switchable Glazing Visible Transmittance",
1472 : OutputProcessor::Unit::None,
1473 30 : state.dataSurface->SurfWinVisTransSelected(SurfLoop),
1474 : OutputProcessor::SOVTimeStepType::Zone,
1475 : OutputProcessor::SOVStoreType::Average,
1476 60 : state.dataSurface->Surface(SurfLoop).Name);
1477 : }
1478 : }
1479 :
1480 5958 : if (state.dataSurface->SurfWinFrameArea(SurfLoop) > 0.0) {
1481 : // CurrentModuleObject='Window Frames'
1482 390 : SetupOutputVariable(state,
1483 : "Surface Window Frame Heat Gain Rate",
1484 : OutputProcessor::Unit::W,
1485 130 : state.dataSurface->SurfWinFrameHeatGain(SurfLoop),
1486 : OutputProcessor::SOVTimeStepType::Zone,
1487 : OutputProcessor::SOVStoreType::Average,
1488 260 : state.dataSurface->Surface(SurfLoop).Name);
1489 390 : SetupOutputVariable(state,
1490 : "Surface Window Frame Heat Loss Rate",
1491 : OutputProcessor::Unit::W,
1492 130 : state.dataSurface->SurfWinFrameHeatLoss(SurfLoop),
1493 : OutputProcessor::SOVTimeStepType::Zone,
1494 : OutputProcessor::SOVStoreType::Average,
1495 260 : state.dataSurface->Surface(SurfLoop).Name);
1496 390 : SetupOutputVariable(state,
1497 : "Surface Window Frame Inside Temperature",
1498 : OutputProcessor::Unit::C,
1499 130 : state.dataSurface->SurfWinFrameTempIn(SurfLoop),
1500 : OutputProcessor::SOVTimeStepType::Zone,
1501 : OutputProcessor::SOVStoreType::Average,
1502 260 : state.dataSurface->Surface(SurfLoop).Name);
1503 390 : SetupOutputVariable(state,
1504 : "Surface Window Frame Outside Temperature",
1505 : OutputProcessor::Unit::C,
1506 130 : state.dataSurface->SurfWinFrameTempSurfOut(SurfLoop),
1507 : OutputProcessor::SOVTimeStepType::Zone,
1508 : OutputProcessor::SOVStoreType::Average,
1509 260 : state.dataSurface->Surface(SurfLoop).Name);
1510 : }
1511 5958 : if (state.dataSurface->SurfWinDividerArea(SurfLoop) > 0.0) {
1512 : // CurrentModuleObject='Window Dividers'
1513 192 : SetupOutputVariable(state,
1514 : "Surface Window Divider Heat Gain Rate",
1515 : OutputProcessor::Unit::W,
1516 64 : state.dataSurface->SurfWinDividerHeatGain(SurfLoop),
1517 : OutputProcessor::SOVTimeStepType::Zone,
1518 : OutputProcessor::SOVStoreType::Average,
1519 128 : state.dataSurface->Surface(SurfLoop).Name);
1520 192 : SetupOutputVariable(state,
1521 : "Surface Window Divider Heat Loss Rate",
1522 : OutputProcessor::Unit::W,
1523 64 : state.dataSurface->SurfWinDividerHeatLoss(SurfLoop),
1524 : OutputProcessor::SOVTimeStepType::Zone,
1525 : OutputProcessor::SOVStoreType::Average,
1526 128 : state.dataSurface->Surface(SurfLoop).Name);
1527 192 : SetupOutputVariable(state,
1528 : "Surface Window Divider Inside Temperature",
1529 : OutputProcessor::Unit::C,
1530 64 : state.dataSurface->SurfWinDividerTempIn(SurfLoop),
1531 : OutputProcessor::SOVTimeStepType::Zone,
1532 : OutputProcessor::SOVStoreType::Average,
1533 128 : state.dataSurface->Surface(SurfLoop).Name);
1534 192 : SetupOutputVariable(state,
1535 : "Surface Window Divider Outside Temperature",
1536 : OutputProcessor::Unit::C,
1537 64 : state.dataSurface->SurfWinDividerTempSurfOut(SurfLoop),
1538 : OutputProcessor::SOVTimeStepType::Zone,
1539 : OutputProcessor::SOVStoreType::Average,
1540 128 : state.dataSurface->Surface(SurfLoop).Name);
1541 : }
1542 :
1543 : // CurrentModuleObject='Windows'
1544 : // Energy
1545 17874 : SetupOutputVariable(state,
1546 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
1547 : OutputProcessor::Unit::J,
1548 5958 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
1549 : OutputProcessor::SOVTimeStepType::Zone,
1550 : OutputProcessor::SOVStoreType::Summed,
1551 11916 : state.dataSurface->Surface(SurfLoop).Name);
1552 17874 : SetupOutputVariable(state,
1553 : "Surface Window Transmitted Solar Radiation Energy",
1554 : OutputProcessor::Unit::J,
1555 5958 : state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
1556 : OutputProcessor::SOVTimeStepType::Zone,
1557 : OutputProcessor::SOVStoreType::Summed,
1558 11916 : state.dataSurface->Surface(SurfLoop).Name);
1559 17874 : SetupOutputVariable(state,
1560 : "Surface Window Transmitted Beam Solar Radiation Energy",
1561 : OutputProcessor::Unit::J,
1562 5958 : state.dataSurface->SurfWinBmSolarEnergy(SurfLoop),
1563 : OutputProcessor::SOVTimeStepType::Zone,
1564 : OutputProcessor::SOVStoreType::Summed,
1565 11916 : state.dataSurface->Surface(SurfLoop).Name);
1566 :
1567 : // added TH 12/9/2009
1568 17874 : SetupOutputVariable(state,
1569 : "Surface Window Transmitted Beam To Beam Solar Radiation Energy",
1570 : OutputProcessor::Unit::J,
1571 5958 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfLoop),
1572 : OutputProcessor::SOVTimeStepType::Zone,
1573 : OutputProcessor::SOVStoreType::Summed,
1574 11916 : state.dataSurface->Surface(SurfLoop).Name);
1575 17874 : SetupOutputVariable(state,
1576 : "Surface Window Transmitted Beam To Diffuse Solar Radiation Energy",
1577 : OutputProcessor::Unit::J,
1578 5958 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfLoop),
1579 : OutputProcessor::SOVTimeStepType::Zone,
1580 : OutputProcessor::SOVStoreType::Summed,
1581 11916 : state.dataSurface->Surface(SurfLoop).Name);
1582 :
1583 17874 : SetupOutputVariable(state,
1584 : "Surface Window Transmitted Diffuse Solar Radiation Energy",
1585 : OutputProcessor::Unit::J,
1586 5958 : state.dataSurface->SurfWinDifSolarEnergy(SurfLoop),
1587 : OutputProcessor::SOVTimeStepType::Zone,
1588 : OutputProcessor::SOVStoreType::Summed,
1589 11916 : state.dataSurface->Surface(SurfLoop).Name);
1590 17874 : SetupOutputVariable(state,
1591 : "Surface Window Heat Gain Energy",
1592 : OutputProcessor::Unit::J,
1593 5958 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfLoop),
1594 : OutputProcessor::SOVTimeStepType::Zone,
1595 : OutputProcessor::SOVStoreType::Summed,
1596 11916 : state.dataSurface->Surface(SurfLoop).Name);
1597 17874 : SetupOutputVariable(state,
1598 : "Surface Window Heat Loss Energy",
1599 : OutputProcessor::Unit::J,
1600 5958 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfLoop),
1601 : OutputProcessor::SOVTimeStepType::Zone,
1602 : OutputProcessor::SOVStoreType::Summed,
1603 11916 : state.dataSurface->Surface(SurfLoop).Name);
1604 17874 : SetupOutputVariable(state,
1605 : "Surface Window Gap Convective Heat Transfer Energy",
1606 : OutputProcessor::Unit::J,
1607 5958 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfLoop),
1608 : OutputProcessor::SOVTimeStepType::Zone,
1609 : OutputProcessor::SOVStoreType::Summed,
1610 11916 : state.dataSurface->Surface(SurfLoop).Name);
1611 17874 : SetupOutputVariable(state,
1612 : "Surface Window Shading Device Absorbed Solar Radiation Energy",
1613 : OutputProcessor::Unit::J,
1614 5958 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfLoop),
1615 : OutputProcessor::SOVTimeStepType::Zone,
1616 : OutputProcessor::SOVStoreType::Summed,
1617 11916 : state.dataSurface->Surface(SurfLoop).Name);
1618 17874 : SetupOutputVariable(state,
1619 : "Surface Window Net Heat Transfer Energy",
1620 : OutputProcessor::Unit::J,
1621 5958 : state.dataSurface->SurfWinHeatTransferRepEnergy(SurfLoop),
1622 : OutputProcessor::SOVTimeStepType::Zone,
1623 : OutputProcessor::SOVStoreType::Summed,
1624 11916 : state.dataSurface->Surface(SurfLoop).Name);
1625 :
1626 17874 : SetupOutputVariable(state,
1627 : "Surface Window System Solar Transmittance",
1628 : OutputProcessor::Unit::None,
1629 5958 : state.dataSurface->SurfWinSysSolTransmittance(SurfLoop),
1630 : OutputProcessor::SOVTimeStepType::Zone,
1631 : OutputProcessor::SOVStoreType::Average,
1632 11916 : state.dataSurface->Surface(SurfLoop).Name);
1633 17874 : SetupOutputVariable(state,
1634 : "Surface Window System Solar Reflectance",
1635 : OutputProcessor::Unit::None,
1636 5958 : state.dataSurface->SurfWinSysSolReflectance(SurfLoop),
1637 : OutputProcessor::SOVTimeStepType::Zone,
1638 : OutputProcessor::SOVStoreType::Average,
1639 11916 : state.dataSurface->Surface(SurfLoop).Name);
1640 17874 : SetupOutputVariable(state,
1641 : "Surface Window System Solar Absorptance",
1642 : OutputProcessor::Unit::None,
1643 5958 : state.dataSurface->SurfWinSysSolAbsorptance(SurfLoop),
1644 : OutputProcessor::SOVTimeStepType::Zone,
1645 : OutputProcessor::SOVStoreType::Average,
1646 11916 : state.dataSurface->Surface(SurfLoop).Name);
1647 23832 : SetupOutputVariable(state,
1648 : "Surface Window Inside Face Glazing Condensation Status",
1649 : OutputProcessor::Unit::None,
1650 5958 : state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfLoop),
1651 : OutputProcessor::SOVTimeStepType::Zone,
1652 : OutputProcessor::SOVStoreType::State,
1653 11916 : state.dataSurface->Surface(SurfLoop).Name);
1654 23832 : SetupOutputVariable(state,
1655 : "Surface Window Inside Face Frame Condensation Status",
1656 : OutputProcessor::Unit::None,
1657 5958 : state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfLoop),
1658 : OutputProcessor::SOVTimeStepType::Zone,
1659 : OutputProcessor::SOVStoreType::State,
1660 11916 : state.dataSurface->Surface(SurfLoop).Name);
1661 23832 : SetupOutputVariable(state,
1662 : "Surface Window Inside Face Divider Condensation Status",
1663 : OutputProcessor::Unit::None,
1664 5958 : state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfLoop),
1665 : OutputProcessor::SOVTimeStepType::Zone,
1666 : OutputProcessor::SOVStoreType::State,
1667 11916 : state.dataSurface->Surface(SurfLoop).Name);
1668 :
1669 : // Outside reveal report variables
1670 : // IF (Surface(SurfLoop)%Reveal > 0.0) THEN
1671 17874 : SetupOutputVariable(state,
1672 : "Surface Window Outside Reveal Reflected Beam Solar Radiation Rate",
1673 : OutputProcessor::Unit::W,
1674 5958 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfLoop),
1675 : OutputProcessor::SOVTimeStepType::Zone,
1676 : OutputProcessor::SOVStoreType::State,
1677 11916 : state.dataSurface->Surface(SurfLoop).Name);
1678 : // Energy
1679 17874 : SetupOutputVariable(state,
1680 : "Surface Window Outside Reveal Reflected Beam Solar Radiation Energy",
1681 : OutputProcessor::Unit::J,
1682 5958 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfLoop),
1683 : OutputProcessor::SOVTimeStepType::Zone,
1684 : OutputProcessor::SOVStoreType::Summed,
1685 11916 : state.dataSurface->Surface(SurfLoop).Name);
1686 : // ENDIF
1687 :
1688 : // Inside reveal report variables
1689 5958 : if (state.dataSurface->SurfWinInsideReveal(SurfLoop) > 0.0 || state.dataSurface->SurfWinInsideSillDepth(SurfLoop) > 0.0) {
1690 0 : SetupOutputVariable(state,
1691 : "Surface Window Inside Reveal Reflected Beam Solar Radiation Rate",
1692 : OutputProcessor::Unit::W,
1693 0 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfLoop),
1694 : OutputProcessor::SOVTimeStepType::Zone,
1695 : OutputProcessor::SOVStoreType::State,
1696 0 : state.dataSurface->Surface(SurfLoop).Name);
1697 : // Energy
1698 0 : SetupOutputVariable(state,
1699 : "Surface Window Inside Reveal Reflected Beam Solar Radiation Energy",
1700 : OutputProcessor::Unit::J,
1701 0 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfLoop),
1702 : OutputProcessor::SOVTimeStepType::Zone,
1703 : OutputProcessor::SOVStoreType::Summed,
1704 0 : state.dataSurface->Surface(SurfLoop).Name);
1705 :
1706 : // Added report variables for inside reveal to debug CR 7596. TH 5/26/2009
1707 : // All reflected solar by the inside reveal is turned into diffuse
1708 0 : SetupOutputVariable(state,
1709 : "Surface Window Inside Reveal Absorbed Beam Solar Radiation Rate",
1710 : OutputProcessor::Unit::W,
1711 0 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfLoop),
1712 : OutputProcessor::SOVTimeStepType::Zone,
1713 : OutputProcessor::SOVStoreType::State,
1714 0 : state.dataSurface->Surface(SurfLoop).Name);
1715 0 : SetupOutputVariable(state,
1716 : "Surface Window Inside Reveal Reflected Diffuse Zone Solar Radiation Rate",
1717 : OutputProcessor::Unit::W,
1718 0 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfLoop),
1719 : OutputProcessor::SOVTimeStepType::Zone,
1720 : OutputProcessor::SOVStoreType::State,
1721 0 : state.dataSurface->Surface(SurfLoop).Name);
1722 0 : SetupOutputVariable(state,
1723 : "Surface Window Inside Reveal Reflected Diffuse Frame Solar Radiation Rate",
1724 : OutputProcessor::Unit::W,
1725 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfLoop),
1726 : OutputProcessor::SOVTimeStepType::Zone,
1727 : OutputProcessor::SOVStoreType::State,
1728 0 : state.dataSurface->Surface(SurfLoop).Name);
1729 0 : SetupOutputVariable(state,
1730 : "Surface Window Inside Reveal Reflected Diffuse Glazing Solar Radiation Rate",
1731 : OutputProcessor::Unit::W,
1732 0 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfLoop),
1733 : OutputProcessor::SOVTimeStepType::Zone,
1734 : OutputProcessor::SOVStoreType::State,
1735 0 : state.dataSurface->Surface(SurfLoop).Name);
1736 : }
1737 :
1738 : // Output blind report variables only when blinds are used
1739 5958 : if (state.dataSurface->SurfWinBlindNumber(SurfLoop) > 0) {
1740 : // CurrentModuleObject='Window Blinds'
1741 102 : SetupOutputVariable(state,
1742 : "Surface Window Blind Beam to Beam Solar Transmittance",
1743 : OutputProcessor::Unit::None,
1744 34 : state.dataSurface->SurfWinBlTsolBmBm(SurfLoop),
1745 : OutputProcessor::SOVTimeStepType::Zone,
1746 : OutputProcessor::SOVStoreType::State,
1747 68 : state.dataSurface->Surface(SurfLoop).Name);
1748 102 : SetupOutputVariable(state,
1749 : "Surface Window Blind Beam to Diffuse Solar Transmittance",
1750 : OutputProcessor::Unit::None,
1751 34 : state.dataSurface->SurfWinBlTsolBmDif(SurfLoop),
1752 : OutputProcessor::SOVTimeStepType::Zone,
1753 : OutputProcessor::SOVStoreType::State,
1754 68 : state.dataSurface->Surface(SurfLoop).Name);
1755 102 : SetupOutputVariable(state,
1756 : "Surface Window Blind Diffuse to Diffuse Solar Transmittance",
1757 : OutputProcessor::Unit::None,
1758 34 : state.dataSurface->SurfWinBlTsolDifDif(SurfLoop),
1759 : OutputProcessor::SOVTimeStepType::Zone,
1760 : OutputProcessor::SOVStoreType::State,
1761 68 : state.dataSurface->Surface(SurfLoop).Name);
1762 102 : SetupOutputVariable(state,
1763 : "Surface Window Blind and Glazing System Beam Solar Transmittance",
1764 : OutputProcessor::Unit::None,
1765 34 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfLoop),
1766 : OutputProcessor::SOVTimeStepType::Zone,
1767 : OutputProcessor::SOVStoreType::State,
1768 68 : state.dataSurface->Surface(SurfLoop).Name);
1769 102 : SetupOutputVariable(state,
1770 : "Surface Window Blind and Glazing System Diffuse Solar Transmittance",
1771 : OutputProcessor::Unit::None,
1772 34 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfLoop),
1773 : OutputProcessor::SOVTimeStepType::Zone,
1774 : OutputProcessor::SOVStoreType::State,
1775 68 : state.dataSurface->Surface(SurfLoop).Name);
1776 : }
1777 :
1778 : // Output screen report variables only when screens are used
1779 5958 : if (state.dataSurface->SurfWinScreenNumber(SurfLoop) > 0) {
1780 : // CurrentModuleObject='Window Screens'
1781 24 : SetupOutputVariable(state,
1782 : "Surface Window Screen Beam to Beam Solar Transmittance",
1783 : OutputProcessor::Unit::None,
1784 8 : state.dataSurface->SurfWinScTsolBmBm(SurfLoop),
1785 : OutputProcessor::SOVTimeStepType::Zone,
1786 : OutputProcessor::SOVStoreType::State,
1787 16 : state.dataSurface->Surface(SurfLoop).Name);
1788 24 : SetupOutputVariable(state,
1789 : "Surface Window Screen Beam to Diffuse Solar Transmittance",
1790 : OutputProcessor::Unit::None,
1791 8 : state.dataSurface->SurfWinScTsolBmDif(SurfLoop),
1792 : OutputProcessor::SOVTimeStepType::Zone,
1793 : OutputProcessor::SOVStoreType::State,
1794 16 : state.dataSurface->Surface(SurfLoop).Name);
1795 24 : SetupOutputVariable(state,
1796 : "Surface Window Screen Diffuse to Diffuse Solar Transmittance",
1797 : OutputProcessor::Unit::None,
1798 8 : state.dataSurface->SurfWinScTsolDifDif(SurfLoop),
1799 : OutputProcessor::SOVTimeStepType::Zone,
1800 : OutputProcessor::SOVStoreType::State,
1801 16 : state.dataSurface->Surface(SurfLoop).Name);
1802 24 : SetupOutputVariable(state,
1803 : "Surface Window Screen and Glazing System Beam Solar Transmittance",
1804 : OutputProcessor::Unit::None,
1805 8 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfLoop),
1806 : OutputProcessor::SOVTimeStepType::Zone,
1807 : OutputProcessor::SOVStoreType::State,
1808 16 : state.dataSurface->Surface(SurfLoop).Name);
1809 24 : SetupOutputVariable(state,
1810 : "Surface Window Screen and Glazing System Diffuse Solar Transmittance",
1811 : OutputProcessor::Unit::None,
1812 8 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfLoop),
1813 : OutputProcessor::SOVTimeStepType::Zone,
1814 : OutputProcessor::SOVStoreType::State,
1815 16 : state.dataSurface->Surface(SurfLoop).Name);
1816 : }
1817 :
1818 : // CurrentModuleObject='Windows'
1819 17874 : SetupOutputVariable(state,
1820 : "Surface Window Solar Horizontal Profile Angle",
1821 : OutputProcessor::Unit::deg,
1822 5958 : state.dataSurface->SurfWinProfileAngHor(SurfLoop),
1823 : OutputProcessor::SOVTimeStepType::Zone,
1824 : OutputProcessor::SOVStoreType::State,
1825 11916 : state.dataSurface->Surface(SurfLoop).Name);
1826 17874 : SetupOutputVariable(state,
1827 : "Surface Window Solar Vertical Profile Angle",
1828 : OutputProcessor::Unit::deg,
1829 5958 : state.dataSurface->SurfWinProfileAngVert(SurfLoop),
1830 : OutputProcessor::SOVTimeStepType::Zone,
1831 : OutputProcessor::SOVStoreType::State,
1832 11916 : state.dataSurface->Surface(SurfLoop).Name);
1833 17874 : SetupOutputVariable(state,
1834 : "Surface Window Glazing Beam to Beam Solar Transmittance",
1835 : OutputProcessor::Unit::None,
1836 5958 : state.dataSurface->SurfWinGlTsolBmBm(SurfLoop),
1837 : OutputProcessor::SOVTimeStepType::Zone,
1838 : OutputProcessor::SOVStoreType::State,
1839 11916 : state.dataSurface->Surface(SurfLoop).Name);
1840 17874 : SetupOutputVariable(state,
1841 : "Surface Window Glazing Beam to Diffuse Solar Transmittance",
1842 : OutputProcessor::Unit::None,
1843 5958 : state.dataSurface->SurfWinGlTsolBmDif(SurfLoop),
1844 : OutputProcessor::SOVTimeStepType::Zone,
1845 : OutputProcessor::SOVStoreType::State,
1846 11916 : state.dataSurface->Surface(SurfLoop).Name);
1847 17874 : SetupOutputVariable(state,
1848 : "Surface Window Glazing Diffuse to Diffuse Solar Transmittance",
1849 : OutputProcessor::Unit::None,
1850 5958 : state.dataSurface->SurfWinGlTsolDifDif(SurfLoop),
1851 : OutputProcessor::SOVTimeStepType::Zone,
1852 : OutputProcessor::SOVStoreType::State,
1853 11916 : state.dataSurface->Surface(SurfLoop).Name);
1854 23832 : SetupOutputVariable(state,
1855 : "Surface Window Model Solver Iteration Count",
1856 : OutputProcessor::Unit::None,
1857 5958 : state.dataSurface->SurfWinWindowCalcIterationsRep(SurfLoop),
1858 : OutputProcessor::SOVTimeStepType::Zone,
1859 : OutputProcessor::SOVStoreType::State,
1860 11916 : state.dataSurface->Surface(SurfLoop).Name);
1861 : } else { // Not ExtSolar
1862 16 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
1863 : // CurrentModuleObject='InteriorWindows(Advanced)'
1864 0 : if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
1865 0 : SetupOutputVariable(state,
1866 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
1867 : OutputProcessor::Unit::W,
1868 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
1869 : OutputProcessor::SOVTimeStepType::Zone,
1870 : OutputProcessor::SOVStoreType::Average,
1871 0 : state.dataSurface->Surface(SurfLoop).Name);
1872 : }
1873 0 : SetupOutputVariable(state,
1874 : "Surface Window Total Glazing Layers Absorbed Shortwave Radiation Rate",
1875 : OutputProcessor::Unit::W,
1876 0 : state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfLoop),
1877 : OutputProcessor::SOVTimeStepType::Zone,
1878 : OutputProcessor::SOVStoreType::Average,
1879 0 : state.dataSurface->Surface(SurfLoop).Name);
1880 :
1881 0 : if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
1882 0 : SetupOutputVariable(state,
1883 : "Surface Window Transmitted Solar Radiation Rate",
1884 : OutputProcessor::Unit::W,
1885 0 : state.dataSurface->SurfWinTransSolar(SurfLoop),
1886 : OutputProcessor::SOVTimeStepType::Zone,
1887 : OutputProcessor::SOVStoreType::Average,
1888 0 : state.dataSurface->Surface(SurfLoop).Name);
1889 : }
1890 0 : SetupOutputVariable(state,
1891 : "Surface Window Transmitted Beam Solar Radiation Rate",
1892 : OutputProcessor::Unit::W,
1893 0 : state.dataSurface->SurfWinBmSolar(SurfLoop),
1894 : OutputProcessor::SOVTimeStepType::Zone,
1895 : OutputProcessor::SOVStoreType::Average,
1896 0 : state.dataSurface->Surface(SurfLoop).Name);
1897 :
1898 : // added TH 12/9/2009
1899 0 : SetupOutputVariable(state,
1900 : "Surface Window Transmitted Beam To Beam Solar Radiation Rate",
1901 : OutputProcessor::Unit::W,
1902 0 : state.dataSurface->SurfWinBmBmSolar(SurfLoop),
1903 : OutputProcessor::SOVTimeStepType::Zone,
1904 : OutputProcessor::SOVStoreType::Average,
1905 0 : state.dataSurface->Surface(SurfLoop).Name);
1906 0 : SetupOutputVariable(state,
1907 : "Surface Window Transmitted Beam To Diffuse Solar Radiation Rate",
1908 : OutputProcessor::Unit::W,
1909 0 : state.dataSurface->SurfWinBmDifSolar(SurfLoop),
1910 : OutputProcessor::SOVTimeStepType::Zone,
1911 : OutputProcessor::SOVStoreType::Average,
1912 0 : state.dataSurface->Surface(SurfLoop).Name);
1913 :
1914 0 : SetupOutputVariable(state,
1915 : "Surface Window Transmitted Diffuse Solar Radiation Rate",
1916 : OutputProcessor::Unit::W,
1917 0 : state.dataSurface->SurfWinDifSolar(SurfLoop),
1918 : OutputProcessor::SOVTimeStepType::Zone,
1919 : OutputProcessor::SOVStoreType::Average,
1920 0 : state.dataSurface->Surface(SurfLoop).Name);
1921 0 : SetupOutputVariable(state,
1922 : "Surface Window Heat Gain Rate",
1923 : OutputProcessor::Unit::W,
1924 0 : state.dataSurface->SurfWinHeatGainRep(SurfLoop),
1925 : OutputProcessor::SOVTimeStepType::Zone,
1926 : OutputProcessor::SOVStoreType::Average,
1927 0 : state.dataSurface->Surface(SurfLoop).Name);
1928 0 : SetupOutputVariable(state,
1929 : "Surface Window Heat Loss Rate",
1930 : OutputProcessor::Unit::W,
1931 0 : state.dataSurface->SurfWinHeatLossRep(SurfLoop),
1932 : OutputProcessor::SOVTimeStepType::Zone,
1933 : OutputProcessor::SOVStoreType::Average,
1934 0 : state.dataSurface->Surface(SurfLoop).Name);
1935 0 : SetupOutputVariable(state,
1936 : "Surface Window Gap Convective Heat Transfer Rate",
1937 : OutputProcessor::Unit::W,
1938 0 : state.dataSurface->SurfWinGapConvHtFlowRep(SurfLoop),
1939 : OutputProcessor::SOVTimeStepType::Zone,
1940 : OutputProcessor::SOVStoreType::Average,
1941 0 : state.dataSurface->Surface(SurfLoop).Name);
1942 0 : SetupOutputVariable(state,
1943 : "Surface Window Shading Device Absorbed Solar Radiation Rate",
1944 : OutputProcessor::Unit::W,
1945 0 : state.dataSurface->SurfWinShadingAbsorbedSolar(SurfLoop),
1946 : OutputProcessor::SOVTimeStepType::Zone,
1947 : OutputProcessor::SOVStoreType::Average,
1948 0 : state.dataSurface->Surface(SurfLoop).Name);
1949 0 : if (state.dataSurface->SurfWinFrameArea(SurfLoop) > 0.0) {
1950 0 : SetupOutputVariable(state,
1951 : "Surface Window Frame Heat Gain Rate",
1952 : OutputProcessor::Unit::W,
1953 0 : state.dataSurface->SurfWinFrameHeatGain(SurfLoop),
1954 : OutputProcessor::SOVTimeStepType::Zone,
1955 : OutputProcessor::SOVStoreType::Average,
1956 0 : state.dataSurface->Surface(SurfLoop).Name);
1957 0 : SetupOutputVariable(state,
1958 : "Surface Window Frame Heat Loss Rate",
1959 : OutputProcessor::Unit::W,
1960 0 : state.dataSurface->SurfWinFrameHeatLoss(SurfLoop),
1961 : OutputProcessor::SOVTimeStepType::Zone,
1962 : OutputProcessor::SOVStoreType::Average,
1963 0 : state.dataSurface->Surface(SurfLoop).Name);
1964 0 : SetupOutputVariable(state,
1965 : "Surface Window Frame Inside Temperature",
1966 : OutputProcessor::Unit::C,
1967 0 : state.dataSurface->SurfWinFrameTempIn(SurfLoop),
1968 : OutputProcessor::SOVTimeStepType::Zone,
1969 : OutputProcessor::SOVStoreType::Average,
1970 0 : state.dataSurface->Surface(SurfLoop).Name);
1971 0 : SetupOutputVariable(state,
1972 : "Surface Window Frame Outside Temperature",
1973 : OutputProcessor::Unit::C,
1974 0 : state.dataSurface->SurfWinFrameTempSurfOut(SurfLoop),
1975 : OutputProcessor::SOVTimeStepType::Zone,
1976 : OutputProcessor::SOVStoreType::Average,
1977 0 : state.dataSurface->Surface(SurfLoop).Name);
1978 : }
1979 0 : if (state.dataSurface->SurfWinDividerArea(SurfLoop) > 0.0) {
1980 0 : SetupOutputVariable(state,
1981 : "Surface Window Divider Heat Gain Rate",
1982 : OutputProcessor::Unit::W,
1983 0 : state.dataSurface->SurfWinDividerHeatGain(SurfLoop),
1984 : OutputProcessor::SOVTimeStepType::Zone,
1985 : OutputProcessor::SOVStoreType::Average,
1986 0 : state.dataSurface->Surface(SurfLoop).Name);
1987 0 : SetupOutputVariable(state,
1988 : "Surface Window Divider Heat Loss Rate",
1989 : OutputProcessor::Unit::W,
1990 0 : state.dataSurface->SurfWinDividerHeatLoss(SurfLoop),
1991 : OutputProcessor::SOVTimeStepType::Zone,
1992 : OutputProcessor::SOVStoreType::Average,
1993 0 : state.dataSurface->Surface(SurfLoop).Name);
1994 0 : SetupOutputVariable(state,
1995 : "Surface Window Divider Inside Temperature",
1996 : OutputProcessor::Unit::C,
1997 0 : state.dataSurface->SurfWinDividerTempIn(SurfLoop),
1998 : OutputProcessor::SOVTimeStepType::Zone,
1999 : OutputProcessor::SOVStoreType::Average,
2000 0 : state.dataSurface->Surface(SurfLoop).Name);
2001 0 : SetupOutputVariable(state,
2002 : "Surface Window Divider Outside Temperature",
2003 : OutputProcessor::Unit::C,
2004 0 : state.dataSurface->SurfWinDividerTempSurfOut(SurfLoop),
2005 : OutputProcessor::SOVTimeStepType::Zone,
2006 : OutputProcessor::SOVStoreType::Average,
2007 0 : state.dataSurface->Surface(SurfLoop).Name);
2008 : }
2009 : // Energy
2010 :
2011 0 : if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
2012 0 : SetupOutputVariable(state,
2013 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
2014 : OutputProcessor::Unit::J,
2015 0 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
2016 : OutputProcessor::SOVTimeStepType::Zone,
2017 : OutputProcessor::SOVStoreType::Summed,
2018 0 : state.dataSurface->Surface(SurfLoop).Name);
2019 : }
2020 :
2021 0 : if (state.dataSurface->SurfWinOriginalClass(SurfLoop) != SurfaceClass::TDD_Diffuser) {
2022 0 : SetupOutputVariable(state,
2023 : "Surface Window Transmitted Solar Radiation Energy",
2024 : OutputProcessor::Unit::J,
2025 0 : state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
2026 : OutputProcessor::SOVTimeStepType::Zone,
2027 : OutputProcessor::SOVStoreType::Summed,
2028 0 : state.dataSurface->Surface(SurfLoop).Name);
2029 : }
2030 0 : SetupOutputVariable(state,
2031 : "Surface Window Transmitted Beam Solar Radiation Energy",
2032 : OutputProcessor::Unit::J,
2033 0 : state.dataSurface->SurfWinBmSolarEnergy(SurfLoop),
2034 : OutputProcessor::SOVTimeStepType::Zone,
2035 : OutputProcessor::SOVStoreType::Summed,
2036 0 : state.dataSurface->Surface(SurfLoop).Name);
2037 :
2038 0 : SetupOutputVariable(state,
2039 : "Surface Window Transmitted Beam To Beam Solar Radiation Energy",
2040 : OutputProcessor::Unit::J,
2041 0 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfLoop),
2042 : OutputProcessor::SOVTimeStepType::Zone,
2043 : OutputProcessor::SOVStoreType::Summed,
2044 0 : state.dataSurface->Surface(SurfLoop).Name);
2045 0 : SetupOutputVariable(state,
2046 : "Surface Window Transmitted Beam To Diffuse Solar Radiation Energy",
2047 : OutputProcessor::Unit::J,
2048 0 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfLoop),
2049 : OutputProcessor::SOVTimeStepType::Zone,
2050 : OutputProcessor::SOVStoreType::Summed,
2051 0 : state.dataSurface->Surface(SurfLoop).Name);
2052 :
2053 0 : SetupOutputVariable(state,
2054 : "Surface Window Transmitted Diffuse Solar Radiation Energy",
2055 : OutputProcessor::Unit::J,
2056 0 : state.dataSurface->SurfWinDifSolarEnergy(SurfLoop),
2057 : OutputProcessor::SOVTimeStepType::Zone,
2058 : OutputProcessor::SOVStoreType::Summed,
2059 0 : state.dataSurface->Surface(SurfLoop).Name);
2060 0 : SetupOutputVariable(state,
2061 : "Surface Window Heat Gain Energy",
2062 : OutputProcessor::Unit::J,
2063 0 : state.dataSurface->SurfWinHeatGainRepEnergy(SurfLoop),
2064 : OutputProcessor::SOVTimeStepType::Zone,
2065 : OutputProcessor::SOVStoreType::Summed,
2066 0 : state.dataSurface->Surface(SurfLoop).Name);
2067 0 : SetupOutputVariable(state,
2068 : "Surface Window Heat Loss Energy",
2069 : OutputProcessor::Unit::J,
2070 0 : state.dataSurface->SurfWinHeatLossRepEnergy(SurfLoop),
2071 : OutputProcessor::SOVTimeStepType::Zone,
2072 : OutputProcessor::SOVStoreType::Summed,
2073 0 : state.dataSurface->Surface(SurfLoop).Name);
2074 0 : SetupOutputVariable(state,
2075 : "Surface Window Gap Convective Heat Transfer Energy",
2076 : OutputProcessor::Unit::J,
2077 0 : state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfLoop),
2078 : OutputProcessor::SOVTimeStepType::Zone,
2079 : OutputProcessor::SOVStoreType::Summed,
2080 0 : state.dataSurface->Surface(SurfLoop).Name);
2081 0 : SetupOutputVariable(state,
2082 : "Surface Window Shading Device Absorbed Solar Radiation Energy",
2083 : OutputProcessor::Unit::J,
2084 0 : state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfLoop),
2085 : OutputProcessor::SOVTimeStepType::Zone,
2086 : OutputProcessor::SOVStoreType::Summed,
2087 0 : state.dataSurface->Surface(SurfLoop).Name);
2088 :
2089 0 : SetupOutputVariable(state,
2090 : "Surface Window System Solar Transmittance",
2091 : OutputProcessor::Unit::None,
2092 0 : state.dataSurface->SurfWinSysSolTransmittance(SurfLoop),
2093 : OutputProcessor::SOVTimeStepType::Zone,
2094 : OutputProcessor::SOVStoreType::Average,
2095 0 : state.dataSurface->Surface(SurfLoop).Name);
2096 0 : SetupOutputVariable(state,
2097 : "Surface Window System Solar Reflectance",
2098 : OutputProcessor::Unit::None,
2099 0 : state.dataSurface->SurfWinSysSolReflectance(SurfLoop),
2100 : OutputProcessor::SOVTimeStepType::Zone,
2101 : OutputProcessor::SOVStoreType::Average,
2102 0 : state.dataSurface->Surface(SurfLoop).Name);
2103 0 : SetupOutputVariable(state,
2104 : "Surface Window System Solar Absorptance",
2105 : OutputProcessor::Unit::None,
2106 0 : state.dataSurface->SurfWinSysSolAbsorptance(SurfLoop),
2107 : OutputProcessor::SOVTimeStepType::Zone,
2108 : OutputProcessor::SOVStoreType::Average,
2109 0 : state.dataSurface->Surface(SurfLoop).Name);
2110 0 : SetupOutputVariable(state,
2111 : "Surface Window Inside Face Glazing Condensation Status",
2112 : OutputProcessor::Unit::None,
2113 0 : state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfLoop),
2114 : OutputProcessor::SOVTimeStepType::Zone,
2115 : OutputProcessor::SOVStoreType::State,
2116 0 : state.dataSurface->Surface(SurfLoop).Name);
2117 0 : SetupOutputVariable(state,
2118 : "Surface Window Inside Face Frame Condensation Status",
2119 : OutputProcessor::Unit::None,
2120 0 : state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfLoop),
2121 : OutputProcessor::SOVTimeStepType::Zone,
2122 : OutputProcessor::SOVStoreType::State,
2123 0 : state.dataSurface->Surface(SurfLoop).Name);
2124 0 : SetupOutputVariable(state,
2125 : "Surface Window Inside Face Divider Condensation Status",
2126 : OutputProcessor::Unit::None,
2127 0 : state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfLoop),
2128 : OutputProcessor::SOVTimeStepType::Zone,
2129 : OutputProcessor::SOVStoreType::State,
2130 0 : state.dataSurface->Surface(SurfLoop).Name);
2131 0 : SetupOutputVariable(state,
2132 : "Surface Window Outside Reveal Reflected Beam Solar Radiation Rate",
2133 : OutputProcessor::Unit::W,
2134 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfLoop),
2135 : OutputProcessor::SOVTimeStepType::Zone,
2136 : OutputProcessor::SOVStoreType::State,
2137 0 : state.dataSurface->Surface(SurfLoop).Name);
2138 0 : SetupOutputVariable(state,
2139 : "Surface Window Inside Reveal Reflected Beam Solar Radiation Rate",
2140 : OutputProcessor::Unit::W,
2141 0 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfLoop),
2142 : OutputProcessor::SOVTimeStepType::Zone,
2143 : OutputProcessor::SOVStoreType::State,
2144 0 : state.dataSurface->Surface(SurfLoop).Name);
2145 : // Energy
2146 0 : SetupOutputVariable(state,
2147 : "Surface Window Outside Reveal Reflected Beam Solar Radiation Energy",
2148 : OutputProcessor::Unit::J,
2149 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfLoop),
2150 : OutputProcessor::SOVTimeStepType::Zone,
2151 : OutputProcessor::SOVStoreType::Summed,
2152 0 : state.dataSurface->Surface(SurfLoop).Name);
2153 0 : SetupOutputVariable(state,
2154 : "Surface Window Inside Reveal Reflected Beam Solar Radiation Energy",
2155 : OutputProcessor::Unit::J,
2156 0 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfLoop),
2157 : OutputProcessor::SOVTimeStepType::Zone,
2158 : OutputProcessor::SOVStoreType::Summed,
2159 0 : state.dataSurface->Surface(SurfLoop).Name);
2160 :
2161 : // Output blind report variables only when blinds are used
2162 0 : if (state.dataSurface->SurfWinBlindNumber(SurfLoop) > 0) {
2163 0 : SetupOutputVariable(state,
2164 : "Surface Window Blind Beam to Beam Solar Transmittance",
2165 : OutputProcessor::Unit::None,
2166 0 : state.dataSurface->SurfWinBlTsolBmBm(SurfLoop),
2167 : OutputProcessor::SOVTimeStepType::Zone,
2168 : OutputProcessor::SOVStoreType::State,
2169 0 : state.dataSurface->Surface(SurfLoop).Name);
2170 0 : SetupOutputVariable(state,
2171 : "Surface Window Blind Beam to Diffuse Solar Transmittance",
2172 : OutputProcessor::Unit::None,
2173 0 : state.dataSurface->SurfWinBlTsolBmDif(SurfLoop),
2174 : OutputProcessor::SOVTimeStepType::Zone,
2175 : OutputProcessor::SOVStoreType::State,
2176 0 : state.dataSurface->Surface(SurfLoop).Name);
2177 0 : SetupOutputVariable(state,
2178 : "Surface Window Blind Diffuse to Diffuse Solar Transmittance",
2179 : OutputProcessor::Unit::None,
2180 0 : state.dataSurface->SurfWinBlTsolDifDif(SurfLoop),
2181 : OutputProcessor::SOVTimeStepType::Zone,
2182 : OutputProcessor::SOVStoreType::State,
2183 0 : state.dataSurface->Surface(SurfLoop).Name);
2184 0 : SetupOutputVariable(state,
2185 : "Surface Window Blind and Glazing System Beam Solar Transmittance",
2186 : OutputProcessor::Unit::None,
2187 0 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfLoop),
2188 : OutputProcessor::SOVTimeStepType::Zone,
2189 : OutputProcessor::SOVStoreType::State,
2190 0 : state.dataSurface->Surface(SurfLoop).Name);
2191 0 : SetupOutputVariable(state,
2192 : "Surface Window Blind and Glazing System Diffuse Solar Transmittance",
2193 : OutputProcessor::Unit::None,
2194 0 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfLoop),
2195 : OutputProcessor::SOVTimeStepType::Zone,
2196 : OutputProcessor::SOVStoreType::State,
2197 0 : state.dataSurface->Surface(SurfLoop).Name);
2198 : }
2199 :
2200 : // Output screen report variables only when screens are used
2201 0 : if (state.dataSurface->SurfWinScreenNumber(SurfLoop) > 0) {
2202 0 : SetupOutputVariable(state,
2203 : "Surface Window Screen Beam to Beam Solar Transmittance",
2204 : OutputProcessor::Unit::None,
2205 0 : state.dataSurface->SurfWinScTsolBmBm(SurfLoop),
2206 : OutputProcessor::SOVTimeStepType::Zone,
2207 : OutputProcessor::SOVStoreType::State,
2208 0 : state.dataSurface->Surface(SurfLoop).Name);
2209 0 : SetupOutputVariable(state,
2210 : "Surface Window Screen Beam to Diffuse Solar Transmittance",
2211 : OutputProcessor::Unit::None,
2212 0 : state.dataSurface->SurfWinScTsolBmDif(SurfLoop),
2213 : OutputProcessor::SOVTimeStepType::Zone,
2214 : OutputProcessor::SOVStoreType::State,
2215 0 : state.dataSurface->Surface(SurfLoop).Name);
2216 0 : SetupOutputVariable(state,
2217 : "Surface Window Screen Diffuse to Diffuse Solar Transmittance",
2218 : OutputProcessor::Unit::None,
2219 0 : state.dataSurface->SurfWinScTsolDifDif(SurfLoop),
2220 : OutputProcessor::SOVTimeStepType::Zone,
2221 : OutputProcessor::SOVStoreType::State,
2222 0 : state.dataSurface->Surface(SurfLoop).Name);
2223 0 : SetupOutputVariable(state,
2224 : "Surface Window Screen and Glazing System Beam Solar Transmittance",
2225 : OutputProcessor::Unit::None,
2226 0 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfLoop),
2227 : OutputProcessor::SOVTimeStepType::Zone,
2228 : OutputProcessor::SOVStoreType::State,
2229 0 : state.dataSurface->Surface(SurfLoop).Name);
2230 0 : SetupOutputVariable(state,
2231 : "Surface Window Screen and Glazing System Diffuse Solar Transmittance",
2232 : OutputProcessor::Unit::None,
2233 0 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfLoop),
2234 : OutputProcessor::SOVTimeStepType::Zone,
2235 : OutputProcessor::SOVStoreType::State,
2236 0 : state.dataSurface->Surface(SurfLoop).Name);
2237 : }
2238 :
2239 0 : SetupOutputVariable(state,
2240 : "Surface Window Solar Horizontal Profile Angle",
2241 : OutputProcessor::Unit::deg,
2242 0 : state.dataSurface->SurfWinProfileAngHor(SurfLoop),
2243 : OutputProcessor::SOVTimeStepType::Zone,
2244 : OutputProcessor::SOVStoreType::State,
2245 0 : state.dataSurface->Surface(SurfLoop).Name);
2246 0 : SetupOutputVariable(state,
2247 : "Surface Window Solar Vertical Profile Angle",
2248 : OutputProcessor::Unit::deg,
2249 0 : state.dataSurface->SurfWinProfileAngVert(SurfLoop),
2250 : OutputProcessor::SOVTimeStepType::Zone,
2251 : OutputProcessor::SOVStoreType::State,
2252 0 : state.dataSurface->Surface(SurfLoop).Name);
2253 0 : SetupOutputVariable(state,
2254 : "Surface Window Glazing Beam to Beam Solar Transmittance",
2255 : OutputProcessor::Unit::None,
2256 0 : state.dataSurface->SurfWinGlTsolBmBm(SurfLoop),
2257 : OutputProcessor::SOVTimeStepType::Zone,
2258 : OutputProcessor::SOVStoreType::State,
2259 0 : state.dataSurface->Surface(SurfLoop).Name);
2260 0 : SetupOutputVariable(state,
2261 : "Surface Window Glazing Beam to Diffuse Solar Transmittance",
2262 : OutputProcessor::Unit::None,
2263 0 : state.dataSurface->SurfWinGlTsolBmDif(SurfLoop),
2264 : OutputProcessor::SOVTimeStepType::Zone,
2265 : OutputProcessor::SOVStoreType::State,
2266 0 : state.dataSurface->Surface(SurfLoop).Name);
2267 0 : SetupOutputVariable(state,
2268 : "Surface Window Glazing Diffuse to Diffuse Solar Transmittance",
2269 : OutputProcessor::Unit::None,
2270 0 : state.dataSurface->SurfWinGlTsolDifDif(SurfLoop),
2271 : OutputProcessor::SOVTimeStepType::Zone,
2272 : OutputProcessor::SOVStoreType::State,
2273 0 : state.dataSurface->Surface(SurfLoop).Name);
2274 0 : SetupOutputVariable(state,
2275 : "Surface Window Model Solver Iteration Count",
2276 : OutputProcessor::Unit::None,
2277 0 : state.dataSurface->SurfWinWindowCalcIterationsRep(SurfLoop),
2278 : OutputProcessor::SOVTimeStepType::Zone,
2279 : OutputProcessor::SOVStoreType::State,
2280 0 : state.dataSurface->Surface(SurfLoop).Name);
2281 : }
2282 : } // end non extsolar reporting as advanced variables
2283 : } // Window Reporting
2284 42221 : if (state.dataSurface->Surface(SurfLoop).Class == SurfaceClass::Window && state.dataSurface->Surface(SurfLoop).ExtBoundCond > 0 &&
2285 14 : state.dataSurface->Surface(SurfLoop).ExtBoundCond != SurfLoop) { // Interzone window
2286 : // CurrentModuleObject='InterzoneWindows'
2287 42 : SetupOutputVariable(state,
2288 : "Surface Window Transmitted Beam Solar Radiation Rate",
2289 : OutputProcessor::Unit::W,
2290 14 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfLoop),
2291 : OutputProcessor::SOVTimeStepType::Zone,
2292 : OutputProcessor::SOVStoreType::State,
2293 28 : state.dataSurface->Surface(SurfLoop).Name);
2294 : // energy
2295 42 : SetupOutputVariable(state,
2296 : "Surface Window Transmitted Beam Solar Radiation Energy",
2297 : OutputProcessor::Unit::J,
2298 14 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfLoop),
2299 : OutputProcessor::SOVTimeStepType::Zone,
2300 : OutputProcessor::SOVStoreType::Summed,
2301 28 : state.dataSurface->Surface(SurfLoop).Name);
2302 : }
2303 42207 : if (state.dataSurface->Surface(SurfLoop).Class == SurfaceClass::TDD_Dome && state.dataSurface->Surface(SurfLoop).ExtSolar) {
2304 : // CurrentModuleObject='TDD Domes'
2305 6 : SetupOutputVariable(state,
2306 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
2307 : OutputProcessor::Unit::W,
2308 2 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
2309 : OutputProcessor::SOVTimeStepType::Zone,
2310 : OutputProcessor::SOVStoreType::Average,
2311 4 : state.dataSurface->Surface(SurfLoop).Name);
2312 6 : SetupOutputVariable(state,
2313 : "Surface Window Transmitted Solar Radiation Rate",
2314 : OutputProcessor::Unit::W,
2315 2 : state.dataSurface->SurfWinTransSolar(SurfLoop),
2316 : OutputProcessor::SOVTimeStepType::Zone,
2317 : OutputProcessor::SOVStoreType::Average,
2318 4 : state.dataSurface->Surface(SurfLoop).Name);
2319 : // energy
2320 6 : SetupOutputVariable(state,
2321 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
2322 : OutputProcessor::Unit::J,
2323 2 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
2324 : OutputProcessor::SOVTimeStepType::Zone,
2325 : OutputProcessor::SOVStoreType::Summed,
2326 4 : state.dataSurface->Surface(SurfLoop).Name);
2327 6 : SetupOutputVariable(state,
2328 : "Surface Window Transmitted Solar Radiation Energy",
2329 : OutputProcessor::Unit::J,
2330 2 : state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
2331 : OutputProcessor::SOVTimeStepType::Zone,
2332 : OutputProcessor::SOVStoreType::Summed,
2333 4 : state.dataSurface->Surface(SurfLoop).Name);
2334 : }
2335 42207 : if (state.dataSurface->SurfWinOriginalClass(SurfLoop) == SurfaceClass::TDD_Diffuser) {
2336 : // CurrentModuleObject='TDD Diffusers'
2337 6 : SetupOutputVariable(state,
2338 : "Surface Outside Face Incident Solar Radiation Rate per Area",
2339 : OutputProcessor::Unit::W_m2,
2340 2 : state.dataHeatBal->SurfQRadSWOutIncident(SurfLoop),
2341 : OutputProcessor::SOVTimeStepType::Zone,
2342 : OutputProcessor::SOVStoreType::Average,
2343 4 : state.dataSurface->Surface(SurfLoop).Name);
2344 6 : SetupOutputVariable(state,
2345 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Rate",
2346 : OutputProcessor::Unit::W,
2347 2 : state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfLoop),
2348 : OutputProcessor::SOVTimeStepType::Zone,
2349 : OutputProcessor::SOVStoreType::Average,
2350 4 : state.dataSurface->Surface(SurfLoop).Name);
2351 6 : SetupOutputVariable(state,
2352 : "Surface Window Transmitted Solar Radiation Rate",
2353 : OutputProcessor::Unit::W,
2354 2 : state.dataSurface->SurfWinTransSolar(SurfLoop),
2355 : OutputProcessor::SOVTimeStepType::Zone,
2356 : OutputProcessor::SOVStoreType::Average,
2357 4 : state.dataSurface->Surface(SurfLoop).Name);
2358 : // energy
2359 6 : SetupOutputVariable(state,
2360 : "Surface Window Total Glazing Layers Absorbed Solar Radiation Energy",
2361 : OutputProcessor::Unit::J,
2362 2 : state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfLoop),
2363 : OutputProcessor::SOVTimeStepType::Zone,
2364 : OutputProcessor::SOVStoreType::Summed,
2365 4 : state.dataSurface->Surface(SurfLoop).Name);
2366 6 : SetupOutputVariable(state,
2367 : "Surface Window Transmitted Solar Radiation Energy",
2368 : OutputProcessor::Unit::J,
2369 2 : state.dataSurface->SurfWinTransSolarEnergy(SurfLoop),
2370 : OutputProcessor::SOVTimeStepType::Zone,
2371 : OutputProcessor::SOVStoreType::Summed,
2372 4 : state.dataSurface->Surface(SurfLoop).Name);
2373 : }
2374 : }
2375 :
2376 44533 : for (SurfLoop = 1; SurfLoop <= state.dataSurface->TotSurfaces; ++SurfLoop) {
2377 43762 : if (!state.dataSurface->Surface(SurfLoop).HeatTransSurf) continue;
2378 : // CurrentModuleObject='Surfaces'
2379 126621 : SetupOutputVariable(state,
2380 : "Surface Inside Face Exterior Windows Incident Beam Solar Radiation Rate per Area",
2381 : OutputProcessor::Unit::W_m2,
2382 42207 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfLoop),
2383 : OutputProcessor::SOVTimeStepType::Zone,
2384 : OutputProcessor::SOVStoreType::Average,
2385 84414 : state.dataSurface->Surface(SurfLoop).Name);
2386 126621 : SetupOutputVariable(state,
2387 : "Surface Inside Face Exterior Windows Incident Beam Solar Radiation Rate",
2388 : OutputProcessor::Unit::W,
2389 42207 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfLoop),
2390 : OutputProcessor::SOVTimeStepType::Zone,
2391 : OutputProcessor::SOVStoreType::Average,
2392 84414 : state.dataSurface->Surface(SurfLoop).Name);
2393 126621 : SetupOutputVariable(state,
2394 : "Surface Inside Face Interior Windows Incident Beam Solar Radiation Rate per Area",
2395 : OutputProcessor::Unit::W_m2,
2396 42207 : state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfLoop),
2397 : OutputProcessor::SOVTimeStepType::Zone,
2398 : OutputProcessor::SOVStoreType::Average,
2399 84414 : state.dataSurface->Surface(SurfLoop).Name);
2400 126621 : SetupOutputVariable(state,
2401 : "Surface Inside Face Interior Windows Incident Beam Solar Radiation Rate",
2402 : OutputProcessor::Unit::W,
2403 42207 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfLoop),
2404 : OutputProcessor::SOVTimeStepType::Zone,
2405 : OutputProcessor::SOVStoreType::Average,
2406 84414 : state.dataSurface->Surface(SurfLoop).Name);
2407 126621 : SetupOutputVariable(state,
2408 : "Surface Inside Face Initial Transmitted Diffuse Absorbed Solar Radiation Rate",
2409 : OutputProcessor::Unit::W,
2410 42207 : state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfLoop),
2411 : OutputProcessor::SOVTimeStepType::Zone,
2412 : OutputProcessor::SOVStoreType::Average,
2413 84414 : state.dataSurface->Surface(SurfLoop).Name);
2414 126621 : SetupOutputVariable(state,
2415 : "Surface Inside Face Initial Transmitted Diffuse Transmitted Out Window Solar Radiation Rate",
2416 : OutputProcessor::Unit::W,
2417 42207 : state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfLoop),
2418 : OutputProcessor::SOVTimeStepType::Zone,
2419 : OutputProcessor::SOVStoreType::Average,
2420 84414 : state.dataSurface->Surface(SurfLoop).Name);
2421 126621 : SetupOutputVariable(state,
2422 : "Surface Inside Face Absorbed Shortwave Radiation Rate",
2423 : OutputProcessor::Unit::W,
2424 42207 : state.dataHeatBal->SurfSWInAbsTotalReport(SurfLoop),
2425 : OutputProcessor::SOVTimeStepType::Zone,
2426 : OutputProcessor::SOVStoreType::Average,
2427 84414 : state.dataSurface->Surface(SurfLoop).Name);
2428 : // energy
2429 126621 : SetupOutputVariable(state,
2430 : "Surface Inside Face Exterior Windows Incident Beam Solar Radiation Energy",
2431 : OutputProcessor::Unit::J,
2432 42207 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfLoop),
2433 : OutputProcessor::SOVTimeStepType::Zone,
2434 : OutputProcessor::SOVStoreType::Summed,
2435 84414 : state.dataSurface->Surface(SurfLoop).Name);
2436 126621 : SetupOutputVariable(state,
2437 : "Surface Inside Face Interior Windows Incident Beam Solar Radiation Energy",
2438 : OutputProcessor::Unit::J,
2439 42207 : state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfLoop),
2440 : OutputProcessor::SOVTimeStepType::Zone,
2441 : OutputProcessor::SOVStoreType::Summed,
2442 84414 : state.dataSurface->Surface(SurfLoop).Name);
2443 : }
2444 771 : }
2445 :
2446 821926 : void AnisoSkyViewFactors(EnergyPlusData &state)
2447 : {
2448 :
2449 : // SUBROUTINE INFORMATION:
2450 : // AUTHOR Fred Winkelmann
2451 : // DATE WRITTEN April 1999
2452 : // MODIFIED LKL; Dec 2002 -- Anisotropic is only sky radiance option
2453 : // RE-ENGINEERED na
2454 :
2455 : // PURPOSE OF THIS SUBROUTINE:
2456 : // Calculates view factor multiplier, SurfAnisoSkyMult, for diffuse
2457 : // sky irradiance on exterior surfaces taking into account
2458 : // anisotropic radiance of the sky. Called by InitSurfaceHeatBalance
2459 : // In this case the diffuse sky irradiance on a surface is given by
2460 : // SurfAnisoSkyMult(SurfNum) * DifSolarRad
2461 : // SurfAnisoSkyMult accounts not only for the sky radiance distribution but
2462 : // also for the effects of shading of sky diffuse radiation by
2463 : // shadowing surfaces such as overhangs. It does not account for reflection
2464 : // of sky diffuse radiation from shadowing surfaces.
2465 : // Based on an empirical model described in
2466 : // R. Perez, P. Ineichen, R. Seals, J. Michalsky and R. Stewart,
2467 : // "Modeling Daylight Availability and Irradiance Components from Direct
2468 : // and Global Irradiance," Solar Energy 44, 271-289, 1990.
2469 : // In this model the radiance of the sky consists of three distributions
2470 : // that are superimposed:
2471 :
2472 : // (1) An isotropic distribution that covers the entire sky dome;
2473 : // (2) A circumsolar brightening centered around the position of the sun;
2474 : // (3) A horizon brightening
2475 : // The circumsolar brightening is assumed to be concentrated at a point
2476 : // source at the center of the sun although this region actually begins at the
2477 : // periphery of the solar disk and falls off in intensity with increasing
2478 : // angular distance from the periphery.
2479 : // The horizon brightening is assumed to be concentrated at the horizon and
2480 : // to be independent of azimuth. In actuality, for clear skies, the horizon
2481 : // brightening is highest at the horizon and decreases in intensity away from
2482 : // the horizon. For overcast skies the horizon brightening has a negative value
2483 : // since for such skies the sky radiance increases rather than decreases away
2484 : // from the horizon.
2485 : // The F11R, F12R, etc. values were provided by R. Perez, private communication,
2486 : // 5/21/99. These values have higher precision than those listed in the above
2487 : // paper.
2488 :
2489 : // Using/Aliasing
2490 :
2491 : // Locals
2492 : // SUBROUTINE PARAMETER DEFINITIONS:
2493 : static constexpr std::array<Real64, 7> EpsilonLimit = {
2494 : 1.065, 1.23, 1.5, 1.95, 2.8, 4.5, 6.2}; // Upper limit of bins of the sky clearness parameter, Epsilon
2495 : // Circumsolar brightening coefficients; index corresponds to range of Epsilon, the sky clearness parameter
2496 : static constexpr std::array<Real64, 8> F11R = {-0.0083117, 0.1299457, 0.3296958, 0.5682053, 0.8730280, 1.1326077, 1.0601591, 0.6777470};
2497 : static constexpr std::array<Real64, 8> F12R = {0.5877285, 0.6825954, 0.4868735, 0.1874525, -0.3920403, -1.2367284, -1.5999137, -0.3272588};
2498 : static constexpr std::array<Real64, 8> F13R = {-0.0620636, -0.1513752, -0.2210958, -0.2951290, -0.3616149, -0.4118494, -0.3589221, -0.2504286};
2499 : // Horizon/zenith brightening coefficient array; index corresponds to range of Epsilon, the sky clearness parameter
2500 : static constexpr std::array<Real64, 8> F21R = {-0.0596012, -0.0189325, 0.0554140, 0.1088631, 0.2255647, 0.2877813, 0.2642124, 0.1561313};
2501 : static constexpr std::array<Real64, 8> F22R = {0.0721249, 0.0659650, -0.0639588, -0.1519229, -0.4620442, -0.8230357, -1.1272340, -1.3765031};
2502 : static constexpr std::array<Real64, 8> F23R = {-0.0220216, -0.0288748, -0.0260542, -0.0139754, 0.0012448, 0.0558651, 0.1310694, 0.2506212};
2503 :
2504 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2505 :
2506 : Real64 CosZenithAng; // Cosine of solar zenith angle
2507 : Real64 ZenithAng; // Solar zenith angle (radians)
2508 : Real64 ZenithAngDeg; // Solar zenith angle (degrees)
2509 : Real64 F1; // Circumsolar brightening coefficient
2510 : Real64 F2; // Horizon/zenith brightening coefficient
2511 : Real64 Epsilon; // Sky clearness parameter
2512 : Real64 Delta; // Sky brightness parameter
2513 : Real64 CosIncAngBeamOnSurface; // Cosine of incidence angle of beam solar on surface
2514 : Real64 IncAng; // Incidence angle of beam solar on surface (radians)
2515 : int EpsilonBin; // Sky clearness (Epsilon) bin index
2516 : Real64 AirMass; // Relative air mass
2517 : Real64 AirMassH; // Intermediate variable for relative air mass calculation
2518 : Real64 CircumSolarFac; // Ratio of cosine of incidence angle to cosine of zenith angle
2519 : Real64 KappaZ3; // Intermediate variable
2520 : Real64 ViewFactorSkyGeom; // Geometrical sky view factor
2521 821926 : Real64 constexpr cosine_tolerance(0.0001);
2522 :
2523 : #ifdef EP_Count_Calls
2524 : ++state.dataTimingsData->NumAnisoSky_Calls;
2525 : #endif
2526 :
2527 821926 : CosZenithAng = state.dataEnvrn->SOLCOS(3);
2528 821926 : ZenithAng = std::acos(CosZenithAng);
2529 821926 : ZenithAngDeg = ZenithAng / DataGlobalConstants::DegToRadians;
2530 :
2531 821926 : state.dataSolarShading->SurfAnisoSkyMult = 0.0;
2532 :
2533 : // Relative air mass
2534 821926 : AirMassH = (1.0 - 0.1 * state.dataEnvrn->Elevation / 1000.0);
2535 821926 : if (ZenithAngDeg <= 75.0) {
2536 657406 : AirMass = AirMassH / CosZenithAng;
2537 : } else {
2538 164520 : AirMass = AirMassH / (CosZenithAng + 0.15 * std::pow(93.9 - ZenithAngDeg, -1.253));
2539 : }
2540 821926 : KappaZ3 = 1.041 * pow_3(ZenithAng);
2541 821926 : Epsilon = ((state.dataEnvrn->BeamSolarRad + state.dataEnvrn->DifSolarRad) / state.dataEnvrn->DifSolarRad + KappaZ3) / (1.0 + KappaZ3);
2542 821926 : Delta = state.dataEnvrn->DifSolarRad * AirMass / 1353.0; // 1353 is average extraterrestrial irradiance (W/m2)
2543 : // Circumsolar (F1) and horizon/zenith (F2) brightening coefficients
2544 5499554 : for (EpsilonBin = 0; EpsilonBin < 8; ++EpsilonBin) {
2545 5499554 : if (EpsilonBin == 7) break;
2546 5205994 : if (Epsilon < EpsilonLimit[EpsilonBin]) break;
2547 : }
2548 821926 : F1 = max(0.0, F11R[EpsilonBin] + F12R[EpsilonBin] * Delta + F13R[EpsilonBin] * ZenithAng);
2549 821926 : F2 = F21R[EpsilonBin] + F22R[EpsilonBin] * Delta + F23R[EpsilonBin] * ZenithAng;
2550 :
2551 21722407 : for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
2552 :
2553 62701443 : CosIncAngBeamOnSurface = state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
2554 41800962 : state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
2555 20900481 : state.dataEnvrn->SOLCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
2556 :
2557 : // So I believe this should only be a diagnostic error...the calcs should always be within -1,+1; it's just round-off that we need to trap
2558 : // for
2559 20900481 : if (CosIncAngBeamOnSurface > 1.0) {
2560 0 : if (CosIncAngBeamOnSurface > (1.0 + cosine_tolerance)) {
2561 0 : ShowSevereError(state, "Cosine of incident angle of beam solar on surface out of range...too high");
2562 0 : ShowContinueError(state, "This is a diagnostic error that should not be encountered under normal circumstances");
2563 0 : ShowContinueError(state, "Occurs on surface: " + state.dataSurface->Surface(SurfNum).Name);
2564 0 : ShowContinueError(state, format("Current value = {} ... should be within [-1, +1]", CosIncAngBeamOnSurface));
2565 0 : ShowFatalError(state, "Anisotropic solar calculation causes fatal error");
2566 : }
2567 0 : CosIncAngBeamOnSurface = 1.0;
2568 20900481 : } else if (CosIncAngBeamOnSurface < -1.0) {
2569 0 : if (CosIncAngBeamOnSurface < (-1.0 - cosine_tolerance)) {
2570 0 : ShowSevereError(state, "Cosine of incident angle of beam solar on surface out of range...too low");
2571 0 : ShowContinueError(state, "This is a diagnostic error that should not be encountered under normal circumstances");
2572 0 : ShowContinueError(state, "Occurs on surface: " + state.dataSurface->Surface(SurfNum).Name);
2573 0 : ShowContinueError(state, format("Current value = {} ... should be within [-1, +1]", CosIncAngBeamOnSurface));
2574 0 : ShowFatalError(state, "Anisotropic solar calculation causes fatal error");
2575 : }
2576 0 : CosIncAngBeamOnSurface = -1.0;
2577 : }
2578 :
2579 20900481 : IncAng = std::acos(CosIncAngBeamOnSurface);
2580 :
2581 20900481 : ViewFactorSkyGeom = state.dataSurface->Surface(SurfNum).ViewFactorSky;
2582 20900481 : state.dataSolarShading->SurfMultIsoSky(SurfNum) = ViewFactorSkyGeom * (1.0 - F1);
2583 : // 0.0871557 below corresponds to a zenith angle of 85 deg
2584 20900481 : CircumSolarFac = max(0.0, CosIncAngBeamOnSurface) / max(0.0871557, CosZenithAng);
2585 : // For near-horizontal roofs, model has an inconsistency that gives sky diffuse
2586 : // irradiance significantly different from DifSolarRad when zenith angle is
2587 : // above 85 deg. The following forces irradiance to be very close to DifSolarRad
2588 : // in this case.
2589 20900481 : if (CircumSolarFac > 0.0 && CosZenithAng < 0.0871557 && state.dataSurface->Surface(SurfNum).Tilt < 2.0) CircumSolarFac = 1.0;
2590 20900481 : state.dataSolarShading->SurfMultCircumSolar(SurfNum) = F1 * CircumSolarFac;
2591 20900481 : state.dataSolarShading->SurfMultHorizonZenith(SurfNum) = F2 * state.dataSurface->Surface(SurfNum).SinTilt;
2592 :
2593 20900481 : if (!state.dataSysVars->DetailedSkyDiffuseAlgorithm || !state.dataSurface->ShadingTransmittanceVaries ||
2594 0 : state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
2595 20900481 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum) =
2596 41800962 : state.dataSolarShading->SurfMultIsoSky(SurfNum) * state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum) +
2597 41800962 : state.dataSolarShading->SurfMultCircumSolar(SurfNum) *
2598 41800962 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) +
2599 20900481 : state.dataSolarShading->SurfMultHorizonZenith(SurfNum) * state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum);
2600 : } else {
2601 0 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum) =
2602 0 : state.dataSolarShading->SurfMultIsoSky(SurfNum) *
2603 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, SurfNum) +
2604 0 : state.dataSolarShading->SurfMultCircumSolar(SurfNum) *
2605 0 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) +
2606 0 : state.dataSolarShading->SurfMultHorizonZenith(SurfNum) *
2607 0 : state.dataSolarShading->SurfDifShdgRatioHorizHRTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, SurfNum);
2608 0 : state.dataSolarShading->SurfCurDifShdgRatioIsoSky(SurfNum) =
2609 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, SurfNum);
2610 : }
2611 20900481 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum) = max(0.0, state.dataSolarShading->SurfAnisoSkyMult(SurfNum)); // make sure not negative.
2612 : }
2613 821926 : }
2614 :
2615 17490 : void CHKBKS(EnergyPlusData &state,
2616 : int const NBS, // Surface Number of the potential back surface
2617 : int const NRS // Surface Number of the potential shadow receiving surface
2618 : )
2619 : {
2620 :
2621 : // SUBROUTINE INFORMATION:
2622 : // AUTHOR Legacy Code
2623 : // DATE WRITTEN
2624 : // MODIFIED Nov 2001, FW: Reverse subroutine arguments NRS and NBS to
2625 : // correspond to how CHKBKS is called
2626 : // Jan 2002, FW: change error message
2627 : // RE-ENGINEERED Lawrie, Oct 2000
2628 : // Sep 2020: Revised the vector computation method to reliabily produce CVec,
2629 : // and simplified the warning messages.
2630 :
2631 : // PURPOSE OF THIS SUBROUTINE:
2632 : // Determines whether a any vertices of the back surface are in front of the receiving surface;
2633 : // if so, gives severe error. Only base heat transfer surfaces are checked.
2634 :
2635 : // METHODOLOGY EMPLOYED:
2636 : // na
2637 :
2638 : // REFERENCES:
2639 : // BLAST/IBLAST code, original author George Walton
2640 :
2641 : // Using/Aliasing
2642 : using namespace Vectors;
2643 :
2644 : int N; // Loop Control (vertex counter)
2645 : int NVRS; // Number of vertices of the receiving surface
2646 : int NVBS; // Number of vertices of the back surface
2647 : Real64 DOTP; // Dot product of C and D
2648 :
2649 : // Object Data
2650 34980 : Vector CVec(0.0); // Vector perpendicular to surface at vertex 1
2651 34980 : Vector DVec(0.0); // Vector from vertex 1 of first surface to vertex 'n' of second surface
2652 :
2653 17490 : NVRS = state.dataSurface->Surface(NRS).Sides;
2654 17490 : NVBS = state.dataSurface->Surface(NBS).Sides;
2655 :
2656 : // SEE IF ANY VERTICES OF THE back surface ARE IN FRONT OF THE receiving surface
2657 :
2658 52530 : for (N = 2; N < NVRS; N++) {
2659 35040 : CVec += cross(state.dataSurface->Surface(NRS).Vertex(N) - state.dataSurface->Surface(NRS).Vertex(1),
2660 70080 : state.dataSurface->Surface(NRS).Vertex((N + 1)) - state.dataSurface->Surface(NRS).Vertex(1));
2661 : }
2662 17490 : CVec /= (NVRS >= 3 ? NVRS : 3);
2663 :
2664 87906 : for (N = 1; N <= NVBS; ++N) {
2665 70416 : DVec = state.dataSurface->Surface(NBS).Vertex(N) - state.dataSurface->Surface(NRS).Vertex(1);
2666 70416 : DOTP = dot(CVec, DVec);
2667 70416 : if (DOTP > 0.0009) {
2668 0 : ShowSevereError(state, "Problem in interior solar distribution calculation (CHKBKS)");
2669 0 : ShowContinueError(state,
2670 0 : " Solar Distribution = FullInteriorExterior will not work in Zone=" + state.dataSurface->Surface(NRS).ZoneName);
2671 0 : ShowContinueError(state,
2672 0 : format(" because one or more of vertices, such as Vertex {} of back surface={}, is in front of receiving surface={}",
2673 : N,
2674 0 : state.dataSurface->Surface(NBS).Name,
2675 0 : state.dataSurface->Surface(NRS).Name));
2676 0 : ShowContinueError(state, format(" (Dot Product indicator={:20.4F})", DOTP));
2677 0 : ShowContinueError(state,
2678 : " Check surface geometry; if OK, use Solar Distribution = FullExterior instead. Use Output:Diagnostics, "
2679 : "DisplayExtraWarnings; for more details.");
2680 0 : if (!state.dataGlobal->DisplayExtraWarnings) break;
2681 : }
2682 : }
2683 17490 : }
2684 :
2685 370193 : void CHKGSS(EnergyPlusData &state,
2686 : int const NRS, // Surface number of the potential shadow receiving surface
2687 : int const NSS, // Surface number of the potential shadow casting surface
2688 : Real64 const ZMIN, // Lowest point of the receiving surface
2689 : bool &CannotShade // TRUE if shadow casting surface cannot shade receiving surface.
2690 : )
2691 : {
2692 :
2693 : // SUBROUTINE INFORMATION:
2694 : // AUTHOR Legacy Code
2695 : // DATE WRITTEN
2696 : // MODIFIED na
2697 : // RE-ENGINEERED Lawrie, Oct 2000
2698 :
2699 : // PURPOSE OF THIS SUBROUTINE:
2700 : // Determines the possible shadowing combinations. The
2701 : // routine checks detached shadowing or base heat transfer surfaces
2702 : // for the possibility that they cannot shade a given base heat transfer surface.
2703 :
2704 : // METHODOLOGY EMPLOYED:
2705 : // Shadowing is not possible if:
2706 : // 1. The lowest point of the shadow receiving surface (receiving surface)
2707 : // Is higher than the highest point of the shadow casting surface (s.s.)
2708 : // 2. The shadow casting surface Faces up (e.g. A flat roof)
2709 : // 3. The shadow casting surface Is behind the receiving surface
2710 : // 4. The receiving surface is behind the shadow casting surface
2711 :
2712 : // REFERENCES:
2713 : // BLAST/IBLAST code, original author George Walton
2714 :
2715 : // Using/Aliasing
2716 : using namespace Vectors;
2717 :
2718 : // Object Data
2719 :
2720 370193 : CannotShade = true;
2721 :
2722 : // see if no point of shadow casting surface is above low point of receiving surface
2723 :
2724 370193 : auto const &surface_C(state.dataSurface->Surface(NSS));
2725 559602 : if (surface_C.OutNormVec(3) > 0.9999) return; // Shadow Casting Surface is horizontal and facing upward
2726 286035 : auto const &vertex_C(surface_C.Vertex);
2727 286035 : Real64 ZMAX(vertex_C(1).z);
2728 1139822 : for (int i = 2, e = surface_C.Sides; i <= e; ++i) {
2729 853787 : ZMAX = std::max(ZMAX, vertex_C(i).z);
2730 : }
2731 286035 : if (ZMAX <= ZMIN) return;
2732 :
2733 : // SEE IF ANY VERTICES OF THE Shadow Casting Surface ARE ABOVE THE PLANE OF THE receiving surface
2734 :
2735 180784 : auto const &surface_R(state.dataSurface->Surface(NRS));
2736 180784 : auto const &vertex_R(surface_R.Vertex);
2737 361568 : auto const vertex_R_2(vertex_R(2));
2738 361568 : Vector const AVec(vertex_R(1) - vertex_R_2); // Vector from vertex 2 to vertex 1 of receiving surface
2739 361568 : Vector const BVec(vertex_R(3) - vertex_R_2); // Vector from vertex 2 to vertex 3 of receiving surface
2740 :
2741 361568 : Vector const CVec(cross(BVec, AVec)); // Vector perpendicular to surface at vertex 2
2742 :
2743 180784 : int const NVSS = surface_C.Sides; // Number of vertices of the shadow casting surface
2744 180784 : Real64 DOTP(0.0); // Dot Product
2745 706222 : for (int I = 1; I <= NVSS; ++I) {
2746 578009 : DOTP = dot(CVec, vertex_C(I) - vertex_R_2);
2747 578009 : if (DOTP > state.dataSolarShading->TolValue) break; // DO loop
2748 : }
2749 :
2750 : // SEE IF ANY VERTICES OF THE receiving surface ARE ABOVE THE PLANE OF THE S.S.
2751 :
2752 180784 : if (DOTP > state.dataSolarShading->TolValue) {
2753 :
2754 105142 : auto const vertex_C_2(vertex_C(2));
2755 105142 : Vector const AVec(vertex_C(1) - vertex_C_2);
2756 105142 : Vector const BVec(vertex_C(3) - vertex_C_2);
2757 :
2758 105142 : Vector const CVec(cross(BVec, AVec));
2759 :
2760 52571 : int const NVRS = surface_R.Sides; // Number of vertices of the receiving surface
2761 169800 : for (int I = 1; I <= NVRS; ++I) {
2762 142222 : DOTP = dot(CVec, vertex_R(I) - vertex_C_2);
2763 142222 : if (DOTP > state.dataSolarShading->TolValue) {
2764 24993 : CannotShade = false;
2765 24993 : break; // DO loop
2766 : }
2767 : }
2768 : }
2769 : }
2770 :
2771 6337 : void CHKSBS(EnergyPlusData &state,
2772 : int const HTS, // Heat transfer surface number of the general receiving surf
2773 : int const GRSNR, // Surface number of general receiving surface
2774 : int const SBSNR // Surface number of subsurface
2775 : )
2776 : {
2777 :
2778 : // SUBROUTINE INFORMATION:
2779 : // AUTHOR Legacy Code
2780 : // DATE WRITTEN
2781 : // MODIFIED na
2782 : // RE-ENGINEERED Lawrie, Oct 2000
2783 :
2784 : // PURPOSE OF THIS SUBROUTINE:
2785 : // Checks that a subsurface is completely
2786 : // enclosed by its base surface.
2787 :
2788 : // REFERENCES:
2789 : // BLAST/IBLAST code, original author George Walton
2790 :
2791 : // 3D Planar Polygons
2792 : // In 3D applications, one sometimes wants to test a point and polygon that are in the same plane.
2793 : // For example, one may have the intersection point of a ray with the plane of a polyhedron's face,
2794 : // and want to test if it is inside the face. Or one may want to know if the base of a 3D perpendicular
2795 : // dropped from a point is inside a planar polygon.
2796 :
2797 : // 3D inclusion is easily determined by projecting the point and polygon into 2D. To do this, one simply
2798 : // ignores one of the 3D coordinates and uses the other two. To optimally select the coordinate to ignore,
2799 : // compute a normal vector to the plane, and select the coordinate with the largest absolute value [Snyder & Barr, 1987].
2800 : // This gives the projection of the polygon with maximum area, and results in robust computations.
2801 : // John M. Snyder & Alan H. Barr, "Ray Tracing Complex Models Containing Surface Tessellations",
2802 : // Computer Graphics 21(4), 119-126 (1987) [also in the Proceedings of SIGGRAPH 1987]
2803 : //--- using adapted routine from Triangulation code -- EnergyPlus.
2804 :
2805 : // MSG - for error message
2806 6337 : static Array1D_string const MSG(4, {"misses", "", "within", "overlaps"});
2807 :
2808 : int N; // Loop Control
2809 : int NVT; // Number of vertices
2810 : int NS1; // Number of the figure being overlapped
2811 : int NS2; // Number of the figure doing overlapping
2812 : int NS3; // Location to place results of overlap
2813 :
2814 : bool inside;
2815 :
2816 : bool Out;
2817 : Real64 X1; // ,SX,SY,SZ
2818 : Real64 Y1;
2819 : Real64 Z1;
2820 : Real64 X2;
2821 : Real64 Y2;
2822 : Real64 Z2;
2823 : Real64 BX;
2824 : Real64 BY;
2825 : Real64 BZ;
2826 : Real64 BMAX;
2827 : // INTEGER M
2828 :
2829 6337 : if (state.dataSolarShading->CHKSBSOneTimeFlag) {
2830 677 : state.dataSolarShading->XVT.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
2831 677 : state.dataSolarShading->YVT.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
2832 677 : state.dataSolarShading->ZVT.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
2833 677 : state.dataSolarShading->XVT = 0.0;
2834 677 : state.dataSolarShading->YVT = 0.0;
2835 677 : state.dataSolarShading->ZVT = 0.0;
2836 677 : state.dataSolarShading->CHKSBSOneTimeFlag = false;
2837 : }
2838 :
2839 6337 : NS1 = 1;
2840 6337 : NS2 = 2;
2841 6337 : NS3 = 3;
2842 6337 : state.dataSolarShading->HCT(1) = 0.0;
2843 6337 : state.dataSolarShading->HCT(2) = 0.0;
2844 :
2845 : // Put coordinates of base surface into clockwise sequence on the x'-y' plane.
2846 :
2847 6337 : state.dataSolarShading->XVT = 0.0;
2848 6337 : state.dataSolarShading->YVT = 0.0;
2849 6337 : state.dataSolarShading->ZVT = 0.0;
2850 6337 : state.dataSolarShading->XVS = 0.0;
2851 6337 : state.dataSolarShading->YVS = 0.0;
2852 6337 : CTRANS(state, GRSNR, HTS, NVT, state.dataSolarShading->XVT, state.dataSolarShading->YVT, state.dataSolarShading->ZVT);
2853 31749 : for (N = 1; N <= NVT; ++N) {
2854 25412 : state.dataSolarShading->XVS(N) = state.dataSolarShading->XVT(NVT + 1 - N);
2855 25412 : state.dataSolarShading->YVS(N) = state.dataSolarShading->YVT(NVT + 1 - N);
2856 : }
2857 :
2858 6337 : HTRANS1(state, NS2, NVT);
2859 :
2860 : // Put coordinates of the subsurface into clockwise sequence.
2861 :
2862 6337 : state.dataSolarShading->NVS = state.dataSurface->Surface(SBSNR).Sides;
2863 31683 : for (N = 1; N <= state.dataSolarShading->NVS; ++N) {
2864 25346 : state.dataSolarShading->XVS(N) = state.dataSurface->ShadeV(SBSNR).XV(state.dataSolarShading->NVS + 1 - N);
2865 25346 : state.dataSolarShading->YVS(N) = state.dataSurface->ShadeV(SBSNR).YV(state.dataSolarShading->NVS + 1 - N);
2866 : }
2867 6337 : HTRANS1(state, NS1, state.dataSolarShading->NVS);
2868 :
2869 : // Determine the overlap condition.
2870 :
2871 6337 : DeterminePolygonOverlap(state, NS1, NS2, NS3);
2872 :
2873 : // Print error condition if necessary.
2874 :
2875 6337 : if (state.dataSolarShading->OverlapStatus != FirstSurfWithinSecond) {
2876 19 : Out = false;
2877 : // C COMPUTE COMPONENTS OF VECTOR
2878 : // C NORMAL TO BASE SURFACE.
2879 19 : X1 = state.dataSurface->Surface(GRSNR).Vertex(1).x - state.dataSurface->Surface(GRSNR).Vertex(2).x; // XV(1,GRSNR)-XV(2,GRSNR)
2880 19 : Y1 = state.dataSurface->Surface(GRSNR).Vertex(1).y - state.dataSurface->Surface(GRSNR).Vertex(2).y; // YV(1,GRSNR)-YV(2,GRSNR)
2881 19 : Z1 = state.dataSurface->Surface(GRSNR).Vertex(1).z - state.dataSurface->Surface(GRSNR).Vertex(2).z; // ZV(1,GRSNR)-ZV(2,GRSNR)
2882 19 : X2 = state.dataSurface->Surface(GRSNR).Vertex(3).x - state.dataSurface->Surface(GRSNR).Vertex(2).x; // XV(3,GRSNR)-XV(2,GRSNR)
2883 19 : Y2 = state.dataSurface->Surface(GRSNR).Vertex(3).y - state.dataSurface->Surface(GRSNR).Vertex(2).y; // YV(3,GRSNR)-YV(2,GRSNR)
2884 19 : Z2 = state.dataSurface->Surface(GRSNR).Vertex(3).z - state.dataSurface->Surface(GRSNR).Vertex(2).z; // ZV(3,GRSNR)-ZV(2,GRSNR)
2885 19 : BX = Y1 * Z2 - Y2 * Z1;
2886 19 : BY = Z1 * X2 - Z2 * X1;
2887 19 : BZ = X1 * Y2 - X2 * Y1;
2888 : // C FIND LARGEST COMPONENT.
2889 19 : BMAX = max(std::abs(BX), std::abs(BY), std::abs(BZ));
2890 : // C
2891 19 : if (std::abs(BX) == BMAX) {
2892 : // write(outputfiledebug,*) ' looking bx-bmax',bmax
2893 10 : for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) { // NV(SBSNR)
2894 8 : inside = polygon_contains_point(state.dataSurface->Surface(GRSNR).Sides,
2895 8 : state.dataSurface->Surface(GRSNR).Vertex,
2896 8 : state.dataSurface->Surface(SBSNR).Vertex(N),
2897 : true,
2898 : false,
2899 : false);
2900 8 : if (!inside) {
2901 0 : Out = true;
2902 : // do m=1,surface(grsnr)%sides
2903 : // write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
2904 : // write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
2905 : // enddo
2906 : // EXIT
2907 : }
2908 : // Y1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(NV(GRSNR),GRSNR)-YV(N,SBSNR)
2909 : // Z1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(NV(GRSNR),GRSNR)-ZV(N,SBSNR)
2910 : // DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
2911 : // Y2 = Y1
2912 : // Z2 = Z1
2913 : // Y1 = Surface(GRSNR)%Vertex(M)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(M,GRSNR)-YV(N,SBSNR)
2914 : // Z1 = Surface(GRSNR)%Vertex(M)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(M,GRSNR)-ZV(N,SBSNR)
2915 : // SX = Y1*Z2-Y2*Z1
2916 : // IF(SX*BX.LT.-1.0d-6) THEN
2917 : // OUT=.TRUE.
2918 : // write(outputfiledebug,*) 'sx*bx=',sx*bx
2919 : // write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
2920 : // write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
2921 : // endif
2922 : // ENDDO
2923 : // IF (OUT) EXIT
2924 : }
2925 17 : } else if (std::abs(BY) == BMAX) {
2926 : // write(outputfiledebug,*) ' looking by-bmax',bmax
2927 5 : for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) { // NV(SBSNR)
2928 4 : inside = polygon_contains_point(state.dataSurface->Surface(GRSNR).Sides,
2929 4 : state.dataSurface->Surface(GRSNR).Vertex,
2930 4 : state.dataSurface->Surface(SBSNR).Vertex(N),
2931 : false,
2932 : true,
2933 : false);
2934 4 : if (!inside) {
2935 0 : Out = true;
2936 : // do m=1,surface(grsnr)%sides
2937 : // write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
2938 : // write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
2939 : // enddo
2940 : // EXIT
2941 : }
2942 : // Z1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(NV(GRSNR),GRSNR)-ZV(N,SBSNR)
2943 : // X1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%X-Surface(SBSNR)%Vertex(N)%X !XV(NV(GRSNR),GRSNR)-XV(N,SBSNR)
2944 : // DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
2945 : // Z2 = Z1
2946 : // X2 = X1
2947 : // Z1 = Surface(GRSNR)%Vertex(M)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(M,GRSNR)-ZV(N,SBSNR)
2948 : // X1 = Surface(GRSNR)%Vertex(M)%X-Surface(SBSNR)%Vertex(N)%X !XV(M,GRSNR)-XV(N,SBSNR)
2949 : // SY = Z1*X2-Z2*X1
2950 : // IF(SY*BY.LT.-1.0d-6) THEN
2951 : // OUT=.TRUE.
2952 : // write(outputfiledebug,*) 'sy*by=',sy*by
2953 : // write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
2954 : // write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
2955 : // ENDIF
2956 : // ENDDO
2957 : // IF (OUT) EXIT
2958 : }
2959 : } else {
2960 : // write(outputfiledebug,*) ' looking bz-bmax',bmax
2961 80 : for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) { // NV(SBSNR)
2962 64 : inside = polygon_contains_point(state.dataSurface->Surface(GRSNR).Sides,
2963 64 : state.dataSurface->Surface(GRSNR).Vertex,
2964 64 : state.dataSurface->Surface(SBSNR).Vertex(N),
2965 : false,
2966 : false,
2967 : true);
2968 64 : if (!inside) {
2969 0 : Out = true;
2970 : // do m=1,surface(grsnr)%sides
2971 : // write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
2972 : // write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
2973 : // enddo
2974 : // EXIT
2975 : }
2976 : // X1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%X-Surface(SBSNR)%Vertex(N)%X !XV(NV(GRSNR),GRSNR)-XV(N,SBSNR)
2977 : // Y1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(NV(GRSNR),GRSNR)-YV(N,SBSNR)
2978 : // DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
2979 : // X2 = X1
2980 : // Y2 = Y1
2981 : // X1 = Surface(GRSNR)%Vertex(M)%X-Surface(SBSNR)%Vertex(N)%X !XV(M,GRSNR)-XV(N,SBSNR)
2982 : // Y1 = Surface(GRSNR)%Vertex(M)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(M,GRSNR)-YV(N,SBSNR)
2983 : // SZ = X1*Y2-X2*Y1
2984 : // IF(SZ*BZ.LT.-1.0d-6) THEN
2985 : // OUT=.TRUE.
2986 : // write(outputfiledebug,*) 'sz*bz=',sz*bz
2987 : // write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
2988 : // write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
2989 : // ENDIF
2990 : // ENDDO
2991 : // IF (OUT) EXIT
2992 : }
2993 : }
2994 : // CALL ShowWarningError(state, 'Base surface does not surround subsurface (CHKSBS), Overlap Status='// &
2995 : // TRIM(cOverLapStatus(OverlapStatus)))
2996 : // CALL ShowContinueError(state, 'Surface "'//TRIM(Surface(GRSNR)%Name)//'" '//TRIM(MSG(OverlapStatus))// &
2997 : // ' SubSurface "'//TRIM(Surface(SBSNR)%Name)//'"')
2998 : // IF (FirstSurroundError) THEN
2999 : // CALL ShowWarningError(state, 'Base Surface does not surround subsurface errors occuring...'// &
3000 : // 'Check that the SurfaceGeometry object is expressing the proper starting corner and '// &
3001 : // 'direction [CounterClockwise/Clockwise]')
3002 : // FirstSurroundError=.FALSE.
3003 : // ENDIF
3004 19 : if (Out) {
3005 0 : state.dataSolarShading->TrackBaseSubSurround.redimension(++state.dataSolarShading->NumBaseSubSurround);
3006 0 : state.dataSolarShading->TrackBaseSubSurround(state.dataSolarShading->NumBaseSubSurround).SurfIndex1 = GRSNR;
3007 0 : state.dataSolarShading->TrackBaseSubSurround(state.dataSolarShading->NumBaseSubSurround).SurfIndex2 = SBSNR;
3008 0 : state.dataSolarShading->TrackBaseSubSurround(state.dataSolarShading->NumBaseSubSurround).MiscIndex =
3009 0 : state.dataSolarShading->OverlapStatus;
3010 : // CALL ShowRecurringWarningErrorAtEnd(state, 'Base surface does not surround subsurface (CHKSBS), Overlap Status='// &
3011 : // TRIM(cOverLapStatus(OverlapStatus)), &
3012 : // TrackBaseSubSurround(GRSNR)%ErrIndex1)
3013 : // CALL ShowRecurringContinueErrorAtEnd(state, 'Surface "'//TRIM(Surface(GRSNR)%Name)//'" '//TRIM(MSG(OverlapStatus))// &
3014 : // ' SubSurface "'//TRIM(Surface(SBSNR)%Name)//'"', &
3015 : // TrackBaseSubSurround(SBSNR)%ErrIndex2)
3016 0 : if (state.dataSolarShading->shd_stream) {
3017 0 : *state.dataSolarShading->shd_stream << "==== Base does not Surround subsurface details ====\n";
3018 0 : *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(GRSNR).Name << ' '
3019 0 : << state.dataSolarShading->cOverLapStatus(state.dataSolarShading->OverlapStatus) << '\n';
3020 0 : *state.dataSolarShading->shd_stream << "Surface#=" << std::setw(5) << GRSNR << " NSides=" << std::setw(5)
3021 0 : << state.dataSurface->Surface(GRSNR).Sides << '\n';
3022 0 : *state.dataSolarShading->shd_stream << std::fixed << std::setprecision(2);
3023 0 : for (N = 1; N <= state.dataSurface->Surface(GRSNR).Sides; ++N) {
3024 0 : Vector const &v(state.dataSurface->Surface(GRSNR).Vertex(N));
3025 0 : *state.dataSolarShading->shd_stream << "Vertex " << std::setw(5) << N << "=(" << std::setw(15) << v.x << ',' << std::setw(15)
3026 0 : << v.y << ',' << std::setw(15) << v.z << ")\n";
3027 : }
3028 0 : *state.dataSolarShading->shd_stream << "SubSurface=" << state.dataSurface->Surface(SBSNR).Name << '\n';
3029 0 : *state.dataSolarShading->shd_stream << "Surface#=" << std::setw(5) << SBSNR << " NSides=" << std::setw(5)
3030 0 : << state.dataSurface->Surface(SBSNR).Sides << '\n';
3031 0 : for (N = 1; N <= state.dataSurface->Surface(SBSNR).Sides; ++N) {
3032 0 : Vector const &v(state.dataSurface->Surface(SBSNR).Vertex(N));
3033 0 : *state.dataSolarShading->shd_stream << "Vertex " << std::setw(5) << N << "=(" << std::setw(15) << v.x << ',' << std::setw(15)
3034 0 : << v.y << ',' << std::setw(15) << v.z << ")\n";
3035 : }
3036 0 : *state.dataSolarShading->shd_stream << "================================\n";
3037 : }
3038 : }
3039 : }
3040 6337 : }
3041 :
3042 76 : bool polygon_contains_point(int const nsides, // number of sides (vertices)
3043 : Array1D<Vector> &polygon_3d, // points of polygon
3044 : Vector const &point_3d, // point to be tested
3045 : bool const ignorex,
3046 : bool const ignorey,
3047 : bool const ignorez)
3048 : {
3049 :
3050 : // Function information:
3051 : // Author Linda Lawrie
3052 : // Date written October 2005
3053 : // Modified na
3054 : // Re-engineered na
3055 :
3056 : // Purpose of this function:
3057 : // Determine if a point is inside a simple 2d polygon. For a simple polygon (one whose
3058 : // boundary never crosses itself). The polygon does not need to be convex.
3059 :
3060 : // References:
3061 : // M Shimrat, Position of Point Relative to Polygon, ACM Algorithm 112,
3062 : // Communications of the ACM, Volume 5, Number 8, page 434, August 1962.
3063 :
3064 : // Use statements:
3065 : // Using/Aliasing
3066 : using namespace DataVectorTypes;
3067 :
3068 : // Return value
3069 : bool inside; // return value, true=inside, false = not inside
3070 :
3071 76 : EP_SIZE_CHECK(polygon_3d, nsides);
3072 :
3073 : int i;
3074 : int ip1;
3075 :
3076 : // Object Data
3077 152 : Array1D<Vector_2d> polygon(nsides);
3078 152 : Vector_2d point;
3079 :
3080 76 : inside = false;
3081 76 : if (ignorex) {
3082 40 : for (int i = 1; i <= nsides; ++i) {
3083 32 : polygon(i).x = polygon_3d(i).y;
3084 32 : polygon(i).y = polygon_3d(i).z;
3085 : }
3086 8 : point.x = point_3d.y;
3087 8 : point.y = point_3d.z;
3088 68 : } else if (ignorey) {
3089 20 : for (int i = 1; i <= nsides; ++i) {
3090 16 : polygon(i).x = polygon_3d(i).x;
3091 16 : polygon(i).y = polygon_3d(i).z;
3092 : }
3093 4 : point.x = point_3d.x;
3094 4 : point.y = point_3d.z;
3095 64 : } else if (ignorez) {
3096 576 : for (int i = 1; i <= nsides; ++i) {
3097 512 : polygon(i).x = polygon_3d(i).x;
3098 512 : polygon(i).y = polygon_3d(i).y;
3099 : }
3100 64 : point.x = point_3d.x;
3101 64 : point.y = point_3d.y;
3102 : } else { // Illegal
3103 0 : assert(false);
3104 : point.x = point.y = 0.0; // Elim possibly used uninitialized warnings
3105 : }
3106 :
3107 636 : for (i = 1; i <= nsides; ++i) {
3108 :
3109 560 : if (i < nsides) {
3110 484 : ip1 = i + 1;
3111 : } else {
3112 76 : ip1 = 1;
3113 : }
3114 :
3115 560 : if ((polygon(i).y < point.y && point.y <= polygon(ip1).y) || (point.y <= polygon(i).y && polygon(ip1).y < point.y)) {
3116 152 : if ((point.x - polygon(i).x) - (point.y - polygon(i).y) * (polygon(ip1).x - polygon(i).x) / (polygon(ip1).y - polygon(i).y) < 0) {
3117 76 : inside = !inside;
3118 : }
3119 : }
3120 : }
3121 :
3122 152 : return inside;
3123 : }
3124 :
3125 331 : void ComputeIntSolarAbsorpFactors(EnergyPlusData &state)
3126 : {
3127 :
3128 : // SUBROUTINE INFORMATION:
3129 : // AUTHOR Legacy Code
3130 : // MODIFIED B. Griffith, Oct 2010, deal with no floor case
3131 : // L. Lawrie, Mar 2012, relax >154 tilt even further (>120 considered non-wall by ASHRAE)
3132 : // RE-ENGINEERED Lawrie, Oct 2000
3133 :
3134 : // PURPOSE OF THIS SUBROUTINE:
3135 : // This routine computes the fractions of diffusely transmitted
3136 : // solar energy absorbed by each zone surface.
3137 :
3138 : // METHODOLOGY EMPLOYED:
3139 : // It is assumed that all transmitted solar energy is incident
3140 : // on the floors of the zone (or enclosure). The fraction directly absorbed in
3141 : // the floor is given by 'ISABSF'. It is proportional to the
3142 : // area * solar absorptance. The remaining solar energy is then
3143 : // distributed uniformly around the room according to
3144 : // area*absorptance product
3145 :
3146 : // REFERENCES:
3147 : // BLAST/IBLAST code, original author George Walton
3148 :
3149 : using namespace DataWindowEquivalentLayer;
3150 :
3151 : Real64 AreaSum; // Intermediate calculation value
3152 : int Lay; // Window glass layer number
3153 : Real64 AbsDiffTotWin; // Sum of a window's glass layer solar absorptances
3154 : Real64 TestFractSum;
3155 : Real64 HorizAreaSum;
3156 :
3157 2324 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
3158 1993 : auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
3159 :
3160 1993 : AreaSum = 0.0;
3161 1993 : TestFractSum = 0.0;
3162 19085 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
3163 34184 : if (state.dataHeatBal->Zone(state.dataSurface->Surface(SurfNum).Zone).OfType == StandardZone &&
3164 17092 : state.dataSurface->Surface(SurfNum).CosTilt < -0.5) {
3165 3046 : AreaSum += state.dataSurface->Surface(SurfNum).Area;
3166 : }
3167 : }
3168 :
3169 1993 : HorizAreaSum = AreaSum;
3170 :
3171 1993 : if ((thisEnclosure.FloorArea <= 0.0) && (HorizAreaSum > 0.0)) {
3172 : // fill floor area even though surfs not called "Floor", they are roughly horizontal and face upwards.
3173 0 : thisEnclosure.FloorArea = HorizAreaSum;
3174 0 : ShowWarningError(state, "ComputeIntSolarAbsorpFactors: Solar distribution model is set to place solar gains on the zone floor,");
3175 0 : ShowContinueError(state, "...Enclosure=\"" + thisEnclosure.Name + "\" has no floor, but has approximate horizontal surfaces.");
3176 0 : ShowContinueError(state, format("...these Tilt > 120 degrees, (area=[{:.2R}] m2) will be used.", HorizAreaSum));
3177 : }
3178 :
3179 : // Compute ISABSF
3180 :
3181 19085 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
3182 :
3183 : // only horizontal surfaces. ! !CR 8229, relaxed from -0.99 to -0.5 (Tilt > 154)
3184 : // only horizontal surfaces. ! !CR8769 use ASHRAE std of >120, -0.9 to -0.5 (Tilt > 120)
3185 51276 : if ((state.dataHeatBal->Zone(state.dataSurface->Surface(SurfNum).Zone).OfType != StandardZone ||
3186 23184 : state.dataSurface->Surface(SurfNum).CosTilt < -0.5) &&
3187 3046 : (state.dataHeatBal->Zone(state.dataSurface->Surface(SurfNum).Zone).OfType == StandardZone ||
3188 0 : state.dataSurface->Surface(SurfNum).ExtBoundCond > 0)) {
3189 :
3190 3046 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3191 : // last minute V3.1
3192 3046 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
3193 3046 : if (AreaSum > 0.0)
3194 3046 : state.dataSolarShading->SurfIntAbsFac(SurfNum) =
3195 3046 : state.dataSurface->Surface(SurfNum).Area * state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar / AreaSum;
3196 : } else { // Window (floor windows are assumed to have no shading device and no divider,
3197 : // and assumed to be non-switchable)
3198 0 : AbsDiffTotWin = 0.0;
3199 0 : if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) {
3200 0 : for (Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNum).TotGlassLayers; ++Lay) {
3201 0 : AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay);
3202 : }
3203 : } else {
3204 0 : for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(ConstrNum).EQLConsPtr).NL; ++Lay) {
3205 0 : AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBackEQL(Lay);
3206 : }
3207 : }
3208 0 : if (AreaSum > 0.0)
3209 0 : state.dataSolarShading->SurfIntAbsFac(SurfNum) = state.dataSurface->Surface(SurfNum).Area * AbsDiffTotWin / AreaSum;
3210 : }
3211 : }
3212 : // CR 8229 test ISABSF for problems
3213 17092 : TestFractSum += state.dataSolarShading->SurfIntAbsFac(SurfNum);
3214 : }
3215 :
3216 1993 : if (TestFractSum <= 0.0) {
3217 0 : if (thisEnclosure.ExtWindowArea > 0.0) { // we have a problem, the sun has no floor to go to
3218 0 : if (thisEnclosure.FloorArea <= 0.0) {
3219 0 : ShowSevereError(state, "ComputeIntSolarAbsorpFactors: Solar distribution model is set to place solar gains on the zone floor,");
3220 0 : ShowContinueError(state, "but Zone or Enclosure =\"" + thisEnclosure.Name + "\" does not appear to have any floor surfaces.");
3221 0 : ShowContinueError(state, "Solar gains will be spread evenly on all surfaces in the zone, and the simulation continues...");
3222 : } else { // Floor Area > 0 but still can't absorb
3223 0 : ShowSevereError(state, "ComputeIntSolarAbsorpFactors: Solar distribution model is set to place solar gains on the zone floor,");
3224 0 : ShowContinueError(state, "but Zone or Enclosure =\"" + thisEnclosure.Name + "\" floor cannot absorb any solar gains. ");
3225 0 : ShowContinueError(state, "Check the solar absorptance of the inside layer of the floor surface construction/material.");
3226 0 : ShowContinueError(state, "Solar gains will be spread evenly on all surfaces in the zone, and the simulation continues...");
3227 : }
3228 :
3229 : // try again but use an even spread across all the surfaces in the zone, regardless of horizontal
3230 : // so as to not lose solar energy
3231 0 : AreaSum = 0.0;
3232 0 : for (int SurfNum : thisEnclosure.SurfacePtr) {
3233 0 : AreaSum += state.dataSurface->Surface(SurfNum).Area;
3234 : }
3235 :
3236 0 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
3237 0 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
3238 0 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface
3239 0 : if (AreaSum > 0.0)
3240 0 : state.dataSolarShading->SurfIntAbsFac(SurfNum) =
3241 0 : state.dataSurface->Surface(SurfNum).Area * state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar / AreaSum;
3242 : } else { // Window (floor windows are assumed to have no shading device and no divider,
3243 : // and assumed to be non-switchable)
3244 0 : AbsDiffTotWin = 0.0;
3245 0 : if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) {
3246 0 : for (Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNum).TotGlassLayers; ++Lay) {
3247 0 : AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay);
3248 : }
3249 : } else {
3250 0 : for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(ConstrNum).EQLConsPtr).NL; ++Lay) {
3251 0 : AbsDiffTotWin += state.dataConstruction->Construct(ConstrNum).AbsDiffBackEQL(Lay);
3252 : }
3253 : }
3254 :
3255 0 : if (AreaSum > 0.0)
3256 0 : state.dataSolarShading->SurfIntAbsFac(SurfNum) = state.dataSurface->Surface(SurfNum).Area * AbsDiffTotWin / AreaSum;
3257 : }
3258 : }
3259 : }
3260 : }
3261 :
3262 : } // enclosure loop
3263 331 : }
3264 :
3265 3190118 : void CLIP(EnergyPlusData &state, int const NVT, Array1D<Real64> &XVT, Array1D<Real64> &YVT, Array1D<Real64> &ZVT)
3266 : {
3267 :
3268 : // SUBROUTINE INFORMATION:
3269 : // AUTHOR Legacy Code
3270 : // DATE WRITTEN
3271 : // MODIFIED na
3272 : // RE-ENGINEERED Lawrie, Oct 2000
3273 :
3274 : // PURPOSE OF THIS SUBROUTINE:
3275 : // This subroutine 'clips' the shadow casting surface polygon so that
3276 : // none of it lies below the plane of the receiving surface polygon. This
3277 : // prevents the casting of 'false' shadows.
3278 :
3279 : // REFERENCES:
3280 : // BLAST/IBLAST code, original author George Walton
3281 :
3282 3190118 : int NABOVE(0); // Number of vertices of shadow casting surface. above the plane of receiving surface
3283 3190118 : int NEXT(0); // First vertex above plane of receiving surface
3284 3190118 : int NON(0); // Number of vertices of shadow casting surface. on plane of receiving surface
3285 3190118 : Real64 XIN(0.0); // X of entry point of shadow casting surface. into plane of receiving surface
3286 3190118 : Real64 XOUT(0.0); // X of exit point of shadow casting surface. from plane of receiving surface
3287 3190118 : Real64 YIN(0.0); // Y of entry point of shadow casting surface. into plane of receiving surface
3288 3190118 : Real64 YOUT(0.0); // Y of exit point of shadow casting surface. from plane of receiving surface
3289 : // INTEGER NVS ! Number of vertices of the shadow/clipped surface
3290 :
3291 : // Determine if the shadow casting surface. is above, below, or intersects with the plane of the receiving surface
3292 :
3293 3190118 : state.dataSolarShading->NumVertInShadowOrClippedSurface = state.dataSolarShading->NVS;
3294 15883650 : for (int N = 1; N <= NVT; ++N) {
3295 12693532 : Real64 const ZVT_N(ZVT(N));
3296 12693532 : if (ZVT_N > 0.0) {
3297 10078171 : ++NABOVE;
3298 2615361 : } else if (ZVT_N == 0.0) {
3299 1286696 : ++NON;
3300 : }
3301 : }
3302 :
3303 3190118 : if (NABOVE + NON == NVT) { // Rename the unclipped shadow casting surface.
3304 :
3305 2524049 : state.dataSolarShading->NVS = NVT;
3306 2524049 : state.dataSolarShading->NumVertInShadowOrClippedSurface = NVT;
3307 12592041 : for (int N = 1; N <= NVT; ++N) {
3308 10067992 : state.dataSolarShading->XVC(N) = XVT(N);
3309 10067992 : state.dataSolarShading->YVC(N) = YVT(N);
3310 10067992 : state.dataSolarShading->ZVC(N) = ZVT(N);
3311 : }
3312 :
3313 666069 : } else if (NABOVE == 0) { // Totally submerged shadow casting surface.
3314 :
3315 0 : state.dataSolarShading->NVS = 0;
3316 0 : state.dataSolarShading->NumVertInShadowOrClippedSurface = 0;
3317 :
3318 : } else { // Remove (clip) that portion of the shadow casting surface. which is below the receiving surface
3319 :
3320 666069 : state.dataSolarShading->NVS = NABOVE + 2;
3321 666069 : state.dataSolarShading->NumVertInShadowOrClippedSurface = NABOVE + 2;
3322 666069 : Real64 ZVT_N, ZVT_P(ZVT(1));
3323 666069 : XVT(NVT + 1) = XVT(1);
3324 666069 : YVT(NVT + 1) = YVT(1);
3325 666069 : ZVT(NVT + 1) = ZVT_P;
3326 3291609 : for (int N = 1, P = 2; N <= NVT; ++N, ++P) {
3327 2625540 : ZVT_N = ZVT_P;
3328 2625540 : ZVT_P = ZVT(P);
3329 2625540 : if (ZVT_N >= 0.0 && ZVT_P < 0.0) { // Line enters plane of receiving surface
3330 666069 : Real64 const ZVT_fac(1.0 / (ZVT_P - ZVT_N));
3331 666069 : XIN = (ZVT_P * XVT(N) - ZVT_N * XVT(P)) * ZVT_fac;
3332 666069 : YIN = (ZVT_P * YVT(N) - ZVT_N * YVT(P)) * ZVT_fac;
3333 1959471 : } else if (ZVT_N <= 0.0 && ZVT_P > 0.0) { // Line exits plane of receiving surface
3334 666069 : NEXT = N + 1;
3335 666069 : Real64 const ZVT_fac(1.0 / (ZVT_P - ZVT_N));
3336 666069 : XOUT = (ZVT_P * XVT(N) - ZVT_N * XVT(P)) * ZVT_fac;
3337 666069 : YOUT = (ZVT_P * YVT(N) - ZVT_N * YVT(P)) * ZVT_fac;
3338 : }
3339 : }
3340 :
3341 : // Renumber the vertices of the clipped shadow casting surface. so they are still counter-clockwise sequential.
3342 :
3343 666069 : state.dataSolarShading->XVC(1) = XOUT; //? Verify that the IN and OUT values were ever set?
3344 666069 : state.dataSolarShading->YVC(1) = YOUT;
3345 666069 : state.dataSolarShading->ZVC(1) = 0.0;
3346 666069 : state.dataSolarShading->XVC(state.dataSolarShading->NVS) = XIN;
3347 666069 : state.dataSolarShading->YVC(state.dataSolarShading->NVS) = YIN;
3348 666069 : state.dataSolarShading->ZVC(state.dataSolarShading->NVS) = 0.0;
3349 1938253 : for (int N = 1; N <= NABOVE; ++N) {
3350 1272184 : if (NEXT > NVT) NEXT = 1;
3351 1272184 : state.dataSolarShading->XVC(N + 1) = XVT(NEXT);
3352 1272184 : state.dataSolarShading->YVC(N + 1) = YVT(NEXT);
3353 1272184 : state.dataSolarShading->ZVC(N + 1) = ZVT(NEXT);
3354 1272184 : ++NEXT;
3355 : }
3356 : }
3357 3190118 : }
3358 :
3359 5969245 : void CTRANS(EnergyPlusData &state,
3360 : int const NS, // Surface number whose vertex coordinates are being transformed
3361 : int const NGRS, // Base surface number for surface NS
3362 : int &NVT, // Number of vertices for surface NS
3363 : Array1D<Real64> &XVT, // XYZ coordinates of vertices of NS in plane of NGRS
3364 : Array1D<Real64> &YVT,
3365 : Array1D<Real64> &ZVT)
3366 : {
3367 :
3368 : // SUBROUTINE INFORMATION:
3369 : // AUTHOR Legacy Code
3370 : // DATE WRITTEN
3371 : // MODIFIED na
3372 : // RE-ENGINEERED Lawrie, Oct 2000
3373 :
3374 : // PURPOSE OF THIS SUBROUTINE:
3375 : // Transforms the general coordinates of the vertices
3376 : // of surface NS to coordinates in the plane of the receiving surface NGRS.
3377 : // See subroutine 'CalcCoordinateTransformation' SurfaceGeometry Module.
3378 :
3379 : // REFERENCES:
3380 : // BLAST/IBLAST code, original author George Walton
3381 : // NECAP subroutine 'SHADOW'
3382 :
3383 : Real64 Xdif; // Intermediate Result
3384 : Real64 Ydif; // Intermediate Result
3385 : Real64 Zdif; // Intermediate Result
3386 :
3387 : // Tuned
3388 5969245 : auto const &surface(state.dataSurface->Surface(NS));
3389 5969245 : auto const &base_surface(state.dataSurface->Surface(NGRS));
3390 5969245 : auto const &base_lcsx(base_surface.lcsx);
3391 5969245 : auto const &base_lcsy(base_surface.lcsy);
3392 5969245 : auto const &base_lcsz(base_surface.lcsz);
3393 5969245 : Real64 const base_X0(state.dataSurface->X0(NGRS));
3394 5969245 : Real64 const base_Y0(state.dataSurface->Y0(NGRS));
3395 5969245 : Real64 const base_Z0(state.dataSurface->Z0(NGRS));
3396 :
3397 5969245 : NVT = surface.Sides;
3398 :
3399 : // Perform transformation
3400 29799103 : for (int N = 1; N <= NVT; ++N) {
3401 23829858 : auto const &vertex(surface.Vertex(N));
3402 :
3403 23829858 : Xdif = vertex.x - base_X0;
3404 23829858 : Ydif = vertex.y - base_Y0;
3405 23829858 : Zdif = vertex.z - base_Z0;
3406 :
3407 23829858 : if (std::abs(Xdif) <= 1.E-15) Xdif = 0.0;
3408 23829858 : if (std::abs(Ydif) <= 1.E-15) Ydif = 0.0;
3409 23829858 : if (std::abs(Zdif) <= 1.E-15) Zdif = 0.0;
3410 :
3411 23829858 : XVT(N) = base_lcsx.x * Xdif + base_lcsx.y * Ydif + base_lcsx.z * Zdif;
3412 23829858 : YVT(N) = base_lcsy.x * Xdif + base_lcsy.y * Ydif + base_lcsy.z * Zdif;
3413 23829858 : ZVT(N) = base_lcsz.x * Xdif + base_lcsz.y * Ydif + base_lcsz.z * Zdif;
3414 : }
3415 5969245 : }
3416 :
3417 0 : void HTRANS(EnergyPlusData &state,
3418 : int const I, // Mode selector: 0 - Compute H.C. of sides
3419 : int const NS, // Figure Number
3420 : int const NumVertices // Number of vertices
3421 : )
3422 : {
3423 :
3424 : // SUBROUTINE INFORMATION:
3425 : // AUTHOR Legacy Code
3426 : // DATE WRITTEN
3427 : // MODIFIED na
3428 : // RE-ENGINEERED Lawrie, Oct 2000
3429 :
3430 : // PURPOSE OF THIS SUBROUTINE:
3431 : // This subroutine sets up the homogeneous coordinates.
3432 : // This routine converts the cartesian coordinates of a surface
3433 : // or shadow polygon to homogeneous coordinates. It also
3434 : // computes the area of the polygon.
3435 :
3436 : // METHODOLOGY EMPLOYED:
3437 : // Note: Original legacy code used integer arithmetic (tests in subroutines
3438 : // INCLOS and INTCPT are sensitive to round-off error). However, porting to Fortran 77
3439 : // (BLAST/IBLAST) required some variables to become REAL(r64) instead.
3440 :
3441 : // Notes on homogeneous coordinates:
3442 : // A point (X,Y) is represented by a 3-element vector
3443 : // (W*X,W*Y,W), where W may be any REAL(r64) number except 0. a line
3444 : // is also represented by a 3-element vector (A,B,C). The
3445 : // directed line (A,B,C) from point (W*X1,W*Y1,W) to point
3446 : // (V*X2,V*Y2,V) is given by (A,B,C) = (W*X1,W*Y1,W) cross
3447 : // (V*X2,V*Y2,V). The sequence of the cross product is a
3448 : // convention to determine sign. The condition that a point lie
3449 : // on a line is that (A,B,C) dot (W*X,W*Y,W) = 0. 'Normalize'
3450 : // the representation of a point by setting W to 1. Then if
3451 : // (A,B,C) dot (X,Y,1) > 0.0, The point is to the left of the
3452 : // line, and if it is less than zero, the point is to the right
3453 : // of the line. The intercept of two lines is given by
3454 : // (W*X,W*Y,W) = (A1,B1,C1) cross (A2,B2,C3).
3455 :
3456 : // REFERENCES:
3457 : // BLAST/IBLAST code, original author George Walton
3458 : // W. M. Newman & R. F. Sproull, 'Principles of Interactive Computer Graphics', Appendix II, McGraw-Hill, 1973.
3459 : // 'CRC Math Tables', 22 ED, 'Analytic Geometry', P.369
3460 :
3461 : // Using/Aliasing
3462 :
3463 : // Locals
3464 : // SUBROUTINE ARGUMENT DEFINITIONS:
3465 : // 1 - Compute H.C. of vertices & sides
3466 :
3467 0 : if (NS > 2 * state.dataSolarShading->MaxHCS) {
3468 0 : ShowFatalError(state, format("Solar Shading: HTrans: Too many Figures (>{})", state.dataSolarShading->MaxHCS));
3469 : }
3470 :
3471 0 : state.dataSolarShading->HCNV(NS) = NumVertices;
3472 :
3473 : // Tuned Linear indexing
3474 :
3475 0 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
3476 0 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
3477 0 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
3478 0 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
3479 0 : auto const l1(state.dataSolarShading->HCX.index(NS, 1));
3480 0 : if (I != 0) { // Transform vertices of figure ns.
3481 :
3482 : // See comment at top of module regarding HCMULT
3483 0 : auto l(l1);
3484 0 : for (int N = 1; N <= NumVertices; ++N, ++l) { // [ l ] == ( NS, N )
3485 0 : state.dataSolarShading->HCX[l] = nint64(state.dataSolarShading->XVS(N) * HCMULT);
3486 0 : state.dataSolarShading->HCY[l] = nint64(state.dataSolarShading->YVS(N) * HCMULT);
3487 : }
3488 : }
3489 :
3490 : // Establish extra point for finding lines between points.
3491 :
3492 0 : auto l(state.dataSolarShading->HCX.index(NS, NumVertices + 1));
3493 0 : Int64 HCX_m(state.dataSolarShading->HCX[l] = state.dataSolarShading->HCX[l1]); // [ l ] == ( NS, NumVertices + 1 ), [ l1 ] == ( NS, 1 )
3494 0 : Int64 HCY_m(state.dataSolarShading->HCY[l] = state.dataSolarShading->HCY[l1]); // [ l ] == ( NS, NumVertices + 1 ), [ l1 ] == ( NS, 1 )
3495 :
3496 : // Determine lines between points.
3497 0 : l = l1;
3498 0 : auto m(l1 + 1u);
3499 : Int64 HCX_l;
3500 : Int64 HCY_l;
3501 0 : Real64 SUM(0.0); // Sum variable
3502 0 : for (int N = 1; N <= NumVertices; ++N, ++l, ++m) { // [ l ] == ( NS, N ), [ m ] == ( NS, N + 1 )
3503 0 : HCX_l = HCX_m;
3504 0 : HCY_l = HCY_m;
3505 0 : HCX_m = state.dataSolarShading->HCX[m];
3506 0 : HCY_m = state.dataSolarShading->HCY[m];
3507 0 : state.dataSolarShading->HCA[l] = HCY_l - HCY_m;
3508 0 : state.dataSolarShading->HCB[l] = HCX_m - HCX_l;
3509 0 : SUM += state.dataSolarShading->HCC[l] = (HCY_m * HCX_l) - (HCX_m * HCY_l);
3510 : }
3511 :
3512 : // Compute area of polygon.
3513 : // SUM=0.0D0
3514 : // DO N = 1, NumVertices
3515 : // SUM = SUM + HCX(N,NS)*HCY(N+1,NS) - HCY(N,NS)*HCX(N+1,NS) ! Since HCX and HCY integerized, value of SUM should be ok
3516 : // END DO
3517 0 : state.dataSolarShading->HCAREA(NS) = SUM * sqHCMULT_fac;
3518 : // HCAREA(NS)=0.5d0*SUM*(kHCMULT)
3519 0 : }
3520 :
3521 12482904 : void HTRANS0(EnergyPlusData &state,
3522 : int const NS, // Figure Number
3523 : int const NumVertices // Number of vertices
3524 : )
3525 : {
3526 : // Using/Aliasing
3527 :
3528 : // Locals
3529 :
3530 12482904 : if (NS > 2 * state.dataSolarShading->MaxHCS) {
3531 0 : ShowFatalError(state, format("Solar Shading: HTrans0: Too many Figures (>{})", state.dataSolarShading->MaxHCS));
3532 : }
3533 :
3534 12482904 : state.dataSolarShading->HCNV(NS) = NumVertices;
3535 :
3536 : // Tuned Linear indexing
3537 :
3538 12482904 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
3539 12482904 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
3540 12482904 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
3541 12482904 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
3542 :
3543 12482904 : auto const l1(state.dataSolarShading->HCX.index(NS, 1));
3544 :
3545 12482904 : auto l(state.dataSolarShading->HCX.index(NS, NumVertices + 1));
3546 12482904 : Int64 HCX_m(state.dataSolarShading->HCX[l] = state.dataSolarShading->HCX[l1]); // [ l1 ] == ( NS, 1 )
3547 12482904 : Int64 HCY_m(state.dataSolarShading->HCY[l] = state.dataSolarShading->HCY[l1]); // [ l1 ] == ( NS, 1 )
3548 :
3549 12482904 : l = l1;
3550 12482904 : auto m(l1 + 1u);
3551 : Int64 HCX_l;
3552 : Int64 HCY_l;
3553 12482904 : Real64 SUM(0.0);
3554 43217562 : for (int N = 1; N <= NumVertices; ++N, ++l, ++m) { // [ l ] == ( NS, N ), [ m ] == ( NS, N + 1 )
3555 30734658 : HCX_l = HCX_m;
3556 30734658 : HCY_l = HCY_m;
3557 30734658 : HCX_m = state.dataSolarShading->HCX[m];
3558 30734658 : HCY_m = state.dataSolarShading->HCY[m];
3559 30734658 : state.dataSolarShading->HCA[l] = HCY_l - HCY_m;
3560 30734658 : state.dataSolarShading->HCB[l] = HCX_m - HCX_l;
3561 30734658 : SUM += state.dataSolarShading->HCC[l] = (HCY_m * HCX_l) - (HCX_m * HCY_l);
3562 : }
3563 :
3564 12482904 : state.dataSolarShading->HCAREA(NS) = SUM * sqHCMULT_fac;
3565 12482904 : }
3566 :
3567 7320027 : void HTRANS1(EnergyPlusData &state,
3568 : int const NS, // Figure Number
3569 : int const NumVertices // Number of vertices
3570 : )
3571 : {
3572 : // Using/Aliasing
3573 :
3574 7320027 : if (NS > 2 * state.dataSolarShading->MaxHCS) {
3575 0 : ShowFatalError(state, format("Solar Shading: HTrans1: Too many Figures (>{})", state.dataSolarShading->MaxHCS));
3576 : }
3577 :
3578 7320027 : state.dataSolarShading->HCNV(NS) = NumVertices;
3579 :
3580 : // Tuned Linear indexing
3581 :
3582 7320027 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
3583 7320027 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
3584 7320027 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
3585 7320027 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
3586 :
3587 7320027 : auto const l1(state.dataSolarShading->HCX.index(NS, 1));
3588 :
3589 : // only in HTRANS1
3590 7320027 : auto l(l1);
3591 36531443 : for (int N = 1; N <= NumVertices; ++N, ++l) { // [ l ] == ( NS, N )
3592 29211416 : state.dataSolarShading->HCX[l] = nint64(state.dataSolarShading->XVS(N) * HCMULT);
3593 29211416 : state.dataSolarShading->HCY[l] = nint64(state.dataSolarShading->YVS(N) * HCMULT);
3594 : }
3595 :
3596 7320027 : l = state.dataSolarShading->HCX.index(NS, NumVertices + 1);
3597 7320027 : Int64 HCX_m(state.dataSolarShading->HCX[l] = state.dataSolarShading->HCX[l1]); // [ l1 ] == ( NS, 1 )
3598 7320027 : Int64 HCY_m(state.dataSolarShading->HCY[l] = state.dataSolarShading->HCY[l1]);
3599 :
3600 7320027 : l = l1;
3601 7320027 : auto m(l1 + 1u);
3602 : Int64 HCX_l;
3603 : Int64 HCY_l;
3604 7320027 : Real64 SUM(0.0);
3605 36531443 : for (int N = 1; N <= NumVertices; ++N, ++l, ++m) { // [ l ] == ( NS, N ), [ m ] == ( NS, N + 1 )
3606 29211416 : HCX_l = HCX_m;
3607 29211416 : HCY_l = HCY_m;
3608 29211416 : HCX_m = state.dataSolarShading->HCX[m];
3609 29211416 : HCY_m = state.dataSolarShading->HCY[m];
3610 29211416 : state.dataSolarShading->HCA[l] = HCY_l - HCY_m;
3611 29211416 : state.dataSolarShading->HCB[l] = HCX_m - HCX_l;
3612 29211416 : SUM += state.dataSolarShading->HCC[l] = (HCY_m * HCX_l) - (HCX_m * HCY_l);
3613 : }
3614 :
3615 7320027 : state.dataSolarShading->HCAREA(NS) = SUM * sqHCMULT_fac;
3616 7320027 : }
3617 :
3618 0 : void INCLOS(EnergyPlusData &state,
3619 : int const N1, // Figure number of figure 1
3620 : int const N1NumVert, // Number of vertices of figure 1
3621 : int const N2, // Figure number of figure 2
3622 : int const N2NumVert, // Number of vertices of figure 2
3623 : int &NumVerticesOverlap, // Number of vertices which overlap
3624 : int &NIN // Number of vertices of figure 1 within figure 2
3625 : )
3626 : {
3627 :
3628 : // SUBROUTINE INFORMATION:
3629 : // AUTHOR Legacy Code
3630 : // DATE WRITTEN
3631 : // MODIFIED na
3632 : // RE-ENGINEERED Lawrie, Oct 2000
3633 :
3634 : // PURPOSE OF THIS SUBROUTINE:
3635 : // This subroutine determines which vertices of figure N1 lie within figure N2.
3636 :
3637 : // METHODOLOGY EMPLOYED:
3638 : // For vertex N of figure N1 to lie within figure N2, it must be
3639 : // on or to the right of all sides of figure N2, assuming
3640 : // figure N2 is convex.
3641 :
3642 : // REFERENCES:
3643 : // BLAST/IBLAST code, original author George Walton
3644 :
3645 : int K; // Vertex number of the overlap
3646 : int M; // Side number of figure N2
3647 : int N; // Vertex number of figure N1
3648 : bool CycleMainLoop; // Sets when to cycle main loop
3649 : Real64 HFunct;
3650 :
3651 0 : NIN = 0;
3652 :
3653 0 : for (N = 1; N <= N1NumVert; ++N) {
3654 :
3655 0 : CycleMainLoop = false;
3656 :
3657 : // Eliminate cases where vertex N is to the left of side M.
3658 :
3659 0 : for (M = 1; M <= N2NumVert; ++M) {
3660 0 : HFunct = state.dataSolarShading->HCX(N1, N) * state.dataSolarShading->HCA(N2, M) +
3661 0 : state.dataSolarShading->HCY(N1, N) * state.dataSolarShading->HCB(N2, M) + state.dataSolarShading->HCC(N2, M);
3662 0 : if (HFunct > 0.0) {
3663 0 : CycleMainLoop = true; // Set to cycle to the next value of N
3664 0 : break; // M DO loop
3665 : }
3666 : }
3667 :
3668 0 : if (CycleMainLoop) continue;
3669 0 : ++NIN;
3670 :
3671 : // Check for duplication of previously determined points.
3672 :
3673 0 : if (NumVerticesOverlap != 0) {
3674 0 : for (K = 1; K <= NumVerticesOverlap; ++K) {
3675 0 : if ((state.dataSolarShading->XTEMP(K) == state.dataSolarShading->HCX(N1, N)) &&
3676 0 : (state.dataSolarShading->YTEMP(K) == state.dataSolarShading->HCY(N1, N))) {
3677 0 : CycleMainLoop = true; // Set to cycle to the next value of N
3678 0 : break; // K DO loop
3679 : }
3680 : }
3681 0 : if (CycleMainLoop) continue;
3682 : }
3683 :
3684 : // Record enclosed vertices in temporary arrays.
3685 :
3686 0 : ++NumVerticesOverlap;
3687 0 : state.dataSolarShading->XTEMP(NumVerticesOverlap) = state.dataSolarShading->HCX(N1, N);
3688 0 : state.dataSolarShading->YTEMP(NumVerticesOverlap) = state.dataSolarShading->HCY(N1, N);
3689 : }
3690 0 : }
3691 :
3692 0 : void INTCPT(EnergyPlusData &state,
3693 : int const NV1, // Number of vertices of figure NS1
3694 : int const NV2, // Number of vertices of figure NS2
3695 : int &NV3, // Number of vertices of figure NS3
3696 : int const NS1, // Number of the figure being overlapped
3697 : int const NS2 // Number of the figure doing overlapping
3698 : )
3699 : {
3700 :
3701 : // SUBROUTINE INFORMATION:
3702 : // AUTHOR Legacy Code
3703 : // DATE WRITTEN
3704 : // MODIFIED na
3705 : // RE-ENGINEERED Lawrie, Oct 2000
3706 :
3707 : // PURPOSE OF THIS SUBROUTINE:
3708 : // This subroutine determines all intercepts between the sides of figure NS1
3709 : // and the sides of figure NS2.
3710 :
3711 : // METHODOLOGY EMPLOYED:
3712 : // The requirements for intersection are that the end points of
3713 : // line N lie on both sides of line M and vice versa. Also
3714 : // eliminate cases where the end point of one line lies exactly
3715 : // on the other to reduce duplication with the enclosed points.
3716 :
3717 : // REFERENCES:
3718 : // BLAST/IBLAST code, original author George Walton
3719 :
3720 : Real64 W; // Normalization factor
3721 : Real64 XUntrunc; // Untruncated X coordinate
3722 : Real64 YUntrunc; // Untruncated Y coordinate
3723 : Int64 I1; // Intermediate result for testing intersection
3724 : Int64 I2; // Intermediate result for testing intersection
3725 : int K;
3726 : int KK;
3727 : int M; // Side number of figure NS2
3728 : int N; // Side number of figure NS1
3729 :
3730 0 : for (N = 1; N <= NV1; ++N) {
3731 0 : for (M = 1; M <= NV2; ++M) {
3732 :
3733 : // Eliminate cases where sides N and M do not intersect.
3734 :
3735 0 : I1 = state.dataSolarShading->HCA(NS1, N) * state.dataSolarShading->HCX(NS2, M) +
3736 0 : state.dataSolarShading->HCB(NS1, N) * state.dataSolarShading->HCY(NS2, M) + state.dataSolarShading->HCC(NS1, N);
3737 0 : I2 = state.dataSolarShading->HCA(NS1, N) * state.dataSolarShading->HCX(NS2, M + 1) +
3738 0 : state.dataSolarShading->HCB(NS1, N) * state.dataSolarShading->HCY(NS2, M + 1) + state.dataSolarShading->HCC(NS1, N);
3739 0 : if (I1 >= 0 && I2 >= 0) continue;
3740 0 : if (I1 <= 0 && I2 <= 0) continue;
3741 :
3742 0 : I1 = state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCX(NS1, N) +
3743 0 : state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCY(NS1, N) + state.dataSolarShading->HCC(NS2, M);
3744 0 : I2 = state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCX(NS1, N + 1) +
3745 0 : state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCY(NS1, N + 1) + state.dataSolarShading->HCC(NS2, M);
3746 0 : if (I1 >= 0 && I2 >= 0) continue;
3747 0 : if (I1 <= 0 && I2 <= 0) continue;
3748 :
3749 : // Determine the point of intersection and record in the temporary array.
3750 :
3751 0 : KK = NV3;
3752 0 : ++NV3;
3753 0 : W = state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCA(NS1, N) -
3754 0 : state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCB(NS1, N);
3755 0 : XUntrunc = (state.dataSolarShading->HCC(NS2, M) * state.dataSolarShading->HCB(NS1, N) -
3756 0 : state.dataSolarShading->HCB(NS2, M) * state.dataSolarShading->HCC(NS1, N)) /
3757 : W;
3758 0 : YUntrunc = (state.dataSolarShading->HCA(NS2, M) * state.dataSolarShading->HCC(NS1, N) -
3759 0 : state.dataSolarShading->HCC(NS2, M) * state.dataSolarShading->HCA(NS1, N)) /
3760 : W;
3761 0 : if (NV3 > isize(state.dataSolarShading->XTEMP)) {
3762 0 : state.dataSolarShading->XTEMP.redimension(isize(state.dataSolarShading->XTEMP) + 10, 0.0);
3763 0 : state.dataSolarShading->YTEMP.redimension(isize(state.dataSolarShading->YTEMP) + 10, 0.0);
3764 : }
3765 0 : state.dataSolarShading->XTEMP(NV3) = nint64(XUntrunc);
3766 0 : state.dataSolarShading->YTEMP(NV3) = nint64(YUntrunc);
3767 :
3768 : // Eliminate near-duplicate points.
3769 :
3770 0 : if (KK != 0) {
3771 0 : auto const x(state.dataSolarShading->XTEMP(NV3));
3772 0 : auto const y(state.dataSolarShading->YTEMP(NV3));
3773 0 : for (K = 1; K <= KK; ++K) {
3774 0 : if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
3775 0 : if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
3776 0 : NV3 = KK;
3777 0 : break; // K DO loop
3778 : }
3779 : }
3780 : }
3781 : }
3782 0 : }
3783 :
3784 0 : inline bool neq(Real64 a, Real64 b)
3785 : {
3786 0 : return std::abs(a - b) > 2.0;
3787 : }
3788 :
3789 0 : inline bool d_eq(Real64 a, Real64 b)
3790 : {
3791 0 : return std::abs(a - b) < 2.0;
3792 : }
3793 :
3794 0 : void CLIPLINE(Real64 &x1, Real64 &x2, Real64 &y1, Real64 &y2, Real64 maxX, Real64 minX, Real64 maxY, Real64 minY, bool &visible, bool &rev)
3795 : {
3796 : // Line segment clipping
3797 : // Reference:
3798 : // Slater, M., Barsky, B.A.
3799 : // 2D line and polygon clipping based on space subdivision.
3800 : // The Visual Computer 10, 407–422 (1994).
3801 : Real64 dx, dy, e, xinc, yinc, tempVar;
3802 0 : bool needX = true, needY = true;
3803 : int c1, c2;
3804 :
3805 0 : if (x1 > x2) { // reverse for efficiency
3806 0 : tempVar = x1;
3807 0 : x1 = x2;
3808 0 : x2 = tempVar;
3809 0 : tempVar = y1;
3810 0 : y1 = y2;
3811 0 : y2 = tempVar;
3812 0 : rev = true;
3813 : }
3814 0 : if (x1 > maxX || x2 < minX) return; // x is positive
3815 0 : if (x1 < minX) {
3816 0 : if (y1 < minY) {
3817 0 : if (y2 < minY) return;
3818 0 : c1 = 0;
3819 0 : dx = x2 - x1;
3820 0 : dy = y2 - y1;
3821 0 : e = dy * (minX - x1) + dx * (y1 - minY);
3822 0 : } else if (y1 > maxY) {
3823 0 : if (y2 > maxY) return;
3824 0 : c1 = 6;
3825 0 : dx = x2 - x1;
3826 0 : dy = y2 - y1;
3827 0 : e = dy * (minX - x1) + dx * (y1 - maxY);
3828 : } else {
3829 0 : c1 = 3;
3830 0 : dx = x2 - x1;
3831 0 : dy = y2 - y1;
3832 0 : if (dy > 0) {
3833 0 : e = dy * (minX - x1) + dx * (y1 - maxY);
3834 : } else {
3835 0 : e = dy * (minX - x1) + dx * (y1 - minY);
3836 : }
3837 : }
3838 : } else {
3839 0 : if (y1 < minY) {
3840 0 : if (y2 < minY) return;
3841 0 : c1 = 1;
3842 0 : dx = x2 - x1;
3843 0 : dy = y2 - y1;
3844 0 : e = dy * (maxX - x1) + dx * (y1 - minY);
3845 0 : } else if (y1 > maxY) {
3846 0 : if (y2 > maxY) return;
3847 0 : c1 = 7;
3848 0 : dx = x2 - x1;
3849 0 : dy = y2 - y1;
3850 0 : e = dy * (maxX - x1) + dx * (y1 - maxY);
3851 : } else {
3852 0 : visible = true;
3853 0 : if (x2 <= maxX && (y2 >= minY && y2 <= maxY)) return;
3854 0 : c1 = 4;
3855 0 : dx = x2 - x1;
3856 0 : dy = y2 - y1;
3857 0 : if (dy > 0) {
3858 0 : e = dy * (maxX - x1) + dx * (y1 - maxY);
3859 : } else {
3860 0 : e = dy * (maxX - x1) + dx * (y1 - minY);
3861 : }
3862 : }
3863 : }
3864 0 : c2 = c1;
3865 0 : if (dy > 0) {
3866 : while (true) {
3867 0 : if (e < 0.0) {
3868 0 : if (c2 == 1)
3869 0 : return;
3870 0 : else if (c2 == 3) {
3871 0 : visible = true;
3872 0 : x1 = minX;
3873 0 : y1 = maxY + e / dx;
3874 0 : if (x2 <= maxX && y2 <= maxY) return;
3875 0 : } else if (c2 == 4) {
3876 0 : x2 = maxX;
3877 0 : y2 = maxY + e / dx;
3878 0 : return;
3879 : }
3880 0 : if (needX) {
3881 0 : xinc = dy * (maxX - minX);
3882 0 : needX = false;
3883 : }
3884 0 : e += xinc;
3885 0 : c2 += 1;
3886 : } else {
3887 0 : if (c2 == 3)
3888 0 : return;
3889 0 : else if (c2 == 1) {
3890 0 : visible = true;
3891 0 : x1 = maxX - e / dy;
3892 0 : y1 = minY;
3893 0 : if (x2 <= maxX && y2 <= maxY) return;
3894 0 : } else if (c2 == 4) {
3895 0 : x2 = maxX - e / dy;
3896 0 : y2 = maxY;
3897 0 : return;
3898 : }
3899 0 : if (needY) {
3900 0 : yinc = dx * (maxY - minY);
3901 0 : needY = false;
3902 : }
3903 0 : e -= yinc;
3904 0 : c2 += 3;
3905 : }
3906 : }
3907 : } else {
3908 : while (true) {
3909 0 : if (e >= 0.0) {
3910 0 : if (c2 == 7)
3911 0 : return;
3912 0 : else if (c2 == 3) {
3913 0 : visible = true;
3914 0 : x1 = minX;
3915 0 : y1 = minY + e / dx;
3916 0 : if (x2 <= maxX && y2 >= minY) return;
3917 0 : } else if (c2 == 4) {
3918 0 : x2 = maxX;
3919 0 : y2 = minY + e / dx;
3920 0 : return;
3921 : }
3922 0 : if (needX) {
3923 0 : xinc = dy * (maxX - minX);
3924 0 : needX = false;
3925 : }
3926 0 : e += xinc;
3927 0 : c2 += 1;
3928 : } else {
3929 0 : if (c2 == 3)
3930 0 : return;
3931 0 : else if (c2 == 7) {
3932 0 : visible = true;
3933 0 : x1 = maxX - e / dy;
3934 0 : y1 = maxY;
3935 0 : if (x2 <= maxX && y2 >= minY) return;
3936 0 : } else if (c2 == 4) {
3937 0 : x2 = maxX - e / dy;
3938 0 : y2 = minY;
3939 0 : return;
3940 : }
3941 0 : if (needY) {
3942 0 : yinc = dx * (maxY - minY);
3943 0 : needY = false;
3944 : }
3945 0 : e += yinc;
3946 0 : c2 -= 3;
3947 : }
3948 : }
3949 : }
3950 : }
3951 :
3952 0 : void CLIPRECT(EnergyPlusData &state, int const NS2, int const NV1, int &NV3)
3953 : {
3954 : // Polygon clipping by line segment clipping for rectangles
3955 : // Reference:
3956 : // Slater, M., Barsky, B.A.
3957 : // 2D line and polygon clipping based on space subdivision.
3958 : // The Visual Computer 10, 407–422 (1994).
3959 0 : bool INTFLAG = false;
3960 0 : auto l(state.dataSolarShading->HCA.index(NS2, 1));
3961 : Real64 maxX, minX, maxY, minY;
3962 0 : if (state.dataSolarShading->HCX[l] > state.dataSolarShading->HCX[l + 2]) {
3963 0 : maxX = state.dataSolarShading->HCX[l];
3964 0 : minX = state.dataSolarShading->HCX[l + 2];
3965 : } else {
3966 0 : maxX = state.dataSolarShading->HCX[l + 2];
3967 0 : minX = state.dataSolarShading->HCX[l];
3968 : }
3969 0 : if (state.dataSolarShading->HCY[l] > state.dataSolarShading->HCY[l + 2]) {
3970 0 : maxY = state.dataSolarShading->HCY[l];
3971 0 : minY = state.dataSolarShading->HCY[l + 2];
3972 : } else {
3973 0 : maxY = state.dataSolarShading->HCY[l + 2];
3974 0 : minY = state.dataSolarShading->HCY[l];
3975 : }
3976 :
3977 : Real64 arrx[20]; // Temp array for output X
3978 : Real64 arry[20]; // Temp array for output Y
3979 0 : int arrc = 0; // Number of items in output
3980 :
3981 0 : for (int j = 0; j < NV1; ++j) {
3982 0 : Real64 x_1 = state.dataSolarShading->XTEMP[j];
3983 0 : Real64 y_1 = state.dataSolarShading->YTEMP[j];
3984 0 : Real64 x_2 = state.dataSolarShading->XTEMP[(j + 1) % NV1];
3985 0 : Real64 y_2 = state.dataSolarShading->YTEMP[(j + 1) % NV1];
3986 0 : Real64 x1 = x_1, x2 = x_2, y1 = y_1, y2 = y_2;
3987 :
3988 0 : bool visible = false;
3989 0 : bool rev = false;
3990 0 : CLIPLINE(x_1, x_2, y_1, y_2, maxX, minX, maxY, minY, visible, rev);
3991 0 : if (visible) {
3992 0 : if ((x_1 != x1 || y_1 != y1) || (x_2 != x2 || y_2 != y2)) {
3993 0 : INTFLAG = true;
3994 : }
3995 0 : if (rev) { // undo reverse
3996 0 : auto tempVar = x_1;
3997 0 : x_1 = x_2;
3998 0 : x_2 = tempVar;
3999 0 : tempVar = y_1;
4000 0 : y_1 = y_2;
4001 0 : y_2 = tempVar;
4002 : }
4003 : // if line on edge, or inside, add both points
4004 0 : if (arrc == 0 || ((neq(arrx[arrc - 1], x_1) || neq(arry[arrc - 1], y_1)) && (neq(arrx[0], x_1) || neq(arry[0], y_1)))) {
4005 0 : arrx[arrc] = x_1;
4006 0 : arry[arrc] = y_1;
4007 0 : arrc += 1;
4008 0 : if ((neq(x_1, x_2) || neq(y_1, y_2)) && (neq(arrx[0], x_2) || neq(arry[0], y_2))) {
4009 0 : arrx[arrc] = x_2;
4010 0 : arry[arrc] = y_2;
4011 0 : arrc += 1;
4012 : }
4013 0 : } else if ((neq(arrx[arrc - 1], x_2) || neq(arry[arrc - 1], y_2)) && (neq(arrx[0], x_2) || neq(arry[0], y_2))) {
4014 0 : arrx[arrc] = x_2;
4015 0 : arry[arrc] = y_2;
4016 0 : arrc += 1;
4017 : }
4018 : }
4019 : }
4020 0 : NV3 = arrc;
4021 :
4022 : // Re-populate XTEMP/YTEMP
4023 0 : if (NV3 > 1) {
4024 0 : int LastEdgeIndex = -1, incr = 0;
4025 0 : double cornerXs[4] = {minX, minX, maxX, maxX};
4026 0 : double cornerYs[4] = {minY, maxY, maxY, minY};
4027 0 : Real64 edges[4] = {minX, maxY, maxX, minY};
4028 : Real64 LastEdgeX, LastEdgeY;
4029 0 : for (int i = 0; i <= arrc; i++) {
4030 0 : int k = i % arrc;
4031 :
4032 0 : Real64 currX = arrx[k], currY = arry[k];
4033 :
4034 0 : int edgeCount = 0, EdgeIndex = -1;
4035 0 : for (int m = 0; m < 4; m++) {
4036 0 : if (m % 2 == 0 && d_eq(currX, edges[m])) { // MinX or MaxX
4037 0 : edgeCount++;
4038 0 : EdgeIndex = m;
4039 0 : } else if (m % 2 == 1 && d_eq(currY, edges[m])) {
4040 0 : edgeCount++;
4041 0 : EdgeIndex = m;
4042 : }
4043 : }
4044 0 : if (edgeCount == 0) { // On inside
4045 0 : if (i != arrc) {
4046 0 : state.dataSolarShading->XTEMP[incr] = currX;
4047 0 : state.dataSolarShading->YTEMP[incr] = currY;
4048 0 : incr++;
4049 : }
4050 0 : continue;
4051 0 : } else if (edgeCount > 1) { // On corner
4052 0 : if (d_eq(currX, minX)) {
4053 0 : if (d_eq(currY, minY)) {
4054 0 : EdgeIndex = 3;
4055 : } else {
4056 0 : EdgeIndex = 0;
4057 : }
4058 : } else {
4059 0 : if (d_eq(currY, maxY)) {
4060 0 : EdgeIndex = 1;
4061 : } else {
4062 0 : EdgeIndex = 2;
4063 : }
4064 : }
4065 : }
4066 0 : if ((LastEdgeIndex > -1 && EdgeIndex > -1) && LastEdgeIndex != EdgeIndex) {
4067 0 : int jumpCount = 0;
4068 0 : if ((EdgeIndex == 0 && LastEdgeIndex == 3) || (EdgeIndex - LastEdgeIndex == 1)) {
4069 0 : jumpCount = 1;
4070 0 : } else if (EdgeIndex % 2 == LastEdgeIndex % 2) {
4071 : // Clockwise double jump
4072 0 : jumpCount = 2;
4073 0 : } else if ((EdgeIndex == 3 && LastEdgeIndex == 0) || (LastEdgeIndex - EdgeIndex == 1)) {
4074 : // Clockwise triple jump
4075 0 : jumpCount = 3;
4076 : }
4077 0 : if (jumpCount > 0) {
4078 : Real64 cornerX;
4079 : Real64 cornerY;
4080 0 : int startIndex = (LastEdgeIndex + 1) % 4;
4081 0 : int added = 0;
4082 0 : for (int i1 = startIndex, j1 = 0; j1 < jumpCount; i1 = (i1 + 1) % 4, j1++) {
4083 0 : cornerX = cornerXs[i1];
4084 0 : cornerY = cornerYs[i1];
4085 0 : if (cornerX == LastEdgeX && cornerY == LastEdgeY) continue; // skip if jump started on corner
4086 :
4087 0 : bool insideFlag = true;
4088 0 : for (int j = 0; j < NV1; ++j) {
4089 0 : if ((state.dataSolarShading->ATEMP[j] * cornerX) + (cornerY * state.dataSolarShading->BTEMP[j]) +
4090 0 : state.dataSolarShading->CTEMP[j] >
4091 : 0.0) {
4092 0 : insideFlag = false;
4093 0 : break;
4094 : }
4095 : }
4096 :
4097 0 : if (insideFlag &&
4098 0 : (incr == 0 ||
4099 0 : ((neq(cornerX, state.dataSolarShading->XTEMP[incr - 1]) || neq(cornerY, state.dataSolarShading->YTEMP[incr - 1])) &&
4100 0 : (neq(cornerX, state.dataSolarShading->XTEMP[0]) || neq(cornerY, state.dataSolarShading->YTEMP[0]))))) {
4101 0 : state.dataSolarShading->XTEMP[incr] = cornerX;
4102 0 : state.dataSolarShading->YTEMP[incr] = cornerY;
4103 0 : incr++;
4104 0 : added++;
4105 : }
4106 : }
4107 0 : if (jumpCount > 2 && (added == jumpCount && edgeCount == 1)) {
4108 0 : if (i != arrc) {
4109 0 : state.dataSolarShading->XTEMP[incr] = currX;
4110 0 : state.dataSolarShading->YTEMP[incr] = currY;
4111 0 : incr++;
4112 : }
4113 0 : break;
4114 : }
4115 : }
4116 : }
4117 0 : if (i != arrc) {
4118 0 : state.dataSolarShading->XTEMP[incr] = currX;
4119 0 : state.dataSolarShading->YTEMP[incr] = currY;
4120 0 : incr++;
4121 : }
4122 0 : LastEdgeIndex = EdgeIndex;
4123 0 : LastEdgeX = currX;
4124 0 : LastEdgeY = currY;
4125 : }
4126 0 : NV3 = incr;
4127 :
4128 : } else {
4129 0 : if (NV3 == 1) {
4130 0 : state.dataSolarShading->XTEMP[0] = arrx[0];
4131 0 : state.dataSolarShading->YTEMP[0] = arry[0];
4132 : }
4133 0 : if (NV3 == 0) {
4134 0 : double cornerXs[4] = {minX, minX, maxX, maxX};
4135 0 : double cornerYs[4] = {minY, maxY, maxY, minY};
4136 0 : Real64 cornerX = cornerXs[0];
4137 0 : Real64 cornerY = cornerYs[0];
4138 0 : bool insideFlag = true;
4139 0 : for (int j = 0; j < NV1; ++j) {
4140 0 : if ((state.dataSolarShading->ATEMP[j] * cornerX) + (cornerY * state.dataSolarShading->BTEMP[j]) + state.dataSolarShading->CTEMP[j] >=
4141 : 0.0) {
4142 0 : insideFlag = false;
4143 0 : break;
4144 : }
4145 : }
4146 0 : if (insideFlag) {
4147 0 : for (int i1 = 0; i1 < 4; i1++) {
4148 0 : state.dataSolarShading->XTEMP[i1] = cornerXs[i1];
4149 0 : state.dataSolarShading->YTEMP[i1] = cornerYs[i1];
4150 : }
4151 0 : NV3 = 4;
4152 0 : INTFLAG = true;
4153 : }
4154 : }
4155 : }
4156 :
4157 : // update homogenous edges A,B,C
4158 0 : if (NV3 > 0) {
4159 0 : Real64 const X_0(state.dataSolarShading->XTEMP[0]);
4160 0 : Real64 const Y_0(state.dataSolarShading->YTEMP[0]);
4161 0 : Real64 XP_0 = X_0, XP_1;
4162 0 : Real64 YP_0 = Y_0, YP_1;
4163 0 : for (int P = 0; P < NV3 - 1; ++P) {
4164 0 : XP_1 = state.dataSolarShading->XTEMP[P + 1];
4165 0 : YP_1 = state.dataSolarShading->YTEMP[P + 1];
4166 :
4167 0 : state.dataSolarShading->ATEMP[P] = YP_0 - YP_1;
4168 0 : state.dataSolarShading->BTEMP[P] = XP_1 - XP_0;
4169 0 : state.dataSolarShading->CTEMP[P] = XP_0 * YP_1 - YP_0 * XP_1;
4170 0 : XP_0 = XP_1;
4171 0 : YP_0 = YP_1;
4172 : }
4173 :
4174 0 : state.dataSolarShading->ATEMP[NV3 - 1] = YP_1 - Y_0;
4175 0 : state.dataSolarShading->BTEMP[NV3 - 1] = X_0 - XP_1;
4176 0 : state.dataSolarShading->CTEMP[NV3 - 1] = XP_1 * Y_0 - YP_1 * X_0;
4177 : }
4178 :
4179 : // Determine overlap status
4180 0 : if (NV3 < 3) { // Determine overlap status
4181 0 : state.dataSolarShading->OverlapStatus = NoOverlap;
4182 0 : } else if (!INTFLAG) {
4183 0 : state.dataSolarShading->OverlapStatus = FirstSurfWithinSecond;
4184 : }
4185 0 : }
4186 :
4187 7838123 : void CLIPPOLY(EnergyPlusData &state,
4188 : int const NS1, // Figure number of figure 1 (The subject polygon)
4189 : int const NS2, // Figure number of figure 2 (The clipping polygon)
4190 : int const NV1, // Number of vertices of figure 1
4191 : int const NV2, // Number of vertices of figure 2
4192 : int &NV3 // Number of vertices of figure 3
4193 : )
4194 : {
4195 :
4196 : // SUBROUTINE INFORMATION:
4197 : // AUTHOR Tyler Hoyt
4198 : // DATE WRITTEN May 4, 2010
4199 : // MODIFIED na
4200 : // RE-ENGINEERED na
4201 :
4202 : // PURPOSE OF THIS SUBROUTINE:
4203 : // Populate global arrays XTEMP and YTEMP with the vertices
4204 : // of the overlap between NS1 and NS2, and determine relevant
4205 : // overlap status.
4206 :
4207 : // METHODOLOGY EMPLOYED:
4208 : // The Sutherland-Hodgman algorithm for polygon clipping is employed.
4209 :
4210 : using General::ReallocateRealArray;
4211 : using General::SafeDivide;
4212 :
4213 : typedef Array2D<Int64>::size_type size_type;
4214 : bool INTFLAG; // For overlap status
4215 : int S; // Test vertex
4216 : int KK; // Duplicate test index
4217 : int NVOUT; // Current output length for loops
4218 : int NVTEMP;
4219 :
4220 : Real64 W; // Normalization factor
4221 : Real64 HFunct;
4222 :
4223 : #ifdef EP_Count_Calls
4224 : ++state.dataTimingsData->NumClipPoly_Calls;
4225 : #endif
4226 : // Tuned Linear indexing
4227 :
4228 7838123 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
4229 7838123 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
4230 7838123 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
4231 7838123 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
4232 :
4233 : // Populate the arrays with the original polygon
4234 39079868 : for (size_type j = 0, l = state.dataSolarShading->HCX.index(NS1, 1), e = NV1; j < e; ++j, ++l) {
4235 31241745 : state.dataSolarShading->XTEMP[j] = state.dataSolarShading->HCX[l]; // [ l ] == ( NS1, j+1 )
4236 31241745 : state.dataSolarShading->YTEMP[j] = state.dataSolarShading->HCY[l];
4237 31241745 : state.dataSolarShading->ATEMP[j] = state.dataSolarShading->HCA[l];
4238 31241745 : state.dataSolarShading->BTEMP[j] = state.dataSolarShading->HCB[l];
4239 31241745 : state.dataSolarShading->CTEMP[j] = state.dataSolarShading->HCC[l];
4240 : }
4241 :
4242 7838123 : NVOUT = NV1; // First point-loop is the length of the subject polygon.
4243 7838123 : INTFLAG = false;
4244 7838123 : NVTEMP = 0;
4245 7838123 : KK = 0;
4246 :
4247 : // Check if clipping polygon is rectangle
4248 7838123 : if (state.dataSysVars->SlaterBarsky) {
4249 0 : auto l1(state.dataSolarShading->HCA.index(NS2, 1));
4250 0 : bool rectFlag = ((NV2 == 4) && (((((state.dataSolarShading->HCX[l1] == state.dataSolarShading->HCX[l1 + 1] &&
4251 0 : state.dataSolarShading->HCY[l1] != state.dataSolarShading->HCY[l1 + 1]) &&
4252 0 : ((state.dataSolarShading->HCY[l1 + 2] == state.dataSolarShading->HCY[l1 + 1] &&
4253 0 : state.dataSolarShading->HCY[l1 + 3] == state.dataSolarShading->HCY[l1]))) &&
4254 0 : state.dataSolarShading->HCX[l1 + 2] == state.dataSolarShading->HCX[l1 + 3]) ||
4255 0 : ((((state.dataSolarShading->HCY[l1] == state.dataSolarShading->HCY[l1 + 1] &&
4256 0 : state.dataSolarShading->HCX[l1] != state.dataSolarShading->HCX[l1 + 1]) &&
4257 0 : (state.dataSolarShading->HCX[l1 + 2] == state.dataSolarShading->HCX[l1 + 1] &&
4258 0 : state.dataSolarShading->HCX[l1 + 3] == state.dataSolarShading->HCX[l1])) &&
4259 0 : (state.dataSolarShading->HCY[l1 + 2] == state.dataSolarShading->HCY[l1 + 3]))))));
4260 0 : if (rectFlag) {
4261 0 : CLIPRECT(state, NS2, NV1, NV3);
4262 0 : return;
4263 : }
4264 : }
4265 :
4266 7838123 : auto l(state.dataSolarShading->HCA.index(NS2, 1));
4267 25528079 : for (int E = 1; E <= NV2; ++E, ++l) { // Loop over edges of the clipping polygon
4268 112363752 : for (int P = 1; P <= NVOUT; ++P) {
4269 90069811 : state.dataSolarShading->XTEMP1(P) = state.dataSolarShading->XTEMP(P);
4270 90069811 : state.dataSolarShading->YTEMP1(P) = state.dataSolarShading->YTEMP(P);
4271 : }
4272 22293941 : S = NVOUT;
4273 22293941 : Real64 const HCA_E(state.dataSolarShading->HCA[l]);
4274 22293941 : Real64 const HCB_E(state.dataSolarShading->HCB[l]);
4275 22293941 : Real64 const HCC_E(state.dataSolarShading->HCC[l]);
4276 22293941 : Real64 XTEMP1_S(state.dataSolarShading->XTEMP1(S));
4277 22293941 : Real64 YTEMP1_S(state.dataSolarShading->YTEMP1(S));
4278 112363752 : for (int P = 1; P <= NVOUT; ++P) {
4279 90069811 : Real64 const XTEMP1_P(state.dataSolarShading->XTEMP1(P));
4280 90069811 : Real64 const YTEMP1_P(state.dataSolarShading->YTEMP1(P));
4281 90069811 : HFunct = XTEMP1_P * HCA_E + YTEMP1_P * HCB_E + HCC_E;
4282 : // S is constant within this block
4283 90069811 : if (HFunct <= 0.0) { // Vertex is not in the clipping plane
4284 59752010 : HFunct = XTEMP1_S * HCA_E + YTEMP1_S * HCB_E + HCC_E;
4285 59752010 : if (HFunct > 0.0) { // Test vertex is in the clipping plane
4286 :
4287 : // Find/store the intersection of the clip edge and the line connecting S and P
4288 6344248 : KK = NVTEMP;
4289 6344248 : ++NVTEMP;
4290 6344248 : Real64 const ATEMP_S(state.dataSolarShading->ATEMP(S));
4291 6344248 : Real64 const BTEMP_S(state.dataSolarShading->BTEMP(S));
4292 6344248 : Real64 const CTEMP_S(state.dataSolarShading->CTEMP(S));
4293 6344248 : W = HCB_E * ATEMP_S - HCA_E * BTEMP_S;
4294 6344248 : if (W != 0.0) {
4295 6344248 : Real64 const W_inv(1.0 / W);
4296 6344248 : state.dataSolarShading->XTEMP(NVTEMP) = nint64((HCC_E * BTEMP_S - HCB_E * CTEMP_S) * W_inv);
4297 6344248 : state.dataSolarShading->YTEMP(NVTEMP) = nint64((HCA_E * CTEMP_S - HCC_E * ATEMP_S) * W_inv);
4298 : } else {
4299 0 : state.dataSolarShading->XTEMP(NVTEMP) = SafeDivide(HCC_E * BTEMP_S - HCB_E * CTEMP_S, W);
4300 0 : state.dataSolarShading->YTEMP(NVTEMP) = SafeDivide(HCA_E * CTEMP_S - HCC_E * ATEMP_S, W);
4301 : }
4302 6344248 : INTFLAG = true;
4303 :
4304 6344248 : if (E == NV2) { // Remove near-duplicates on last edge
4305 1278121 : if (KK != 0) {
4306 494754 : auto const x(state.dataSolarShading->XTEMP(NVTEMP));
4307 494754 : auto const y(state.dataSolarShading->YTEMP(NVTEMP));
4308 1219887 : for (int K = 1; K <= KK; ++K) {
4309 728003 : if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
4310 38011 : if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
4311 2870 : NVTEMP = KK;
4312 2870 : break; // K loop
4313 : }
4314 : }
4315 : }
4316 : }
4317 :
4318 59752010 : KK = NVTEMP;
4319 59752010 : ++NVTEMP;
4320 59752010 : if (NVTEMP > state.dataSolarShading->MAXHCArrayBounds) {
4321 0 : int const NewArrayBounds(state.dataSolarShading->MAXHCArrayBounds + state.dataSolarShading->MAXHCArrayIncrement);
4322 0 : state.dataSolarShading->XTEMP.redimension(NewArrayBounds, 0.0);
4323 0 : state.dataSolarShading->YTEMP.redimension(NewArrayBounds, 0.0);
4324 0 : state.dataSolarShading->XTEMP1.redimension(NewArrayBounds, 0.0);
4325 0 : state.dataSolarShading->YTEMP1.redimension(NewArrayBounds, 0.0);
4326 0 : state.dataSolarShading->ATEMP.redimension(NewArrayBounds, 0.0);
4327 0 : state.dataSolarShading->BTEMP.redimension(NewArrayBounds, 0.0);
4328 0 : state.dataSolarShading->CTEMP.redimension(NewArrayBounds, 0.0);
4329 0 : state.dataSolarShading->MAXHCArrayBounds = NewArrayBounds;
4330 : }
4331 :
4332 59752010 : state.dataSolarShading->XTEMP(NVTEMP) = XTEMP1_P;
4333 59752010 : state.dataSolarShading->YTEMP(NVTEMP) = YTEMP1_P;
4334 :
4335 59752010 : if (E == NV2) { // Remove near-duplicates on last edge
4336 11056198 : if (KK != 0) {
4337 8899818 : auto const x(state.dataSolarShading->XTEMP(NVTEMP));
4338 8899818 : auto const y(state.dataSolarShading->YTEMP(NVTEMP));
4339 25363640 : for (int K = 1; K <= KK; ++K) {
4340 17768646 : if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
4341 5211454 : if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
4342 1304824 : NVTEMP = KK;
4343 1304824 : break; // K loop
4344 : }
4345 : }
4346 : }
4347 :
4348 : } else {
4349 30317801 : HFunct = XTEMP1_S * HCA_E + YTEMP1_S * HCB_E + HCC_E;
4350 30317801 : if (HFunct <= 0.0) { // Test vertex is not in the clipping plane
4351 6344248 : if (NVTEMP < 2 * (state.dataSurface->MaxVerticesPerSurface + 1)) { // avoid assigning to element outside of XTEMP array size
4352 6344248 : KK = NVTEMP;
4353 6344248 : ++NVTEMP;
4354 6344248 : Real64 const ATEMP_S(state.dataSolarShading->ATEMP(S));
4355 6344248 : Real64 const BTEMP_S(state.dataSolarShading->BTEMP(S));
4356 6344248 : Real64 const CTEMP_S(state.dataSolarShading->CTEMP(S));
4357 6344248 : W = HCB_E * ATEMP_S - HCA_E * BTEMP_S;
4358 6344248 : if (W != 0.0) {
4359 6344248 : Real64 const W_inv(1.0 / W);
4360 6344248 : state.dataSolarShading->XTEMP(NVTEMP) = nint64((HCC_E * BTEMP_S - HCB_E * CTEMP_S) * W_inv);
4361 6344248 : state.dataSolarShading->YTEMP(NVTEMP) = nint64((HCA_E * CTEMP_S - HCC_E * ATEMP_S) * W_inv);
4362 : } else {
4363 0 : state.dataSolarShading->XTEMP(NVTEMP) = SafeDivide(HCC_E * BTEMP_S - HCB_E * CTEMP_S, W);
4364 0 : state.dataSolarShading->YTEMP(NVTEMP) = SafeDivide(HCA_E * CTEMP_S - HCC_E * ATEMP_S, W);
4365 : }
4366 6344248 : INTFLAG = true;
4367 :
4368 6344248 : if (E == NV2) { // Remove near-duplicates on last edge
4369 1278121 : if (KK != 0) {
4370 983730 : auto const x(state.dataSolarShading->XTEMP(NVTEMP));
4371 983730 : auto const y(state.dataSolarShading->YTEMP(NVTEMP));
4372 3417417 : for (int K = 1; K <= KK; ++K) {
4373 2522781 : if (std::abs(x - state.dataSolarShading->XTEMP(K)) > 2.0) continue;
4374 467729 : if (std::abs(y - state.dataSolarShading->YTEMP(K)) > 2.0) continue;
4375 89094 : NVTEMP = KK;
4376 89094 : break; // K loop
4377 : }
4378 : }
4379 : }
4380 : }
4381 : }
4382 : }
4383 90069811 : S = P;
4384 90069811 : XTEMP1_S = XTEMP1_P;
4385 90069811 : YTEMP1_S = YTEMP1_P;
4386 : } // end loop over points of subject polygon
4387 :
4388 22293941 : NVOUT = NVTEMP;
4389 22293941 : if (NVOUT == 0) break; // Added to avoid array bounds violation of XTEMP1 and YTEMP1 and wasted looping
4390 17689956 : NVTEMP = 0;
4391 :
4392 17689956 : if (E != NV2) {
4393 14455818 : if (NVOUT > 2) { // Compute HC values for edges of output polygon
4394 14455818 : Real64 const X_1(state.dataSolarShading->XTEMP(1));
4395 14455818 : Real64 const Y_1(state.dataSolarShading->YTEMP(1));
4396 14455818 : Real64 X_P(X_1), X_P1;
4397 14455818 : Real64 Y_P(Y_1), Y_P1;
4398 58828066 : for (int P = 1; P < NVOUT; ++P) {
4399 44372248 : X_P1 = state.dataSolarShading->XTEMP(P + 1);
4400 44372248 : Y_P1 = state.dataSolarShading->YTEMP(P + 1);
4401 44372248 : state.dataSolarShading->ATEMP(P) = Y_P - Y_P1;
4402 44372248 : state.dataSolarShading->BTEMP(P) = X_P1 - X_P;
4403 44372248 : state.dataSolarShading->CTEMP(P) = X_P * Y_P1 - Y_P * X_P1;
4404 44372248 : X_P = X_P1;
4405 44372248 : Y_P = Y_P1;
4406 : }
4407 14455818 : state.dataSolarShading->ATEMP(NVOUT) = Y_P1 - Y_1;
4408 14455818 : state.dataSolarShading->BTEMP(NVOUT) = X_1 - X_P1;
4409 14455818 : state.dataSolarShading->CTEMP(NVOUT) = X_P1 * Y_1 - Y_P1 * X_1;
4410 : }
4411 : }
4412 :
4413 : } // end loop over edges in NS2
4414 :
4415 7838123 : NV3 = NVOUT;
4416 :
4417 7838123 : if (NV3 < 3) { // Determine overlap status
4418 4785307 : state.dataSolarShading->OverlapStatus = NoOverlap;
4419 3052816 : } else if (!INTFLAG) {
4420 329008 : state.dataSolarShading->OverlapStatus = FirstSurfWithinSecond;
4421 : }
4422 : }
4423 :
4424 2168612 : void MULTOL(EnergyPlusData &state,
4425 : int const NNN, // argument
4426 : int const LOC0, // Location in the homogeneous coordinate array
4427 : int const NRFIGS // Number of figures overlapped
4428 : )
4429 : {
4430 :
4431 : // SUBROUTINE INFORMATION:
4432 : // AUTHOR Legacy Code
4433 : // DATE WRITTEN
4434 : // MODIFIED na
4435 : // RE-ENGINEERED Lawrie, Oct 2000
4436 :
4437 : // PURPOSE OF THIS SUBROUTINE:
4438 : // This subroutine determines the overlaps of figure 'NS2' with previous figures
4439 : // 'LOC0+1' through 'LOC0+NRFIGS'. For example, if NS2
4440 : // is a shadow, overlap with previous shadows.
4441 :
4442 : // REFERENCES:
4443 : // BLAST/IBLAST code, original author George Walton
4444 :
4445 : int I; // Loop Control
4446 : int NS1; // Number of the figure being overlapped
4447 : int NS2; // Number of the figure doing overlapping
4448 : int NS3; // Location to place results of overlap
4449 :
4450 2168612 : state.dataSolarShading->maxNumberOfFigures = max(state.dataSolarShading->maxNumberOfFigures, NRFIGS);
4451 :
4452 2168612 : NS2 = NNN;
4453 5343293 : for (I = 1; I <= NRFIGS; ++I) {
4454 3174681 : NS1 = LOC0 + I;
4455 3174681 : NS3 = state.dataSolarShading->LOCHCA + 1;
4456 :
4457 3174681 : DeterminePolygonOverlap(state, NS1, NS2, NS3); // Find overlap of figure NS2 on figure NS1.
4458 :
4459 : // Process overlap cases:
4460 :
4461 3174681 : if (state.dataSolarShading->OverlapStatus == NoOverlap) continue;
4462 :
4463 1507952 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures)) break;
4464 :
4465 1507952 : state.dataSolarShading->LOCHCA = NS3; // Increment h.c. arrays pointer.
4466 : }
4467 2168612 : }
4468 :
4469 0 : void ORDER(EnergyPlusData &state,
4470 : int const NV3, // Number of vertices of figure NS3
4471 : int const NS3 // Location to place results of overlap
4472 : )
4473 : {
4474 :
4475 : // SUBROUTINE INFORMATION:
4476 : // AUTHOR Legacy Code
4477 : // DATE WRITTEN
4478 : // MODIFIED na
4479 : // RE-ENGINEERED Lawrie, Oct 2000
4480 :
4481 : // PURPOSE OF THIS SUBROUTINE:
4482 : // This subroutine sorts the vertices found by inclosure and
4483 : // intercept in to clockwise order so that the overlap polygon
4484 : // may be used in computing subsequent overlaps.
4485 :
4486 : // METHODOLOGY EMPLOYED:
4487 : // The slopes of the lines from the left-most vertex to all
4488 : // others are found. The slopes are sorted into descending
4489 : // sequence. This sequence puts the vertices in clockwise order.
4490 :
4491 : // REFERENCES:
4492 : // BLAST/IBLAST code, original author George Walton
4493 :
4494 : Real64 DELTAX; // Difference between X coordinates of two vertices
4495 : Real64 DELTAY; // Difference between Y coordinates of two vertices
4496 : Real64 SAVES; // Temporary location for exchange of variables
4497 : Real64 SAVEX; // Temporary location for exchange of variables
4498 : Real64 SAVEY; // Temporary location for exchange of variables
4499 : Real64 XMIN; // X coordinate of left-most vertex
4500 : Real64 YXMIN;
4501 : int I; // Sort index
4502 : int IM1; // Sort control
4503 : int J; // Sort index
4504 : int M; // Number of slopes to be sorted
4505 : int N; // Vertex number
4506 : int P; // Location of first slope to be sorted
4507 :
4508 0 : if (state.dataSolarShading->ORDERFirstTimeFlag) {
4509 0 : state.dataSolarShading->SLOPE.allocate(max(10, state.dataSurface->MaxVerticesPerSurface + 1));
4510 0 : state.dataSolarShading->ORDERFirstTimeFlag = false;
4511 : }
4512 : // Determine left-most vertex.
4513 :
4514 0 : XMIN = state.dataSolarShading->XTEMP(1);
4515 0 : YXMIN = state.dataSolarShading->YTEMP(1);
4516 0 : for (N = 2; N <= NV3; ++N) {
4517 0 : if (state.dataSolarShading->XTEMP(N) >= XMIN) continue;
4518 0 : XMIN = state.dataSolarShading->XTEMP(N);
4519 0 : YXMIN = state.dataSolarShading->YTEMP(N);
4520 : }
4521 :
4522 : // Determine slopes from left-most vertex to all others. Identify
4523 : // first and second or last points as they occur.
4524 :
4525 0 : P = 1;
4526 0 : M = 0;
4527 0 : for (N = 1; N <= NV3; ++N) {
4528 :
4529 0 : DELTAX = state.dataSolarShading->XTEMP(N) - XMIN;
4530 0 : DELTAY = state.dataSolarShading->YTEMP(N) - YXMIN;
4531 :
4532 0 : if (std::abs(DELTAX) > 0.5) {
4533 :
4534 0 : ++M;
4535 0 : state.dataSolarShading->SLOPE(M) = DELTAY / DELTAX;
4536 0 : state.dataSolarShading->XTEMP(M) = state.dataSolarShading->XTEMP(N);
4537 0 : state.dataSolarShading->YTEMP(M) = state.dataSolarShading->YTEMP(N);
4538 :
4539 0 : } else if (DELTAY > 0.5) {
4540 :
4541 0 : P = 2;
4542 0 : state.dataSolarShading->HCX(NS3, 2) = nint64(state.dataSolarShading->XTEMP(N));
4543 0 : state.dataSolarShading->HCY(NS3, 2) = nint64(state.dataSolarShading->YTEMP(N));
4544 :
4545 0 : } else if (DELTAY < -0.5) {
4546 :
4547 0 : state.dataSolarShading->HCX(NS3, NV3) = nint64(state.dataSolarShading->XTEMP(N));
4548 0 : state.dataSolarShading->HCY(NS3, NV3) = nint64(state.dataSolarShading->YTEMP(N));
4549 :
4550 : } else {
4551 :
4552 0 : state.dataSolarShading->HCX(NS3, 1) = nint64(XMIN);
4553 0 : state.dataSolarShading->HCY(NS3, 1) = nint64(YXMIN);
4554 : }
4555 : }
4556 :
4557 : // Sequence the temporary arrays in order of decreasing slopes.(bubble sort)
4558 :
4559 0 : if (M != 1) {
4560 :
4561 0 : for (I = 2; I <= M; ++I) {
4562 0 : IM1 = I - 1;
4563 0 : for (J = 1; J <= IM1; ++J) {
4564 0 : if (state.dataSolarShading->SLOPE(I) <= state.dataSolarShading->SLOPE(J)) continue;
4565 0 : SAVEX = state.dataSolarShading->XTEMP(I);
4566 0 : SAVEY = state.dataSolarShading->YTEMP(I);
4567 0 : SAVES = state.dataSolarShading->SLOPE(I);
4568 0 : state.dataSolarShading->XTEMP(I) = state.dataSolarShading->XTEMP(J);
4569 0 : state.dataSolarShading->YTEMP(I) = state.dataSolarShading->YTEMP(J);
4570 0 : state.dataSolarShading->SLOPE(I) = state.dataSolarShading->SLOPE(J);
4571 0 : state.dataSolarShading->XTEMP(J) = SAVEX;
4572 0 : state.dataSolarShading->YTEMP(J) = SAVEY;
4573 0 : state.dataSolarShading->SLOPE(J) = SAVES;
4574 : }
4575 : }
4576 : }
4577 :
4578 : // Place sequenced points in the homogeneous coordinate arrays.
4579 :
4580 0 : for (N = 1; N <= M; ++N) {
4581 0 : state.dataSolarShading->HCX(NS3, N + P) = nint64(state.dataSolarShading->XTEMP(N));
4582 0 : state.dataSolarShading->HCY(NS3, N + P) = nint64(state.dataSolarShading->YTEMP(N));
4583 : }
4584 0 : }
4585 :
4586 7838123 : void DeterminePolygonOverlap(EnergyPlusData &state,
4587 : int const NS1, // Number of the figure being overlapped
4588 : int const NS2, // Number of the figure doing overlapping
4589 : int const NS3 // Location to place results of overlap
4590 : )
4591 : {
4592 :
4593 : // SUBROUTINE INFORMATION:
4594 : // AUTHOR Legacy Code
4595 : // DATE WRITTEN
4596 : // MODIFIED na
4597 : // RE-ENGINEERED Lawrie, Oct 2000
4598 :
4599 : // PURPOSE OF THIS SUBROUTINE:
4600 : // This subroutine computes the possible overlap of two polygons.
4601 : // It uses homogeneous coordinate techniques to determine the overlap area
4602 : // between two convex polygons. Results are stored in the homogeneous coordinate (HC) arrays.
4603 :
4604 : // METHODOLOGY EMPLOYED:
4605 : // The vertices defining the overlap between fig.1 and fig.2
4606 : // consist of: the vertices of fig.1 enclosed by fig.2 (A)
4607 : // plus the vertices of fig.2 enclosed by fig.1 (B)
4608 : // plus the intercepts of fig.1 and fig.2 (C & D)
4609 :
4610 : // +----------------------+
4611 : // ! !
4612 : // ! FIG.2 !
4613 : // ! !
4614 : // +--------------C----------A !
4615 : // ! ! / !
4616 : // ! ! / !
4617 : // ! B-------D--------------+
4618 : // ! FIG.1 /
4619 : // ! /
4620 : // +-------------------+
4621 :
4622 : // REFERENCES:
4623 : // BLAST/IBLAST code, original author George Walton
4624 :
4625 : // Using/Aliasing
4626 :
4627 : int N; // Loop index
4628 : int NV1; // Number of vertices of figure NS1
4629 : int NV2; // Number of vertices of figure NS2
4630 : int NV3; // Number of vertices of figure NS3 (the overlap of NS1 and NS2)
4631 : int NIN1; // Number of vertices of NS1 within NS2
4632 : int NIN2; // Number of vertices of NS2 within NS1
4633 :
4634 : // Check for exceeding array limits.
4635 : #ifdef EP_Count_Calls
4636 : ++state.dataTimingsData->NumDetPolyOverlap_Calls;
4637 : #endif
4638 :
4639 7838123 : if (NS3 > state.dataSolarShading->MaxHCS) {
4640 :
4641 0 : state.dataSolarShading->OverlapStatus = TooManyFigures;
4642 :
4643 0 : if (!state.dataSolarShading->TooManyFiguresMessage && !state.dataGlobal->DisplayExtraWarnings) {
4644 0 : ShowWarningError(state,
4645 0 : format("DeterminePolygonOverlap: Too many figures [>{}] detected in an overlap calculation. Use "
4646 : "Output:Diagnostics,DisplayExtraWarnings; for more details.",
4647 0 : state.dataSolarShading->MaxHCS));
4648 0 : state.dataSolarShading->TooManyFiguresMessage = true;
4649 : }
4650 :
4651 0 : if (state.dataGlobal->DisplayExtraWarnings) {
4652 0 : state.dataSolarShading->TrackTooManyFigures.redimension(++state.dataSolarShading->NumTooManyFigures);
4653 0 : state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex1 =
4654 0 : state.dataSolarShading->CurrentShadowingSurface;
4655 0 : state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex2 =
4656 0 : state.dataSolarShading->CurrentSurfaceBeingShadowed;
4657 : }
4658 :
4659 0 : return;
4660 : }
4661 :
4662 7838123 : state.dataSolarShading->OverlapStatus = PartialOverlap;
4663 7838123 : NV1 = state.dataSolarShading->HCNV(NS1);
4664 7838123 : NV2 = state.dataSolarShading->HCNV(NS2);
4665 7838123 : NV3 = 0;
4666 :
4667 7838123 : if (!state.dataSysVars->SutherlandHodgman) {
4668 0 : INCLOS(state, NS1, NV1, NS2, NV2, NV3, NIN1); // Find vertices of NS1 within NS2.
4669 :
4670 0 : if (NIN1 >= NV1) {
4671 :
4672 0 : state.dataSolarShading->OverlapStatus = FirstSurfWithinSecond;
4673 :
4674 : } else {
4675 :
4676 0 : INCLOS(state, NS2, NV2, NS1, NV1, NV3, NIN2); // Find vertices of NS2 within NS1.
4677 :
4678 0 : if (NIN2 >= NV2) {
4679 :
4680 0 : state.dataSolarShading->OverlapStatus = SecondSurfWithinFirst;
4681 :
4682 : } else {
4683 :
4684 0 : INTCPT(state, NV1, NV2, NV3, NS1, NS2); // Find intercepts of NS1 & NS2.
4685 :
4686 0 : if (NV3 < 3) { // Overlap must have 3 or more vertices
4687 0 : state.dataSolarShading->OverlapStatus = NoOverlap;
4688 0 : return;
4689 : }
4690 : }
4691 : }
4692 :
4693 : } else {
4694 : // simple polygon clipping
4695 7838123 : CLIPPOLY(state, NS1, NS2, NV1, NV2, NV3);
4696 : }
4697 :
4698 7838123 : if (NV3 < state.dataSolarShading->MaxHCV && NS3 <= state.dataSolarShading->MaxHCS) {
4699 :
4700 7838123 : if (!state.dataSysVars->SutherlandHodgman) {
4701 0 : ORDER(state, NV3, NS3); // Put vertices in clockwise order.
4702 : } else {
4703 7838123 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
4704 7838123 : auto l(state.dataSolarShading->HCX.index(NS3, 1));
4705 20053775 : for (N = 1; N <= NV3; ++N, ++l) {
4706 12215652 : state.dataSolarShading->HCX[l] = nint64(state.dataSolarShading->XTEMP(N)); // [ l ] == ( N, NS3 )
4707 12215652 : state.dataSolarShading->HCY[l] = nint64(state.dataSolarShading->YTEMP(N));
4708 : }
4709 : }
4710 :
4711 7838123 : HTRANS0(state, NS3, NV3); // Determine h.c. values of sides.
4712 : // Skip overlaps of negligible area.
4713 :
4714 7838123 : if (std::abs(state.dataSolarShading->HCAREA(NS3)) * HCMULT < std::abs(state.dataSolarShading->HCAREA(NS1))) {
4715 4788348 : state.dataSolarShading->OverlapStatus = NoOverlap;
4716 : } else {
4717 3049775 : if (state.dataSolarShading->HCAREA(NS1) * state.dataSolarShading->HCAREA(NS2) > 0.0)
4718 1182879 : state.dataSolarShading->HCAREA(NS3) = -state.dataSolarShading->HCAREA(NS3); // Determine sign of area of overlap
4719 3049775 : Real64 const HCT_1(state.dataSolarShading->HCT(NS1));
4720 3049775 : Real64 const HCT_2(state.dataSolarShading->HCT(NS2));
4721 3049775 : Real64 HCT_3(HCT_2 * HCT_1); // Determine transmission of overlap
4722 3049775 : if (HCT_2 >= 0.5 && HCT_1 >= 0.5) {
4723 2025590 : if (HCT_2 != 1.0 && HCT_1 != 1.0) {
4724 0 : HCT_3 = 1.0 - HCT_3;
4725 : }
4726 : }
4727 3049775 : state.dataSolarShading->HCT(NS3) = HCT_3;
4728 : }
4729 :
4730 0 : } else if (NV3 > state.dataSolarShading->MaxHCV) {
4731 :
4732 0 : state.dataSolarShading->OverlapStatus = TooManyVertices;
4733 :
4734 0 : if (!state.dataSolarShading->TooManyVerticesMessage && !state.dataGlobal->DisplayExtraWarnings) {
4735 0 : ShowWarningError(state,
4736 0 : format("DeterminePolygonOverlap: Too many vertices [>{}] detected in an overlap calculation. Use "
4737 : "Output:Diagnostics,DisplayExtraWarnings; for more details.",
4738 0 : state.dataSolarShading->MaxHCV));
4739 0 : state.dataSolarShading->TooManyVerticesMessage = true;
4740 : }
4741 :
4742 0 : if (state.dataGlobal->DisplayExtraWarnings) {
4743 0 : state.dataSolarShading->TrackTooManyVertices.redimension(++state.dataSolarShading->NumTooManyVertices);
4744 0 : state.dataSolarShading->TrackTooManyVertices(state.dataSolarShading->NumTooManyVertices).SurfIndex1 =
4745 0 : state.dataSolarShading->CurrentShadowingSurface;
4746 0 : state.dataSolarShading->TrackTooManyVertices(state.dataSolarShading->NumTooManyVertices).SurfIndex2 =
4747 0 : state.dataSolarShading->CurrentSurfaceBeingShadowed;
4748 : }
4749 :
4750 0 : } else if (NS3 > state.dataSolarShading->MaxHCS) {
4751 :
4752 0 : state.dataSolarShading->OverlapStatus = TooManyFigures;
4753 :
4754 0 : if (!state.dataSolarShading->TooManyFiguresMessage && !state.dataGlobal->DisplayExtraWarnings) {
4755 0 : ShowWarningError(state,
4756 0 : format("DeterminePolygonOverlap: Too many figures [>{}] detected in an overlap calculation. Use "
4757 : "Output:Diagnostics,DisplayExtraWarnings; for more details.",
4758 0 : state.dataSolarShading->MaxHCS));
4759 0 : state.dataSolarShading->TooManyFiguresMessage = true;
4760 : }
4761 :
4762 0 : if (state.dataGlobal->DisplayExtraWarnings) {
4763 0 : state.dataSolarShading->TrackTooManyFigures.redimension(++state.dataSolarShading->NumTooManyFigures);
4764 0 : state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex1 =
4765 0 : state.dataSolarShading->CurrentShadowingSurface;
4766 0 : state.dataSolarShading->TrackTooManyFigures(state.dataSolarShading->NumTooManyFigures).SurfIndex2 =
4767 0 : state.dataSolarShading->CurrentSurfaceBeingShadowed;
4768 : }
4769 : }
4770 : }
4771 :
4772 14330 : void CalcPerSolarBeam(EnergyPlusData &state,
4773 : Real64 const AvgEqOfTime, // Average value of Equation of Time for period
4774 : Real64 const AvgSinSolarDeclin, // Average value of Sine of Solar Declination for period
4775 : Real64 const AvgCosSolarDeclin // Average value of Cosine of Solar Declination for period
4776 : )
4777 : {
4778 :
4779 : // SUBROUTINE INFORMATION:
4780 : // AUTHOR Legacy Code
4781 : // DATE WRITTEN
4782 : // MODIFIED BG, Nov 2012 - Timestep solar. DetailedSolarTimestepIntegration
4783 : // RE-ENGINEERED Lawrie, Oct 2000
4784 :
4785 : // PURPOSE OF THIS SUBROUTINE:
4786 : // This subroutine manages computation of solar gain multipliers for beam radiation. These
4787 : // are calculated for a period of days depending on the input "Shadowing Calculations".
4788 :
4789 : // REFERENCES:
4790 : // BLAST/IBLAST code, original author George Walton
4791 :
4792 : // Using/Aliasing
4793 :
4794 : using ScheduleManager::LookUpScheduleValue;
4795 : using WindowComplexManager::InitComplexWindows;
4796 : using WindowComplexManager::UpdateComplexWindows;
4797 :
4798 : int iHour; // Hour index number
4799 : int TS; // TimeStep Loop Countergit
4800 :
4801 14330 : if (state.dataSolarShading->InitComplexOnce) InitComplexWindows(state);
4802 14330 : state.dataSolarShading->InitComplexOnce = false;
4803 :
4804 14330 : if (state.dataGlobal->KickOffSizing || state.dataGlobal->KickOffSimulation) return; // Skip solar calcs for these Initialization steps.
4805 :
4806 : #ifdef EP_Count_Calls
4807 : ++state.dataTimingsData->NumCalcPerSolBeam_Calls;
4808 : #endif
4809 :
4810 : // Initialize some values for the appropriate period
4811 10621 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
4812 21635 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
4813 38180 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4814 19102 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
4815 19102 : int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
4816 19102 : int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
4817 162518 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4818 143416 : state.dataSurface->SurfOpaqAO(surfNum) = 0.0;
4819 : }
4820 19102 : firstSurf = thisSpace.HTSurfaceFirst;
4821 19102 : lastSurf = thisSpace.HTSurfaceLast;
4822 186371 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4823 167269 : state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0;
4824 : }
4825 477550 : for (int hour = 1; hour <= 24; ++hour) {
4826 4472904 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4827 4014456 : state.dataHeatBal->SurfSunlitFracHR(hour, surfNum) = 0.0;
4828 4014456 : state.dataHeatBal->SurfCosIncAngHR(hour, surfNum) = 0.0;
4829 : }
4830 : }
4831 477550 : for (int hour = 1; hour <= 24; ++hour) {
4832 2850576 : for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) {
4833 23067312 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4834 20675184 : state.dataHeatBal->SurfSunlitFrac(hour, timestep, surfNum) = 0.0;
4835 20675184 : state.dataHeatBal->SurfCosIncAng(hour, timestep, surfNum) = 0.0;
4836 20675184 : state.dataHeatBal->SurfSunlitFracWithoutReveal(hour, timestep, surfNum) = 0.0;
4837 : }
4838 : }
4839 : }
4840 477550 : for (int hour = 1; hour <= 24; ++hour) {
4841 2850576 : for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) {
4842 50234688 : for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) {
4843 461346240 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4844 413503680 : state.dataHeatBal->SurfWinBackSurfaces(hour, timestep, backSurfNum, surfNum) = 0.0;
4845 413503680 : state.dataHeatBal->SurfWinOverlapAreas(hour, timestep, backSurfNum, surfNum) = 0.0;
4846 : }
4847 : }
4848 : }
4849 : }
4850 : }
4851 : }
4852 :
4853 175426 : for (auto &e : state.dataSurface->SurfaceWindow) {
4854 172869 : e.OutProjSLFracMult = 1.0;
4855 172869 : e.InOutProjSLFracMult = 1.0;
4856 : }
4857 : } else {
4858 56448 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
4859 96768 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
4860 48384 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
4861 48384 : int const firstSurf = thisSpace.HTSurfaceFirst;
4862 48384 : int const lastSurf = thisSpace.HTSurfaceLast;
4863 604800 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4864 556416 : state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0;
4865 556416 : state.dataSurface->SurfOpaqAO(surfNum) = 0.0;
4866 556416 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0;
4867 556416 : state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0;
4868 556416 : state.dataHeatBal->SurfSunlitFracHR(state.dataGlobal->HourOfDay, surfNum) = 0.0;
4869 556416 : state.dataHeatBal->SurfCosIncAngHR(state.dataGlobal->HourOfDay, surfNum) = 0.0;
4870 556416 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0;
4871 : }
4872 1016064 : for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) {
4873 12096000 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
4874 11128320 : state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0;
4875 11128320 : state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0.0;
4876 : }
4877 : }
4878 : }
4879 : }
4880 :
4881 564480 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4882 556416 : state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay) = 1.0;
4883 556416 : state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay) = 1.0;
4884 : }
4885 : }
4886 :
4887 10621 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
4888 63925 : for (iHour = 1; iHour <= 24; ++iHour) { // Do for all hours
4889 397704 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
4890 336336 : FigureSunCosines(state, iHour, TS, AvgEqOfTime, AvgSinSolarDeclin, AvgCosSolarDeclin);
4891 : }
4892 : }
4893 : } else {
4894 8064 : FigureSunCosines(state, state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, AvgEqOfTime, AvgSinSolarDeclin, AvgCosSolarDeclin);
4895 : }
4896 : // Initialize/update the Complex Fenestration geometry and optical properties
4897 10621 : UpdateComplexWindows(state);
4898 10621 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
4899 63925 : for (iHour = 1; iHour <= 24; ++iHour) { // Do for all hours.
4900 397704 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
4901 336336 : FigureSolarBeamAtTimestep(state, iHour, TS);
4902 : } // TimeStep Loop
4903 : } // Hour Loop
4904 : } else {
4905 8064 : FigureSolarBeamAtTimestep(state, state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
4906 : }
4907 : }
4908 :
4909 344400 : void FigureSunCosines(EnergyPlusData &state,
4910 : int const iHour,
4911 : int const iTimeStep,
4912 : Real64 const EqOfTime, // value of Equation of Time for period
4913 : Real64 const SinSolarDeclin, // value of Sine of Solar Declination for period
4914 : Real64 const CosSolarDeclin // value of Cosine of Solar Declination for period
4915 : )
4916 : {
4917 :
4918 : // SUBROUTINE INFORMATION:
4919 : // AUTHOR B. Griffith
4920 : // DATE WRITTEN October 2012
4921 : // MODIFIED na
4922 : // RE-ENGINEERED na
4923 :
4924 : // PURPOSE OF THIS SUBROUTINE:
4925 : // Determine solar position. Default for sun below horizon.
4926 :
4927 : // METHODOLOGY EMPLOYED:
4928 : // Given hour, timestep, equation of time, solar declination sine, and solar declination cosine,
4929 : // determine sun directions for use elsewhere
4930 :
4931 : // Using/Aliasing
4932 :
4933 : Real64 CurrentTime; // Current Time for passing to Solar Position Routine
4934 :
4935 344400 : if (state.dataGlobal->NumOfTimeStepInHour != 1) {
4936 343776 : CurrentTime = double(iHour - 1) + double(iTimeStep) * (state.dataGlobal->TimeStepZone);
4937 : } else {
4938 624 : CurrentTime = double(iHour) + state.dataEnvrn->TS1TimeOffset;
4939 : }
4940 344400 : SUN4(state, CurrentTime, EqOfTime, SinSolarDeclin, CosSolarDeclin);
4941 :
4942 : // Save hourly values for use in DaylightingManager
4943 344400 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
4944 336336 : if (iTimeStep == state.dataGlobal->NumOfTimeStepInHour) state.dataSurface->SurfSunCosHourly(iHour) = state.dataSolarShading->SUNCOS;
4945 : } else {
4946 8064 : state.dataSurface->SurfSunCosHourly(iHour) = state.dataSolarShading->SUNCOS;
4947 : }
4948 : // Save timestep values for use in WindowComplexManager
4949 344400 : state.dataBSDFWindow->SUNCOSTS(iTimeStep, iHour) = state.dataSolarShading->SUNCOS;
4950 344400 : }
4951 :
4952 344400 : void FigureSolarBeamAtTimestep(EnergyPlusData &state, int const iHour, int const iTimeStep)
4953 : {
4954 :
4955 : // SUBROUTINE INFORMATION:
4956 : // AUTHOR B.Griffith, derived from CalcPerSolarBeam, Legacy and Lawrie.
4957 : // DATE WRITTEN October 2012
4958 : // MODIFIED na
4959 : // RE-ENGINEERED na
4960 :
4961 : // PURPOSE OF THIS SUBROUTINE:
4962 : // This subroutine computes solar gain multipliers for beam solar
4963 :
4964 : using DataSystemVariables::ShadingMethod;
4965 : using ScheduleManager::LookUpScheduleValue;
4966 :
4967 : Real64 SurfArea; // Surface area. For walls, includes all window frame areas.
4968 : Real64 Fac1WoShdg; // Intermediate calculation factor, without shading
4969 : Real64 Fac1WithShdg; // Intermediate calculation factor, with shading
4970 : Real64 FracIlluminated; // Fraction of surface area illuminated by a sky patch
4971 :
4972 : // Recover the sun direction from the array stored in previous loop
4973 344400 : state.dataSolarShading->SUNCOS = state.dataBSDFWindow->SUNCOSTS(iTimeStep, iHour);
4974 :
4975 344400 : state.dataSolarShading->SurfSunCosTheta = 0.0;
4976 :
4977 344400 : if (state.dataSolarShading->SUNCOS(3) < DataEnvironment::SunIsUpValue) return;
4978 :
4979 11218080 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4980 33134031 : state.dataSolarShading->SurfSunCosTheta(SurfNum) = state.dataSolarShading->SUNCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
4981 22089354 : state.dataSolarShading->SUNCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
4982 11044677 : state.dataSolarShading->SUNCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
4983 11044677 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
4984 10766469 : if (iTimeStep == state.dataGlobal->NumOfTimeStepInHour)
4985 2093327 : state.dataHeatBal->SurfCosIncAngHR(iHour, SurfNum) = state.dataSolarShading->SurfSunCosTheta(SurfNum);
4986 : } else {
4987 278208 : state.dataHeatBal->SurfCosIncAngHR(iHour, SurfNum) = state.dataSolarShading->SurfSunCosTheta(SurfNum);
4988 : }
4989 11044677 : state.dataHeatBal->SurfCosIncAng(iHour, iTimeStep, SurfNum) = state.dataSolarShading->SurfSunCosTheta(SurfNum);
4990 : }
4991 :
4992 520304 : if ((state.dataSysVars->shadingMethod == ShadingMethod::Scheduled || state.dataSysVars->shadingMethod == ShadingMethod::Imported) &&
4993 173783 : !state.dataGlobal->DoingSizing && state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
4994 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
4995 0 : if (state.dataSurface->Surface(SurfNum).SurfSchedExternalShadingFrac) {
4996 0 : state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) =
4997 0 : LookUpScheduleValue(state, state.dataSurface->Surface(SurfNum).SurfExternalShadingSchInd, iHour, iTimeStep);
4998 : } else {
4999 0 : state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = 1.0;
5000 : }
5001 : }
5002 : } else {
5003 173403 : SHADOW(state, iHour, iTimeStep); // Determine sunlit areas and solar multipliers for all surfaces.
5004 11218080 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5005 11044677 : if (state.dataSurface->Surface(SurfNum).Area >= 1.e-10) {
5006 11044677 : SurfArea = state.dataSurface->Surface(SurfNum).NetAreaShadowCalc;
5007 11044677 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
5008 10766469 : if (iTimeStep == state.dataGlobal->NumOfTimeStepInHour)
5009 2093327 : state.dataHeatBal->SurfSunlitFracHR(iHour, SurfNum) = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
5010 : } else {
5011 278208 : state.dataHeatBal->SurfSunlitFracHR(iHour, SurfNum) = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
5012 : }
5013 11044677 : state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
5014 11044677 : if (state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) < 1.e-5)
5015 8560454 : state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = 0.0;
5016 : }
5017 : // Added check
5018 11044677 : if (state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) > 1.0) {
5019 0 : state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) = 1.0;
5020 : }
5021 : }
5022 : }
5023 : // Note -- if not the below, values are set in SkyDifSolarShading routine (constant for simulation)
5024 173403 : if (state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
5025 0 : state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) {
5026 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5027 0 : state.dataSolarShading->SurfWithShdgIsoSky(SurfNum) = 0.;
5028 0 : state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) = 0.;
5029 0 : state.dataSolarShading->SurfWithShdgHoriz(SurfNum) = 0.;
5030 0 : state.dataSolarShading->SurfWoShdgHoriz(SurfNum) = 0.;
5031 : }
5032 :
5033 0 : for (int IPhi = 0; IPhi < NPhi; ++IPhi) { // Loop over patch altitude values
5034 0 : state.dataSolarShading->SUNCOS(3) = state.dataSolarShading->sin_Phi[IPhi];
5035 :
5036 0 : for (int ITheta = 0; ITheta < NTheta; ++ITheta) { // Loop over patch azimuth values
5037 0 : state.dataSolarShading->SUNCOS(1) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->cos_Theta[ITheta];
5038 0 : state.dataSolarShading->SUNCOS(2) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->sin_Theta[ITheta];
5039 :
5040 0 : for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
5041 0 : state.dataSolarShading->SurfSunCosTheta(SurfNum) =
5042 0 : state.dataSolarShading->SUNCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
5043 0 : state.dataSolarShading->SUNCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
5044 0 : state.dataSolarShading->SUNCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
5045 : }
5046 :
5047 0 : SHADOW(state, iHour, iTimeStep); // Determine sunlit areas and solar multipliers for all surfaces.
5048 :
5049 0 : for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
5050 :
5051 0 : if (state.dataSolarShading->SurfSunCosTheta(SurfNum) < 0.0) continue;
5052 :
5053 0 : Fac1WoShdg = state.dataSolarShading->cos_Phi[IPhi] * DThetaDPhi * state.dataSolarShading->SurfSunCosTheta(SurfNum);
5054 0 : SurfArea = state.dataSurface->Surface(SurfNum).NetAreaShadowCalc;
5055 0 : if (SurfArea > Eps) {
5056 0 : FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
5057 : } else {
5058 0 : FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / (SurfArea + Eps);
5059 : }
5060 0 : Fac1WithShdg = Fac1WoShdg * FracIlluminated;
5061 0 : state.dataSolarShading->SurfWithShdgIsoSky(SurfNum) += Fac1WithShdg;
5062 0 : state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) += Fac1WoShdg;
5063 :
5064 : // Horizon region
5065 0 : if (IPhi == 0) {
5066 0 : state.dataSolarShading->SurfWithShdgHoriz(SurfNum) += Fac1WithShdg;
5067 0 : state.dataSolarShading->SurfWoShdgHoriz(SurfNum) += Fac1WoShdg;
5068 : }
5069 : } // End of surface loop
5070 : } // End of Theta loop
5071 : } // End of Phi loop
5072 :
5073 0 : for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
5074 : // Original conditions:
5075 : // if (!state.dataSurface->Surface(SurfNum).IsShadowing &&
5076 : // (!state.dataSurface->Surface(SurfNum).HeatTransSurf || !state.dataSurface->Surface(SurfNum).ExtSolar))
5077 : // continue;
5078 :
5079 0 : if (std::abs(state.dataSolarShading->SurfWoShdgIsoSky(SurfNum)) > Eps) {
5080 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(iTimeStep, iHour, SurfNum) =
5081 0 : (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum));
5082 : } else {
5083 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(iTimeStep, iHour, SurfNum) =
5084 0 : (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) + Eps);
5085 : }
5086 0 : if (std::abs(state.dataSolarShading->SurfWoShdgHoriz(SurfNum)) > Eps) {
5087 0 : state.dataSolarShading->SurfDifShdgRatioHorizHRTS(iTimeStep, iHour, SurfNum) =
5088 0 : (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum));
5089 : } else {
5090 0 : state.dataSolarShading->SurfDifShdgRatioHorizHRTS(iTimeStep, iHour, SurfNum) =
5091 0 : (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum) + Eps);
5092 : }
5093 : }
5094 :
5095 : // ! Get IR view factors. An exterior surface can receive IR radiation from
5096 : // ! sky, ground or shadowing surfaces. Assume shadowing surfaces have same
5097 : // ! temperature as outside air (and therefore same temperature as ground),
5098 : // ! so that the view factor to these shadowing surfaces can be included in
5099 : // ! the ground view factor. Sky IR is assumed to be isotropic and shadowing
5100 : // ! surfaces are assumed to be opaque to IR so they totally "shade" IR from
5101 : // ! sky or ground.
5102 :
5103 : // DO SurfNum = 1,TotSurfaces
5104 : // Surface(SurfNum)%ViewFactorSkyIR = Surface(SurfNum)%ViewFactorSkyIR * DifShdgRatioIsoSky(SurfNum,IHOUR,TS)
5105 : // Surface(SurfNum)%ViewFactorGroundIR = 1.0 - Surface(SurfNum)%ViewFactorSkyIR
5106 : // END DO
5107 :
5108 : } // test for shading surfaces
5109 :
5110 249106 : for (int SurfNum : state.dataSurface->AllExtSolWinWithFrameSurfaceList) {
5111 : // For exterior windows with frame/divider that are partially or fully sunlit,
5112 : // correct SunlitFrac due to shadowing of frame and divider projections onto window glass.
5113 : // Note: if SunlitFrac = 0.0 the window is either completely shaded or the sun is in back
5114 : // of the window; in either case, frame/divider shadowing doesn't have to be done.
5115 :
5116 75703 : if (state.dataHeatBal->SurfSunlitFrac(iHour, iTimeStep, SurfNum) > 0.0) {
5117 68875 : CalcFrameDividerShadow(state, SurfNum, state.dataSurface->Surface(SurfNum).FrameDivider, iHour);
5118 : }
5119 : }
5120 : }
5121 :
5122 771 : void DetermineShadowingCombinations(EnergyPlusData &state)
5123 : {
5124 :
5125 : // SUBROUTINE INFORMATION:
5126 : // AUTHOR From Legacy Code
5127 : // DATE WRITTEN
5128 : // MODIFIED LKL; March 2002 -- another missing translation from BLAST's routine
5129 : // FCW; Jan 2003 -- removed line that prevented beam solar through interior windows
5130 : // RE-ENGINEERED Rick Strand; 1998
5131 : // Linda Lawrie; Oct 2000
5132 :
5133 : // PURPOSE OF THIS SUBROUTINE:
5134 : // This routine prepares a list of heat transfer surfaces and
5135 : // their possible shadowers which is used to direct the hourly
5136 : // calculation of shadows and sunlit areas.
5137 :
5138 : // METHODOLOGY EMPLOYED:
5139 : // As appropriate surfaces are identified, they are placed into the
5140 : // ShadowComb data structure (module level) with the accompanying lists
5141 : // of other surface numbers.
5142 :
5143 : // REFERENCES:
5144 : // BLAST/IBLAST code, original author George Walton
5145 :
5146 : // Using/Aliasing
5147 : using namespace DataErrorTracking;
5148 :
5149 1542 : Array1D_int GSS; // List of shadowing surfaces numbers for a receiving surface
5150 1542 : Array1D_int BKS; // List of back surface numbers for a receiving surface
5151 1542 : Array1D_int SBS; // List of subsurfaces for a receiving surface
5152 : bool CannotShade; // TRUE if subsurface cannot shade receiving surface
5153 : bool HasWindow; // TRUE if a window is present on receiving surface
5154 : Real64 ZMIN; // Lowest point on the receiving surface
5155 : int BackSurfaceNumber; // Back surface number
5156 : int HTS; // Heat transfer surface number for a receiving surface
5157 : int GRSNR; // Receiving surface number
5158 : int GSSNR; // Shadowing surface number
5159 : int SBSNR; // Subsurface number
5160 : int NBKS; // Number of back surfaces for a receiving surface
5161 : int NGSS; // Number of shadowing surfaces for a receiving surface
5162 : int NSBS; // Number of subsurfaces for a receiving surface
5163 : bool ShadowingSurf; // True if a receiving surface is a shadowing surface
5164 1542 : Array1D_bool CastingSurface; // tracking during setup of ShadowComb
5165 :
5166 : #ifdef EP_Count_Calls
5167 : ++state.dataTimingsData->NumDetShadowCombs_Calls;
5168 : #endif
5169 :
5170 2313 : state.dataShadowComb->ShadowComb.dimension(state.dataSurface->TotSurfaces,
5171 2313 : ShadowingCombinations{}); // Set all elements to default constructed state
5172 :
5173 771 : CastingSurface.dimension(state.dataSurface->TotSurfaces, false);
5174 :
5175 771 : state.dataSolarShading->HCA.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
5176 771 : state.dataSolarShading->HCB.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
5177 771 : state.dataSolarShading->HCC.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
5178 771 : state.dataSolarShading->HCX.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
5179 771 : state.dataSolarShading->HCY.dimension(2 * state.dataSolarShading->MaxHCS, state.dataSolarShading->MaxHCV + 1, 0);
5180 771 : state.dataSolarShading->HCAREA.dimension(2 * state.dataSolarShading->MaxHCS, 0.0);
5181 771 : state.dataSolarShading->HCNS.dimension(2 * state.dataSolarShading->MaxHCS, 0);
5182 771 : state.dataSolarShading->HCNV.dimension(2 * state.dataSolarShading->MaxHCS, 0);
5183 771 : state.dataSolarShading->HCT.dimension(2 * state.dataSolarShading->MaxHCS, 0.0);
5184 :
5185 771 : GSS.dimension(state.dataSolarShading->MaxGSS, 0);
5186 771 : BKS.dimension(state.dataSolarShading->MaxGSS, 0);
5187 771 : SBS.dimension(state.dataSolarShading->MaxGSS, 0);
5188 :
5189 771 : state.dataSolarShading->penumbraIDs.clear();
5190 :
5191 771 : HTS = 0;
5192 :
5193 : // Check every surface as a possible shadow receiving surface ("RS" = receiving surface).
5194 771 : if (state.dataEnvrn->IgnoreSolarRadiation) {
5195 0 : return;
5196 : }
5197 :
5198 44533 : for (GRSNR = 1; GRSNR <= state.dataSurface->TotSurfaces; ++GRSNR) { // Loop through all surfaces (looking for potential receiving surfaces)...
5199 :
5200 43762 : ShadowingSurf = state.dataSurface->Surface(GRSNR).IsShadowing;
5201 43762 : NGSS = 0;
5202 43762 : NSBS = 0;
5203 43762 : NBKS = 0;
5204 :
5205 43762 : if (!ShadowingSurf && !state.dataSurface->Surface(GRSNR).HeatTransSurf) continue;
5206 43748 : HTS = GRSNR;
5207 :
5208 : #ifndef EP_NO_OPENGL
5209 43748 : if (state.dataSolarShading->penumbra) {
5210 113 : bool skipSurface = state.dataSurface->Surface(GRSNR).MirroredSurf;
5211 : // Penumbra doesn't need mirrored surfaces TODO: Don't bother creating them in the first place?
5212 :
5213 : // Skip interior surfaces if the other side has already been added to penumbra
5214 113 : if (state.dataSurface->Surface(GRSNR).ExtBoundCond > 0) {
5215 20 : if (state.dataSurface->SurfPenumbraID(state.dataSurface->Surface(GRSNR).ExtBoundCond) >= 0) {
5216 10 : state.dataSurface->SurfPenumbraID(GRSNR) = state.dataSurface->SurfPenumbraID(state.dataSurface->Surface(GRSNR).ExtBoundCond);
5217 10 : skipSurface = true;
5218 : }
5219 : }
5220 :
5221 113 : if (!skipSurface) {
5222 : // Add surfaces to penumbra...
5223 184 : Pumbra::Polygon poly;
5224 :
5225 92 : if (state.dataSurface->Surface(GRSNR).Reveal > 0.0) {
5226 21 : Real64 R = state.dataSurface->Surface(GRSNR).Reveal;
5227 21 : auto &norm = state.dataSurface->Surface(GRSNR).NewellSurfaceNormalVector;
5228 21 : auto &v = state.dataSurface->Surface(GRSNR).Vertex;
5229 105 : for (unsigned i = 0; i < v.size(); ++i) {
5230 84 : poly.push_back(v[i].x);
5231 84 : poly.push_back(v[i].y);
5232 84 : poly.push_back(v[i].z);
5233 :
5234 168 : Vector vPrev;
5235 84 : if (i == 0) {
5236 21 : vPrev = v[v.size() - 1];
5237 : } else {
5238 63 : vPrev = v[i - 1];
5239 : }
5240 :
5241 168 : Pumbra::Polygon rPoly; // Reveal surface
5242 84 : rPoly.push_back(v[i].x);
5243 84 : rPoly.push_back(v[i].y);
5244 84 : rPoly.push_back(v[i].z);
5245 :
5246 84 : rPoly.push_back(v[i].x + norm.x * R);
5247 84 : rPoly.push_back(v[i].y + norm.y * R);
5248 84 : rPoly.push_back(v[i].z + norm.z * R);
5249 :
5250 84 : rPoly.push_back(vPrev.x + norm.x * R);
5251 84 : rPoly.push_back(vPrev.y + norm.y * R);
5252 84 : rPoly.push_back(vPrev.z + norm.z * R);
5253 :
5254 84 : rPoly.push_back(vPrev.x);
5255 84 : rPoly.push_back(vPrev.y);
5256 84 : rPoly.push_back(vPrev.z);
5257 :
5258 168 : Pumbra::Surface rSurf(rPoly);
5259 84 : state.dataSolarShading->penumbra->addSurface(rSurf);
5260 : }
5261 : } else {
5262 353 : for (auto v : state.dataSurface->Surface(GRSNR).Vertex) {
5263 282 : poly.push_back(v.x);
5264 282 : poly.push_back(v.y);
5265 282 : poly.push_back(v.z);
5266 : }
5267 : }
5268 184 : Pumbra::Surface pSurf(poly);
5269 :
5270 : // Punch holes for subsurfaces
5271 92 : if (state.dataSurface->Surface(GRSNR).BaseSurf == GRSNR) { // Only look for subsurfaces on base surfaces
5272 6840 : for (int subSurface = 1; subSurface <= state.dataSurface->TotSurfaces; ++subSurface) {
5273 13539 : if (state.dataSurface->Surface(subSurface).BaseSurf != GRSNR) continue; // Ignore subsurfaces of other surfaces
5274 81 : if (!state.dataSurface->Surface(subSurface).HeatTransSurf) continue; // Skip non heat transfer subsurfaces
5275 81 : if (subSurface == GRSNR) continue; // Surface itself cannot be its own subsurface
5276 :
5277 42 : Pumbra::Polygon subPoly;
5278 21 : if (state.dataSurface->Surface(subSurface).Reveal > 0.0) {
5279 21 : Real64 R = state.dataSurface->Surface(subSurface).Reveal;
5280 21 : auto &norm = state.dataSurface->Surface(subSurface).NewellSurfaceNormalVector;
5281 105 : for (auto v : state.dataSurface->Surface(subSurface).Vertex) {
5282 84 : subPoly.push_back(v.x + norm.x * R);
5283 84 : subPoly.push_back(v.y + norm.y * R);
5284 84 : subPoly.push_back(v.z + norm.z * R);
5285 : }
5286 : } else {
5287 0 : for (auto v : state.dataSurface->Surface(subSurface).Vertex) {
5288 0 : subPoly.push_back(v.x);
5289 0 : subPoly.push_back(v.y);
5290 0 : subPoly.push_back(v.z);
5291 : }
5292 : }
5293 :
5294 21 : pSurf.addHole(subPoly);
5295 : }
5296 : }
5297 92 : state.dataSurface->SurfPenumbraID(GRSNR) = state.dataSolarShading->penumbra->addSurface(pSurf);
5298 92 : state.dataSolarShading->penumbraIDs.push_back(state.dataSurface->SurfPenumbraID(GRSNR));
5299 : }
5300 : }
5301 : #endif
5302 :
5303 43748 : if (!ShadowingSurf && !state.dataSurface->Surface(GRSNR).ExtSolar) continue; // Skip surfaces with no external solar
5304 :
5305 18505 : if (!ShadowingSurf && state.dataSurface->Surface(GRSNR).BaseSurf != GRSNR) { // Skip subsurfaces (SBS)
5306 6337 : continue;
5307 : }
5308 :
5309 : // Get the lowest point of receiving surface
5310 12168 : ZMIN = minval(state.dataSurface->Surface(GRSNR).Vertex, &Vector::z);
5311 :
5312 : // Check every surface as a possible shadow casting surface ("SS" = shadow sending)
5313 12168 : NGSS = 0;
5314 12168 : if (state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) { // Except when doing simplified exterior shadowing.
5315 :
5316 1553482 : for (GSSNR = 1; GSSNR <= state.dataSurface->TotSurfaces; ++GSSNR) { // Loop through all surfaces, looking for ones that could shade GRSNR
5317 :
5318 1542814 : if (GSSNR == GRSNR) continue; // Receiving surface cannot shade itself
5319 1532146 : if ((state.dataSurface->Surface(GSSNR).HeatTransSurf) && (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR))
5320 5416 : continue; // A heat transfer subsurface of a receiving surface
5321 : // cannot shade the receiving surface
5322 1526730 : if (ShadowingSurf) {
5323 : // If receiving surf is a shadowing surface exclude matching shadow surface as sending surface
5324 : // IF((GSSNR == GRSNR+1 .AND. Surface(GSSNR)%Name(1:3) == 'Mir').OR. &
5325 : // (GSSNR == GRSNR-1 .AND. Surface(GRSNR)%Name(1:3) == 'Mir')) CYCLE
5326 251538 : if (((GSSNR == GRSNR + 1) && state.dataSurface->Surface(GSSNR).MirroredSurf) ||
5327 125901 : ((GSSNR == GRSNR - 1) && state.dataSurface->Surface(GRSNR).MirroredSurf))
5328 1540 : continue;
5329 : }
5330 :
5331 1525190 : if (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR) { // Shadowing subsurface of receiving surface
5332 :
5333 0 : ++NGSS;
5334 0 : if (NGSS > state.dataSolarShading->MaxGSS) {
5335 0 : GSS.redimension(state.dataSolarShading->MaxGSS *= 2, 0);
5336 : }
5337 0 : GSS(NGSS) = GSSNR;
5338 :
5339 3367075 : } else if ((state.dataSurface->Surface(GSSNR).BaseSurf == 0) ||
5340 2691573 : ((state.dataSurface->Surface(GSSNR).BaseSurf == GSSNR) &&
5341 2123579 : ((state.dataSurface->Surface(GSSNR).ExtBoundCond == ExternalEnvironment) ||
5342 903698 : state.dataSurface->Surface(GSSNR).ExtBoundCond ==
5343 : OtherSideCondModeledExt))) { // Detached shadowing surface or | any other base surface
5344 : // exposed to outside environment
5345 :
5346 370193 : CHKGSS(state, GRSNR, GSSNR, ZMIN, CannotShade); // Check to see if this can shade the receiving surface
5347 370193 : if (!CannotShade) { // Update the shadowing surface data if shading is possible
5348 24993 : ++NGSS;
5349 24993 : if (NGSS > state.dataSolarShading->MaxGSS) {
5350 0 : GSS.redimension(state.dataSolarShading->MaxGSS *= 2, 0);
5351 : }
5352 24993 : GSS(NGSS) = GSSNR;
5353 : }
5354 : }
5355 :
5356 : } // ...end of surfaces DO loop (GSSNR)
5357 : } else { // Simplified Distribution -- still check for Shading Subsurfaces
5358 :
5359 469239 : for (GSSNR = 1; GSSNR <= state.dataSurface->TotSurfaces;
5360 : ++GSSNR) { // Loop through all surfaces (looking for surfaces which could shade GRSNR) ...
5361 :
5362 467739 : if (GSSNR == GRSNR) continue; // Receiving surface cannot shade itself
5363 466239 : if ((state.dataSurface->Surface(GSSNR).HeatTransSurf) && (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR))
5364 921 : continue; // Skip heat transfer subsurfaces of receiving surface
5365 465318 : if (state.dataSurface->Surface(GSSNR).BaseSurf == GRSNR) { // Shadowing subsurface of receiving surface
5366 0 : ++NGSS;
5367 0 : if (NGSS > state.dataSolarShading->MaxGSS) {
5368 0 : GSS.redimension(state.dataSolarShading->MaxGSS *= 2, 0);
5369 : }
5370 0 : GSS(NGSS) = GSSNR;
5371 : }
5372 : }
5373 :
5374 : } // ...end of check for simplified solar distribution
5375 :
5376 : // Check every surface as a receiving subsurface of the receiving surface
5377 12168 : NSBS = 0;
5378 12168 : HasWindow = false;
5379 : // legacy: IF (OSENV(HTS) > 10) WINDOW=.TRUE. -->Note: WINDOW was set true for roof ponds, solar walls, or other zones
5380 2022721 : for (SBSNR = 1; SBSNR <= state.dataSurface->TotSurfaces;
5381 : ++SBSNR) { // Loop through the surfaces yet again (looking for subsurfaces of GRSNR)...
5382 :
5383 2010553 : if (!state.dataSurface->Surface(SBSNR).HeatTransSurf) continue; // Skip non heat transfer subsurfaces
5384 1953571 : if (SBSNR == GRSNR) continue; // Surface itself cannot be its own subsurface
5385 1942944 : if (state.dataSurface->Surface(SBSNR).BaseSurf != GRSNR) continue; // Ignore subsurfaces of other surfaces and other surfaces
5386 :
5387 6337 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SBSNR).Construction).TransDiff > 0.0)
5388 5955 : HasWindow = true; // Check for window
5389 6337 : CHKSBS(state, HTS, GRSNR, SBSNR); // Check that the receiving surface completely encloses the subsurface;
5390 : // severe error if not
5391 6337 : ++NSBS;
5392 6337 : if (NSBS > state.dataSolarShading->MaxSBS) {
5393 3 : SBS.redimension(state.dataSolarShading->MaxSBS *= 2, 0);
5394 : }
5395 6337 : SBS(NSBS) = SBSNR;
5396 :
5397 : } // ...end of surfaces DO loop (SBSNR)
5398 :
5399 : // Check every surface as a back surface
5400 12168 : NBKS = 0;
5401 : // Except for simplified
5402 : // interior solar distribution,
5403 12168 : if ((state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) &&
5404 : (HasWindow)) { // For full interior solar distribution | and a window present on base surface (GRSNR)
5405 :
5406 711526 : for (BackSurfaceNumber = 1; BackSurfaceNumber <= state.dataSurface->TotSurfaces;
5407 : ++BackSurfaceNumber) { // Loop through surfaces yet again, looking for back surfaces to GRSNR
5408 :
5409 709246 : if (!state.dataSurface->Surface(BackSurfaceNumber).HeatTransSurf) continue; // Skip non-heat transfer surfaces
5410 704452 : if (state.dataSurface->Surface(BackSurfaceNumber).BaseSurf == GRSNR) continue; // Skip subsurfaces of this GRSNR
5411 698497 : if (BackSurfaceNumber == GRSNR) continue; // A back surface cannot be GRSNR itself
5412 698497 : if (state.dataSurface->Surface(BackSurfaceNumber).SolarEnclIndex != state.dataSurface->Surface(GRSNR).SolarEnclIndex)
5413 679141 : continue; // Skip if back surface not in same solar enclosure
5414 :
5415 19356 : if (state.dataSurface->Surface(BackSurfaceNumber).Class == SurfaceClass::IntMass) continue;
5416 :
5417 : // Following line removed 1/27/03 by FCW. Was in original code that didn't do beam solar transmitted through
5418 : // interior windows. Was removed to allow such beam solar but then somehow was put back in.
5419 : // IF (Surface(BackSurfaceNumber)%BaseSurf /= BackSurfaceNumber) CYCLE ! Not for subsurfaces of Back Surface
5420 :
5421 17679 : if (!state.dataSolarShading->penumbra) {
5422 17490 : CHKBKS(state, BackSurfaceNumber, GRSNR); // CHECK FOR CONVEX ZONE; severe error if not
5423 : }
5424 17679 : ++NBKS;
5425 17679 : if (NBKS > state.dataSolarShading->MaxBKS) {
5426 0 : BKS.redimension(state.dataSolarShading->MaxBKS *= 2, 0);
5427 : }
5428 17679 : BKS(NBKS) = BackSurfaceNumber;
5429 :
5430 : } // ...end of surfaces DO loop (BackSurfaceNumber)
5431 : }
5432 :
5433 : // Put this into the ShadowComb data structure
5434 12168 : state.dataShadowComb->ShadowComb(GRSNR).UseThisSurf = true;
5435 12168 : state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf = NGSS;
5436 12168 : state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf = NBKS;
5437 12168 : state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf = NSBS;
5438 12168 : state.dataSolarShading->MaxDim = max(state.dataSolarShading->MaxDim, NGSS, NBKS, NSBS);
5439 :
5440 12168 : state.dataShadowComb->ShadowComb(GRSNR).GenSurf.allocate({0, state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf});
5441 12168 : state.dataShadowComb->ShadowComb(GRSNR).GenSurf(0) = 0;
5442 12168 : if (state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf > 0) {
5443 3703 : state.dataShadowComb->ShadowComb(GRSNR).GenSurf({1, state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf}) = GSS({1, NGSS});
5444 : }
5445 :
5446 12168 : state.dataShadowComb->ShadowComb(GRSNR).BackSurf.allocate({0, state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf});
5447 12168 : state.dataShadowComb->ShadowComb(GRSNR).BackSurf(0) = 0;
5448 12168 : if (state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf > 0) {
5449 2280 : state.dataShadowComb->ShadowComb(GRSNR).BackSurf({1, state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf}) = BKS({1, NBKS});
5450 : }
5451 :
5452 12168 : state.dataShadowComb->ShadowComb(GRSNR).SubSurf.allocate({0, state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf});
5453 12168 : state.dataShadowComb->ShadowComb(GRSNR).SubSurf(0) = 0;
5454 12168 : if (state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf > 0) {
5455 4031 : state.dataShadowComb->ShadowComb(GRSNR).SubSurf({1, state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf}) = SBS({1, NSBS});
5456 : }
5457 :
5458 : } // ...end of surfaces (GRSNR) DO loop
5459 :
5460 771 : GSS.deallocate();
5461 771 : SBS.deallocate();
5462 771 : BKS.deallocate();
5463 :
5464 771 : if (!state.dataSolarShading->penumbra) {
5465 770 : if (state.dataSolarShading->shd_stream) {
5466 770 : *state.dataSolarShading->shd_stream << "Shadowing Combinations\n";
5467 770 : if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
5468 102 : *state.dataSolarShading->shd_stream
5469 102 : << "..Solar Distribution=Minimal Shadowing, Detached Shading will not be used in shadowing calculations\n";
5470 668 : } else if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullExterior) {
5471 229 : if (state.dataSurface->CalcSolRefl) {
5472 3 : *state.dataSolarShading->shd_stream << "..Solar Distribution=FullExteriorWithReflectionsFromExteriorSurfaces\n";
5473 : } else {
5474 226 : *state.dataSolarShading->shd_stream << "..Solar Distribution=FullExterior\n";
5475 : }
5476 439 : } else if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) {
5477 439 : if (state.dataSurface->CalcSolRefl) {
5478 6 : *state.dataSolarShading->shd_stream << "..Solar Distribution=FullInteriorAndExteriorWithReflectionsFromExteriorSurfaces\n";
5479 : } else {
5480 433 : *state.dataSolarShading->shd_stream << "..Solar Distribution=FullInteriorAndExterior\n";
5481 : }
5482 : } else {
5483 : }
5484 :
5485 770 : *state.dataSolarShading->shd_stream << "..In the following, only the first 10 reference surfaces will be shown.\n";
5486 770 : *state.dataSolarShading->shd_stream << "..But all surfaces are used in the calculations.\n";
5487 :
5488 44419 : for (int HTSnum : state.dataSurface->AllSurfaceListReportOrder) {
5489 43649 : *state.dataSolarShading->shd_stream << "==================================\n";
5490 43649 : if (state.dataShadowComb->ShadowComb(HTSnum).UseThisSurf) {
5491 12100 : if (state.dataSurface->Surface(HTSnum).IsConvex) {
5492 24138 : *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(HTSnum).Name
5493 24138 : << " is used as Receiving Surface in calculations and is convex.\n";
5494 : } else {
5495 62 : *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(HTSnum).Name
5496 62 : << " is used as Receiving Surface in calculations and is non-convex.\n";
5497 31 : if (state.dataShadowComb->ShadowComb(HTSnum).NumGenSurf > 0) {
5498 0 : if (state.dataGlobal->DisplayExtraWarnings) {
5499 0 : ShowWarningError(state,
5500 0 : "DetermineShadowingCombinations: Surface=\"" + state.dataSurface->Surface(HTSnum).Name +
5501 : "\" is a receiving surface and is non-convex.");
5502 0 : ShowContinueError(state,
5503 : "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
5504 : } else {
5505 0 : ++state.dataErrTracking->TotalReceivingNonConvexSurfaces;
5506 : }
5507 : }
5508 : }
5509 : } else {
5510 63098 : *state.dataSolarShading->shd_stream << "Surface=" << state.dataSurface->Surface(HTSnum).Name
5511 63098 : << " is not used as Receiving Surface in calculations.\n";
5512 : }
5513 43649 : *state.dataSolarShading->shd_stream << "Number of general casting surfaces=" << state.dataShadowComb->ShadowComb(HTSnum).NumGenSurf
5514 43649 : << '\n';
5515 68009 : for (NGSS = 1; NGSS <= state.dataShadowComb->ShadowComb(HTSnum).NumGenSurf; ++NGSS) {
5516 24360 : if (NGSS <= 10)
5517 14735 : *state.dataSolarShading->shd_stream
5518 14735 : << "..Surface=" << state.dataSurface->Surface(state.dataShadowComb->ShadowComb(HTSnum).GenSurf(NGSS)).Name << '\n';
5519 24360 : CastingSurface(state.dataShadowComb->ShadowComb(HTSnum).GenSurf(NGSS)) = true;
5520 : }
5521 43649 : *state.dataSolarShading->shd_stream << "Number of back surfaces=" << state.dataShadowComb->ShadowComb(HTSnum).NumBackSurf << '\n';
5522 57968 : for (NGSS = 1; NGSS <= min(10, state.dataShadowComb->ShadowComb(HTSnum).NumBackSurf); ++NGSS) {
5523 14319 : *state.dataSolarShading->shd_stream
5524 14319 : << "...Surface=" << state.dataSurface->Surface(state.dataShadowComb->ShadowComb(HTSnum).BackSurf(NGSS)).Name << '\n';
5525 : }
5526 43649 : *state.dataSolarShading->shd_stream << "Number of receiving sub surfaces=" << state.dataShadowComb->ShadowComb(HTSnum).NumSubSurf
5527 43649 : << '\n';
5528 49700 : for (NGSS = 1; NGSS <= min(10, state.dataShadowComb->ShadowComb(HTSnum).NumSubSurf); ++NGSS) {
5529 6051 : *state.dataSolarShading->shd_stream
5530 6051 : << "....Surface=" << state.dataSurface->Surface(state.dataShadowComb->ShadowComb(HTSnum).SubSurf(NGSS)).Name << '\n';
5531 : }
5532 : }
5533 : }
5534 :
5535 44419 : for (HTS = 1; HTS <= state.dataSurface->TotSurfaces; ++HTS) {
5536 43649 : if (CastingSurface(HTS) && !state.dataSurface->Surface(HTS).IsConvex) {
5537 0 : if (state.dataGlobal->DisplayExtraWarnings) {
5538 0 : ShowSevereError(state,
5539 0 : "DetermineShadowingCombinations: Surface=\"" + state.dataSurface->Surface(HTS).Name +
5540 : "\" is a casting surface and is non-convex.");
5541 0 : ShowContinueError(state, "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
5542 : } else {
5543 0 : ++state.dataErrTracking->TotalCastingNonConvexSurfaces;
5544 : }
5545 : }
5546 : }
5547 :
5548 770 : if (state.dataErrTracking->TotalReceivingNonConvexSurfaces > 0) {
5549 0 : ShowWarningMessage(state,
5550 0 : format("DetermineShadowingCombinations: There are {} surfaces which are receiving surfaces and are non-convex.",
5551 0 : state.dataErrTracking->TotalReceivingNonConvexSurfaces));
5552 0 : ShowContinueError(state, "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
5553 0 : ShowContinueError(state, "...Add Output:Diagnostics,DisplayExtraWarnings; to see individual warnings for each surface.");
5554 0 : state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalReceivingNonConvexSurfaces;
5555 : }
5556 :
5557 770 : if (state.dataErrTracking->TotalCastingNonConvexSurfaces > 0) {
5558 0 : ShowSevereMessage(state,
5559 0 : format("DetermineShadowingCombinations: There are {} surfaces which are casting surfaces and are non-convex.",
5560 0 : state.dataErrTracking->TotalCastingNonConvexSurfaces));
5561 0 : ShowContinueError(state, "...Shadowing values may be inaccurate. Check .shd report file for more surface shading details");
5562 0 : ShowContinueError(state, "...Add Output:Diagnostics,DisplayExtraWarnings; to see individual severes for each surface.");
5563 0 : state.dataErrTracking->TotalSevereErrors += state.dataErrTracking->TotalCastingNonConvexSurfaces;
5564 : }
5565 : }
5566 :
5567 771 : CastingSurface.deallocate();
5568 :
5569 : #ifndef EP_NO_OPENGL
5570 771 : if (state.dataSolarShading->penumbra && state.dataSolarShading->penumbra->getNumSurfaces() > 0) {
5571 1 : state.dataSolarShading->penumbra->setModel();
5572 : }
5573 : #endif
5574 : }
5575 :
5576 284427 : void SHADOW(EnergyPlusData &state,
5577 : int const iHour, // Hour index
5578 : int const TS // Time Step
5579 : )
5580 : {
5581 :
5582 : // SUBROUTINE INFORMATION:
5583 : // AUTHOR Legacy Code
5584 : // DATE WRITTEN
5585 : // MODIFIED Nov 2003, FCW: modify to do shadowing on shadowing surfaces
5586 : // RE-ENGINEERED Lawrie, Oct 2000
5587 :
5588 : // PURPOSE OF THIS SUBROUTINE:
5589 : // This subroutine is a driving routine for calculations of shadows
5590 : // and sunlit areas used in computing the solar beam flux multipliers.
5591 :
5592 : // REFERENCES:
5593 : // BLAST/IBLAST code, original author George Walton
5594 :
5595 : Real64 XS; // Intermediate result
5596 : Real64 YS; // Intermediate result
5597 : Real64 ZS; // Intermediate result
5598 : int N; // Vertex number
5599 : int NGRS; // Coordinate transformation index
5600 : int NVT;
5601 : int HTS; // Heat transfer surface number of the general receiving surface
5602 : int GRSNR; // Surface number of general receiving surface
5603 : int NBKS; // Number of back surfaces
5604 : int NGSS; // Number of general shadowing surfaces
5605 : int NSBS; // Number of subsurfaces (windows and doors)
5606 : Real64 SurfArea; // Surface area. For walls, includes all window frame areas.
5607 : // For windows, includes divider area
5608 :
5609 284427 : if (state.dataSolarShading->ShadowOneTimeFlag) {
5610 771 : state.dataSolarShading->XVrt.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
5611 771 : state.dataSolarShading->YVrt.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
5612 771 : state.dataSolarShading->ZVrt.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
5613 771 : state.dataSolarShading->XVrt = 0.0;
5614 771 : state.dataSolarShading->YVrt = 0.0;
5615 771 : state.dataSolarShading->ZVrt = 0.0;
5616 771 : state.dataSolarShading->ShadowOneTimeFlag = false;
5617 : }
5618 :
5619 : #ifdef EP_Count_Calls
5620 : if (iHour == 0) {
5621 : ++state.dataTimingsData->NumShadow_Calls;
5622 : } else {
5623 : ++state.dataTimingsData->NumShadowAtTS_Calls;
5624 : }
5625 : #endif
5626 :
5627 284427 : state.dataSolarShading->SurfSunlitArea = 0.0;
5628 :
5629 : #ifndef EP_NO_OPENGL
5630 284427 : if (state.dataSolarShading->penumbra) {
5631 239 : Real64 ElevSun = DataGlobalConstants::PiOvr2 - std::acos(state.dataSolarShading->SUNCOS(3));
5632 239 : Real64 AzimSun = std::atan2(state.dataSolarShading->SUNCOS(1), state.dataSolarShading->SUNCOS(2));
5633 239 : state.dataSolarShading->penumbra->setSunPosition(AzimSun, ElevSun);
5634 239 : state.dataSolarShading->penumbra->submitPSSA();
5635 : }
5636 : #endif
5637 :
5638 17630832 : for (GRSNR = 1; GRSNR <= state.dataSurface->TotSurfaces; ++GRSNR) {
5639 :
5640 17346405 : if (!state.dataShadowComb->ShadowComb(GRSNR).UseThisSurf) continue;
5641 :
5642 4531243 : state.dataSolarShading->SurfSunlitArea(GRSNR) = 0.0;
5643 :
5644 4531243 : NGSS = state.dataShadowComb->ShadowComb(GRSNR).NumGenSurf;
5645 4531243 : state.dataSolarShading->NGSSHC = 0;
5646 4531243 : NBKS = state.dataShadowComb->ShadowComb(GRSNR).NumBackSurf;
5647 4531243 : state.dataSolarShading->NBKSHC = 0;
5648 4531243 : NSBS = state.dataShadowComb->ShadowComb(GRSNR).NumSubSurf;
5649 4531243 : state.dataSolarShading->NRVLHC = 0;
5650 4531243 : state.dataSolarShading->NSBSHC = 0;
5651 4531243 : state.dataSolarShading->LOCHCA = 1;
5652 : // Temporarily determine the old heat transfer surface number (HTS)
5653 4531243 : HTS = GRSNR;
5654 :
5655 4531243 : if (state.dataSolarShading->SurfSunCosTheta(GRSNR) < DataEnvironment::SunIsUpValue) { //.001) THEN ! Receiving surface is not in the sun
5656 :
5657 1907122 : state.dataSolarShading->SurfSunlitArea(HTS) = 0.0;
5658 1907122 : SHDSBS(state, iHour, GRSNR, NBKS, NSBS, HTS, TS);
5659 :
5660 2624121 : } else if ((NGSS <= 0) && (NSBS <= 0)) { // Simple surface--no shaders or subsurfaces
5661 :
5662 1310781 : state.dataSolarShading->SurfSunlitArea(HTS) = state.dataSurface->Surface(GRSNR).NetAreaShadowCalc;
5663 : } else { // Surface in sun and either shading surfaces or subsurfaces present (or both)
5664 :
5665 : #ifndef EP_NO_OPENGL
5666 1313340 : auto id = state.dataSurface->SurfPenumbraID(HTS);
5667 1313340 : if (state.dataSolarShading->penumbra && id >= 0) {
5668 : // SurfSunlitArea(HTS) = buildingPSSF.at(id) / SurfSunCosTheta(HTS);
5669 5410 : state.dataSolarShading->SurfSunlitArea(HTS) =
5670 5410 : state.dataSolarShading->penumbra->fetchPSSA(id) / state.dataSolarShading->SurfSunCosTheta(HTS);
5671 : // SurfSunlitArea(HTS) = penumbra->fetchPSSA(Surface(HTS).PenumbraID)/SurfSunCosTheta(HTS);
5672 7987 : for (int SS = 1; SS <= NSBS; ++SS) {
5673 2577 : auto HTSS = state.dataShadowComb->ShadowComb(HTS).SubSurf(SS);
5674 2577 : id = state.dataSurface->SurfPenumbraID(HTSS);
5675 2577 : if (id >= 0) {
5676 : // SurfSunlitArea(HTSS) = buildingPSSF.at(id) / SurfSunCosTheta(HTSS);
5677 2577 : state.dataSolarShading->SurfSunlitArea(HTSS) =
5678 2577 : state.dataSolarShading->penumbra->fetchPSSA(id) / state.dataSolarShading->SurfSunCosTheta(HTSS);
5679 : // SurfSunlitArea(HTSS) = penumbra->fetchPSSA(Surface(HTSS).PenumbraID)/SurfSunCosTheta(HTSS);
5680 2577 : if (state.dataSolarShading->SurfSunlitArea(HTSS) > 0.0) {
5681 2329 : if (iHour > 0 && TS > 0)
5682 1059 : state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) =
5683 1059 : state.dataSolarShading->SurfSunlitArea(HTSS) / state.dataSurface->Surface(HTSS).Area;
5684 : }
5685 : }
5686 : }
5687 1307930 : } else if (!state.dataSolarShading->penumbra) {
5688 : #else
5689 : {
5690 : #endif
5691 1305779 : NGRS = state.dataSurface->Surface(GRSNR).BaseSurf;
5692 1305779 : if (state.dataSurface->Surface(GRSNR).IsShadowing) NGRS = GRSNR;
5693 :
5694 : // Compute the X and Y displacements of a shadow.
5695 3917337 : XS = state.dataSurface->Surface(NGRS).lcsx.x * state.dataSolarShading->SUNCOS(1) +
5696 1305779 : state.dataSurface->Surface(NGRS).lcsx.y * state.dataSolarShading->SUNCOS(2) +
5697 1305779 : state.dataSurface->Surface(NGRS).lcsx.z * state.dataSolarShading->SUNCOS(3);
5698 3917337 : YS = state.dataSurface->Surface(NGRS).lcsy.x * state.dataSolarShading->SUNCOS(1) +
5699 1305779 : state.dataSurface->Surface(NGRS).lcsy.y * state.dataSolarShading->SUNCOS(2) +
5700 1305779 : state.dataSurface->Surface(NGRS).lcsy.z * state.dataSolarShading->SUNCOS(3);
5701 3917337 : ZS = state.dataSurface->Surface(NGRS).lcsz.x * state.dataSolarShading->SUNCOS(1) +
5702 1305779 : state.dataSurface->Surface(NGRS).lcsz.y * state.dataSolarShading->SUNCOS(2) +
5703 1305779 : state.dataSurface->Surface(NGRS).lcsz.z * state.dataSolarShading->SUNCOS(3);
5704 :
5705 1305779 : if (std::abs(ZS) > 1.e-4) {
5706 1305776 : state.dataSolarShading->XShadowProjection = XS / ZS;
5707 1305776 : state.dataSolarShading->YShadowProjection = YS / ZS;
5708 1305776 : if (std::abs(state.dataSolarShading->XShadowProjection) < 1.e-8) state.dataSolarShading->XShadowProjection = 0.0;
5709 1305776 : if (std::abs(state.dataSolarShading->YShadowProjection) < 1.e-8) state.dataSolarShading->YShadowProjection = 0.0;
5710 : } else {
5711 3 : state.dataSolarShading->XShadowProjection = 0.0;
5712 3 : state.dataSolarShading->YShadowProjection = 0.0;
5713 : }
5714 :
5715 3917337 : CTRANS(state,
5716 : GRSNR,
5717 : NGRS,
5718 : NVT,
5719 1305779 : state.dataSolarShading->XVrt,
5720 1305779 : state.dataSolarShading->YVrt,
5721 1305779 : state.dataSolarShading->ZVrt); // Transform coordinates of the receiving surface to 2-D form
5722 :
5723 : // Re-order its vertices to clockwise sequential.
5724 6520609 : for (N = 1; N <= NVT; ++N) {
5725 5214830 : state.dataSolarShading->XVS(N) = state.dataSolarShading->XVrt(NVT + 1 - N);
5726 5214830 : state.dataSolarShading->YVS(N) = state.dataSolarShading->YVrt(NVT + 1 - N);
5727 : }
5728 :
5729 1305779 : HTRANS1(state, 1, NVT); // Transform to homogeneous coordinates.
5730 :
5731 1305779 : state.dataSolarShading->HCAREA(1) = -state.dataSolarShading->HCAREA(1); // Compute (+) gross surface area.
5732 1305779 : state.dataSolarShading->HCT(1) = 1.0;
5733 :
5734 1305779 : SHDGSS(state, NGRS, iHour, TS, GRSNR, NGSS, HTS); // Determine shadowing on surface.
5735 :
5736 1305779 : if (!state.dataSolarShading->CalcSkyDifShading) {
5737 833552 : SHDBKS(state, state.dataSurface->Surface(GRSNR).BaseSurf, GRSNR, NBKS, HTS); // Determine possible back surfaces.
5738 : }
5739 : }
5740 :
5741 1313340 : SHDSBS(state, iHour, GRSNR, NBKS, NSBS, HTS, TS); // Subtract subsurf areas from total
5742 :
5743 : // Error checking: require that 0 <= SurfSunlitArea <= AREA. + or - .01*AREA added for round-off errors
5744 1313340 : SurfArea = state.dataSurface->Surface(GRSNR).NetAreaShadowCalc;
5745 1313340 : state.dataSolarShading->SurfSunlitArea(HTS) = max(0.0, state.dataSolarShading->SurfSunlitArea(HTS));
5746 :
5747 1313340 : state.dataSolarShading->SurfSunlitArea(HTS) = min(state.dataSolarShading->SurfSunlitArea(HTS), SurfArea);
5748 : } // ...end of surface in sun/surface with shaders and/or subsurfaces IF-THEN block
5749 :
5750 : // NOTE:
5751 : // There used to be a call to legacy subroutine SHDCVR here when the
5752 : // zone type was not a standard zone.
5753 : }
5754 284427 : }
5755 :
5756 833552 : void SHDBKS(EnergyPlusData &state,
5757 : int const NGRS, // Number of the general receiving surface
5758 : int const CurSurf,
5759 : int const NBKS, // Number of back surfaces
5760 : int const HTS // Heat transfer surface number of the general receiving surf
5761 : )
5762 : {
5763 :
5764 : // SUBROUTINE INFORMATION:
5765 : // AUTHOR Legacy Code
5766 : // DATE WRITTEN
5767 : // MODIFIED na
5768 : // RE-ENGINEERED Lawrie, Oct 2000
5769 :
5770 : // PURPOSE OF THIS SUBROUTINE:
5771 : // This is the driving subroutine for computing
5772 : // the sunlit areas for back surfaces.
5773 :
5774 : // REFERENCES:
5775 : // BLAST/IBLAST code, original author George Walton
5776 :
5777 : typedef Array2D<Int64>::size_type size_type;
5778 : int I;
5779 : int M;
5780 : int N;
5781 : int NVR;
5782 : int NVT; // Number of vertices of back surface
5783 : int BackSurfaceNumber;
5784 : int NS1; // Number of the figure being overlapped
5785 : int NS2; // Number of the figure doing overlapping
5786 : int NS3; // Location to place results of overlap
5787 :
5788 : // Tuned Linear indexing
5789 :
5790 833552 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
5791 833552 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
5792 :
5793 833552 : if (state.dataSolarShading->SHDBKSOneTimeFlag) {
5794 681 : state.dataSolarShading->XVrtx.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
5795 681 : state.dataSolarShading->YVrtx.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
5796 681 : state.dataSolarShading->ZVrtx.allocate(state.dataSurface->MaxVerticesPerSurface + 1);
5797 681 : state.dataSolarShading->XVrtx = 0.0;
5798 681 : state.dataSolarShading->YVrtx = 0.0;
5799 681 : state.dataSolarShading->ZVrtx = 0.0;
5800 681 : state.dataSolarShading->SHDBKSOneTimeFlag = false;
5801 : }
5802 :
5803 1188084 : if ((NBKS <= 0) || (state.dataSolarShading->SurfSunlitArea(HTS) <= 0.0) || (state.dataSolarShading->OverlapStatus == TooManyVertices) ||
5804 354532 : (state.dataSolarShading->OverlapStatus == TooManyFigures))
5805 479020 : return;
5806 :
5807 354532 : state.dataSolarShading->FBKSHC = state.dataSolarShading->LOCHCA + 1;
5808 :
5809 2805491 : for (I = 1; I <= NBKS; ++I) { // Loop through all back surfaces associated with the receiving surface
5810 :
5811 2450959 : BackSurfaceNumber = state.dataShadowComb->ShadowComb(CurSurf).BackSurf(I);
5812 :
5813 2450959 : if (state.dataSolarShading->SurfSunCosTheta(BackSurfaceNumber) > -DataEnvironment::SunIsUpValue)
5814 996296 : continue; //-0.001) CYCLE ! go to next back surface since inside of this surface
5815 : // cannot be in sun if the outside can be
5816 :
5817 : // Transform coordinates of back surface from general system to the
5818 : // plane of the receiving surface
5819 :
5820 1454663 : CTRANS(state, BackSurfaceNumber, NGRS, NVT, state.dataSolarShading->XVrtx, state.dataSolarShading->YVrtx, state.dataSolarShading->ZVrtx);
5821 :
5822 : // Project "shadow" from back surface along sun's rays to receiving surface. Back surface vertices
5823 : // become clockwise sequential.
5824 :
5825 7301355 : for (N = 1; N <= NVT; ++N) {
5826 5846692 : state.dataSolarShading->XVS(N) =
5827 5846692 : state.dataSolarShading->XVrtx(N) - state.dataSolarShading->XShadowProjection * state.dataSolarShading->ZVrtx(N);
5828 5846692 : state.dataSolarShading->YVS(N) =
5829 5846692 : state.dataSolarShading->YVrtx(N) - state.dataSolarShading->YShadowProjection * state.dataSolarShading->ZVrtx(N);
5830 : }
5831 :
5832 : // Transform to the homogeneous coordinate system.
5833 :
5834 1454663 : NS3 = state.dataSolarShading->LOCHCA + 1;
5835 1454663 : state.dataSolarShading->HCT(NS3) = 0.0;
5836 1454663 : HTRANS1(state, NS3, NVT);
5837 :
5838 : // Adjust near-duplicate points.
5839 :
5840 1454663 : NVR = state.dataSolarShading->HCNV(1);
5841 1454663 : auto l3(state.dataSolarShading->HCX.index(NS3, 1));
5842 7301355 : for (N = 1; N <= NVT; ++N, ++l3) {
5843 5846692 : auto const x3(state.dataSolarShading->HCX[l3]); // [ l3 ] == ( NS3, N )
5844 5846692 : auto const y3(state.dataSolarShading->HCY[l3]);
5845 5846692 : size_type l1(0);
5846 25457248 : for (M = 1; M <= NVR; ++M, ++l1) {
5847 21127914 : if (std::abs(state.dataSolarShading->HCX[l1] - x3) > 6) continue; // [ l1 ] == ( 1, M )
5848 2475414 : if (std::abs(state.dataSolarShading->HCY[l1] - y3) > 6) continue;
5849 1517358 : state.dataSolarShading->HCX[l3] = state.dataSolarShading->HCX[l1];
5850 1517358 : state.dataSolarShading->HCY[l3] = state.dataSolarShading->HCY[l1];
5851 1517358 : break;
5852 : }
5853 : }
5854 :
5855 1454663 : HTRANS0(state, NS3, NVT);
5856 :
5857 : // Determine area of overlap of projected back surface and receiving surface.
5858 :
5859 1454663 : NS1 = 1;
5860 1454663 : NS2 = NS3;
5861 1454663 : state.dataSolarShading->HCT(NS3) = 1.0;
5862 1454663 : DeterminePolygonOverlap(state, NS1, NS2, NS3);
5863 :
5864 1454663 : if (state.dataSolarShading->OverlapStatus == NoOverlap) continue; // to next back surface
5865 947937 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
5866 0 : break; // back surfaces DO loop
5867 :
5868 : // Increment back surface count.
5869 :
5870 947937 : state.dataSolarShading->LOCHCA = NS3;
5871 947937 : state.dataSolarShading->HCNS(state.dataSolarShading->LOCHCA) = BackSurfaceNumber;
5872 947937 : state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA) = -state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
5873 947937 : state.dataSolarShading->NBKSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FBKSHC + 1;
5874 : }
5875 : }
5876 :
5877 1305779 : void SHDGSS(EnergyPlusData &state,
5878 : int const NGRS,
5879 : int const iHour, // Hour Counter
5880 : int const TS, // TimeStep
5881 : int const CurSurf, // Current Surface
5882 : int const NGSS, // Number of general shadowing surfaces
5883 : int const HTS // Heat transfer surface number of the general receiving surf
5884 : )
5885 : {
5886 :
5887 : // SUBROUTINE INFORMATION:
5888 : // AUTHOR Legacy Code
5889 : // DATE WRITTEN
5890 : // MODIFIED na
5891 : // RE-ENGINEERED Lawrie, Oct 2000
5892 :
5893 : // PURPOSE OF THIS SUBROUTINE:
5894 : // This subroutine determines the shadows on a general receiving surface.
5895 :
5896 : // REFERENCES:
5897 : // BLAST/IBLAST code, original author George Walton
5898 :
5899 : // Using/Aliasing
5900 : using ScheduleManager::GetCurrentScheduleValue;
5901 : using ScheduleManager::GetScheduleMinValue;
5902 : using ScheduleManager::GetScheduleName;
5903 : using ScheduleManager::LookUpScheduleValue;
5904 :
5905 : typedef Array2D<Int64>::size_type size_type;
5906 : int GSSNR; // General shadowing surface number
5907 : int MainOverlapStatus; // Overlap status of the main overlap calculation not the check for
5908 : // multiple overlaps (unless there was an error)
5909 : int NS1; // Number of the figure being overlapped
5910 : int NS2; // Number of the figure doing overlapping
5911 : int NS3; // Location to place results of overlap
5912 : Real64 SchValue; // Value for Schedule of shading transmittence
5913 :
5914 1305779 : if (state.dataSolarShading->SHDGSSOneTimeFlag) {
5915 682 : state.dataSolarShading->XVert.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
5916 682 : state.dataSolarShading->YVert.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
5917 682 : state.dataSolarShading->ZVert.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
5918 682 : state.dataSolarShading->SHDGSSOneTimeFlag = false;
5919 : }
5920 :
5921 1305779 : state.dataSolarShading->FGSSHC = state.dataSolarShading->LOCHCA + 1;
5922 1305779 : MainOverlapStatus = NoOverlap; // Set to ensure that the value from the last surface is not saved
5923 1305779 : state.dataSolarShading->OverlapStatus = NoOverlap;
5924 :
5925 1305779 : if (NGSS <= 0) { // IF NO S.S., receiving surface FULLY SUNLIT.
5926 :
5927 613451 : state.dataSolarShading->SurfSunlitArea(HTS) = state.dataSolarShading->HCAREA(1); // Surface fully sunlit
5928 :
5929 : } else {
5930 :
5931 692328 : int ExitLoopStatus(-1);
5932 692328 : auto const &GenSurf(state.dataShadowComb->ShadowComb(CurSurf).GenSurf);
5933 692328 : auto const sunIsUp(DataEnvironment::SunIsUpValue);
5934 5652249 : for (int I = 1; I <= NGSS; ++I) { // Loop through all shadowing surfaces...
5935 :
5936 4975846 : GSSNR = GenSurf(I);
5937 :
5938 6761574 : if (state.dataSolarShading->SurfSunCosTheta(GSSNR) > sunIsUp) continue; //.001) CYCLE ! NO SHADOW IF GSS IN SUNLIGHT.
5939 :
5940 3228506 : auto const &surface(state.dataSurface->Surface(GSSNR));
5941 3228506 : bool const notHeatTransSurf(!surface.HeatTransSurf);
5942 :
5943 : // This used to check to see if the shadowing surface was not opaque (within the scheduled dates of
5944 : // transmittance value. Perhaps it ignored it if it were outside the range. (if so, was an error)
5945 : // The proper action seems to be delete this statement all together, but there would also be no shading if
5946 : // the shading surface were transparent...
5947 : //---former stmt IF ((.NOT.Surface(GSSNR)%HeatTransSurf) .AND. &
5948 : //---former stmt GetCurrentScheduleValue(state, Surface(GSSNR)%SchedShadowSurfIndex,IHOUR) == 0.0) CYCLE
5949 :
5950 3228506 : if (notHeatTransSurf) {
5951 1288260 : if (surface.IsTransparent) continue; // No shadow if shading surface is transparent
5952 1288260 : if (surface.SchedShadowSurfIndex > 0) {
5953 1000951 : if (LookUpScheduleValue(state, surface.SchedShadowSurfIndex, iHour) == 1.0) continue;
5954 1000951 : if (!state.dataSolarShading->CalcSkyDifShading) {
5955 531787 : if (LookUpScheduleValue(state, surface.SchedShadowSurfIndex, iHour, TS) == 1.0) continue;
5956 : }
5957 : }
5958 : }
5959 : // Elimate shawdowing surfaces that is supposed to be disabled.
5960 3228506 : if (state.dataSysVars->DisableAllSelfShading) {
5961 61671 : if (surface.Zone != 0) {
5962 32098 : continue; // Disable all shadowing surfaces in all zones. Attached shading surfaces are not part of a zone, zone value is 0.
5963 : }
5964 3166835 : } else if (state.dataSysVars->DisableGroupSelfShading) {
5965 113920 : std::vector<int> DisabledZones = state.dataSurface->SurfShadowDisabledZoneList(CurSurf);
5966 60105 : bool isDisabledShadowSurf = false;
5967 165705 : for (int i : DisabledZones) {
5968 111890 : if (surface.Zone == i) {
5969 6290 : isDisabledShadowSurf = true;
5970 6290 : break;
5971 : }
5972 : }
5973 60105 : if (isDisabledShadowSurf) continue; // Disable all shadowing surfaces in all disabled zones.
5974 : }
5975 :
5976 : // IF ((.NOT.Surface(GSSNR)%HeatTransSurf) .AND. &
5977 : // GetCurrentScheduleValue(state, Surface(GSSNR)%SchedShadowSurfIndex) == 1.0) CYCLE
5978 :
5979 : // Transform shadow casting surface from cartesian to homogeneous coordinates according to surface type.
5980 :
5981 3190118 : if ((notHeatTransSurf) && (surface.BaseSurf != 0)) {
5982 :
5983 : // For shadowing subsurface coordinates of shadow casting surface are relative to the receiving surface
5984 : // project shadow to the receiving surface
5985 :
5986 0 : state.dataSolarShading->NVS = surface.Sides;
5987 0 : auto const &XV(state.dataSurface->ShadeV(GSSNR).XV);
5988 0 : auto const &YV(state.dataSurface->ShadeV(GSSNR).YV);
5989 0 : auto const &ZV(state.dataSurface->ShadeV(GSSNR).ZV);
5990 0 : for (int N = 1; N <= state.dataSolarShading->NVS; ++N) {
5991 0 : state.dataSolarShading->XVS(N) = XV(N) - state.dataSolarShading->XShadowProjection * ZV(N);
5992 0 : state.dataSolarShading->YVS(N) = YV(N) - state.dataSolarShading->YShadowProjection * ZV(N);
5993 0 : }
5994 :
5995 : } else {
5996 : // Transform coordinates of shadow casting surface from general system to the system relative to the receiving surface
5997 : int NVT;
5998 3190118 : CTRANS(state, GSSNR, NGRS, NVT, state.dataSolarShading->XVert, state.dataSolarShading->YVert, state.dataSolarShading->ZVert);
5999 9570354 : CLIP(state,
6000 : NVT,
6001 3190118 : state.dataSolarShading->XVert,
6002 3190118 : state.dataSolarShading->YVert,
6003 3190118 : state.dataSolarShading->ZVert); // Clip portions of the shadow casting surface which are behind the receiving surface
6004 :
6005 3190118 : if (state.dataSolarShading->NumVertInShadowOrClippedSurface <= 2) continue;
6006 :
6007 : // Project shadow from shadow casting surface along sun's rays to receiving surface Shadow vertices
6008 : // become clockwise sequential
6009 :
6010 15862432 : for (int N = 1; N <= state.dataSolarShading->NumVertInShadowOrClippedSurface; ++N) {
6011 12672314 : state.dataSolarShading->XVS(N) =
6012 12672314 : state.dataSolarShading->XVC(N) - state.dataSolarShading->XShadowProjection * state.dataSolarShading->ZVC(N);
6013 12672314 : state.dataSolarShading->YVS(N) =
6014 12672314 : state.dataSolarShading->YVC(N) - state.dataSolarShading->YShadowProjection * state.dataSolarShading->ZVC(N);
6015 : }
6016 : }
6017 :
6018 : // Transform to the homogeneous coordinate system.
6019 :
6020 3190118 : NS3 = state.dataSolarShading->LOCHCA + 1;
6021 3190118 : HTRANS1(state, NS3, state.dataSolarShading->NVS);
6022 :
6023 : // Adjust near-duplicate points.
6024 :
6025 3190118 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
6026 3190118 : assert(state.dataSolarShading->HCX.index(1, 1) == 0u);
6027 3190118 : size_type j(state.dataSolarShading->HCX.index(NS3, 1));
6028 3190118 : size_type NVR(state.dataSolarShading->HCNV(1));
6029 15862432 : for (int N = 1; N <= state.dataSolarShading->NumVertInShadowOrClippedSurface;
6030 : ++N, ++j) { // Tuned Logic change: break after 1st "close" point found
6031 12672314 : auto const HCX_N(state.dataSolarShading->HCX[j]); // [ j ] == ( NS3, N )
6032 12672314 : auto const HCY_N(state.dataSolarShading->HCY[j]);
6033 62460841 : for (size_type l = 0; l < NVR; ++l) { // [ l ] == ( 1, l+1 )
6034 50077796 : auto const delX(std::abs(state.dataSolarShading->HCX[l] - HCX_N));
6035 50077796 : if (delX > 6) continue;
6036 937672 : auto const delY(std::abs(state.dataSolarShading->HCY[l] - HCY_N));
6037 937672 : if (delY > 6) continue;
6038 289269 : if (delX > 0) state.dataSolarShading->HCX[j] = state.dataSolarShading->HCX[l]; // [ j ] == ( NS3, N )
6039 289269 : if (delY > 0) state.dataSolarShading->HCY[j] = state.dataSolarShading->HCY[l];
6040 289269 : break;
6041 : }
6042 : }
6043 3190118 : HTRANS0(state, NS3, state.dataSolarShading->NumVertInShadowOrClippedSurface);
6044 3190118 : if (!state.dataSolarShading->CalcSkyDifShading) {
6045 1873434 : if (iHour != 0) {
6046 1873434 : SchValue = LookUpScheduleValue(state, surface.SchedShadowSurfIndex, iHour, TS);
6047 : } else {
6048 0 : SchValue = surface.SchedMinValue;
6049 : }
6050 : } else {
6051 1316684 : SchValue = surface.SchedMinValue;
6052 : }
6053 :
6054 3190118 : state.dataSolarShading->HCT(NS3) = SchValue;
6055 :
6056 : // Determine overlap of shadow with receiving surface
6057 :
6058 3190118 : state.dataSolarShading->CurrentShadowingSurface = I;
6059 3190118 : state.dataSolarShading->CurrentSurfaceBeingShadowed = GSSNR;
6060 3190118 : NS1 = 1;
6061 3190118 : NS2 = NS3;
6062 3190118 : DeterminePolygonOverlap(state, NS1, NS2, NS3);
6063 : // Next statement is special to deal with transmitting shading devices
6064 3190118 : if (state.dataSolarShading->OverlapStatus == FirstSurfWithinSecond && SchValue > 0.0)
6065 328 : state.dataSolarShading->OverlapStatus = PartialOverlap;
6066 3190118 : MainOverlapStatus = state.dataSolarShading->OverlapStatus;
6067 3190118 : ExitLoopStatus = MainOverlapStatus;
6068 :
6069 3190118 : if (MainOverlapStatus == NoOverlap) { // No overlap of general surface shadow and receiving surface
6070 : // Continue
6071 582941 : } else if ((MainOverlapStatus == FirstSurfWithinSecond) || (MainOverlapStatus == TooManyVertices) ||
6072 : (MainOverlapStatus == TooManyFigures)) {
6073 : goto ShadowingSurfaces_exit;
6074 567016 : } else if ((MainOverlapStatus == SecondSurfWithinFirst) || (MainOverlapStatus == PartialOverlap)) {
6075 : // Determine overlaps with previous shadows.
6076 567016 : state.dataSolarShading->LOCHCA = NS3;
6077 567016 : state.dataSolarShading->NGSSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FGSSHC + 1;
6078 567016 : if (state.dataSolarShading->NGSSHC > 1)
6079 680130 : MULTOL(state,
6080 226710 : state.dataSolarShading->LOCHCA,
6081 226710 : state.dataSolarShading->FGSSHC - 1,
6082 226710 : state.dataSolarShading->NGSSHC - 1); // HOYT - Remove this call
6083 : } else {
6084 : goto ShadowingSurfaces_exit;
6085 : }
6086 :
6087 3174193 : ExitLoopStatus = -1;
6088 : }
6089 676403 : ShadowingSurfaces_exit:;
6090 :
6091 : // Compute sunlit area of surface (excluding effects of subsurfs).
6092 :
6093 692328 : if (ExitLoopStatus == FirstSurfWithinSecond) { // Surface fully shaded
6094 15925 : state.dataSolarShading->SurfSunlitArea(HTS) = 0.0;
6095 15925 : state.dataSolarShading->LOCHCA = state.dataSolarShading->FGSSHC;
6096 :
6097 676403 : } else if ((ExitLoopStatus == TooManyVertices) || (ExitLoopStatus == TooManyFigures)) { // Array limits exceeded, estimate
6098 0 : state.dataSolarShading->SurfSunlitArea(HTS) = 0.25 * state.dataSolarShading->HCAREA(1);
6099 :
6100 : } else {
6101 :
6102 : // Compute the sunlit area here.
6103 : // Call UnionShadow(FGSSHC,LOCHCA)
6104 :
6105 676403 : state.dataSolarShading->NGSSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FGSSHC + 1;
6106 676403 : if (state.dataSolarShading->NGSSHC <= 0) {
6107 337199 : state.dataSolarShading->SurfSunlitArea(HTS) = state.dataSolarShading->HCAREA(1); // Surface fully sunlit
6108 : } else {
6109 339204 : Real64 A(state.dataSolarShading->HCAREA(1)); // Area
6110 985368 : for (int i = state.dataSolarShading->FGSSHC, e = state.dataSolarShading->FGSSHC + state.dataSolarShading->NGSSHC - 1; i <= e; ++i) {
6111 646164 : A += state.dataSolarShading->HCAREA(i) * (1.0 - state.dataSolarShading->HCT(i));
6112 : }
6113 339204 : state.dataSolarShading->SurfSunlitArea(HTS) = A;
6114 339204 : if (state.dataSolarShading->SurfSunlitArea(HTS) <= 0.0) { // Surface fully shaded
6115 8175 : state.dataSolarShading->SurfSunlitArea(HTS) = 0.0;
6116 8175 : state.dataSolarShading->LOCHCA = state.dataSolarShading->FGSSHC;
6117 : }
6118 : }
6119 : }
6120 : }
6121 1305779 : state.dataSolarShading->NGSSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FGSSHC + 1;
6122 1305779 : }
6123 :
6124 1534620 : void CalcInteriorSolarOverlaps(EnergyPlusData &state,
6125 : int const iHour, // Hour Index
6126 : int const NBKS, // Number of back surfaces associated with this GRSNR (in general, only
6127 : int const HTSS, // Surface number of the subsurface (exterior window)
6128 : int const GRSNR, // General receiving surface number (base surface of the exterior window)
6129 : int const TS // Time step Index
6130 : )
6131 : {
6132 :
6133 : // SUBROUTINE INFORMATION:
6134 : // AUTHOR Fred Winkelmann
6135 : // DATE WRITTEN January 1999
6136 : // MODIFIED Nov 2001, FW: include beam radiation overlaps with
6137 : // back windows and doors; previously these subsurfaces ignored.
6138 : // May 2002, FW: fix problem where reveal was not being considered
6139 : // in calculating overlap areas if window is shaded only by reveal.
6140 : // June 2002, FW: fix problem that gave incorrect calculation when
6141 : // window is not shaded only by reveal
6142 : // June 2002, FW: remove incorrect multiplication of overlap areas
6143 : // by sunlit fraction when window is shaded only by reveal
6144 :
6145 : // PURPOSE OF THIS SUBROUTINE:
6146 : // For an exterior window with surface number HTSS, determines (1) the surface numbers of back
6147 : // surfaces receiving beam radiation from the window and (2) for each such back surface, the area
6148 : // of the portion of the window sending beam radiation to the back surface; this is called the
6149 : // "overlap area."
6150 :
6151 : // REFERENCES:
6152 : // BLAST/IBLAST code, original author George Walton
6153 :
6154 : // SUBROUTINE ARGUMENT DEFINITIONS:
6155 : // some of these will receive beam radiation from HTSS this hour)
6156 :
6157 : // SUBROUTINE PARAMETER DEFINITIONS:
6158 1534620 : int constexpr WindowShadedOnlyByReveal(2); // for use with RevealStatus
6159 :
6160 : typedef Array2D<Int64>::size_type size_type;
6161 : int JBKS; // Counter of back surfaces with non-zero overlap with HTSS
6162 : int BackSurfNum; // Back surface number
6163 :
6164 : bool UseSimpleDistribution; // TRUE means simple interior solar distribution
6165 : // (all incoming beam assumed to strike floor),
6166 : // FALSE means exact interior solar distribution
6167 : // (track which back surfaces beam illuminates)
6168 :
6169 : // Tuned Linear indexing
6170 :
6171 1534620 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCY));
6172 1534620 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCA));
6173 1534620 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCB));
6174 1534620 : assert(equal_dimensions(state.dataSolarShading->HCX, state.dataSolarShading->HCC));
6175 :
6176 1534620 : if (state.dataSolarShading->SurfSunlitArea(HTSS) > 0.0) {
6177 :
6178 825857 : UseSimpleDistribution = false;
6179 :
6180 825857 : if ((NBKS <= 0) || (state.dataSurface->Surface(GRSNR).ExtBoundCond > 0)) {
6181 :
6182 248631 : UseSimpleDistribution = true;
6183 :
6184 : } else {
6185 : // Using 'exact' distribution, replace subsurface HC entries with reveal HC entries
6186 : // so that the reveal HC is used in calculating interior solar overlap areas
6187 :
6188 : // Adding the following line fixes a problem where, if the window was shaded only
6189 : // by reveal, then the reveal was not considered in calculating interior solar
6190 : // overlap areas (FCW 5/3/02).
6191 : // IF(Surface(HTSS)%Reveal > 0.0) NRVLHC = 1
6192 : // Changing the line to the following avoids incorrect calculation when window is not shaded
6193 : // only by reveal (FCW 6/28/02).
6194 577226 : if (state.dataSolarShading->SurfWinRevealStatus(iHour, TS, HTSS) == WindowShadedOnlyByReveal) state.dataSolarShading->NRVLHC = 1;
6195 577226 : if (state.dataSolarShading->NRVLHC > 0) {
6196 23630 : for (int I = 1; I <= state.dataSolarShading->NRVLHC; ++I) {
6197 15530 : int const iS(state.dataSolarShading->FSBSHC - 1 + I);
6198 15530 : int const iR(state.dataSolarShading->FRVLHC - 1 + I);
6199 15530 : state.dataSolarShading->HCT(iS) = state.dataSolarShading->HCT(iR);
6200 15530 : state.dataSolarShading->HCNV(iS) = state.dataSolarShading->HCNV(iR);
6201 15530 : state.dataSolarShading->HCAREA(iS) = state.dataSolarShading->HCAREA(iR);
6202 15530 : size_type lS(state.dataSolarShading->HCX.index(iS, 1));
6203 15530 : size_type lR(state.dataSolarShading->HCX.index(iR, 1));
6204 248480 : for (int J = 1; J <= state.dataSolarShading->MaxHCV; ++J, ++lS, ++lR) { // [ lS ] == ( iS, J ), [ lR ] == ( iR, J )
6205 232950 : state.dataSolarShading->HCX[lS] = state.dataSolarShading->HCX[lR];
6206 232950 : state.dataSolarShading->HCY[lS] = state.dataSolarShading->HCY[lR];
6207 232950 : state.dataSolarShading->HCA[lS] = state.dataSolarShading->HCA[lR];
6208 232950 : state.dataSolarShading->HCB[lS] = state.dataSolarShading->HCB[lR];
6209 232950 : state.dataSolarShading->HCC[lS] = state.dataSolarShading->HCC[lR];
6210 : }
6211 : }
6212 8100 : state.dataSolarShading->NSBSHC = state.dataSolarShading->NRVLHC;
6213 : }
6214 : }
6215 :
6216 : // Check for array space.
6217 825857 : if (state.dataSolarShading->FSBSHC + state.dataSolarShading->NBKSHC > state.dataSolarShading->MaxHCS) UseSimpleDistribution = true;
6218 :
6219 825857 : if (!UseSimpleDistribution) { // Compute overlaps
6220 :
6221 1154452 : std::map<unsigned, float> pssas;
6222 :
6223 : #ifndef EP_NO_OPENGL
6224 577226 : if (state.dataSolarShading->penumbra) {
6225 : // Add back surfaces to array
6226 2118 : std::vector<unsigned> pbBackSurfaces;
6227 11599 : for (auto bkSurfNum : state.dataShadowComb->ShadowComb(GRSNR).BackSurf) {
6228 10540 : if (bkSurfNum == 0) continue;
6229 9481 : if (state.dataSolarShading->SurfSunCosTheta(bkSurfNum) < DataEnvironment::SunIsUpValue) {
6230 5405 : pbBackSurfaces.push_back(state.dataSurface->SurfPenumbraID(bkSurfNum));
6231 : }
6232 : }
6233 1059 : pssas = state.dataSolarShading->penumbra->calculateInteriorPSSAs({(unsigned)state.dataSurface->SurfPenumbraID(HTSS)}, pbBackSurfaces);
6234 : // penumbra->renderInteriorScene({(unsigned)Surface(HTSS).PenumbraID}, pbBackSurfaces);
6235 :
6236 1059 : JBKS = 0;
6237 11599 : for (auto bkSurfNum : state.dataShadowComb->ShadowComb(GRSNR).BackSurf) {
6238 10540 : if (bkSurfNum == 0) continue;
6239 9481 : if (pssas[state.dataSurface->SurfPenumbraID(bkSurfNum)] > 0) {
6240 1655 : ++JBKS;
6241 1655 : state.dataHeatBal->SurfWinBackSurfaces(iHour, TS, JBKS, HTSS) = bkSurfNum;
6242 1655 : Real64 OverlapArea = pssas[state.dataSurface->SurfPenumbraID(bkSurfNum)] / state.dataSolarShading->SurfSunCosTheta(HTSS);
6243 1655 : state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, JBKS, HTSS) = OverlapArea * state.dataSurface->SurfWinGlazedFrac(HTSS);
6244 : }
6245 : }
6246 : }
6247 : #endif
6248 :
6249 577226 : if (!state.dataSolarShading->penumbra) {
6250 :
6251 576167 : state.dataSolarShading->FINSHC = state.dataSolarShading->FSBSHC + state.dataSolarShading->NSBSHC;
6252 :
6253 576167 : JBKS = 0;
6254 :
6255 2252777 : for (int IBKS = 1; IBKS <= state.dataSolarShading->NBKSHC;
6256 : ++IBKS) { // Loop over back surfaces to GRSNR this hour. NBKSHC is the number of
6257 : // back surfaces that would receive beam radiation from the base surface, GRSNR,
6258 : // if the base surface was transparent. In general, some (at least one) or all of these
6259 : // will receive beam radiation from the exterior window subsurface, HTSS, of GRSNR,
6260 : // depending on the size of HTSS and its location on GRSNR
6261 :
6262 1676610 : BackSurfNum = state.dataSolarShading->HCNS(state.dataSolarShading->FBKSHC - 1 + IBKS);
6263 :
6264 : // Determine if this back surface number can receive beam radiation from the
6265 : // exterior window, HTSS, this hour, i.e., overlap area is positive
6266 :
6267 1676610 : state.dataSolarShading->LOCHCA = state.dataSolarShading->FINSHC - 1;
6268 :
6269 1676610 : MULTOL(state, state.dataSolarShading->FBKSHC - 1 + IBKS, state.dataSolarShading->FSBSHC - 1, state.dataSolarShading->NSBSHC);
6270 :
6271 : // Compute overlap area for this back surface
6272 :
6273 1676610 : state.dataSolarShading->NINSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FINSHC + 1;
6274 1676610 : if (state.dataSolarShading->NINSHC <= 0) continue;
6275 1073029 : Real64 OverlapArea = state.dataSolarShading->HCAREA(state.dataSolarShading->FINSHC);
6276 1147420 : for (int J = 2; J <= state.dataSolarShading->NINSHC; ++J) {
6277 148782 : OverlapArea += state.dataSolarShading->HCAREA(state.dataSolarShading->FINSHC - 1 + J) *
6278 74391 : (1.0 - state.dataSolarShading->HCT(state.dataSolarShading->FINSHC - 1 + J));
6279 : }
6280 :
6281 1073029 : if (OverlapArea > 0.001) {
6282 1065281 : ++JBKS;
6283 1065281 : if (JBKS <= state.dataBSDFWindow->MaxBkSurf) {
6284 1065281 : state.dataHeatBal->SurfWinBackSurfaces(iHour, TS, JBKS, HTSS) = BackSurfNum;
6285 1065281 : int baseSurfaceNum = state.dataSurface->Surface(BackSurfNum).BaseSurf;
6286 1065281 : state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, JBKS, HTSS) = OverlapArea * state.dataSurface->SurfWinGlazedFrac(HTSS);
6287 : // If this is a subsurface, subtract its overlap area from its base surface
6288 1065281 : if (baseSurfaceNum != BackSurfNum) {
6289 76066 : for (int iBaseBKS = 1; iBaseBKS <= JBKS; ++iBaseBKS) {
6290 76064 : if (baseSurfaceNum == state.dataHeatBal->SurfWinBackSurfaces(iHour, TS, iBaseBKS, HTSS)) {
6291 58041 : state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, iBaseBKS, HTSS) =
6292 58041 : max(0.0,
6293 58041 : state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, iBaseBKS, HTSS) -
6294 58041 : state.dataHeatBal->SurfWinOverlapAreas(iHour, TS, JBKS, HTSS));
6295 58041 : break;
6296 : }
6297 : }
6298 : }
6299 : }
6300 : }
6301 : } // End of loop over back surfaces
6302 : }
6303 : }
6304 : } // End of check that sunlit area > 0.
6305 1534620 : }
6306 821277 : void CalcInteriorSolarDistribution(EnergyPlusData &state)
6307 : {
6308 :
6309 : // SUBROUTINE INFORMATION:
6310 : // AUTHOR Fred Winkelmann
6311 : // DATE WRITTEN January 1999
6312 : // MODIFIED Nov 1999, FW, for Window5 calculation method
6313 : // Oct 2000, FW: add transmitted solar variables for reporting
6314 : // Mar 2001, FW: add new calc of solar absorbed by window shades
6315 : // May 2001, FW: add calc of solar transmitted and absorbed by window blinds
6316 : // Oct 2001, LL: remove interpolation, solar now at time step
6317 : // Oct 2001, FW: add solar transmitted through interior windows
6318 : // Mar 24, 2001, FW: remove incorrect multiplication of Boverlap by sunlit fraction
6319 : // since effect of shadowing is already included in Aoverlap
6320 : // Apr 2001, FW: add effects of beam solar reflection from outside and inside reveals
6321 : // Jan 2003, FW: add between-glass shades and blinds
6322 : // Dec 2003, FW: report beam incident on inside of surface
6323 : // Jan 2004, FW: for blinds with horizontal slats, allow different diffuse/diffuse
6324 : // transmittance for ground and sky solar
6325 : // Apr 2004, FW: allow diffusing glazing
6326 : // May 2006, RR: allow external window screen
6327 : // Jan 2010, TH: add calculating and reporting of WinBmBmSolar, WinBmDifSolar,
6328 : // WinBmBmSolarEnergy, and WinBmDifSolarEnergy
6329 : // Jun 2013, SV: scheduled surface gains for walls and windows
6330 :
6331 : // PURPOSE OF THIS SUBROUTINE:
6332 : // For a time step, calculates solar radiation absorbed by exterior
6333 : // surfaces and interior solar radiation distribution
6334 :
6335 : using DaylightingDevices::TransTDD;
6336 : using General::POLYF;
6337 : using ScheduleManager::GetCurrentScheduleValue;
6338 : using namespace DataWindowEquivalentLayer;
6339 :
6340 1642554 : Array1D<Real64> CFBoverlap; // Sum of boverlap for each back surface
6341 1642554 : Array2D<Real64> CFDirBoverlap; // Directional boverlap (Direction, IBack)
6342 :
6343 : #ifdef EP_Count_Calls
6344 : ++state.dataTimingsData->NumIntSolarDist_Calls;
6345 : #endif
6346 6668675 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
6347 11699752 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
6348 5852354 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
6349 5852354 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
6350 5852354 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
6351 12977287 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
6352 56999464 : for (int lay = 1; lay <= CFSMAXNL + 1; ++lay) {
6353 49874531 : state.dataSurface->SurfWinA(SurfNum, lay) = 0.0;
6354 : }
6355 7124933 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfNum) = 0.0;
6356 7124933 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = 0.0;
6357 : }
6358 5852354 : int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
6359 5852354 : int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
6360 49240560 : for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
6361 43388206 : state.dataSurface->SurfOpaqAI(SurfNum) = 0.0;
6362 43388206 : state.dataSurface->SurfOpaqAO(SurfNum) = 0.0;
6363 : }
6364 : }
6365 : }
6366 821277 : if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
6367 1848 : for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
6368 1232 : int SurfDome = e.Dome;
6369 9856 : for (int lay = 1; lay <= CFSMAXNL + 1; ++lay) {
6370 8624 : state.dataSurface->SurfWinA(SurfDome, lay) = 0.0;
6371 : }
6372 1232 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfDome) = 0.0;
6373 1232 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfDome) = 0.0;
6374 : }
6375 : }
6376 :
6377 6664958 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
6378 : // Solar entering a zone as beam or diffuse radiation, originating as beam solar incident on exterior windows)/(Beam normal solar) [W/(W/m2)]
6379 5843681 : Real64 BTOTZone = 0.0;
6380 : // Beam radiation from exterior windows absorbed in a zone or transmitted through
6381 5843681 : Real64 BABSZone = 0.0;
6382 5843681 : state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
6383 5843681 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) = 0.0;
6384 5843681 : state.dataHeatBal->EnclSolDBIntWin(enclosureNum) = 0.0;
6385 : // Loop over exterior surfaces in this zone
6386 5843681 : auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
6387 : // delete values from previous timestep
6388 5843681 : if (state.dataHeatBal->AnyBSDF) state.dataSurface->SurfWinACFOverlap = 0.0;
6389 :
6390 : //-------------------------------------------------------------------------
6391 : // EXTERIOR BEAM SOLAR RADIATION ABSORBED ON THE OUTSIDE OF OPAQUE SURFACES
6392 : //-------------------------------------------------------------------------
6393 : // TODO: use opaq and window loop after airboundary is sorted
6394 : // TODO: It may be useful to sort SurfacePtr to group windows and domes together to reduce if conditions
6395 56358052 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
6396 93903809 : if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Window &&
6397 43389438 : state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome) {
6398 43388206 : if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue;
6399 43388206 : if (!state.dataSurface->Surface(SurfNum).ExtSolar) continue;
6400 12356802 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
6401 12356802 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
6402 12356802 : Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
6403 12356802 : state.dataSurface->SurfOpaqAO(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar * CosInc * SunLitFract;
6404 : }
6405 : }
6406 :
6407 : //--------------------------------------------------------------------------------------------------------
6408 : // EXTERIOR WINDOWS OR TDD DOMES
6409 : //--------------------------------------------------------------------------------------------------------
6410 56358052 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
6411 93903809 : if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Window &&
6412 43389438 : state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome)
6413 43388206 : continue;
6414 7126165 : if (!state.dataSurface->Surface(SurfNum).ExtSolar && state.dataSurface->SurfWinOriginalClass(SurfNum) != SurfaceClass::TDD_Diffuser)
6415 8510 : continue;
6416 7117655 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
6417 7117655 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
6418 7117655 : int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum);
6419 7117655 : int ScNum = state.dataSurface->SurfWinScreenNumber(SurfNum);
6420 7117655 : WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); // Set in subr. WindowShadingManager
6421 :
6422 7117655 : Real64 ProfAng = 0.0; // Window solar profile angle (radians)
6423 :
6424 7117655 : Real64 SlatAng = state.dataSurface->SurfWinSlatAngThisTS(SurfNum);
6425 7117655 : Real64 VarSlats = state.dataSurface->SurfWinMovableSlats(SurfNum);
6426 7117655 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
6427 7117655 : int SurfNum2 = SurfNum;
6428 7117655 : if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
6429 1232 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
6430 : }
6431 7117655 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
6432 7117655 : Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
6433 :
6434 : //-----------------------------------------
6435 : // BLOCK 1
6436 : // EXTERIOR BEAM AND DIFFUSE SOLAR RADIATION ABSORBED IN THE GLASS LAYERS OF (SurfWinA)
6437 : // EXTERIOR BEAM ABSORBED BY SHADING DEVICE (SurfWinExtBeamAbsByShadFac)
6438 : //-----------------------------------------
6439 : // Somewhat of a kludge
6440 14234078 : if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::TDD_Dome ||
6441 7116423 : state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser)
6442 2464 : state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) =
6443 : SunLitFract; // Frames/dividers not allow
6444 7117655 : int FenSolAbsPtr = 0;
6445 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
6446 12243 : FenSolAbsPtr = WindowScheduledSolarAbs(state, SurfNum, ConstrNum);
6447 : }
6448 : bool SunlitFracWithoutReveal =
6449 7117655 : state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) > 0;
6450 :
6451 : // Calculate interpolated blind properties
6452 : Real64 FrontDiffDiffTrans; // Bare-blind front diffuse-diffuse solar transmittance
6453 : Real64 FrontDiffDiffRefl;
6454 : Real64 FrontDiffAbs; // Bare-blind front diffuse solar reflectance
6455 : Real64 BackDiffDiffTrans; // Bare-blind back diffuse-diffuse solar transmittance
6456 : Real64 BackDiffDiffRefl;
6457 : Real64 BackDiffAbs; // Bare-blind back diffuse solar reflectance
6458 :
6459 : Real64 FrontBeamDiffTrans; // Blind ProfileAnglesolar front beam-diffuse transmittance
6460 : Real64 BackBeamDiffTrans; // Blind solar back beam-diffuse transmittance
6461 : Real64 FrontBeamDiffRefl; // Blind solar front beam-diffuse reflectance
6462 : Real64 BackBeamDiffRefl; // Blind solar back beam-diffuse reflectance
6463 : Real64 FrontBeamAbs; // Blind solar front beam absorptance
6464 : Real64 BackBeamAbs; // Blind solar back beam absorptance
6465 :
6466 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL && ANY_BLIND(ShadeFlag)) {
6467 18094 : int SlatsAngIndexLower = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
6468 18094 : int ProfAngIndexLower = state.dataSurface->SurfWinProfAngIndex(SurfNum);
6469 18094 : int SlatsAngIndexUpper = std::min(MaxProfAngs, SlatsAngIndexLower + 1);
6470 18094 : int ProfAngIndexUpper = std::min(MaxProfAngs, ProfAngIndexLower + 1);
6471 18094 : Real64 SlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
6472 18094 : Real64 ProfAngInterpFac = state.dataSurface->SurfWinProfAngInterpFac(SurfNum);
6473 18094 : if (VarSlats) {
6474 : // Used in time step variable reporting
6475 1722 : FrontDiffDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexLower),
6476 1722 : state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexUpper),
6477 : SlatsAngInterpFac);
6478 : } else {
6479 16372 : FrontDiffDiffTrans = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(1);
6480 : }
6481 :
6482 18094 : if (SunLitFract > 0.0 || SunlitFracWithoutReveal) {
6483 12003 : if (VarSlats) {
6484 1092 : FrontBeamDiffTrans =
6485 3276 : General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexLower),
6486 1092 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexLower),
6487 1092 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexUpper),
6488 1092 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexUpper),
6489 : SlatsAngInterpFac,
6490 : ProfAngInterpFac);
6491 3276 : FrontBeamAbs = General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLower, ProfAngIndexLower),
6492 1092 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpper, ProfAngIndexLower),
6493 1092 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLower, ProfAngIndexUpper),
6494 1092 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpper, ProfAngIndexUpper),
6495 : SlatsAngInterpFac,
6496 : ProfAngInterpFac);
6497 1092 : if (ShadeFlag != WinShadingType::ExtBlind) { // FRONT: interior or bg blinds
6498 728 : FrontDiffDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(SlatsAngIndexLower),
6499 728 : state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(SlatsAngIndexUpper),
6500 : SlatsAngInterpFac);
6501 728 : FrontDiffAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(SlatsAngIndexLower),
6502 728 : state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(SlatsAngIndexUpper),
6503 : SlatsAngInterpFac);
6504 728 : FrontBeamDiffRefl =
6505 2184 : General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexLower),
6506 728 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexLower),
6507 728 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexUpper),
6508 728 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexUpper),
6509 : SlatsAngInterpFac,
6510 : ProfAngInterpFac);
6511 : }
6512 1092 : if (ShadeFlag != WinShadingType::IntBlind) { // BACK: exterior or bg blinds
6513 364 : BackDiffDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(SlatsAngIndexLower),
6514 364 : state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(SlatsAngIndexUpper),
6515 : SlatsAngInterpFac);
6516 364 : BackDiffDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(SlatsAngIndexLower),
6517 364 : state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(SlatsAngIndexUpper),
6518 : SlatsAngInterpFac);
6519 364 : BackDiffAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(SlatsAngIndexLower),
6520 364 : state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(SlatsAngIndexUpper),
6521 : SlatsAngInterpFac);
6522 364 : BackBeamDiffTrans =
6523 1092 : General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexLower),
6524 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexLower),
6525 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLower, ProfAngIndexUpper),
6526 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpper, ProfAngIndexUpper),
6527 : SlatsAngInterpFac,
6528 : ProfAngInterpFac);
6529 364 : BackBeamDiffRefl =
6530 1092 : General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexLower),
6531 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexLower),
6532 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLower, ProfAngIndexUpper),
6533 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpper, ProfAngIndexUpper),
6534 : SlatsAngInterpFac,
6535 : ProfAngInterpFac);
6536 364 : BackBeamAbs =
6537 1092 : General::InterpProfSlat(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLower, ProfAngIndexLower),
6538 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpper, ProfAngIndexLower),
6539 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLower, ProfAngIndexUpper),
6540 364 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpper, ProfAngIndexUpper),
6541 : SlatsAngInterpFac,
6542 : ProfAngInterpFac);
6543 : }
6544 : } else {
6545 10911 : FrontBeamAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexLower),
6546 10911 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexUpper),
6547 : ProfAngInterpFac);
6548 10911 : FrontBeamDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexLower),
6549 10911 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexUpper),
6550 : ProfAngInterpFac);
6551 10911 : if (ShadeFlag != WinShadingType::ExtBlind) { // FRONT: interior or bg blinds
6552 10547 : FrontDiffDiffRefl = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffRefl(1);
6553 10547 : FrontDiffAbs = state.dataHeatBal->Blind(BlNum).SolFrontDiffAbs(1);
6554 10547 : FrontBeamDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexLower),
6555 10547 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexUpper),
6556 : ProfAngInterpFac);
6557 : }
6558 10911 : if (ShadeFlag != WinShadingType::IntBlind) { // BACK: exterior or bg blinds{
6559 2310 : BackDiffDiffTrans = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(1);
6560 2310 : BackDiffDiffRefl = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffRefl(1);
6561 2310 : BackDiffAbs = state.dataHeatBal->Blind(BlNum).SolBackDiffAbs(1);
6562 2310 : BackBeamDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexLower),
6563 2310 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexUpper),
6564 : ProfAngInterpFac);
6565 2310 : BackBeamDiffRefl = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLower),
6566 2310 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpper),
6567 : ProfAngInterpFac);
6568 2310 : BackBeamAbs = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLower),
6569 2310 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpper),
6570 : ProfAngInterpFac);
6571 : }
6572 : }
6573 : }
6574 : }
6575 :
6576 7117655 : if (SunlitFracWithoutReveal) {
6577 :
6578 3670733 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {
6579 :
6580 : // For bare glazing or switchable glazing, the following includes the effects of
6581 : // (1) diffuse solar produced by beam solar incident on the outside and inside reveal
6582 : // surfaces, and (2) absorption of beam solar by outside and inside reveal surfaces.
6583 : // If there is an exterior shade/blind both of these effects are ignored. If there
6584 : // is an interior or between-glass shade/blind the effects of beam incident on
6585 : // inside reveal surfaces is ignored.
6586 3662886 : int NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
6587 7325772 : Array1D<Real64> AbWin(NGlass); // Factor for front beam radiation absorbed in window glass layer
6588 8414893 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6589 9504014 : AbWin(Lay) = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(Lay)) * CosInc * SunLitFract *
6590 4752007 : state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay);
6591 : }
6592 3662886 : if (!IS_SHADED_NO_GLARE_CTRL(ShadeFlag)) {
6593 : // (ShadeFlag <= 0 || ShadeFlag >= 10) - Bare window (ShadeFlag = -1 or 0 or shading device of off)
6594 8165348 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6595 : // Add contribution of beam reflected from outside and inside reveal
6596 13770384 : state.dataSurface->SurfWinA(SurfNum, Lay) = AbWin(Lay) +
6597 9180256 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
6598 9180256 : state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay) +
6599 9180256 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) *
6600 4590128 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay);
6601 : }
6602 : } else {
6603 : // Shade, screen, blind or switchable glazing on (ShadeFlag > 0)
6604 175332 : Real64 FracSunLit = SunLitFract * state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(
6605 175332 : state.dataGlobal->HourOfDay); // Effective fraction of window that is sunlit;
6606 87666 : Real64 InOutProjSLFracMult = state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
6607 175332 : Array1D<Real64> AbWinSh(NGlass); // Like AbWin, but for shaded window
6608 175332 : Array1D<Real64> ADiffWinSh(NGlass); // Diffuse solar absorptance of glass layer, window with shading device
6609 87666 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) FracSunLit = SunLitFract;
6610 :
6611 87666 : if (ANY_SHADE(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
6612 : // Shade or switchable glazing on
6613 218805 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6614 144766 : AbWinSh(Lay) = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).AbsBeamCoef(Lay)) * CosInc * FracSunLit;
6615 144766 : ADiffWinSh(Lay) = state.dataConstruction->Construct(ConstrNumSh).AbsDiff(Lay);
6616 : }
6617 74039 : if (ShadeFlag == WinShadingType::IntShade) { // Exterior beam absorbed by INTERIOR SHADE
6618 : // Note that AbsBeamShadeCoef includes effect of shade/glazing inter-reflection
6619 10905 : Real64 AbsShade = POLYF(CosInc,
6620 10905 : state.dataConstruction->Construct(ConstrNumSh)
6621 10905 : .AbsBeamShadeCoef); // Interior shade or blind beam solar absorptance
6622 10905 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
6623 21810 : (AbsShade * CosInc * SunLitFract * InOutProjSLFracMult +
6624 21810 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
6625 21810 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade) *
6626 10905 : state.dataSurface->SurfWinGlazedFrac(SurfNum);
6627 : // In the above, GlazedFrac corrects for shadowing of divider onto interior shade
6628 63134 : } else if (ShadeFlag == WinShadingType::ExtShade) { // Exterior beam absorbed by EXTERIOR SHADE
6629 4094 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
6630 4094 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade * CosInc * SunLitFract;
6631 59040 : } else if (ShadeFlag == WinShadingType::BGShade) { // Exterior beam absorbed by BETWEEN-GLASS SHADE
6632 1456 : Real64 AbsShade = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).AbsBeamShadeCoef);
6633 1456 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
6634 2912 : AbsShade * CosInc * SunLitFract + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
6635 1456 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade;
6636 : }
6637 :
6638 : } else {
6639 : // Blind or screen on
6640 13627 : ProfAng = state.dataSurface->SurfWinProfileAng(SurfNum);
6641 13627 : if (ShadeFlag == WinShadingType::IntBlind) {
6642 : // Interior blind on
6643 9329 : Real64 TBmBm = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
6644 : Real64 RGlDiffBack =
6645 9329 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; // Glazing system back diffuse solar reflectance
6646 9329 : Real64 RhoBlFront = FrontBeamDiffRefl; // Blind solar front beam reflectance
6647 9329 : Real64 RhoBlDiffFront = FrontDiffDiffRefl; // Blind solar front diffuse reflectance
6648 18658 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6649 9329 : Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(
6650 9329 : Lay); // Diffuse solar absorptance of glass layer, bare window
6651 : Real64 AGlDiffBack =
6652 9329 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay); // Glass layer back diffuse solar absorptance
6653 9329 : AbWinSh(Lay) =
6654 9329 : AbWin(Lay) + (TBmBm * AGlDiffBack * RhoBlFront / (1.0 - RhoBlFront * RGlDiffBack)) * CosInc * FracSunLit;
6655 18658 : ADiffWinSh(Lay) = ADiffWin + state.dataConstruction->Construct(ConstrNum).TransDiff * AGlDiffBack *
6656 9329 : RhoBlDiffFront / (1.0 - RhoBlDiffFront * RGlDiffBack);
6657 : }
6658 : // Exterior beam absorbed by INTERIOR BLIND
6659 :
6660 9329 : Real64 AbsBlFront = FrontBeamAbs; // Blind solar front beam absorptance
6661 9329 : Real64 AbsBlDiffFront = FrontDiffAbs; // Blind solar front diffuse absorptance
6662 9329 : Real64 AbsShade =
6663 9329 : TBmBm * (AbsBlFront + RhoBlFront * RGlDiffBack * AbsBlDiffFront / (1.0 - RhoBlDiffFront * RGlDiffBack));
6664 : Real64 AbsShadeDiff =
6665 9329 : state.dataConstruction->Construct(ConstrNum).TransDiff *
6666 18658 : (AbsBlDiffFront + RhoBlDiffFront * RGlDiffBack * AbsBlDiffFront /
6667 18658 : (1.0 - RhoBlDiffFront * RGlDiffBack)); // Interior shade or blind diffuse solar absorptance
6668 :
6669 9329 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
6670 18658 : (AbsShade * CosInc * SunLitFract * InOutProjSLFracMult +
6671 18658 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * AbsShadeDiff) *
6672 9329 : state.dataSurface->SurfWinGlazedFrac(SurfNum);
6673 : // In the above, GlazedFrac corrects for shadowing of divider onto interior blind
6674 4298 : } else if (ShadeFlag == WinShadingType::ExtBlind) {
6675 : // Exterior blind on
6676 728 : Real64 TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum); // Blind solar front beam-beam transmittance
6677 728 : Real64 TBlDifDif = FrontDiffDiffTrans; // Diffuse-diffuse solar transmittance of blind
6678 728 : Real64 TBlBmDiff = FrontBeamDiffTrans; // Blind solar front beam-diffuse transmittance
6679 728 : Real64 RhoBlBack = BackBeamDiffRefl; // Blind solar back beam-diffuse reflectance
6680 728 : Real64 RhoBlDiffBack = BackDiffDiffRefl; // Blind solar back diffuse reflectance
6681 728 : Real64 RGlFront = POLYF(CosInc,
6682 728 : state.dataConstruction->Construct(ConstrNum)
6683 728 : .ReflSolBeamFrontCoef); // Glazing system solar front beam-beam reflectance
6684 728 : Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNum)
6685 728 : .ReflectSolDiffFront; // Glazing system front diffuse solar reflectance
6686 1456 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6687 728 : Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(
6688 728 : Lay); // Diffuse solar absorptance of glass layer, bare window
6689 : Real64 AGlDiffFront =
6690 728 : state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay); // Glass layer front diffuse solar absorptance
6691 2184 : AbWinSh(Lay) = TBlBmBm * AbWin(Lay) + ((TBlBmBm * RGlFront * RhoBlBack + TBlBmDiff) * AGlDiffFront /
6692 1456 : (1 - RGlDiffFront * RhoBlDiffBack)) *
6693 728 : CosInc * FracSunLit;
6694 : // ADiffWinSh = 0.0 ! Assumes no contribution from reveal reflection when exterior blind in place
6695 : // Replaced above line with (FCW, 2/10/03):
6696 728 : ADiffWinSh(Lay) = ADiffWin * TBlDifDif / (1.0 - RGlDiffFront * RhoBlDiffBack);
6697 : }
6698 : // Exterior beam absorbed by EXTERIOR BLIND
6699 728 : Real64 AbsBlFront = FrontBeamAbs;
6700 728 : Real64 AbsBlBack = BackBeamAbs; // Blind solar back beam absorptance
6701 728 : Real64 AbsBlDiffBack = BackDiffAbs; // Blind solar back diffuse absorptance
6702 1456 : Real64 AbsShade = AbsBlFront + AbsBlBack * RGlFront * TBlBmBm +
6703 1456 : (AbsBlDiffBack * RGlDiffFront / (1.0 - RhoBlDiffBack * RGlDiffFront)) *
6704 728 : (RGlFront * TBlBmBm * RhoBlBack + TBlBmDiff);
6705 728 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = AbsShade * CosInc * SunLitFract * InOutProjSLFracMult;
6706 728 : if (state.dataEnvrn->Month == 7 && state.dataEnvrn->DayOfMonth == 21 && state.dataGlobal->HourOfDay == 8) {
6707 42 : double tst = state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum);
6708 42 : tst = 0;
6709 : }
6710 3570 : } else if (ShadeFlag == WinShadingType::ExtScreen) {
6711 : // Exterior screen on
6712 1624 : Real64 TScBmBm = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTrans; // Screen solar front beam-beam transmittance
6713 : Real64 TScBmDiff =
6714 1624 : state.dataHeatBal->SurfaceScreens(ScNum).BmDifTrans; // Screen solar front beam-diffuse transmittance
6715 : Real64 RScBack =
6716 1624 : state.dataHeatBal->SurfaceScreens(ScNum).ReflectSolBeamFront; // Screen solar back beam-diffuse reflectance
6717 : Real64 RScDifBack =
6718 1624 : state.dataHeatBal->SurfaceScreens(ScNum).DifReflect; // Screen solar back diffuse-diffuse reflectance
6719 1624 : Real64 RGlFront = POLYF(CosInc,
6720 1624 : state.dataConstruction->Construct(ConstrNum)
6721 1624 : .ReflSolBeamFrontCoef); // Glazing system solar front beam-beam reflectance
6722 1624 : Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNum)
6723 1624 : .ReflectSolDiffFront; // Glazing system front diffuse solar reflectance
6724 : Real64 TScDifDif =
6725 1624 : state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans; // Diffuse-diffuse solar transmittance of screen
6726 : Real64 RGlDifFr =
6727 1624 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront; // Diffuse front reflectance of glass
6728 : // Reduce the bare window absorbed beam by the screen beam transmittance and then account for
6729 : // interreflections
6730 4060 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6731 2436 : Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(
6732 2436 : Lay); // Diffuse solar absorptance of glass layer, bare window
6733 7308 : AbWinSh(Lay) = TScBmBm * AbWin(Lay) + (TScBmBm * RGlFront * RScBack + TScBmDiff) *
6734 4872 : state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay) /
6735 4872 : (1.0 - RGlDiffFront * RScDifBack) * CosInc * FracSunLit;
6736 2436 : ADiffWinSh(Lay) = ADiffWin * TScDifDif / (1.0 - RGlDifFr * RScDifBack);
6737 : }
6738 : // Exterior beam absorbed by EXTERIOR SCREEN
6739 1624 : Real64 AbsScBeam = state.dataHeatBal->SurfaceScreens(ScNum).AbsorpSolarBeamFront; // Screen solar beam absorptance
6740 : Real64 AbsScDiffBack =
6741 1624 : state.dataHeatBal->SurfaceScreens(ScNum).DifScreenAbsorp; // Screen solar back diffuse absorptance
6742 3248 : Real64 AbsScreen = AbsScBeam * (1.0 + TScBmBm * RGlFront) +
6743 3248 : (AbsScDiffBack * TScBmBm * RGlFront * RGlDiffFront * RScBack /
6744 1624 : (1.0 - RScDifBack * RGlDiffFront)); // Exterior screen beam solar absorptance
6745 1624 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = AbsScreen * CosInc * SunLitFract * InOutProjSLFracMult;
6746 1946 : } else if (ShadeFlag == WinShadingType::BGBlind) {
6747 : // Between-glass blind o
6748 : // Isolated glass and blind properties at current incidence angle, profile angle and slat angle
6749 : Real64 t1 = POLYF(CosInc,
6750 1946 : state.dataConstruction->Construct(ConstrNum).tBareSolCoef(
6751 1946 : 1)); // Bare-glass beam solar transmittance for glass layers 1,2 and 3
6752 1946 : Real64 t2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(2));
6753 : Real64 af1 = POLYF(CosInc,
6754 1946 : state.dataConstruction->Construct(ConstrNum).afBareSolCoef(
6755 1946 : 1)); // Bare-glass beam solar front absorptance for glass layers 1,2 and 3
6756 1946 : Real64 af2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).afBareSolCoef(2));
6757 : Real64 ab1 = POLYF(CosInc,
6758 1946 : state.dataConstruction->Construct(ConstrNum).abBareSolCoef(
6759 1946 : 1)); // Bare-glass beam solar back absorptance for glass layers 1,2 and 3
6760 1946 : Real64 ab2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).abBareSolCoef(2));
6761 1946 : Real64 rf2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(2));
6762 1946 : Real64 td1 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(
6763 1946 : 1); // Bare-glass diffuse solar transmittance for glass layers 1,2 and 3
6764 1946 : Real64 td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
6765 1946 : Real64 afd1 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(
6766 1946 : 1); // Bare-glass diffuse solar front absorptance for glass layers 1,2 and 3
6767 1946 : Real64 afd2 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(2);
6768 1946 : Real64 abd1 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(
6769 1946 : 1); // Bare-glass diffuse solar back absorptance for glass layers 1,2 and 3
6770 1946 : Real64 abd2 = state.dataConstruction->Construct(ConstrNum).abBareSolDiff(2);
6771 1946 : Real64 rfd2 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(2);
6772 1946 : Real64 rbd1 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(
6773 1946 : 1); // Bare-glass diffuse solar back reflectance for glass layers 1,2 and 3
6774 1946 : Real64 rbd2 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(2);
6775 : Real64 tfshBB =
6776 1946 : state.dataSurface->SurfWinBlindBmBmTrans(SurfNum); // Bare-blind front and back beam-beam solar transmittance
6777 5838 : Real64 tbshBB = General::BlindBeamBeamTrans(ProfAng,
6778 : DataGlobalConstants::Pi - SlatAng,
6779 1946 : state.dataHeatBal->Blind(BlNum).SlatWidth,
6780 1946 : state.dataHeatBal->Blind(BlNum).SlatSeparation,
6781 3892 : state.dataHeatBal->Blind(BlNum).SlatThickness);
6782 1946 : Real64 tfshBd = FrontBeamDiffTrans; // Bare-blind front and back beam-diffuse solar transmittance
6783 1946 : Real64 tbshBd = BackBeamDiffTrans;
6784 1946 : Real64 rfshB = FrontBeamDiffRefl; // Bare-blind front and back beam solar reflectance
6785 1946 : Real64 rbshB = BackBeamDiffRefl;
6786 1946 : Real64 afshB = FrontBeamAbs;
6787 1946 : Real64 abshB = BackBeamAbs;
6788 :
6789 1946 : Real64 tfshd = FrontDiffDiffTrans; // Bare-blind front and back diffuse-diffuse solar transmittance
6790 1946 : Real64 tbshd = BackDiffDiffTrans;
6791 1946 : Real64 rfshd = FrontDiffDiffRefl; // Bare-blind front and back diffuse solar reflectance
6792 1946 : Real64 rbshd = BackDiffDiffRefl;
6793 1946 : Real64 afshd = FrontDiffAbs;
6794 1946 : Real64 abshd = BackDiffAbs;
6795 :
6796 1946 : Real64 AbsShade = 0.0;
6797 1946 : Real64 AbsShadeDiff = 0.0;
6798 1946 : if (NGlass == 2) {
6799 2436 : AbWinSh(1) = CosInc * FracSunLit *
6800 2436 : (af1 + t1 * tfshBB * rf2 * tbshBB * ab1 +
6801 1218 : t1 * (rfshB + rfshB * rbd1 * rfshd + tfshBB * rf2 * tbshBd + tfshBd * rfd2 * tbshd) * abd1);
6802 1218 : ADiffWinSh(1) = afd1 + td1 * (rfshd + rfshd * rbd1 * rfshd + tfshd * rfd2 * tbshd) * abd1;
6803 1218 : AbWinSh(2) =
6804 2436 : CosInc * FracSunLit *
6805 1218 : (t1 * rfshB * af2 + t1 * (rfshB * rf2 * rbshd + tfshBd * (1 + rfd2 * rbshd) + rfshB * rbd1 * tfshd) * afd2);
6806 1218 : ADiffWinSh(2) = td1 * (tfshd * (1 + rfd2 * rbshd) + rfshd * rbd1 * tfshd) * afd2;
6807 1218 : AbsShade = t1 * (afshB + tfshBB * rf2 * abshB + tfshBd * rfd2 * abshd + rfshB * rbd1 * afshd);
6808 1218 : AbsShadeDiff = td1 * (afshd * (1 + rfshd * rbd1) + tfshd * rfd2 * abshd);
6809 728 : } else if (NGlass == 3) {
6810 728 : Real64 t1t2 = t1 * t2; // t1*t2
6811 728 : Real64 td1td2 = td1 * td2;
6812 728 : Real64 af3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).afBareSolCoef(3));
6813 728 : Real64 rf3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(3));
6814 728 : Real64 afd3 = state.dataConstruction->Construct(ConstrNum).afBareSolDiff(3);
6815 728 : Real64 rfd3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
6816 728 : Real64 td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
6817 1456 : AbWinSh(1) = CosInc * FracSunLit *
6818 1456 : (af1 + t1 * rf2 * ab1 + t1t2 * tfshBB * rf3 * tbshBB * t2 * ab1 +
6819 728 : t1t2 * (rfshB * td2 + rfshB * rbd2 * rfshd * td2 + tfshBd * rfd3 * tbshd * td2) * abd1);
6820 1456 : ADiffWinSh(1) = afd1 + td1 * rbd2 * abd1 +
6821 728 : td1td2 *
6822 1456 : (rfshd * (1 + rbd2 * rfshd + td2 * rbd1 * td2 * rfshd) +
6823 1456 : tfshd * (rfd3 * tbshd + rfd3 * rbshd * rfd3 * tbshd)) *
6824 728 : td2 * abd1;
6825 1456 : AbWinSh(2) = CosInc * FracSunLit *
6826 1456 : (t1 * af2 + t1t2 * (tfshBB * rf3 * tbshBB * ab2 + rfshB * td2 * rbd1 * afd2) +
6827 728 : t1t2 * (rfshB * (1 + rbd2 * rfshd) + tfshBB * rf3 * tbshBd + tfshBd * rfd3 * tbshd) * abd2);
6828 1456 : ADiffWinSh(2) = td1 * afd2 + td1td2 * rfshd * td2 * rbd1 * afd2 +
6829 728 : td1td2 * (rfshd * (1 + rbd2 * rfshd) + tfshd * rfd3 * tbshd) * abd2;
6830 1456 : AbWinSh(3) = CosInc * FracSunLit *
6831 2184 : (t1t2 * tfshBB * af3 + t1t2 *
6832 1456 : (tfshBB * rf3 * rbshB + tfshBd * (1 + rfd3 * rbshd) +
6833 1456 : rfshB * (rbd2 * tfshd + td2 * rbd1 * td2 * tfshd)) *
6834 : afd3);
6835 728 : ADiffWinSh(3) = td1td2 * (tfshd * (1 + rfd3 * rbshd) + rfshd * (rbd2 * tfshd + td2 * rbd1 * td2 * tfshd)) * afd3;
6836 728 : AbsShade = t1t2 * (afshB * (1 + tfshBB * rf3) + afshd * (tfshBd * rfd3 + rfshB * (rbd2 + td2 * rbd1 * td2)));
6837 728 : AbsShadeDiff = td1td2 * (afshd + tfshd * rfd3 * abshd + rfshd * (rfd2 + td2 * rbd2 * td2) * afshd);
6838 : } // End of check if NGlass
6839 1946 : state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) =
6840 3892 : AbsShade * CosInc * SunLitFract * InOutProjSLFracMult +
6841 1946 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * AbsShadeDiff;
6842 : } // End of check if blind is interior, exterior or between-glass
6843 : } // End of check if a blind is on
6844 :
6845 87666 : if (ShadeFlag != WinShadingType::SwitchableGlazing) {
6846 : // Interior or between glass shade or blind on
6847 76793 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6848 46711 : state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinSh(Lay);
6849 : // Add contribution of diffuse from beam on outside reveal
6850 46711 : if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) || ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag))
6851 37831 : state.dataSurface->SurfWinA(SurfNum, Lay) +=
6852 37831 : ADiffWinSh(Lay) * state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum);
6853 : }
6854 : } else {
6855 : // Switchable glazing
6856 172752 : for (int Lay = 1; Lay <= NGlass; ++Lay) {
6857 115168 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
6858 115168 : Real64 ADiffWin = state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay);
6859 115168 : state.dataSurface->SurfWinA(SurfNum, Lay) = General::InterpSw(SwitchFac, AbWin(Lay), AbWinSh(Lay));
6860 : // Add contribution of diffuse from beam on outside and inside reveal
6861 115168 : state.dataSurface->SurfWinA(SurfNum, Lay) +=
6862 230336 : General::InterpSw(SwitchFac, ADiffWin, ADiffWinSh(Lay)) *
6863 230336 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) +
6864 230336 : General::InterpSw(SwitchFac,
6865 115168 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(Lay),
6866 230336 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(Lay)) *
6867 115168 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum);
6868 : }
6869 : }
6870 : }
6871 :
6872 7847 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
6873 : // Do not read from schedule file here since this will be called only if direct beam is hitting the window and schedule
6874 : // will not be loaded in that case even if diffuse part of solar radiation is entering through the window
6875 6461 : if (FenSolAbsPtr == 0) {
6876 : // Put in the equivalent layer absorptions
6877 : // Simon: This should not be multiplied with CosInc since Abs coefficient already includes angular
6878 : // factor
6879 48090 : for (int Lay = 1; Lay <= state.dataSurface->SurfaceWindow(SurfNum)
6880 24045 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6881 24045 : .NLayers;
6882 : ++Lay) {
6883 17640 : auto absBeamWin = state.dataSurface->SurfaceWindow(SurfNum)
6884 17640 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6885 17640 : .WinBmFtAbs(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, Lay);
6886 17640 : Real64 AbWin = absBeamWin * CosInc * SunLitFract *
6887 17640 : state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay);
6888 :
6889 : // Add contribution of beam reflected from outside and inside reveal
6890 17640 : state.dataSurface->SurfWinA(SurfNum, Lay) =
6891 17640 : AbWin +
6892 35280 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
6893 17640 : state.dataSurface->SurfaceWindow(SurfNum)
6894 17640 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6895 35280 : .WinFtHemAbs(Lay) +
6896 35280 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) *
6897 17640 : state.dataSurface->SurfaceWindow(SurfNum)
6898 17640 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6899 17640 : .WinBkHemAbs(Lay);
6900 : }
6901 : }
6902 :
6903 1386 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
6904 : // call the ASHWAT fenestration model for optical properties
6905 : // determine the beam radiation absorptance and tranmittance of the
6906 : // the equivalent layer window model
6907 1386 : WindowEquivalentLayer::CalcEQLOpticalProperty(state, SurfNum, SolarArrays::BEAM, state.dataSolarShading->SurfWinAbsSolBeamEQL);
6908 1386 : auto &CFS = state.dataWindowEquivLayer->CFS;
6909 : // recalcuate the diffuse absorptance and transmittance of the
6910 : // the equivalent layer window model if there is shade control
6911 1386 : int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction)
6912 1386 : .EQLConsPtr; // equivalent layer fenestration index
6913 1386 : if (CFS(EQLNum).ISControlled) {
6914 0 : WindowEquivalentLayer::CalcEQLOpticalProperty(
6915 0 : state, SurfNum, SolarArrays::DIFF, state.dataSolarShading->SurfWinAbsSolDiffEQL);
6916 : } else {
6917 1386 : state.dataSolarShading->SurfWinAbsSolDiffEQL(_, {1, CFS(EQLNum).NL + 1}) =
6918 2772 : state.dataWindowEquivalentLayer->CFSDiffAbsTrans(_, {1, CFS(EQLNum).NL + 1}, EQLNum);
6919 : }
6920 1386 : state.dataConstruction->Construct(ConstrNum).TransDiff = state.dataSolarShading->SurfWinAbsSolDiffEQL(1, CFS(EQLNum).NL + 1);
6921 :
6922 7658 : for (int Lay = 1; Lay <= CFS(EQLNum).NL + 1; ++Lay) {
6923 : // Factor for front beam radiation absorbed for equivalent layer window model
6924 6272 : Real64 AbWinEQL = state.dataSolarShading->SurfWinAbsSolBeamEQL(1, Lay) * CosInc * SunLitFract *
6925 6272 : state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
6926 : ;
6927 6272 : if (CFS(EQLNum).L(1).LTYPE != LayerType::GLAZE) {
6928 : // if the first layer is not glazing (or it is a shade) do not
6929 2842 : state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinEQL;
6930 : } else {
6931 : // the first layer is a glazing, include the outside reveal reflection
6932 : // and the inside reveal reflection until indoor shade layer is encountered.
6933 3430 : if (CFS(EQLNum).L(Lay).LTYPE == LayerType::GLAZE) {
6934 3920 : state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinEQL +
6935 3920 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
6936 3920 : state.dataSolarShading->SurfWinAbsSolBeamEQL(1, Lay) +
6937 3920 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) *
6938 1960 : state.dataSolarShading->SurfWinAbsSolDiffEQL(2, Lay);
6939 : } else {
6940 2940 : state.dataSurface->SurfWinA(SurfNum, Lay) = AbWinEQL + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) *
6941 1470 : state.dataSolarShading->SurfWinAbsSolBeamEQL(1, Lay);
6942 : }
6943 : }
6944 : }
6945 : }
6946 : } // End of SunlitFrac check
6947 :
6948 : //-----------------------------------------------------------------
6949 : // BLOCK 2
6950 : // SKY AND GROUND DIFFUSE SOLAR GAIN INTO ZONE FROM EXTERIOR WINDOW
6951 : //-----------------------------------------------------------------
6952 :
6953 7117655 : Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(
6954 7117655 : SurfNum); // Incident solar radiation on a window: sky diffuse plus beam reflected from obstruction (W/m2)
6955 7117655 : Real64 DiffTrans = 0.0; // Glazing diffuse solar transmittance (including shade/blind/switching, if present)
6956 : Real64 DiffTransGnd; // Ground diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
6957 : Real64 DiffTransBmGnd; // Complex fen: diffuse solar transmittance for ground-reflected beam radiation
6958 : Real64 DiffTransSky; // Sky diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
6959 7117655 : Real64 NomDiffTrans = 0.0;
6960 :
6961 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { // complex fenestration
6962 12243 : if (FenSolAbsPtr == 0) {
6963 : // Sky diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
6964 24290 : DiffTransSky = state.dataSurface->SurfaceWindow(SurfNum)
6965 12145 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6966 : .WinSkyTrans;
6967 : // Ground diffuse solar transmittance for glazing with blind with horiz. slats or complex fen
6968 24290 : DiffTransGnd = state.dataSurface->SurfaceWindow(SurfNum)
6969 12145 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6970 : .WinSkyGndTrans;
6971 : // Complex fen: diffuse solar transmittance for ground-reflected beam radiation
6972 24290 : DiffTransBmGnd = state.dataSurface->SurfaceWindow(SurfNum)
6973 12145 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6974 12145 : .WinBmGndTrans(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
6975 : // Define the effective transmittance for total sky and ground radiation
6976 12145 : if ((SkySolarInc + state.dataSurface->SurfWinBmGndSolarInc(SurfNum) + state.dataSurface->SurfWinSkyGndSolarInc(SurfNum)) != 0.0) {
6977 12145 : DiffTrans =
6978 24290 : (SkySolarInc * DiffTransSky + state.dataSurface->SurfWinBmGndSolarInc(SurfNum) * DiffTransBmGnd +
6979 12145 : state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) * DiffTransGnd) /
6980 12145 : (SkySolarInc + state.dataSurface->SurfWinBmGndSolarInc(SurfNum) + state.dataSurface->SurfWinSkyGndSolarInc(SurfNum));
6981 : }
6982 : // Also update the nominal diffuse transmittance
6983 24290 : NomDiffTrans = state.dataSurface->SurfaceWindow(SurfNum)
6984 12145 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
6985 : .WinDiffTrans;
6986 : // Do not store in TransDiff because it is not used by BSDF and rest of the code uses it as flag for opaque
6987 : // surface incorrectly assuming wall heat transfer routines for windows.
6988 : // Construct( Surface( SurfNum ).Construction ).TransDiff = NomDiffTrans;
6989 : }
6990 7105412 : } else if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
6991 1232 : DiffTrans = TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarAniso);
6992 : } else {
6993 7104180 : DiffTrans = state.dataConstruction->Construct(ConstrNum).TransDiff;
6994 : }
6995 :
6996 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {
6997 7102934 : if (IS_SHADED_NO_GLARE_CTRL(state.dataSurface->SurfWinShadingFlag(SurfNum))) {
6998 123072 : if (ShadeFlag != WinShadingType::SwitchableGlazing) {
6999 : // Shade or blind
7000 51818 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
7001 : // Shade or screen
7002 33724 : DiffTrans = state.dataConstruction->Construct(ConstrNumSh).TransDiff;
7003 : } else {
7004 : // Blind
7005 18094 : int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum);
7006 18094 : Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum);
7007 18094 : if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
7008 3444 : DiffTrans = General::InterpGeneral(
7009 1722 : state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(SurfWinSlatsAngIndex),
7010 3444 : state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
7011 : SurfWinSlatsAngInterpFac);
7012 : } else {
7013 16372 : DiffTrans = state.dataConstruction->Construct(ConstrNumSh).BlTransDiff(1);
7014 : }
7015 : // For blinds with horizontal slats, allow different diffuse/diffuse transmittance for
7016 : // ground and sky solar
7017 18094 : if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
7018 : DataWindowEquivalentLayer::Orientation::Horizontal) {
7019 18094 : if (state.dataSurface->SurfWinMovableSlats(SurfNum)) {
7020 1722 : DiffTransGnd =
7021 1722 : General::InterpGeneral(state.dataConstruction->Construct(ConstrNumSh).BlTransDiffGnd(SurfWinSlatsAngIndex),
7022 1722 : state.dataConstruction->Construct(ConstrNumSh)
7023 3444 : .BlTransDiffGnd(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
7024 : SurfWinSlatsAngInterpFac);
7025 1722 : DiffTransSky =
7026 1722 : General::InterpGeneral(state.dataConstruction->Construct(ConstrNumSh).BlTransDiffSky(SurfWinSlatsAngIndex),
7027 1722 : state.dataConstruction->Construct(ConstrNumSh)
7028 3444 : .BlTransDiffSky(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
7029 : SurfWinSlatsAngInterpFac);
7030 : } else {
7031 16372 : DiffTransGnd = state.dataConstruction->Construct(ConstrNumSh).BlTransDiffGnd(1);
7032 16372 : DiffTransSky = state.dataConstruction->Construct(ConstrNumSh).BlTransDiffSky(1);
7033 : }
7034 : }
7035 : }
7036 :
7037 : } else {
7038 : // Switchable glazing
7039 71254 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for a window
7040 142508 : DiffTrans = General::InterpSw(SwitchFac,
7041 71254 : state.dataConstruction->Construct(ConstrNum).TransDiff,
7042 71254 : state.dataConstruction->Construct(ConstrNumSh).TransDiff);
7043 : }
7044 : }
7045 : }
7046 :
7047 : // Reporting variables
7048 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) {
7049 7115177 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = DiffTrans;
7050 7115177 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = DiffTrans;
7051 7115177 : if (ANY_BLIND(ShadeFlag) || ShadeFlag == WinShadingType::ExtScreen) {
7052 21342 : state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = DiffTrans;
7053 21342 : state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = DiffTrans;
7054 21342 : if (ShadeFlag == WinShadingType::ExtScreen) {
7055 3248 : state.dataSurface->SurfWinScTsolDifDif(SurfNum) = state.dataHeatBal->SurfaceScreens(ScNum).DifDifTrans;
7056 : } else {
7057 18094 : state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = FrontDiffDiffTrans;
7058 : }
7059 : }
7060 : }
7061 :
7062 : //-----------------------------------------------------------------
7063 : // BEAM SOLAR ON EXTERIOR WINDOW TRANSMITTED AS BEAM AND/OR DIFFUSE
7064 : //-----------------------------------------------------------------
7065 7117655 : Real64 TBmBm = 0.0; // Beam-beam solar transmittance for bare window or window with switchable glazing
7066 7117655 : Real64 TBmDif = 0.0; // Beam-diffuse solar transmittance for bare window with diffusing glass
7067 7117655 : Real64 TBmAllShBlSc = 0.0; // Beam-beam + beam-diffuse transmittance for window with shade, blind, screen, or switchable glazing
7068 7117655 : Real64 TBmBmShBlSc = 0.0; // Beam-beam transmittance for window with shade, blind, screen, or switchable glazing
7069 7117655 : Real64 TBmDifShBlSc = 0.0; // Beam-diffuse transmittance for window with shade, blind, screen, or switchable glazing
7070 : Real64 TBmBmBl; // Beam-beam transmittance for window with blind
7071 : Real64 TBmBmSc; // Beam-beam transmittance for window with screen
7072 : Real64 TDifBare; // Bare diffuse transmittance of exterior window
7073 : // Beam-beam transmittance for bare exterior window
7074 7117655 : if (SunLitFract > 0.0) {
7075 3661727 : if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
7076 1148 : TBmDif = TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarBeam);
7077 1148 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolBeam = TBmDif; // Report variable
7078 3660579 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) { // Regular window
7079 3652732 : if (!state.dataSurface->SurfWinSolarDiffusing(SurfNum)) { // Clear glazing
7080 3652732 : TBmBm = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); //[-]
7081 : } else { // Diffusing glazing
7082 0 : TBmDif = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); //[-]
7083 : }
7084 7847 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
7085 : // Need to check what effect, if any, defining these here has
7086 12922 : TBmBm = state.dataSurface->SurfaceWindow(SurfNum)
7087 6461 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
7088 6461 : .WinDirSpecTrans(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
7089 12922 : TBmDif = state.dataSurface->SurfaceWindow(SurfNum)
7090 6461 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
7091 6461 : .WinDirHemiTrans(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep) -
7092 : TBmBm;
7093 1386 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
7094 : // get ASHWAT fenestration model beam-beam and beam-diffuse properties
7095 1386 : int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction)
7096 1386 : .EQLConsPtr; // equivalent layer fenestration index
7097 1386 : Real64 TBmBmEQL = state.dataSolarShading->SurfWinAbsSolBeamEQL(1, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1);
7098 : // Beam-diffuse transmittance
7099 1386 : Real64 TBmDiffEQL = max(0.0, state.dataSolarShading->SurfWinAbsSolBeamEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1));
7100 : // Beam-beam transmittance: difference between beam-total and beam-diffuse transmittance
7101 1386 : TBmBmEQL = max(0.0, (TBmBmEQL - TBmDiffEQL));
7102 1386 : TBmBm = TBmBmEQL;
7103 1386 : TBmDif = TBmDiffEQL;
7104 : }
7105 : }
7106 : // Diffuse-diffuse transmittance for bare exterior window
7107 7117655 : if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
7108 1232 : TDifBare = TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarAniso);
7109 : } else {
7110 7116423 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
7111 : // Complex Fenestration: use hemispherical ave of directional-hemispherical transmittance
7112 : // Note: this is not quite the same as the effective transmittance for total of sky and ground radiation
7113 24486 : TDifBare = state.dataSurface->SurfaceWindow(SurfNum)
7114 12243 : .ComplexFen.State(state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState)
7115 : .WinDiffTrans;
7116 : } else { // Regular window
7117 7104180 : TDifBare = state.dataConstruction->Construct(ConstrNum).TransDiff;
7118 : }
7119 : }
7120 :
7121 : //-----------------------------------------------------------------
7122 : // BLOCK 3 - SCREEN, BLINDS AND GLAZING SYSTEM BEAM SOLAR TRANSMITTANCE
7123 : //-----------------------------------------------------------------
7124 7117655 : if (ConstrNumSh != 0 && SunLitFract > 0.0) {
7125 114957 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) {
7126 114957 : if (IS_SHADED_NO_GLARE_CTRL(ShadeFlag)) {
7127 : // Shade or screen or blind on, or switchable glazing
7128 : // (note in the following that diffusing glass is not allowed in a window with shade, blind or switchable glazing)
7129 87666 : if (ANY_SHADE(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
7130 : // Shade on or switchable glazing
7131 74039 : TBmAllShBlSc = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef);
7132 : } else {
7133 : // Blind or Screen on
7134 : Real64 TScBmDif; // Beam-diffuse solar transmittance of screen
7135 : Real64 TBlBmDif; // Beam-diffuse solar transmittance of blind
7136 : Real64 TBlDifDif; // Diffuse-diffuse solar transmittance of blind
7137 : Real64 TScBmBm;
7138 : Real64 TBlBmBm;
7139 13627 : if (ShadeFlag == WinShadingType::ExtScreen) { // Exterior screen
7140 1624 : Real64 RScBack = state.dataHeatBal->SurfaceScreens(ScNum).ReflectSolBeamFront;
7141 1624 : Real64 RScDifDifBk = state.dataHeatBal->SurfaceScreens(ScNum).DifReflect; // Diffuse-diffuse back refectance of screen
7142 1624 : Real64 RGlBmFr = POLYF(
7143 3248 : CosInc, state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef); // Beam front reflectance of glass
7144 : Real64 RGlDifFr =
7145 1624 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront; // Diffuse front reflectance of glass
7146 : // beam transmittance (written in subroutine CalcScreenTransmittance each time step)
7147 1624 : TScBmBm = state.dataHeatBal->SurfaceScreens(ScNum).BmBmTrans;
7148 1624 : TBmBmSc = TBmBm * TScBmBm;
7149 1624 : TScBmDif = state.dataHeatBal->SurfaceScreens(ScNum).BmDifTrans;
7150 : // beam-beam and diffuse transmittance of exterior beam
7151 3248 : TBmAllShBlSc = TScBmBm * (TBmBm + RGlBmFr * RScBack * TDifBare / (1 - RGlDifFr * RScDifDifBk)) +
7152 1624 : TScBmDif * TDifBare / (1 - RGlDifFr * RScDifDifBk);
7153 1624 : TBmBmShBlSc = TBmBmSc;
7154 1624 : TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
7155 : // Report variable for Beam-to-Diffuse transmittance (scattered transmittance)
7156 1624 : state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = TBmBmSc;
7157 1624 : state.dataSurface->SurfWinScTsolBmBm(SurfNum) = TScBmBm;
7158 1624 : state.dataSurface->SurfWinScTsolBmDif(SurfNum) = TScBmDif;
7159 : } else {
7160 12003 : TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum);
7161 12003 : TBlBmDif = FrontBeamDiffTrans;
7162 12003 : if (ShadeFlag == WinShadingType::IntBlind) {
7163 9329 : Real64 RhoBlBmDifFr = FrontBeamDiffRefl; // Beam-diffuse front reflectance of blind
7164 : Real64 RGlDifBk =
7165 9329 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; // Diffuse front reflectance of glass
7166 9329 : Real64 RhoBlDifDifFr = FrontDiffDiffRefl; // Diffuse-diffuse front refectance of blind
7167 : // beam-beam and diffuse transmittance of exterior beam
7168 9329 : TBmBmBl = TBmBm * TBlBmBm;
7169 9329 : TBlDifDif = FrontDiffDiffTrans;
7170 9329 : TBmAllShBlSc =
7171 9329 : TBmBm * (TBlBmBm + TBlBmDif + TBlDifDif * RhoBlBmDifFr * RGlDifBk / (1 - RhoBlDifDifFr * RGlDifBk));
7172 9329 : TBmBmShBlSc = TBmBmBl; // TBmBm * TBlBmBm
7173 9329 : TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
7174 9329 : if (TBmDifShBlSc < 0.0) TBmDifShBlSc = 0.0;
7175 2674 : } else if (ShadeFlag == WinShadingType::ExtBlind) {
7176 728 : Real64 RhoBlBmDifBk = BackBeamDiffRefl; // Beam-diffuse back reflectance of blind
7177 728 : Real64 RhoBlDifDifBk = BackDiffDiffRefl; // Diffuse-diffuse back refectance of blind
7178 728 : Real64 RGlBmFr = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef);
7179 728 : Real64 RGlDifFr = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront;
7180 : // beam-beam and diffuse transmittance of exterior beam
7181 728 : TBmBmBl = TBmBm * TBlBmBm;
7182 1456 : TBmAllShBlSc = TBlBmBm * (TBmBm + TDifBare * RGlBmFr * RhoBlBmDifBk / (1 - RGlDifFr * RhoBlDifDifBk)) +
7183 728 : TBlBmDif * TDifBare / (1 - RGlDifFr * RhoBlDifDifBk);
7184 728 : TBmBmShBlSc = TBmBmBl; // TBmBm * TBlBmBm
7185 728 : TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
7186 : } else {
7187 : // Between-glass blind on
7188 1946 : int NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
7189 1946 : Real64 td2 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(2);
7190 1946 : Real64 rbd1 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(1);
7191 1946 : Real64 rbshB = BackBeamDiffRefl;
7192 1946 : Real64 rfshd = FrontDiffDiffRefl;
7193 1946 : Real64 rbshd = BackDiffDiffRefl;
7194 1946 : Real64 tfshBd = FrontBeamDiffTrans;
7195 1946 : Real64 t1 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(1));
7196 1946 : Real64 t2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(2));
7197 1946 : Real64 tfshBB = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum);
7198 1946 : if (NGlass == 2) {
7199 1218 : Real64 rf2 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(2));
7200 1218 : Real64 rfshB = FrontBeamDiffRefl;
7201 1218 : Real64 rfd2 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(2);
7202 1218 : TBmBmBl = t1 * tfshBB * t2;
7203 2436 : TBmAllShBlSc = t1 * tfshBB * t2 +
7204 1218 : t1 * (tfshBB * rf2 * rbshB + tfshBd * (1.0 + rfd2 * rbshd) + rfshB * rbd1 * rfshd) * td2;
7205 : } else { // NGlass = 3
7206 728 : Real64 t1t2 = t1 * t2;
7207 728 : Real64 t3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).tBareSolCoef(3));
7208 728 : Real64 td3 = state.dataConstruction->Construct(ConstrNum).tBareSolDiff(3);
7209 728 : Real64 rf3 = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).rfBareSolCoef(3));
7210 728 : Real64 rbd2 = state.dataConstruction->Construct(ConstrNum).rbBareSolDiff(2);
7211 728 : Real64 rfd3 = state.dataConstruction->Construct(ConstrNum).rfBareSolDiff(3);
7212 728 : Real64 tfshd = FrontDiffDiffTrans;
7213 728 : TBmBmBl = t1 * t2 * tfshBB * t3;
7214 2184 : TBmAllShBlSc = t1t2 * tfshBB * t3 + t1t2 *
7215 1456 : (tfshBB * rf3 * rbshB + tfshBd * (1.0 + rfd3 * rbshd) +
7216 1456 : rbshB * (rbd2 * tfshd + td2 * rbd1 * td2 * tfshd)) *
7217 : td3;
7218 : }
7219 : // added TH 12/9/2009
7220 1946 : TBmBmShBlSc = TBmBmBl;
7221 1946 : TBmDifShBlSc = TBmAllShBlSc - TBmBmShBlSc;
7222 : }
7223 12003 : state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = TBlBmBm;
7224 12003 : state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = TBlBmDif;
7225 12003 : state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = TBmBmBl;
7226 : }
7227 : }
7228 : } // End of check if ShadeFlag > 0 and ShadeFlag < 10
7229 : } // end of checking if not eql window model
7230 : } // end of checking if sunlitfract > 0
7231 :
7232 7117655 : if (ShadeFlag == WinShadingType::SwitchableGlazing) {
7233 : // Switchable glazing
7234 71254 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
7235 71254 : if (!state.dataSurface->SurfWinSolarDiffusing(SurfNum)) {
7236 71254 : TBmBm = General::InterpSw(SwitchFac, TBmBm, TBmAllShBlSc);
7237 : } else {
7238 0 : TBmDif = General::InterpSw(SwitchFac, TBmDif, TBmAllShBlSc);
7239 : }
7240 : }
7241 : // Report variables
7242 7117655 : state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = TBmBm;
7243 7117655 : state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = TBmDif;
7244 7117655 : state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = TDifBare;
7245 :
7246 : //-----------------------------------------------------------------
7247 : // BLOCK 4 - REPORT WINDOW TRANSMITTANCE
7248 : //-----------------------------------------------------------------
7249 :
7250 : // The following SurfWinTransBmSolar and SurfWinTransDifSolar will be combined later to give
7251 : // WinTransSolar for reporting
7252 7117655 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) = 0.0;
7253 7117655 : state.dataSolarShading->SurfWinTransDifSolar(SurfNum) = 0.0;
7254 7117655 : state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum) = 0.0;
7255 7117655 : state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) = 0.0;
7256 7117655 : state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
7257 : 0.0; // Factor for exterior beam to beam solar transmitted through window, or window plus shade, into zone at current time (m2)
7258 7117655 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
7259 : 0.0; // Factor for exterior beam to diffuse solar transmitted through window, or window plus shade, into zone at current time (m2)
7260 :
7261 7117655 : Real64 InOutProjSLFracMult = state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
7262 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) {
7263 7115177 : state.dataSolarShading->SurfWinTransDifSolar(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7264 7115177 : if (ANY_BLIND(ShadeFlag)) {
7265 18094 : if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
7266 : DataWindowEquivalentLayer::Orientation::Horizontal) {
7267 18094 : state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum) = DiffTransGnd * state.dataSurface->Surface(SurfNum).Area;
7268 18094 : state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) = DiffTransSky * state.dataSurface->Surface(SurfNum).Area;
7269 : }
7270 : }
7271 : } else {
7272 : // In equivalent layer window model system diffuse transmittance is based on unit
7273 : // diffuse radiation flux, and hence doesn't distinguish between sky and
7274 : // ground reflected diffuse radiations
7275 2478 : state.dataSolarShading->SurfWinTransDifSolar(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7276 2478 : state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7277 2478 : state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) = DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7278 : }
7279 :
7280 7117655 : if (!IS_SHADED_NO_GLARE_CTRL(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
7281 : // Unshaded or switchable glazing
7282 : // Note: with previous defs of TBmBm & TBmDif, these come out right for Complex Fenestration
7283 : // SurfWinTransBmSolar uses the directional-hemispherical transmittance
7284 7057787 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) =
7285 7057787 : (TBmBm + TBmDif) * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
7286 7057787 : state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
7287 7057787 : TBmBm * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
7288 7057787 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
7289 7057787 : TBmDif * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
7290 :
7291 : } else {
7292 59868 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) =
7293 59868 : TBmAllShBlSc * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
7294 59868 : state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
7295 59868 : TBmBmShBlSc * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
7296 59868 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
7297 59868 : TBmDifShBlSc * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
7298 : }
7299 :
7300 : // Add diffuse transmitted by window from beam reflected from outside reveal
7301 7117655 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { // Complex Fenestration
7302 12243 : if (FenSolAbsPtr == 0) {
7303 12145 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) =
7304 12145 : (TBmBm + TBmDif) * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult;
7305 12145 : state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum) =
7306 12145 : TBmBm * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
7307 12145 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) =
7308 12145 : TBmDif * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // m2
7309 12145 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) +=
7310 12145 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * NomDiffTrans * state.dataSurface->Surface(SurfNum).Area;
7311 12145 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) +=
7312 12145 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * NomDiffTrans * state.dataSurface->Surface(SurfNum).Area;
7313 : } else {
7314 98 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) = 0.0;
7315 98 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) = 0.0;
7316 : }
7317 : } else { // Regular window
7318 : // this is also valid for equivalent layer window
7319 7105412 : state.dataSolarShading->SurfWinTransBmSolar(SurfNum) +=
7320 7105412 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7321 7105412 : state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum) +=
7322 7105412 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7323 : }
7324 :
7325 : //-----------------------------------------------------------------
7326 : // BLOCK 5 - UPDATE SOLAR ENTERING A ZONE AS BEAM OR DIFFUSE RADIATION
7327 : //-----------------------------------------------------------------
7328 : // Increment factor for total exterior beam solar entering zone through window as beam or diffuse
7329 7117655 : if (SunLitFract > 0.0 && state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome) {
7330 : // Window is schedule surface gained. Do not make addition to what enters into zone since that information is not available
7331 3660579 : if (FenSolAbsPtr == 0) {
7332 : Real64 TBmAll; // Window beam-to-(beam+diffuse) transmittance
7333 7344723 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::BSDF &&
7334 7296233 : (ANY_BLIND(ShadeFlag) || ANY_SHADE_SCREEN(ShadeFlag))) {
7335 30082 : TBmAll = TBmAllShBlSc;
7336 : } else {
7337 3630441 : TBmAll = TBmBm + TBmDif;
7338 : }
7339 3660523 : BTOTZone += TBmAll * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult; // [m2]
7340 : }
7341 : }
7342 :
7343 : // Correct for effect of (1) beam absorbed by inside reveal, (2) diffuse entering zone from beam
7344 : // reflected by inside reveal and (3) diffuse transmitted by window from beam reflected from outside reveal.
7345 7117655 : if (CosInc > 0.0) {
7346 : // The BTOTZone is the solar into zone assuming no inside or outside reveals
7347 : // The inside reveals receive solar (reflected part + absorbed part) from the window, this amount should be deducted from the
7348 : // BTOTZone, then adds the InsRevealDiffIntoZone
7349 3852729 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { // Complex Fenestration
7350 : // Do not add total into zone from scheduled surface gains. That will be added later
7351 6461 : if (SurfaceScheduledSolarInc(state, SurfNum, ConstrNum) == 0) {
7352 6461 : BTOTZone =
7353 12922 : BTOTZone - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) -
7354 12922 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) +
7355 6461 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * NomDiffTrans * state.dataSurface->Surface(SurfNum).Area;
7356 : }
7357 : } else { // Regular window
7358 11538804 : BTOTZone = BTOTZone - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) -
7359 7692536 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) +
7360 3846268 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) * DiffTrans * state.dataSurface->Surface(SurfNum).Area;
7361 : }
7362 : // Add beam solar absorbed by outside reveal to outside of window's base surface. Add beam solar absorbed by inside reveal to inside
7363 : // of window's base surface. This ignores 2-D heat transfer effects.
7364 3852729 : int BaseSurfNum = state.dataSurface->Surface(SurfNum).BaseSurf;
7365 3852729 : state.dataSurface->SurfOpaqAI(BaseSurfNum) +=
7366 3852729 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) / state.dataSurface->Surface(BaseSurfNum).Area;
7367 3852729 : state.dataSurface->SurfOpaqAO(BaseSurfNum) +=
7368 3852729 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) / state.dataSurface->Surface(BaseSurfNum).Area;
7369 : }
7370 :
7371 : //-----------------------------------------------------------------
7372 : // BLOCK 6 - INTERIOR BEAM FROM EXTERIOR WINDOW THAT IS ABSORBED/TRANSMITTED BY BACK SURFACES
7373 : //-----------------------------------------------------------------
7374 :
7375 : // If shade is in place or there is a diffusing glass layer there is no interior beam
7376 : // from this exterior window since the beam-beam transmittance of shades and diffusing glass
7377 : // is assumed to be zero. The beam-beam transmittance of tubular daylighting devices is also
7378 : // assumed to be zero.
7379 :
7380 7117655 : if (SunLitFract > 0.0) {
7381 3661727 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::BSDF)
7382 14588154 : if (ANY_SHADE(ShadeFlag) || state.dataSurface->SurfWinSolarDiffusing(SurfNum) ||
7383 10931740 : state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser ||
7384 3637663 : state.dataSurface->Surface(SurfNum).Class == SurfaceClass::TDD_Dome)
7385 18751 : continue;
7386 :
7387 : // Find interior beam radiation that is:
7388 : // (1) absorbed by opaque back surfaces;
7389 : // (2) absorbed by glass layers of back surfaces that are interior or exterior windows;
7390 : // (3) absorbed by interior, exterior or between-glass shades or blinds of back surfaces
7391 : // that are exterior windows; and
7392 : // (4) transmitted through back surfaces that are interior or exterior windows.
7393 : // Beam-beam transmittance of exterior window
7394 : Real64 TBm; // Window beam-beam transmittance
7395 : Real64 TBmDenom; // TBmDenominator
7396 3642976 : Real64 TBmBmSc = state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum);
7397 3642976 : Real64 TBmBmBl = state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum);
7398 3642976 : Real64 TBmBm = state.dataSurface->SurfWinGlTsolBmBm(SurfNum);
7399 :
7400 3642976 : Real64 InOutProjSLFracMult = state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(state.dataGlobal->HourOfDay);
7401 3642976 : int InShelfSurf = 0; // Inside daylighting shelf surface number
7402 3642976 : int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum);
7403 3642976 : if (ShelfNum > 0) { // Daylighting shelf
7404 364 : InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf;
7405 : }
7406 3642976 : if (ANY_BLIND(ShadeFlag)) {
7407 12003 : TBm = TBmBmBl; // Interior, exterior or between-glass blind on
7408 3630973 : } else if (ShadeFlag == WinShadingType::ExtScreen) {
7409 1624 : TBm = TBmBmSc; // Exterior screen on
7410 : } else {
7411 3629349 : TBm = TBmBm; // Bare glass or switchable glazing
7412 : // Correction for beam absorbed by inside reveal
7413 3629349 : TBmDenom = (SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * InOutProjSLFracMult);
7414 3629349 : if (TBmDenom != 0.0) { // when =0.0, no correction
7415 3629349 : TBm -= state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) / TBmDenom;
7416 : }
7417 3629349 : TBm = max(0.0, TBm);
7418 : }
7419 :
7420 3642976 : if (TBm == 0.0) continue;
7421 3627602 : if (InShelfSurf > 0) { // Inside daylighting shelf
7422 : // Inside daylighting shelves assume that no beam will pass the end of the shelf.
7423 : // Since all beam is absorbed on the shelf, this might cause them to get unrealistically hot at times.
7424 : // BTOTWinZone - Transmitted beam solar factor for a window [m2]
7425 364 : Real64 BTOTWinZone = TBm * SunLitFract * state.dataSurface->Surface(SurfNum).Area * CosInc * InOutProjSLFracMult;
7426 : // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
7427 364 : state.dataSurface->SurfOpaqAI(InShelfSurf) += BTOTWinZone / (0.5 * state.dataSurface->Surface(InShelfSurf).Area); //[-]
7428 364 : BABSZone += BTOTWinZone; //[m2]
7429 364 : continue;
7430 : }
7431 :
7432 3627238 : if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) { // Full interior solar distribution
7433 2434124 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) {
7434 : // Loop over back surfaces irradiated by beam from this exterior window
7435 6907178 : for (int IBack = 1; IBack <= state.dataBSDFWindow->MaxBkSurf; ++IBack) {
7436 : int BackSurfNum =
7437 6907178 : state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
7438 6907178 : if (BackSurfNum == 0) break; // No more irradiated back surfaces for this exterior window
7439 4478451 : int ConstrNumBack = state.dataSurface->SurfActiveConstruction(BackSurfNum);
7440 4478451 : int NBackGlass = state.dataConstruction->Construct(ConstrNumBack).TotGlassLayers;
7441 : // Irradiated (overlap) area for this back surface, projected onto window plane
7442 : // (includes effect of shadowing on exterior window)
7443 : Real64 AOverlap =
7444 4478451 : state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
7445 : // Back surface area irradiated by beam solar from an exterior window, projected onto window plane
7446 4478451 : Real64 BOverlap = TBm * AOverlap * CosInc; //[m2]
7447 : // AOverlap multiplied by exterior window beam transmittance and cosine of incidence angle
7448 4478451 : if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
7449 :
7450 : // Back surface is opaque interior or exterior wall
7451 : // Interior solar absorptance of opaque surface
7452 4193441 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(BackSurfNum);
7453 4193441 : state.dataSurface->SurfOpaqAI(BackSurfNum) +=
7454 4193441 : BOverlap * AbsIntSurf / state.dataSurface->Surface(BackSurfNum).Area; //[-]
7455 4193441 : BABSZone += BOverlap * AbsIntSurf; //[m2]
7456 :
7457 : } else {
7458 :
7459 : // Back surface is an interior or exterior window
7460 : // Note that exterior back windows can have a shading device but interior back windows
7461 : // are assumed to be bare, i.e., they have no shading device and are non-switchable.
7462 : // The layer order for interior windows is "outside" to "inside," where "outside" refers to
7463 : // the adjacent zone and "inside" refers to the current zone.
7464 285010 : WinShadingType ShadeFlagBack = state.dataSurface->SurfWinShadingFlag(BackSurfNum);
7465 285010 : Real64 SlatAngBack = state.dataSurface->SurfWinSlatAngThisTS(BackSurfNum);
7466 : Real64 CosIncBack =
7467 285010 : std::abs(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, BackSurfNum));
7468 285010 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
7469 : // Transmitting window is complex fen, change the incident angle to one for ray joining
7470 : // transmitting and back window centers
7471 0 : CosIncBack = std::abs(state.dataBSDFWindow->ComplexWind(SurfNum).sdotN(IBack));
7472 : }
7473 285010 : int ConstrNumBackShRaw = state.dataSurface->SurfWinActiveShadedConstruction(BackSurfNum);
7474 285010 : int const ConstrNumBackSh = ConstrNumBackShRaw == 0 ? ConstrNumBack : ConstrNumBackShRaw;
7475 285010 : state.dataSolarShading->SurfWinAbsBeam.dimension(state.dataHeatBal->MaxSolidWinLayers, 0.0);
7476 285010 : Real64 TransBeamWin = 0.0; // Beam solar transmittance of a window
7477 285010 : Real64 AbsBeamTotWin = 0.0; // Sum of window glass layer beam solar absorptances
7478 :
7479 : // Interior beam absorptance of glass layers and beam transmittance of back exterior &
7480 : // or interior window WITHOUT SHADING this timestep
7481 285010 : if (NOT_SHADED(ShadeFlagBack)) {
7482 710908 : for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
7483 425898 : state.dataSolarShading->SurfWinAbsBeam(Lay) =
7484 425898 : POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).AbsBeamBackCoef(Lay));
7485 : }
7486 285010 : TransBeamWin = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef);
7487 : }
7488 :
7489 : // Interior beam absorptance of glass layers and beam transmittance
7490 : // of back exterior window with SHADE
7491 285010 : if (ANY_SHADE(ShadeFlagBack)) {
7492 0 : for (int Lay = 1; Lay <= state.dataConstruction->Construct(ConstrNumBackSh).TotGlassLayers; ++Lay) {
7493 0 : state.dataSolarShading->SurfWinAbsBeam(Lay) =
7494 0 : POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).AbsBeamBackCoef(Lay));
7495 : }
7496 0 : TransBeamWin = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).TransSolBeamCoef);
7497 : }
7498 :
7499 : // Interior beam absorbed by INTERIOR SHADE of back exterior window
7500 :
7501 285010 : if (ShadeFlagBack == WinShadingType::IntShade) {
7502 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7503 0 : BOverlap * state.dataConstruction->Construct(ConstrNumBackSh).AbsDiffBackShade /
7504 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
7505 0 : BABSZone += BOverlap * state.dataConstruction->Construct(ConstrNumBackSh).AbsDiffBackShade;
7506 285010 : } else if (ShadeFlagBack ==
7507 : WinShadingType::ExtShade) { // Interior beam absorbed by EXTERIOR SHADE of back exterior window
7508 0 : Real64 RGlFront = state.dataConstruction->Construct(ConstrNumBack).ReflectSolDiffFront;
7509 : Real64 AbsSh =
7510 0 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(1)).AbsorpSolar;
7511 : Real64 RhoSh =
7512 0 : 1.0 - AbsSh -
7513 0 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(1)).Trans;
7514 0 : Real64 AShBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef) * AbsSh /
7515 0 : (1.0 - RGlFront * RhoSh);
7516 0 : BABSZone += BOverlap * AShBack;
7517 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7518 0 : BOverlap * AShBack /
7519 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
7520 285010 : } else if (ShadeFlagBack ==
7521 : WinShadingType::BGShade) { // Interior beam absorbed by BETWEEN-GLASS SHADE of back exterior window
7522 0 : Real64 rbd1k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(1);
7523 0 : Real64 rfd2k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(2);
7524 : Real64 AShBack; // System shade absorptance for interior beam solar
7525 0 : if (NBackGlass == 2) {
7526 0 : Real64 t2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(2));
7527 0 : Real64 TrSh = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(3))
7528 0 : .Trans; // Shade material solar transmittance
7529 0 : Real64 RhoSh = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(3))
7530 0 : .ReflectShade; // Shade material solar absorptance
7531 0 : Real64 AbsSh = min(1.0, max(0.0, 1 - TrSh - RhoSh)); // Shade material solar absorptance
7532 0 : AShBack = t2k * (1 + RhoSh * rfd2k + TrSh * rbd1k) * AbsSh;
7533 : } else { // NBackGlass = 3
7534 0 : Real64 t3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(3));
7535 0 : Real64 td2k = state.dataConstruction->Construct(ConstrNumBack).tBareSolDiff(2);
7536 0 : Real64 rbd2k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(2);
7537 0 : Real64 rfd3k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(3);
7538 : Real64 TrSh =
7539 0 : state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(5)).Trans;
7540 0 : Real64 RhoSh = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumBackSh).LayerPoint(5))
7541 0 : .ReflectShade;
7542 0 : Real64 AbsSh = min(1.0, max(0.0, 1 - TrSh - RhoSh));
7543 0 : AShBack = t3k * (1 + RhoSh * rfd3k + TrSh * (rbd2k + td2k * rbd1k * td2k)) * AbsSh;
7544 : }
7545 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7546 0 : BOverlap * AShBack / state.dataSurface->Surface(BackSurfNum).Area;
7547 0 : BABSZone += BOverlap * AShBack;
7548 : }
7549 :
7550 : // Interior beam absorptance of glass layers and beam absorbed in blind
7551 : // of back exterior window with BLIND
7552 285010 : if (ANY_BLIND(ShadeFlagBack)) {
7553 0 : int BlNumBack = state.dataSurface->SurfWinBlindNumber(BackSurfNum); // Back surface blind number
7554 : Real64 ProfAngBack =
7555 0 : state.dataSurface->SurfWinProfileAng(BackSurfNum); // Back window solar profile angle (radians)
7556 :
7557 0 : int SlatsAngIndexLowerBack = state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum);
7558 0 : int ProfAngIndexLowerBack = state.dataSurface->SurfWinProfAngIndex(BackSurfNum);
7559 0 : int SlatsAngIndexUpperBack = std::min(MaxProfAngs, SlatsAngIndexLowerBack + 1);
7560 0 : int ProfAngIndexUpperBack = std::min(MaxProfAngs, ProfAngIndexLowerBack + 1);
7561 0 : Real64 SlatsAngInterpFacBack = state.dataSurface->SurfWinSlatsAngInterpFac(BackSurfNum);
7562 0 : Real64 ProfAngInterpFacBack = state.dataSurface->SurfWinProfAngInterpFac(BackSurfNum);
7563 :
7564 0 : Real64 TGlBmBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef);
7565 0 : Real64 TBlBmBmBack = General::BlindBeamBeamTrans(
7566 : ProfAngBack,
7567 : DataGlobalConstants::Pi - SlatAngBack,
7568 0 : state.dataHeatBal->Blind(BlNumBack).SlatWidth,
7569 0 : state.dataHeatBal->Blind(BlNumBack).SlatSeparation,
7570 0 : state.dataHeatBal->Blind(BlNumBack).SlatThickness); // Blind solar back beam-beam transmittance
7571 : Real64 TBlBmDiffBack; // Blind solar back beam-diffuse transmittance
7572 0 : if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
7573 0 : TBlBmDiffBack = General::InterpProfSlat(
7574 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7575 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7576 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7577 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7578 : SlatsAngInterpFacBack,
7579 : ProfAngInterpFacBack);
7580 : } else {
7581 0 : TBlBmDiffBack =
7582 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexLowerBack),
7583 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexUpperBack),
7584 : ProfAngInterpFacBack);
7585 : }
7586 :
7587 0 : if (ShadeFlagBack == WinShadingType::IntBlind) {
7588 : // Interior beam absorptance of GLASS LAYERS of exterior back window with INTERIOR BLIND
7589 : Real64 RhoBlFront; // Blind solar front diffuse reflectance
7590 : Real64 AbsBlFront; // Blind solar front beam absorptance
7591 : Real64 AbsBlBack; // Blind solar back beam absorptance
7592 0 : if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
7593 0 : FrontDiffDiffRefl =
7594 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(
7595 0 : state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum)),
7596 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(std::min(
7597 0 : MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum) + 1)),
7598 0 : state.dataSurface->SurfWinSlatsAngInterpFac(BackSurfNum));
7599 0 : FrontDiffAbs =
7600 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(
7601 0 : state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum)),
7602 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(std::min(
7603 0 : MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(BackSurfNum) + 1)),
7604 0 : state.dataSurface->SurfWinSlatsAngInterpFac(BackSurfNum));
7605 0 : RhoBlFront = General::InterpProfSlat(
7606 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7607 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7608 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7609 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7610 : SlatsAngInterpFacBack,
7611 : ProfAngInterpFacBack);
7612 0 : AbsBlFront = General::InterpProfSlat(
7613 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7614 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7615 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7616 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7617 : SlatsAngInterpFacBack,
7618 : ProfAngInterpFacBack);
7619 0 : AbsBlBack = General::InterpProfSlat(
7620 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7621 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7622 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7623 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7624 : SlatsAngInterpFacBack,
7625 : ProfAngInterpFacBack);
7626 : } else {
7627 0 : FrontDiffDiffRefl =
7628 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(1); // Blind solar front beam reflectance
7629 0 : FrontDiffAbs = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(1);
7630 0 : RhoBlFront =
7631 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexLowerBack),
7632 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexUpperBack),
7633 : ProfAngInterpFacBack);
7634 0 : AbsBlFront =
7635 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexLowerBack),
7636 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexUpperBack),
7637 : ProfAngInterpFacBack);
7638 0 : AbsBlBack =
7639 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLowerBack),
7640 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpperBack),
7641 : ProfAngInterpFacBack);
7642 : }
7643 :
7644 0 : Real64 RhoBlDiffFront = FrontDiffDiffRefl; // Glazing system solar back beam-beam reflectance
7645 0 : Real64 RGlBack = POLYF(CosIncBack,
7646 0 : state.dataConstruction->Construct(ConstrNumBack)
7647 0 : .ReflSolBeamBackCoef); // Glazing system back diffuse solar reflectance
7648 0 : Real64 RGlDiffBack = state.dataConstruction->Construct(ConstrNumBack).ReflectSolDiffBack;
7649 0 : for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
7650 : Real64 AbWinBack =
7651 : POLYF(CosIncBack,
7652 0 : state.dataConstruction->Construct(ConstrNumBack)
7653 0 : .AbsBeamBackCoef(Lay)); // Factor for back beam radiation absorbed in window glass layer
7654 0 : Real64 AGlDiffBack = state.dataConstruction->Construct(ConstrNumBack)
7655 0 : .AbsDiffBack(Lay); // Glass layer back diffuse solar absorptance
7656 0 : state.dataSolarShading->SurfWinAbsBeam(Lay) =
7657 0 : TBlBmBmBack * AbWinBack + ((TBlBmBmBack * RGlBack * RhoBlFront + TBlBmDiffBack) * AGlDiffBack /
7658 0 : (1.0 - RGlDiffBack * RhoBlDiffFront));
7659 : }
7660 :
7661 : // Interior beam transmitted by exterior back window with INTERIOR BLIND
7662 : Real64 TGlDif =
7663 0 : state.dataConstruction->Construct(ConstrNumBack).TransDiff; // Bare diffuse transmittance of back window
7664 0 : TransBeamWin =
7665 0 : TBlBmBmBack * (TGlBmBack + TGlDif * RGlBack * RhoBlFront / (1.0 - RGlDiffBack * RhoBlDiffFront)) +
7666 0 : TBlBmDiffBack * TGlDif / (1.0 - RGlDiffBack * RhoBlDiffFront);
7667 :
7668 : // Interior beam absorbed by BLIND on exterior back window with INTERIOR BLIND
7669 :
7670 0 : Real64 AbsBlDiffFront = FrontDiffAbs; // Blind solar front diffuse absorptance
7671 0 : Real64 ABlBack = AbsBlBack + TBlBmBmBack * RGlBack * AbsBlFront +
7672 0 : (AbsBlDiffFront * RGlDiffBack / (1 - RhoBlDiffFront * RGlDiffBack)) *
7673 0 : (RGlBack * TBlBmBmBack * RhoBlFront +
7674 : TBlBmDiffBack); // Blind solar back absorptance for interior solar
7675 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7676 0 : BOverlap * ABlBack /
7677 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
7678 0 : BABSZone += BOverlap * ABlBack;
7679 :
7680 0 : } else if (ShadeFlagBack == WinShadingType::ExtBlind) {
7681 :
7682 : // Interior beam absorptance of GLASS LAYERS of exterior back window with EXTERIOR BLIND
7683 :
7684 0 : Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNumBack)
7685 0 : .ReflectSolDiffFront; // Glazing system front diffuse solar reflectance
7686 : Real64 RhoBlBack; // Blind solar back beam-diffuse reflectance
7687 : Real64 RhoBlBmDifBk;
7688 : Real64 AbsBlBack;
7689 0 : if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
7690 0 : RhoBlBack = General::InterpProfSlat(
7691 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7692 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7693 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7694 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7695 : SlatsAngInterpFacBack,
7696 : ProfAngInterpFacBack);
7697 0 : RhoBlBmDifBk = General::InterpProfSlat(
7698 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7699 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7700 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7701 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7702 : SlatsAngInterpFacBack,
7703 : ProfAngInterpFacBack);
7704 0 : AbsBlBack = General::InterpProfSlat(
7705 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7706 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7707 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7708 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7709 : SlatsAngInterpFacBack,
7710 : ProfAngInterpFacBack);
7711 : } else {
7712 0 : RhoBlBack =
7713 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLowerBack),
7714 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpperBack),
7715 : ProfAngInterpFacBack);
7716 0 : RhoBlBmDifBk =
7717 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLowerBack),
7718 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpperBack),
7719 : ProfAngInterpFacBack);
7720 0 : AbsBlBack =
7721 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLowerBack),
7722 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpperBack),
7723 : ProfAngInterpFacBack);
7724 : }
7725 :
7726 0 : for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
7727 : Real64 AbWinBack =
7728 0 : POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).AbsBeamBackCoef(Lay));
7729 0 : Real64 AGlDiffFront = state.dataConstruction->Construct(ConstrNumBack).AbsDiff(Lay);
7730 0 : state.dataSolarShading->SurfWinAbsBeam(Lay) =
7731 0 : AbWinBack + (TGlBmBack * AGlDiffFront * RhoBlBack / (1.0 - RhoBlBack * RGlDiffFront));
7732 : }
7733 :
7734 : // Interior beam transmitted by exterior back window with EXTERIOR BLIND
7735 0 : Real64 TBlDifDif = BackDiffDiffTrans;
7736 0 : Real64 RhoBlDifDifBk = BackDiffDiffRefl;
7737 0 : Real64 AbsBlDiffBack = BackDiffAbs;
7738 0 : Real64 ABlBack =
7739 0 : TGlBmBack * (AbsBlBack + RhoBlBack * RGlDiffFront * AbsBlDiffBack / (1 - RhoBlDifDifBk * RGlDiffFront));
7740 0 : Real64 RGlDifFr = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront;
7741 0 : TransBeamWin = TGlBmBack * (TBlBmBmBack + TBlBmDiffBack +
7742 0 : TBlDifDif * RhoBlBmDifBk * RGlDifFr / (1.0 - RhoBlDifDifBk * RGlDifFr));
7743 : // Interior beam absorbed by EXTERIOR BLIND on exterior back window
7744 0 : BABSZone += BOverlap * ABlBack;
7745 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7746 0 : BOverlap * ABlBack /
7747 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
7748 :
7749 : } else {
7750 : // ShadeFlagBack == BGBlindOn
7751 0 : Real64 t1k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(1));
7752 0 : Real64 t2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(2));
7753 0 : Real64 af2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).afBareSolCoef(2));
7754 0 : Real64 ab1k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).abBareSolCoef(1));
7755 0 : Real64 ab2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).abBareSolCoef(2));
7756 0 : Real64 rb1k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).rbBareSolCoef(1));
7757 0 : Real64 rb2k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).rbBareSolCoef(2));
7758 0 : Real64 td1k = state.dataConstruction->Construct(ConstrNumBack).tBareSolDiff(1);
7759 0 : Real64 td2k = state.dataConstruction->Construct(ConstrNumBack).tBareSolDiff(2);
7760 0 : Real64 afd2k = state.dataConstruction->Construct(ConstrNumBack).afBareSolDiff(2);
7761 0 : Real64 abd1k = state.dataConstruction->Construct(ConstrNumBack).abBareSolDiff(1);
7762 0 : Real64 abd2k = state.dataConstruction->Construct(ConstrNumBack).abBareSolDiff(2);
7763 0 : Real64 rfd2k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(2);
7764 0 : Real64 rbd1k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(1);
7765 0 : Real64 rbd2k = state.dataConstruction->Construct(ConstrNumBack).rbBareSolDiff(2);
7766 0 : Real64 tfshBBk = General::BlindBeamBeamTrans(ProfAngBack,
7767 : SlatAngBack,
7768 0 : state.dataHeatBal->Blind(BlNumBack).SlatWidth,
7769 0 : state.dataHeatBal->Blind(BlNumBack).SlatSeparation,
7770 0 : state.dataHeatBal->Blind(BlNumBack).SlatThickness);
7771 0 : Real64 tbshBBk = General::BlindBeamBeamTrans(ProfAngBack,
7772 : DataGlobalConstants::Pi - SlatAngBack,
7773 0 : state.dataHeatBal->Blind(BlNumBack).SlatWidth,
7774 0 : state.dataHeatBal->Blind(BlNumBack).SlatSeparation,
7775 0 : state.dataHeatBal->Blind(BlNumBack).SlatThickness);
7776 :
7777 : Real64 tfshBdk =
7778 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexLowerBack),
7779 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, ProfAngIndexUpperBack),
7780 0 : ProfAngInterpFacBack);
7781 : Real64 tbshBdk =
7782 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexLowerBack),
7783 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(1, ProfAngIndexUpperBack),
7784 0 : ProfAngInterpFacBack);
7785 : Real64 rfshBk =
7786 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexLowerBack),
7787 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(1, ProfAngIndexUpperBack),
7788 0 : ProfAngInterpFacBack);
7789 : Real64 rbshBk =
7790 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexLowerBack),
7791 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(1, ProfAngIndexUpperBack),
7792 0 : ProfAngInterpFacBack);
7793 : Real64 afshBk =
7794 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexLowerBack),
7795 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(1, ProfAngIndexUpperBack),
7796 0 : ProfAngInterpFacBack);
7797 : Real64 abshBk =
7798 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexLowerBack),
7799 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(1, ProfAngIndexUpperBack),
7800 0 : ProfAngInterpFacBack);
7801 0 : Real64 tfshdk = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffTrans(1);
7802 0 : Real64 rfshdk = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(1);
7803 0 : Real64 afshdk = state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(1);
7804 0 : Real64 tbshdk = state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffTrans(1);
7805 0 : Real64 rbshdk = state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffRefl(1);
7806 0 : Real64 abshdk = state.dataHeatBal->Blind(BlNumBack).SolBackDiffAbs(1);
7807 0 : if (state.dataSurface->SurfWinMovableSlats(BackSurfNum)) {
7808 0 : tfshdk = General::InterpGeneral(
7809 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffTrans(SlatsAngIndexLowerBack),
7810 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffTrans(SlatsAngIndexUpperBack),
7811 : SlatsAngInterpFacBack);
7812 0 : rfshdk = General::InterpGeneral(
7813 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(SlatsAngIndexLowerBack),
7814 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffDiffRefl(SlatsAngIndexUpperBack),
7815 : SlatsAngInterpFacBack);
7816 0 : afshdk =
7817 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(SlatsAngIndexLowerBack),
7818 0 : state.dataHeatBal->Blind(BlNumBack).SolFrontDiffAbs(SlatsAngIndexUpperBack),
7819 : SlatsAngInterpFacBack);
7820 0 : tbshdk = General::InterpGeneral(
7821 0 : state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffTrans(SlatsAngIndexLowerBack),
7822 0 : state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffTrans(SlatsAngIndexUpperBack),
7823 : SlatsAngInterpFacBack);
7824 0 : rbshdk = General::InterpGeneral(
7825 0 : state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffRefl(SlatsAngIndexLowerBack),
7826 0 : state.dataHeatBal->Blind(BlNumBack).SolBackDiffDiffRefl(SlatsAngIndexUpperBack),
7827 : SlatsAngInterpFacBack);
7828 0 : abshdk =
7829 0 : General::InterpGeneral(state.dataHeatBal->Blind(BlNumBack).SolBackDiffAbs(SlatsAngIndexLowerBack),
7830 0 : state.dataHeatBal->Blind(BlNumBack).SolBackDiffAbs(SlatsAngIndexUpperBack),
7831 : SlatsAngInterpFacBack);
7832 0 : tfshBdk = General::InterpProfSlat(
7833 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7834 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7835 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7836 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7837 : SlatsAngInterpFacBack,
7838 : ProfAngInterpFacBack);
7839 0 : tbshBdk = General::InterpProfSlat(
7840 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7841 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7842 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7843 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffTrans(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7844 : SlatsAngInterpFacBack,
7845 : ProfAngInterpFacBack);
7846 0 : rfshBk = General::InterpProfSlat(
7847 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7848 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7849 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7850 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7851 : SlatsAngInterpFacBack,
7852 : ProfAngInterpFacBack);
7853 0 : rbshBk = General::InterpProfSlat(
7854 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7855 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7856 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7857 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamDiffRefl(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7858 : SlatsAngInterpFacBack,
7859 : ProfAngInterpFacBack);
7860 0 : afshBk = General::InterpProfSlat(
7861 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7862 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7863 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7864 0 : state.dataHeatBal->Blind(BlNum).SolFrontBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7865 : SlatsAngInterpFacBack,
7866 : ProfAngInterpFacBack);
7867 0 : abshBk = General::InterpProfSlat(
7868 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexLowerBack),
7869 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexLowerBack),
7870 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexLowerBack, ProfAngIndexUpperBack),
7871 0 : state.dataHeatBal->Blind(BlNum).SolBackBeamAbs(SlatsAngIndexUpperBack, ProfAngIndexUpperBack),
7872 : SlatsAngInterpFacBack,
7873 : ProfAngInterpFacBack);
7874 : }
7875 :
7876 : Real64 ABlBack;
7877 0 : if (NBackGlass == 2) {
7878 : // Interior beam absorptance of GLASS LAYERS of exterior back window with BETWEEN-GLASS BLIND
7879 0 : state.dataSolarShading->SurfWinAbsBeam(2) =
7880 0 : ab2k + t2k * tbshBBk * rb1k * tfshBBk * af2k +
7881 0 : t2k * (tbshBBk * rb1k * tfshBdk + tbshBdk * rbd1k * tfshdk + rbshBk * (1.0 + rfd2k * rbshdk)) * afd2k;
7882 0 : state.dataSolarShading->SurfWinAbsBeam(1) =
7883 0 : t2k * tbshBBk * ab1k + t2k * (rbshBk * rfd2k * tbshdk + tbshBdk * (1.0 + rbd1k * rfshdk)) * abd1k;
7884 : // Interior beam transmitted by exterior back window with BETWEEN-GLASS BLIND
7885 0 : TransBeamWin =
7886 0 : t2k * tbshBBk * t1k +
7887 0 : t2k * (tbshBBk * rb1k * rfshBk + rbshBk * rfd2k * tbshdk + tbshBdk * (1.0 + rbd1k * rfshdk)) * td1k;
7888 : // Interior beam absorbed by BLIND on exterior back window with BETWEEN-GLASS BLIND
7889 0 : ABlBack = t2k * (abshBk + tbshBBk * rb1k * afshBk + rbshBk * rfd2k * abshdk + tbshBdk * rbd1k * afshdk);
7890 : } else { // NBackGlass = 3
7891 0 : Real64 t3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).tBareSolCoef(3));
7892 0 : Real64 af3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).afBareSolCoef(3));
7893 0 : Real64 ab3k = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).abBareSolCoef(3));
7894 0 : Real64 afd3k = state.dataConstruction->Construct(ConstrNumBack).afBareSolDiff(3);
7895 0 : Real64 rfd3k = state.dataConstruction->Construct(ConstrNumBack).rfBareSolDiff(3);
7896 0 : state.dataSolarShading->SurfWinAbsBeam(3) =
7897 0 : ab3k + t3k * tbshBBk * (rb2k + t2k * rb1k * t2k) * tfshBBk * af3k +
7898 0 : t3k *
7899 0 : (tbshBdk * rbd2k * tfshdk + tbshBdk * td2k * rbd1k * td2k * tfshdk +
7900 0 : rbshBk * (1.0 + rfd3k * rbshdk)) *
7901 : afd3k;
7902 0 : state.dataSolarShading->SurfWinAbsBeam(2) =
7903 0 : t3k * tbshBBk * (ab2k + t2k * rb1k * (af2k + t2k * rfshBk * abd2k)) +
7904 0 : t3k * (tbshBdk + tbshBdk * (rbd2k + td2k * rbd1k * td2k) * rfshdk + rbshBk * rfd3k * tbshdk) * abd2k +
7905 0 : t3k * tbshBdk * td2k * rbd1k * afd2k;
7906 0 : state.dataSolarShading->SurfWinAbsBeam(1) =
7907 0 : t3k * tbshBBk * (t2k * ab1k + (rb2k + t2k * rb1k * t2k) * rfshBk * td2k * abd1k) +
7908 0 : t3k * (rbshBk * rfd3k * tbshdk + tbshBdk * (1.0 + rbd2k * rfshdk + td2k * rbd2k * td2k * rfshdk)) *
7909 0 : td2k * abd1k;
7910 0 : TransBeamWin = t3k * tbshBBk * t2k * t1k +
7911 0 : t3k *
7912 0 : (tbshBBk * (rb2k * rfshBk + t2k * rb1k * t2k * rfshBk) + rbshBk * rfd3k * tbshdk +
7913 0 : tbshBdk * (1.0 + rbd2k * rfshdk + td2k * rbd1k * td2k * rfshdk)) *
7914 0 : td2k * td1k;
7915 0 : ABlBack = t3k * abshBk + t3k * tbshBBk * (rb2k + t2k * rb1k * t2k) * afshBk +
7916 0 : t3k * rbshBk * rfd3k * abshdk + t3k * tbshBdk * (rbd2k + td2k * rbd1k * td2k) * afshdk;
7917 : }
7918 :
7919 0 : BABSZone += BOverlap * ABlBack;
7920 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7921 0 : BOverlap * ABlBack / state.dataSurface->Surface(BackSurfNum).Area;
7922 :
7923 : } // End of check if between-glass blind is on back window
7924 285010 : } else if (ShadeFlagBack == WinShadingType::ExtScreen) {
7925 :
7926 : // Interior beam absorptance of GLASS LAYERS of exterior back window with EXTERIOR SCREEN
7927 0 : int ScNumBack = state.dataSurface->SurfWinScreenNumber(BackSurfNum); // Back surface screen number
7928 0 : Real64 TGlBmBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).TransSolBeamCoef);
7929 0 : Real64 RGlDiffFront = state.dataConstruction->Construct(ConstrNumBack).ReflectSolDiffFront;
7930 : Real64 TScBmBmBack =
7931 0 : state.dataHeatBal->SurfaceScreens(ScNumBack).BmBmTransBack; // Screen solar back beam-beam transmittance
7932 : Real64 TScBmDiffBack =
7933 0 : state.dataHeatBal->SurfaceScreens(ScNumBack).BmDifTransBack; // Screen solar back beam-diffuse transmittance
7934 0 : Real64 RScBack = state.dataHeatBal->SurfaceScreens(ScNumBack).ReflectSolBeamFront;
7935 0 : Real64 RScDifBack = state.dataHeatBal->SurfaceScreens(ScNumBack).DifReflect;
7936 0 : for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
7937 0 : Real64 AbWinBack = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBack).AbsBeamBackCoef(Lay));
7938 0 : Real64 AGlDiffFront = state.dataConstruction->Construct(ConstrNumBack).AbsDiff(Lay);
7939 0 : state.dataSolarShading->SurfWinAbsBeam(Lay) =
7940 0 : AbWinBack + (TGlBmBack * AGlDiffFront * RScBack / (1.0 - RScDifBack * RGlDiffFront));
7941 : }
7942 :
7943 : // Interior beam transmitted by exterior back window with EXTERIOR SCREEN
7944 0 : Real64 TScDifDif = state.dataHeatBal->SurfaceScreens(ScNumBack).DifDifTrans;
7945 : Real64 RScBmDifBk =
7946 0 : state.dataHeatBal->SurfaceScreens(ScNumBack).ReflectSolBeamBack; // Beam-diffuse back reflectance of blind
7947 0 : Real64 RGlDifFr = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront;
7948 0 : Real64 RScDifDifBk = state.dataHeatBal->SurfaceScreens(ScNumBack).DifReflect;
7949 0 : TransBeamWin = TGlBmBack *
7950 0 : (TScBmBmBack + TScBmDiffBack + TScDifDif * RScBmDifBk * RGlDifFr / (1.0 - RScDifDifBk * RGlDifFr));
7951 :
7952 : // Interior beam absorbed by EXTERIOR SCREEN on exterior back window
7953 : Real64 AbsScBack =
7954 0 : state.dataHeatBal->SurfaceScreens(ScNumBack).AbsorpSolarBeamBack; // Screen solar back beam absorptance
7955 : Real64 AbsScDiffBack =
7956 0 : state.dataHeatBal->SurfaceScreens(ScNumBack).DifScreenAbsorp; // Screen solar back diffuse absorptance
7957 : Real64 RScDiffBack =
7958 0 : state.dataHeatBal->SurfaceScreens(ScNumBack).ReflectSolBeamFront; // Screen solar back diffuse reflectance
7959 0 : Real64 AScBack =
7960 : TGlBmBack *
7961 0 : (AbsScBack + RScBack * RGlDiffFront * AbsScDiffBack /
7962 0 : (1.0 - RScDiffBack * RGlDiffFront)); // Screen solar back absorptance for interior solar
7963 0 : BABSZone += BOverlap * AScBack;
7964 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
7965 0 : BOverlap * AScBack /
7966 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
7967 :
7968 : } // End of check if exterior screen on back window
7969 :
7970 : // Interior beam absorptance of glass layers of back exterior window with SWITCHABLE GLAZING
7971 285010 : if (ShadeFlagBack == WinShadingType::SwitchableGlazing && state.dataSurface->Surface(BackSurfNum).ExtBoundCond == 0) {
7972 0 : Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for a window
7973 : Real64 AbsBeamWinSh; // Glass layer beam solar absorptance of a shaded window
7974 0 : for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
7975 0 : AbsBeamWinSh = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).AbsBeamBackCoef(Lay));
7976 0 : state.dataSolarShading->SurfWinAbsBeam(Lay) =
7977 0 : General::InterpSw(SwitchFac, state.dataSolarShading->SurfWinAbsBeam(Lay), AbsBeamWinSh);
7978 : }
7979 : // Beam solar transmittance of a shaded window
7980 0 : Real64 TransBeamWinSh = POLYF(CosIncBack, state.dataConstruction->Construct(ConstrNumBackSh).TransSolBeamCoef);
7981 0 : TransBeamWin = General::InterpSw(SwitchFac, TransBeamWin, TransBeamWinSh);
7982 : }
7983 :
7984 : // Sum of interior beam absorbed by all glass layers of back window
7985 285010 : AbsBeamTotWin = 0.0;
7986 710908 : for (int Lay = 1; Lay <= NBackGlass; ++Lay) {
7987 425898 : AbsBeamTotWin += state.dataSolarShading->SurfWinAbsBeam(Lay);
7988 425898 : state.dataSurface->SurfWinA(BackSurfNum, Lay) +=
7989 851796 : BOverlap * state.dataSolarShading->SurfWinAbsBeam(Lay) /
7990 425898 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum)); //[-]
7991 : }
7992 :
7993 : // To BABSZon, add interior beam glass absorption and overall beam transmission for this back window
7994 285010 : BABSZone += BOverlap * (AbsBeamTotWin + TransBeamWin);
7995 : // Interior beam transmitted to adjacent zone through an interior back window (assumed unshaded);
7996 : // this beam radiation is categorized as diffuse radiation in the adjacent zone.
7997 285010 : int AdjSurfNum = state.dataSurface->Surface(BackSurfNum).ExtBoundCond;
7998 285010 : if (AdjSurfNum > 0) {
7999 399 : int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
8000 399 : state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) += BOverlap * TransBeamWin; //[m2]
8001 399 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) +=
8002 399 : BOverlap * TransBeamWin * state.dataEnvrn->BeamSolarRad; //[W]
8003 399 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(BackSurfNum) =
8004 399 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
8005 : }
8006 : } // End of check if back surface is opaque or window
8007 4478451 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) += BOverlap;
8008 4478451 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(BackSurfNum) =
8009 4478451 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
8010 : } // End of loop over back surfaces
8011 5397 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
8012 : // For complex window calculation goes over outgoing basis directions for current state
8013 : int CurCplxFenState =
8014 5397 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState; // Current state for complex fenestration
8015 : // Get construction number which keeps transmittance properties
8016 : int IConst =
8017 5397 : state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurCplxFenState).Konst; // Current surface construction number
8018 : // (it depends of state too)
8019 : // Solar radiation from this window will be calculated only in case when this window is not scheduled surface gained
8020 5397 : if (WindowScheduledSolarAbs(state, SurfNum, IConst) == 0) {
8021 : // Current incoming direction number (Sun direction)
8022 5341 : int IBm = state.dataBSDFWindow->ComplexWind(SurfNum)
8023 5341 : .Geom(CurCplxFenState)
8024 5341 : .SolBmIndex(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
8025 : // Report variables for complex fenestration here
8026 5341 : state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = IBm;
8027 5341 : state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) =
8028 5341 : state.dataBSDFWindow->ComplexWind(SurfNum)
8029 5341 : .Geom(CurCplxFenState)
8030 5341 : .ThetaBm(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
8031 10682 : state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = state.dataBSDFWindow->ComplexWind(SurfNum)
8032 5341 : .Geom(CurCplxFenState)
8033 5341 : .PhiBm(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
8034 :
8035 5341 : int BaseSurf = state.dataSurface->Surface(SurfNum).BaseSurf; // Base surface number for current complex window
8036 : // Get total number of back surfaces for current window (surface)
8037 : // Note that it is organized by base surface
8038 5341 : int NBkSurf = state.dataShadowComb->ShadowComb(BaseSurf).NumBackSurf;
8039 5341 : if (!allocated(CFBoverlap)) {
8040 5341 : CFBoverlap.allocate(NBkSurf);
8041 : }
8042 5341 : if (!allocated(CFDirBoverlap)) {
8043 5341 : CFDirBoverlap.allocate(NBkSurf, state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).Trn.NBasis);
8044 : }
8045 :
8046 5341 : CFBoverlap = 0.0;
8047 : // Calculate effects on all back surfaces for each of basis directions. Each of basis directions from the back of the
8048 : // window has to be considered as beam and therefore calcualte CFBoverlap for each of them
8049 491498 : for (int CurTrnDir = 1; CurTrnDir <= state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).Trn.NBasis;
8050 : ++CurTrnDir) {
8051 486157 : Real64 CurLambda = state.dataBSDFWindow->ComplexWind(SurfNum)
8052 486157 : .Geom(CurCplxFenState)
8053 486157 : .Trn.Lamda(CurTrnDir); // Current lambda value in BSDF outgoing directions
8054 486157 : Real64 DirTrans = state.dataConstruction->Construct(IConst).BSDFInput.SolFrtTrans(
8055 486157 : IBm, CurTrnDir); // Current BSDF directional transmittance
8056 : // Now calculate effect of this direction on all back surfaces
8057 3545346 : for (int IBack = 1; IBack <= NBkSurf; ++IBack) {
8058 3059189 : CFDirBoverlap(IBack, CurTrnDir) =
8059 3059189 : state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).AOverlap(IBack, CurTrnDir) * DirTrans *
8060 3059189 : CurLambda * CosInc;
8061 3059189 : CFBoverlap(IBack) += CFDirBoverlap(IBack, CurTrnDir);
8062 : } // DO IBack = 1,MaxBkSurf
8063 : }
8064 :
8065 : // Summarizing results
8066 38850 : for (int IBack = 1; IBack <= NBkSurf; ++IBack) {
8067 33509 : int BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(IBack);
8068 33509 : int ConstrNumBack = state.dataSurface->Surface(BackSurfaceNumber).Construction;
8069 : // Do not perform any calculation if surface is scheduled for incoming solar radiation
8070 33509 : int SurfSolIncPtr = SurfaceScheduledSolarInc(state, BackSurfaceNumber, ConstrNumBack);
8071 :
8072 33509 : if (SurfSolIncPtr == 0) {
8073 : // Surface hit is another complex fenestration
8074 33509 : if (state.dataSurface->SurfWinWindowModelType(BackSurfaceNumber) == WindowModel::BSDF) {
8075 : int CurBackState =
8076 6804 : state.dataSurface->SurfaceWindow(BackSurfaceNumber)
8077 6804 : .ComplexFen.CurrentState; // Current state for back surface if that surface is complex fenestration
8078 : // Do not take into account this window if it is scheduled for surface gains
8079 6804 : if (WindowScheduledSolarAbs(state, BackSurfaceNumber, ConstrNumBack) == 0) {
8080 : // Calculate energy loss per each outgoing orientation
8081 635208 : for (int CurTrnDir = 1;
8082 635208 : CurTrnDir <= state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).Trn.NBasis;
8083 : ++CurTrnDir) {
8084 : Real64 bestDot; // complex fenestration hits other complex fenestration, it is important to find
8085 : // matching beam directions. Beam leving one window will have certaing number for it's basis
8086 : // while same beam reaching back surface will have different beam number. This value is used
8087 : // to keep best matching dot product for those directions
8088 : Real64 curDot; // temporary variable for current dot product
8089 : int bestBackTrn; // Direction corresponding best dot product for back surface window
8090 77061768 : for (int CurBackDir = 1;
8091 77061768 : CurBackDir <= state.dataBSDFWindow->ComplexWind(BackSurfaceNumber).Geom(CurBackState).Trn.NBasis;
8092 : ++CurBackDir) {
8093 : // Purpose of this part is to find best match for outgoing beam number of window back surface
8094 : // and incoming beam number of complex fenestration which this beam will hit on (back surface
8095 : // again)
8096 76433364 : curDot =
8097 76433364 : dot(state.dataBSDFWindow->ComplexWind(SurfNum).Geom(CurCplxFenState).sTrn(CurTrnDir),
8098 76433364 : state.dataBSDFWindow->ComplexWind(BackSurfaceNumber).Geom(CurBackState).sTrn(CurBackDir));
8099 76433364 : if (CurBackDir == 1) {
8100 628404 : bestDot = curDot;
8101 628404 : bestBackTrn = CurBackDir;
8102 : } else {
8103 75804960 : if (curDot < bestDot) {
8104 8032227 : bestDot = curDot;
8105 8032227 : bestBackTrn = CurBackDir;
8106 : }
8107 : }
8108 : }
8109 : // CurLambda = ComplexWind(BackSurfaceNumber)%Geom(CurBackState)%Trn%Lamda(CurTrnDir)
8110 : // Add influence of this exact direction to what stays in the zone. It is important to note that
8111 : // this needs to be done for each outgoing direction
8112 1256808 : BABSZone += CFDirBoverlap(IBack, CurTrnDir) * (1 - state.dataSurface->SurfaceWindow(BackSurfaceNumber)
8113 628404 : .ComplexFen.State(CurBackState)
8114 628404 : .IntegratedBkRefl(bestBackTrn));
8115 :
8116 : // Absorptance from current back direction
8117 628404 : int TotSolidLay = state.dataConstruction->Construct(ConstrNumBack).TotSolidLayers;
8118 2625266 : for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
8119 : // IF (ALLOCATED(Construct(ConstrNumBack)%BSDFInput)) THEN
8120 : // CFDirBoverlap is energy transmitted for current basis beam. It is important to note that
8121 : // AWinOverlap array needs to contain flux and not absorbed energy because later in the code
8122 : // this will be multiplied with window area
8123 1996862 : state.dataSurface->SurfWinACFOverlap(BackSurfaceNumber, Lay) +=
8124 3993724 : state.dataConstruction->Construct(ConstrNumBack).BSDFInput.Layer(Lay).BkAbs(bestBackTrn, 1) *
8125 3993724 : CFDirBoverlap(IBack, CurTrnDir) / state.dataSurface->Surface(BackSurfaceNumber).Area;
8126 : // END IF
8127 : }
8128 :
8129 : // Interior beam transmitted to adjacent zone through an interior back window;
8130 : // This beam radiation is categorized as diffuse radiation in the adjacent zone.
8131 : // Note that this is done for each outgoing direction of exterior window
8132 628404 : int AdjSurfNum = state.dataSurface->Surface(BackSurfaceNumber).ExtBoundCond;
8133 628404 : if (AdjSurfNum > 0) {
8134 0 : int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
8135 0 : state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) +=
8136 0 : CFDirBoverlap(IBack, CurTrnDir) * state.dataSurface->SurfaceWindow(BackSurfaceNumber)
8137 0 : .ComplexFen.State(CurBackState)
8138 0 : .IntegratedBkTrans(bestBackTrn);
8139 0 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfaceNumber) +=
8140 0 : CFDirBoverlap(IBack, CurTrnDir) *
8141 0 : state.dataSurface->SurfaceWindow(BackSurfaceNumber)
8142 0 : .ComplexFen.State(CurBackState)
8143 0 : .IntegratedBkTrans(bestBackTrn) *
8144 0 : state.dataEnvrn->BeamSolarRad; //[W]
8145 0 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(BackSurfaceNumber) =
8146 0 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfaceNumber) *
8147 0 : state.dataGlobal->TimeStepZoneSec;
8148 : }
8149 : }
8150 : }
8151 : } else {
8152 26705 : if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
8153 : // Do not take into account this window if it is scheduled for surface gains
8154 26705 : Real64 AbsIntSurf = state.dataConstruction->Construct(ConstrNumBack).InsideAbsorpSolar;
8155 26705 : state.dataSurface->SurfOpaqAI(BackSurfaceNumber) +=
8156 26705 : CFBoverlap(IBack) * AbsIntSurf / state.dataSurface->Surface(BackSurfaceNumber).Area;
8157 26705 : BABSZone += CFBoverlap(IBack) * AbsIntSurf;
8158 : } else {
8159 : // Code for mixed windows goes here. It is same as above code for "ordinary" windows.
8160 : // Try to do something which will not produce duplicate code.
8161 : }
8162 : }
8163 : }
8164 : }
8165 :
8166 5341 : if (allocated(CFBoverlap)) CFBoverlap.deallocate();
8167 5341 : if (allocated(CFDirBoverlap)) CFDirBoverlap.deallocate();
8168 : }
8169 :
8170 0 : } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) {
8171 :
8172 0 : for (int IBack = 1; IBack <= state.dataBSDFWindow->MaxBkSurf; ++IBack) {
8173 : int BackSurfNum =
8174 0 : state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
8175 0 : if (BackSurfNum == 0) break; // No more irradiated back surfaces for this exterior window
8176 0 : if (state.dataSurface->SurfWinWindowModelType(IBack) != WindowModel::EQL) continue; // only EQL back window is allowed
8177 :
8178 0 : int ConstrNumBack = state.dataSurface->Surface(BackSurfNum).Construction;
8179 0 : int NBackGlass = state.dataConstruction->Construct(ConstrNumBack).TotGlassLayers;
8180 : // Irradiated (overlap) area for this back surface, projected onto window plane
8181 : // (includes effect of shadowing on exterior window)
8182 :
8183 : Real64 AOverlap =
8184 0 : state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
8185 0 : Real64 BOverlap = TBm * AOverlap * CosInc; //[m2]
8186 :
8187 0 : if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
8188 :
8189 : // Back surface is opaque interior or exterior wall
8190 0 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(BackSurfNum);
8191 0 : state.dataSurface->SurfOpaqAI(BackSurfNum) +=
8192 0 : BOverlap * AbsIntSurf / state.dataSurface->Surface(BackSurfNum).Area; //[-]
8193 0 : BABSZone += BOverlap * AbsIntSurf; //[m2]
8194 :
8195 : } else {
8196 :
8197 : // Back surface is an interior or exterior window
8198 : // Note that exterior back windows with and without shades are treated as defined.
8199 : // Equivalent Layer window model has no distinction when treating windows with and
8200 : // without shades (interior, inbetween and exterior shades)
8201 : // Note in equivalent layer window model if storm window exists it is defined as part of
8202 : // window construction, hence it does not require a separate treatment
8203 0 : state.dataSolarShading->SurfWinAbsBeamEQL = 0.0;
8204 0 : Real64 TransBeamWin = 0.0; // Beam solar transmittance of a window
8205 :
8206 : // Interior beam absorptance of glass layers and beam transmittance of back exterior &
8207 : // or interior window (treates windows with/without shades as defined) for this timestep
8208 :
8209 : // call the ASHWAT fenestration model for beam radiation here
8210 0 : WindowEquivalentLayer::CalcEQLOpticalProperty(
8211 0 : state, BackSurfNum, SolarArrays::BEAM, state.dataSolarShading->SurfWinAbsSolBeamBackEQL);
8212 0 : auto &CFS = state.dataWindowEquivLayer->CFS;
8213 0 : int EQLNum = state.dataConstruction->Construct(ConstrNumBack).EQLConsPtr;
8214 0 : state.dataSolarShading->SurfWinAbsBeamEQL({1, CFS(EQLNum).NL}) =
8215 0 : state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, {1, CFS(EQLNum).NL});
8216 : // get the interior beam transmitted through back exterior or interior EQL window
8217 0 : TransBeamWin = state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, CFS(EQLNum).NL + 1);
8218 : // Absorbed by the interior shade layer of back exterior window
8219 0 : if (CFS(EQLNum).L(CFS(EQLNum).NL).LTYPE != LayerType::GLAZE) {
8220 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
8221 0 : BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, CFS(EQLNum).NL) /
8222 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
8223 0 : BABSZone += BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, CFS(EQLNum).NL);
8224 : }
8225 : // Absorbed by the exterior shade layer of back exterior window
8226 0 : if (CFS(EQLNum).L(1).LTYPE != LayerType::GLAZE) {
8227 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) =
8228 0 : BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, 1) /
8229 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum));
8230 0 : BABSZone += BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, 1);
8231 : }
8232 :
8233 : // determine the number of glass layers
8234 0 : NBackGlass = 0;
8235 0 : for (int Lay = 1; Lay <= CFS(EQLNum).NL; ++Lay) {
8236 0 : if (CFS(EQLNum).L(Lay).LTYPE != LayerType::GLAZE) continue;
8237 0 : ++NBackGlass;
8238 : }
8239 0 : if (NBackGlass >= 2) {
8240 : // If the number of glass is greater than 2, in between glass shade can be present
8241 0 : for (int Lay = 2; Lay <= CFS(EQLNum).NL - 1; ++Lay) {
8242 0 : if (CFS(EQLNum).L(CFS(EQLNum).NL).LTYPE != LayerType::GLAZE) {
8243 : // if there is in between shade glass determine the shade absorptance
8244 0 : state.dataSolarShading->SurfWinIntBeamAbsByShadFac(BackSurfNum) +=
8245 0 : BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, Lay) /
8246 0 : state.dataSurface->Surface(BackSurfNum).Area;
8247 0 : BABSZone += BOverlap * state.dataSolarShading->SurfWinAbsSolBeamBackEQL(1, Lay);
8248 : }
8249 : }
8250 : }
8251 : // Sum of interior beam absorbed by all glass layers of back window
8252 0 : Real64 AbsBeamTotWin = 0.0; // Glass layer beam solar absorptance of a shaded window
8253 0 : for (int Lay = 1; Lay <= CFS(EQLNum).NL; ++Lay) {
8254 0 : AbsBeamTotWin += state.dataSolarShading->SurfWinAbsBeamEQL(Lay);
8255 0 : state.dataSurface->SurfWinA(BackSurfNum, Lay) +=
8256 0 : BOverlap * state.dataSolarShading->SurfWinAbsBeamEQL(Lay) /
8257 0 : (state.dataSurface->Surface(BackSurfNum).Area + state.dataSurface->SurfWinDividerArea(BackSurfNum)); //[-]
8258 : }
8259 :
8260 : // To BABSZon, add interior beam glass absorption and overall beam transmission for this back window
8261 :
8262 0 : BABSZone += BOverlap * (AbsBeamTotWin + TransBeamWin);
8263 :
8264 : // Interior beam transmitted to adjacent zone through an interior back window (assumed unshaded);
8265 : // this beam radiation is categorized as diffuse radiation in the adjacent zone.
8266 :
8267 0 : int AdjSurfNum = state.dataSurface->Surface(BackSurfNum).ExtBoundCond;
8268 0 : if (AdjSurfNum > 0) {
8269 0 : int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
8270 0 : state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) += BOverlap * TransBeamWin; //[m2]
8271 0 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) +=
8272 0 : BOverlap * TransBeamWin * state.dataEnvrn->BeamSolarRad; //[W]
8273 0 : state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(BackSurfNum) =
8274 0 : state.dataSurface->SurfWinBmSolTransThruIntWinRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
8275 : }
8276 : } // End of check if back surface is opaque or window
8277 0 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) += BOverlap;
8278 0 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(BackSurfNum) =
8279 0 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(BackSurfNum) * state.dataGlobal->TimeStepZoneSec;
8280 : } // End of loop over back surfaces
8281 :
8282 : // *****************************
8283 :
8284 : } // IF (SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: BSDF) THEN
8285 : } else { // Simple interior solar distribution. All beam from exterior windows falls on floor;
8286 : // some of this is absorbed/transmitted, rest is reflected to other surfaces.
8287 :
8288 17702651 : for (int const FloorNum : thisEnclosure.SurfacePtr) {
8289 : // In following, ISABSF is zero except for nominal floor surfaces
8290 16509537 : if (state.dataSolarShading->SurfIntAbsFac(FloorNum) <= 0.0 || FloorNum == SurfNum) continue; // Keep only floor surfaces
8291 1375112 : int const FlConstrNum = state.dataSurface->SurfActiveConstruction(FloorNum);
8292 :
8293 1375112 : Real64 BTOTWinZone = TBm * SunLitFract * state.dataSurface->Surface(SurfNum).Area * CosInc * InOutProjSLFracMult; //[m2]
8294 1375112 : Real64 AbsBeamTotWin = 0.0;
8295 :
8296 1375112 : if (state.dataConstruction->Construct(FlConstrNum).TransDiff <= 0.0) {
8297 : // Opaque surface
8298 1375112 : state.dataSurface->SurfOpaqAI(FloorNum) +=
8299 1375112 : BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) / state.dataSurface->Surface(FloorNum).Area; //[-]
8300 : } else {
8301 : // Window
8302 :
8303 : // Note that diffuse solar absorptance is used here for floor windows even though we're
8304 : // dealing with incident beam radiation. This is because, for this simple interior distribution,
8305 : // the beam radiation from exterior windows is assumed to be uniformly distributed over the
8306 : // floor and so it makes no sense to use directional absorptances. Note also that floor windows
8307 : // are assumed to not have blinds or shades in this calculation.
8308 : // For the case of the floor window a complex fenestration (strange situation) the correct back
8309 : // diffuse layer absorptions have already been put into the construction
8310 :
8311 0 : for (int Lay = 1; Lay <= state.dataConstruction->Construct(FlConstrNum).TotGlassLayers; ++Lay) {
8312 0 : AbsBeamTotWin += state.dataConstruction->Construct(FlConstrNum).AbsDiffBack(Lay);
8313 : }
8314 : // In the following we have to multiply by the AbsDiffBack(Lay)/AbsBeamTotWin ratio to get the
8315 : // layer by layer absorbed beam since ISABSF(FloorNum) is proportional to AbsBeamTotWin
8316 : // (see ComputeIntSolarAbsorpFactors).
8317 :
8318 0 : for (int Lay = 1; Lay <= state.dataConstruction->Construct(FlConstrNum).TotGlassLayers; ++Lay) {
8319 0 : state.dataSurface->SurfWinA(FloorNum, Lay) +=
8320 0 : state.dataConstruction->Construct(FlConstrNum).AbsDiffBack(Lay) / AbsBeamTotWin * BTOTWinZone *
8321 0 : state.dataSolarShading->SurfIntAbsFac(FloorNum) / state.dataSurface->Surface(FloorNum).Area; //[-]
8322 : }
8323 : }
8324 :
8325 1375112 : BABSZone += BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum); //[m2]
8326 :
8327 1375112 : int AdjSurfNum = state.dataSurface->Surface(FloorNum).ExtBoundCond;
8328 1375112 : if (state.dataConstruction->Construct(FlConstrNum).TransDiff > 0.0 && AdjSurfNum > 0) {
8329 :
8330 : // Window in an interior floor
8331 :
8332 0 : int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
8333 :
8334 : // Contribution (assumed diffuse) to adjacent zone of beam radiation passing
8335 : // through this window
8336 0 : state.dataHeatBal->EnclSolDBIntWin(adjEnclosureNum) += BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) *
8337 0 : state.dataConstruction->Construct(FlConstrNum).TransDiff /
8338 : AbsBeamTotWin;
8339 :
8340 0 : BABSZone += BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) *
8341 0 : state.dataConstruction->Construct(FlConstrNum).TransDiff / AbsBeamTotWin;
8342 : }
8343 :
8344 : } // End of loop over floor sections
8345 : } // End of check on complex vs. simple interior solar distribution
8346 :
8347 : } // End of sunlit fraction > 0 test
8348 : } // End of first loop over surfaces in zone
8349 :
8350 5843681 : Real64 BABSZoneSSG = 0.0; // Beam radiation from exterior windows absorbed in a zone (only for scheduled surface gains)
8351 5843681 : Real64 BTOTZoneSSG = 0.0; // Solar entering a zone in case of scheduled surface gains
8352 5844269 : for (int iSSG = 1; iSSG <= state.dataSurface->TotSurfIncSolSSG; ++iSSG) {
8353 588 : int SurfNum = state.dataSurface->SurfIncSolSSG(iSSG).SurfPtr;
8354 : // do calculation only if construction number match.
8355 588 : if (state.dataSurface->SurfIncSolSSG(iSSG).ConstrPtr == state.dataSurface->Surface(SurfNum).Construction) {
8356 588 : if (state.dataSurface->Surface(SurfNum).SolarEnclIndex == enclosureNum) {
8357 588 : Real64 AbsIntSurf = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).InsideAbsorpSolar;
8358 : // SolarIntoZone = GetCurrentScheduleValue(SurfIncSolSSG(iSSG)%SchedPtr) * Surface(SurfNum)%Area
8359 588 : Real64 SolarIntoZone = GetCurrentScheduleValue(
8360 1176 : state, state.dataSurface->SurfIncSolSSG(iSSG).SchedPtr); // Solar radiation into zone to current surface
8361 588 : state.dataSurface->SurfOpaqAI(SurfNum) = SolarIntoZone * AbsIntSurf;
8362 588 : BABSZoneSSG += state.dataSurface->SurfOpaqAI(SurfNum) * state.dataSurface->Surface(SurfNum).Area;
8363 588 : BTOTZoneSSG += SolarIntoZone * state.dataSurface->Surface(SurfNum).Area;
8364 : }
8365 : }
8366 : }
8367 5843681 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) = BTOTZoneSSG - BABSZoneSSG;
8368 5843681 : state.dataHeatBal->EnclSolDB(enclosureNum) = BTOTZone - BABSZone;
8369 :
8370 5843681 : if (state.dataHeatBal->EnclSolDB(enclosureNum) < 0.0) {
8371 13846 : state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
8372 : }
8373 :
8374 : // Variables for reporting
8375 56358052 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
8376 50514371 : Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
8377 50514371 : Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
8378 50514371 : Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
8379 50514371 : Real64 currGndSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
8380 50514371 : if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) {
8381 33277199 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) *= currBeamSolarRad;
8382 33277199 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfNum) =
8383 33277199 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8384 33277199 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) =
8385 66554398 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) /
8386 33277199 : (state.dataSurface->Surface(SurfNum).Area + state.dataSurface->SurfWinDividerArea(SurfNum));
8387 : } else { // Simple interior solar distribution. All beam falls on floor.
8388 17237172 : if (state.dataSolarShading->SurfIntAbsFac(SurfNum) > 0.0 && state.dataSurface->Surface(SurfNum).HeatTransSurf) {
8389 3085832 : if (thisEnclosure.FloorArea > 0.0) {
8390 : // spread onto all floor surfaces, these may or may not be called "floor"
8391 3085832 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = currBeamSolarRad * BTOTZone / thisEnclosure.FloorArea;
8392 0 : } else if (thisEnclosure.TotalSurfArea > 0.0) {
8393 : // spread onto all interior surfaces
8394 0 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = currBeamSolarRad * BTOTZone / thisEnclosure.TotalSurfArea;
8395 : } else { // divide be zero otherwise
8396 0 : state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
8397 : }
8398 : }
8399 17237172 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) =
8400 17237172 : state.dataSurface->Surface(SurfNum).Area * state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum);
8401 17237172 : state.dataHeatBal->SurfBmIncInsSurfAmountRepEnergy(SurfNum) =
8402 17237172 : state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8403 : }
8404 93903809 : if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window ||
8405 43389438 : state.dataSurface->Surface(SurfNum).Class == SurfaceClass::TDD_Dome) {
8406 :
8407 7126165 : state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfNum);
8408 7126165 : state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum);
8409 :
8410 7134675 : if ((state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) ||
8411 8510 : (state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCondModeledExt)) {
8412 :
8413 7117655 : WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
8414 7117655 : int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum);
8415 7117655 : int OutShelfSurf = 0;
8416 7117655 : if (ShelfNum > 0) { // Outside daylighting shelf
8417 616 : OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf;
8418 : }
8419 :
8420 : // This lookup may be avoid if this 2nd surf loop can be combined with the 1st
8421 7117655 : if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
8422 1232 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8423 1232 : int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
8424 1232 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
8425 : // Exterior diffuse solar incident on window (W/m2)
8426 1232 : Real64 DifSolarInc = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) +
8427 1232 : currGndSolarRad * state.dataSurface->Surface(SurfNum2).ViewFactorGround;
8428 : // Exterior diffuse sky solar transmitted by TDD (W/m2)
8429 1232 : Real64 SkySolarTrans = currDifSolarRad * TransTDD(state, PipeNum, CosInc, DataDaylightingDevices::RadType::SolarAniso) *
8430 1232 : state.dataSolarShading->SurfAnisoSkyMult(SurfNum2);
8431 : // Exterior diffuse ground solar transmitted by TDD (W/m2)
8432 1232 : Real64 GndSolarTrans = currGndSolarRad * state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso *
8433 1232 : state.dataSurface->Surface(SurfNum2).ViewFactorGround;
8434 :
8435 1232 : state.dataSurface->SurfWinBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmSolar(SurfNum);
8436 1232 : state.dataSurface->SurfWinDifSolar(SurfNum) =
8437 1232 : SkySolarTrans * state.dataSurface->Surface(SurfNum).Area + GndSolarTrans * state.dataSurface->Surface(SurfNum).Area;
8438 1232 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) =
8439 1232 : state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8440 1232 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
8441 1232 : state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8442 :
8443 1232 : state.dataSurface->SurfWinTransSolar(SurfNum) =
8444 1232 : state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum); //[W]
8445 1232 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) =
8446 1232 : state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8447 :
8448 1232 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransmittedSolar = state.dataSurface->SurfWinTransSolar(SurfNum);
8449 : // TDDPipe(PipeNum)%TransSolBeam = TBmBm ! Reported above
8450 1232 : if (DifSolarInc > 0) {
8451 1232 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolDiff = (SkySolarTrans + GndSolarTrans) / DifSolarInc;
8452 : } else {
8453 0 : state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolDiff = 0.0;
8454 : }
8455 :
8456 7116423 : } else if (OutShelfSurf > 0) { // Outside daylighting shelf
8457 : Real64 ShelfSolarRad =
8458 616 : (currBeamSolarRad *
8459 1232 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
8460 1232 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
8461 616 : currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
8462 616 : state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
8463 :
8464 1232 : Real64 DifSolarInc = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum) +
8465 616 : currGndSolarRad * state.dataSurface->Surface(SurfNum).ViewFactorGround +
8466 616 : ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
8467 :
8468 616 : state.dataSurface->SurfWinBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmSolar(SurfNum);
8469 616 : state.dataSurface->SurfWinDifSolar(SurfNum) = DifSolarInc * state.dataSolarShading->SurfWinTransDifSolar(SurfNum);
8470 616 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) =
8471 616 : state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8472 616 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
8473 616 : state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8474 :
8475 616 : state.dataSurface->SurfWinTransSolar(SurfNum) =
8476 616 : state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum); //[W]
8477 616 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) =
8478 616 : state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8479 :
8480 : } else { // Regular window
8481 7115807 : Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum);
8482 7115807 : Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum);
8483 7115807 : Real64 DifSolarInc = SkySolarInc + GndSolarInc;
8484 7115807 : state.dataSurface->SurfWinBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmSolar(SurfNum);
8485 : // Note: for complex fenestration, SurfWinTransDifSolar has previously been defined using the effective
8486 : // transmittance for sky and ground diffuse radiation (including beam radiation reflected from the ground)
8487 : // so these calculations should be correct
8488 7115807 : state.dataSurface->SurfWinDifSolar(SurfNum) = DifSolarInc * state.dataSolarShading->SurfWinTransDifSolar(SurfNum);
8489 7115807 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) =
8490 7115807 : state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8491 7115807 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
8492 7115807 : state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8493 7115807 : if (ANY_BLIND(ShadeFlag)) {
8494 18094 : if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation ==
8495 : DataWindowEquivalentLayer::Orientation::Horizontal) {
8496 36188 : state.dataSurface->SurfWinDifSolar(SurfNum) = SkySolarInc * state.dataSolarShading->SurfWinTransDifSolarSky(SurfNum) +
8497 18094 : GndSolarInc * state.dataSolarShading->SurfWinTransDifSolarGnd(SurfNum);
8498 18094 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) =
8499 18094 : state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8500 : }
8501 : }
8502 :
8503 7115807 : state.dataSurface->SurfWinTransSolar(SurfNum) =
8504 7115807 : state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum); //[W]
8505 7115807 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) =
8506 7115807 : state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8507 : }
8508 :
8509 : // added TH 12/9/2009, CR 7907 & 7809
8510 7117655 : state.dataSurface->SurfWinBmBmSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmBmSolar(SurfNum);
8511 :
8512 7117655 : state.dataSurface->SurfWinBmDifSolar(SurfNum) = currBeamSolarRad * state.dataSolarShading->SurfWinTransBmDifSolar(SurfNum);
8513 7117655 : state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) =
8514 7117655 : state.dataSurface->SurfWinBmBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8515 7117655 : state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) =
8516 7117655 : state.dataSurface->SurfWinBmDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8517 :
8518 : // Solar not added by TDD:DOME; added to zone via TDD:DIFFUSER
8519 7117655 : if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::TDD_Dome) {
8520 7116423 : state.dataHeatBal->ZoneTransSolar(enclosureNum) += state.dataSurface->SurfWinTransSolar(SurfNum); //[W]
8521 7116423 : state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum) =
8522 7116423 : state.dataHeatBal->ZoneTransSolar(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8523 7116423 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinBmSolar(SurfNum);
8524 7116423 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinDifSolar(SurfNum);
8525 7116423 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum) =
8526 7116423 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8527 7116423 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum) =
8528 7116423 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8529 : }
8530 : }
8531 : }
8532 : } // End of second loop over surfaces in zone
8533 :
8534 : } // End of first zone loop
8535 :
8536 : // Add interior window contribution to EnclSolDB
8537 :
8538 6664958 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
8539 5843681 : state.dataHeatBal->EnclSolDB(enclosureNum) += state.dataHeatBal->EnclSolDBIntWin(enclosureNum);
8540 5843681 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) = state.dataHeatBal->EnclSolDBIntWin(enclosureNum) * state.dataEnvrn->BeamSolarRad;
8541 5843681 : state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclosureNum) =
8542 5843681 : state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8543 : }
8544 :
8545 : // RJH - Calculate initial distribution of diffuse solar transmitted by exterior windows into each zone
8546 : // to all interior surfaces in the zone
8547 : // Includes subsequent transmittance of diffuse solar to adjacent zones through interior windows
8548 821277 : CalcWinTransDifSolInitialDistribution(state);
8549 821277 : }
8550 826 : void CalcAbsorbedOnExteriorOpaqueSurfaces(EnergyPlusData &state)
8551 : {
8552 : // SUBROUTINE INFORMATION:
8553 : // AUTHOR Simon Vidanovic
8554 : // DATE WRITTEN May 2017
8555 : // MODIFIED na
8556 : // RE-ENGINEERED na
8557 :
8558 : // PURPOSE OF THIS SUBROUTINE:
8559 : // Calculates solar energy absorbed on exterior opaque surfaces
8560 :
8561 1652 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
8562 1652 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
8563 826 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
8564 6608 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
8565 : // TH added 3/24/2010 while debugging CR 7872
8566 5782 : if (!state.dataSurface->Surface(SurfNum).ExtSolar && state.dataSurface->SurfWinOriginalClass(SurfNum) != SurfaceClass::TDD_Diffuser)
8567 4130 : continue;
8568 1652 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
8569 1652 : int SurfNum2 = SurfNum;
8570 1652 : if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
8571 0 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8572 0 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
8573 : }
8574 1652 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
8575 1652 : Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
8576 :
8577 : //-------------------------------------------------------------------------
8578 : // EXTERIOR BEAM SOLAR RADIATION ABSORBED ON THE OUTSIDE OF OPAQUE SURFACES
8579 : //-------------------------------------------------------------------------
8580 :
8581 1652 : if (SunLitFract > 0.0 && state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) {
8582 490 : state.dataSurface->SurfOpaqAO(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar * CosInc * SunLitFract;
8583 :
8584 : // Note: movable insulation, if present, is accounted for in subr. InitIntSolarDistribution,
8585 : // where SurfQRadSWOutMvIns is calculated from SurfOpaqQRadSWOutAbs and insulation solar absorptance
8586 : }
8587 : }
8588 : }
8589 : }
8590 826 : }
8591 :
8592 826 : void CalcInteriorSolarDistributionWCESimple(EnergyPlusData &state)
8593 : {
8594 :
8595 : // SUBROUTINE INFORMATION:
8596 : // AUTHOR Simon Vidanovic
8597 : // DATE WRITTEN May 2017
8598 :
8599 : // PURPOSE OF THIS SUBROUTINE:
8600 : // For a time step, calculates solar radiation absorbed by window layers, sky and diffuse solar
8601 : // gain into zone from exterior window, beam solar on exterior window transmitted as beam and/or diffuse
8602 : // and interior beam from exterior window that is absorbed/transmitted by back surfaces
8603 :
8604 : using ScheduleManager::GetCurrentScheduleValue;
8605 : using namespace MultiLayerOptics;
8606 :
8607 1652 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
8608 1652 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
8609 826 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
8610 826 : int const firstSurf = thisSpace.HTSurfaceFirst;
8611 826 : int const lastSurf = thisSpace.HTSurfaceLast;
8612 6608 : for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
8613 5782 : state.dataSurface->SurfOpaqAI(surfNum) = 0.0;
8614 5782 : state.dataSurface->SurfOpaqAO(surfNum) = 0.0;
8615 : }
8616 : }
8617 : }
8618 :
8619 1652 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
8620 :
8621 826 : Real64 BABSZone = 0;
8622 826 : Real64 BTOTZone = 0;
8623 826 : state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
8624 826 : state.dataHeatBal->EnclSolDBIntWin(enclosureNum) = 0.0;
8625 826 : state.dataHeatBal->ZoneTransSolar(enclosureNum) = 0;
8626 826 : state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum) = 0;
8627 826 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) = 0;
8628 826 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) = 0;
8629 826 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum) = 0;
8630 826 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum) = 0;
8631 826 : auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
8632 :
8633 6608 : for (int const SurfNum : thisEnclosure.SurfacePtr) {
8634 5782 : if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Window) continue;
8635 826 : int SurfNum2 = 0;
8636 826 : if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) {
8637 0 : int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
8638 0 : SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;
8639 : } else {
8640 826 : SurfNum2 = SurfNum;
8641 : }
8642 826 : auto &window = state.dataSurface->SurfaceWindow(SurfNum2);
8643 826 : Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2); // Note: surfnum 2
8644 826 : Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
8645 :
8646 826 : std::pair<Real64, Real64> incomingAngle = getSunWCEAngles(state, SurfNum2, BSDFDirection::Incoming);
8647 826 : Real64 Theta = incomingAngle.first;
8648 826 : Real64 Phi = incomingAngle.second;
8649 :
8650 826 : int ConstrNum = state.dataSurface->Surface(SurfNum2).Construction;
8651 826 : if (state.dataSurface->Surface(SurfNum2).activeShadedConstruction > 0)
8652 826 : ConstrNum = state.dataSurface->Surface(SurfNum2).activeShadedConstruction;
8653 1652 : auto aLayer = CWindowConstructionsSimplified::instance().getEquivalentLayer(state, WavelengthRange::Solar, ConstrNum);
8654 :
8655 : ///////////////////////////////////////////////
8656 : // Solar absorbed in window layers
8657 : ///////////////////////////////////////////////
8658 826 : if (state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2) > 0.0) {
8659 490 : auto numOfLayers = aLayer->getNumOfLayers();
8660 490 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) {
8661 0 : auto CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
8662 0 : auto &cplxState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState);
8663 0 : for (size_t Lay = 1; Lay <= numOfLayers; ++Lay) {
8664 : // Simon: Imporant note about this equation is to use BeamSolarRad and not SurfQRadSWOutIncident
8665 : // is becuase BeamSolarRad is direct normal radiation (looking at the Sun) while SurfRadSWOutIncident
8666 : // is normal to window incidence. Since BSDF coefficients are taking into account angle of incidence,
8667 : // BeamSolarRad should be used in this case
8668 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
8669 0 : cplxState.WinSkyFtAbs(Lay) * state.dataSurface->SurfSkySolarInc(SurfNum2) +
8670 0 : cplxState.WinSkyGndAbs(Lay) * state.dataSurface->SurfGndSolarInc(SurfNum2) +
8671 0 : state.dataSurface->SurfWinA(SurfNum, Lay) * state.dataEnvrn->BeamSolarRad +
8672 0 : state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * state.dataEnvrn->BeamSolarRad;
8673 0 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
8674 0 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * state.dataSurface->Surface(SurfNum).Area;
8675 0 : state.dataSurface->SurfWinADiffFront(SurfNum, Lay) = cplxState.WinSkyGndAbs(Lay);
8676 : }
8677 : } else {
8678 1470 : for (size_t Lay = 1; Lay <= numOfLayers; ++Lay) {
8679 980 : auto AbWinBeam = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Direct, Theta, Phi) *
8680 980 : window.OutProjSLFracMult(state.dataGlobal->HourOfDay);
8681 980 : auto AbWinDiffFront = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Diffuse, Theta, Phi);
8682 : // auto AbWinDiffBack = aLayer->getAbsorptanceLayer(Lay, Side::Back, ScatteringSimple::Diffuse,
8683 : // Theta, Phi);
8684 :
8685 : // Simon: This should not be multiplied with cosine of incident angle. This however gives same
8686 : // results as BSDF and Winkelmann models.
8687 980 : state.dataSurface->SurfWinA(SurfNum, Lay) =
8688 1960 : AbWinBeam * CosInc * SunLitFract *
8689 980 : state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(state.dataGlobal->HourOfDay);
8690 980 : state.dataSurface->SurfWinADiffFront(SurfNum, Lay) = AbWinDiffFront;
8691 :
8692 : // Simon: Same not as for BSDF. Normal solar radiation should be taken here because angle of
8693 : // incidence is already taken into account
8694 980 : auto absBeam = state.dataSurface->SurfWinA(SurfNum, Lay) * state.dataEnvrn->BeamSolarRad;
8695 980 : auto absDiff = state.dataSurface->SurfWinADiffFront(SurfNum, Lay) *
8696 980 : (state.dataSurface->SurfSkySolarInc(SurfNum2) + state.dataSurface->SurfGndSolarInc(SurfNum2));
8697 980 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = (absBeam + absDiff);
8698 980 : state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
8699 980 : state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * state.dataSurface->Surface(SurfNum).Area;
8700 : }
8701 : }
8702 : }
8703 :
8704 : ////////////////////////////////////////////////////////////////////
8705 : // SKY AND GROUND DIFFUSE SOLAR GAIN INTO ZONE FROM EXTERIOR WINDOW
8706 : ////////////////////////////////////////////////////////////////////
8707 826 : const auto minLambda{0.3};
8708 826 : const auto maxLambda{2.5};
8709 : const Real64 Tdiff =
8710 826 : aLayer->getPropertySimple(minLambda, maxLambda, PropertySimple::T, Side::Front, Scattering::DiffuseDiffuse, Theta, Phi);
8711 826 : state.dataConstruction->Construct(ConstrNum).TransDiff = Tdiff;
8712 826 : Real64 EnclSolDSWin = state.dataSurface->SurfSkySolarInc(SurfNum2) * Tdiff * state.dataSurface->Surface(SurfNum2).Area;
8713 826 : if ((state.dataEnvrn->DifSolarRad != 0)) {
8714 826 : EnclSolDSWin /= state.dataEnvrn->DifSolarRad;
8715 : } else {
8716 0 : EnclSolDSWin /= 1e-8;
8717 : }
8718 :
8719 826 : Real64 EnclSolDGWin = state.dataSurface->SurfGndSolarInc(SurfNum2) * Tdiff * state.dataSurface->Surface(SurfNum2).Area;
8720 826 : (state.dataEnvrn->GndSolarRad != 0) ? EnclSolDGWin /= state.dataEnvrn->GndSolarRad : EnclSolDGWin /= 1e-8;
8721 :
8722 : ////////////////////////////////////////////////////////////////////
8723 : // BEAM SOLAR ON EXTERIOR WINDOW TRANSMITTED AS BEAM AND/OR DIFFUSE
8724 : ////////////////////////////////////////////////////////////////////
8725 826 : Real64 TBmBm = aLayer->getPropertySimple(minLambda, maxLambda, PropertySimple::T, Side::Front, Scattering::DirectDirect, Theta, Phi);
8726 826 : Real64 TBmDif = aLayer->getPropertySimple(minLambda, maxLambda, PropertySimple::T, Side::Front, Scattering::DirectDiffuse, Theta, Phi);
8727 : Real64 SurfWinTransBmBmSolar =
8728 826 : TBmBm * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * window.InOutProjSLFracMult(state.dataGlobal->HourOfDay);
8729 : Real64 SurfWinTransBmDifSolar =
8730 826 : TBmDif * SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * window.InOutProjSLFracMult(state.dataGlobal->HourOfDay);
8731 826 : BTOTZone += SurfWinTransBmBmSolar + SurfWinTransBmDifSolar;
8732 :
8733 826 : Real64 DifSolarRadiation = state.dataSurface->SurfSkySolarInc(SurfNum2) + state.dataSurface->SurfGndSolarInc(SurfNum2);
8734 826 : state.dataSurface->SurfWinBmSolar(SurfNum) =
8735 826 : state.dataEnvrn->BeamSolarRad * (TBmBm + TBmDif) * state.dataSurface->Surface(SurfNum).Area * CosInc;
8736 826 : state.dataSurface->SurfWinDifSolar(SurfNum) = DifSolarRadiation * Tdiff * state.dataSurface->Surface(SurfNum).Area;
8737 826 : state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = state.dataSurface->SurfWinBmSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8738 826 : state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = state.dataSurface->SurfWinDifSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8739 826 : state.dataSurface->SurfWinTransSolar(SurfNum) = state.dataSurface->SurfWinBmSolar(SurfNum) + state.dataSurface->SurfWinDifSolar(SurfNum);
8740 826 : state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = state.dataSurface->SurfWinTransSolar(SurfNum) * state.dataGlobal->TimeStepZoneSec;
8741 :
8742 : // Add beam solar absorbed by outside reveal to outside of window's base surface.
8743 : // Add beam solar absorbed by inside reveal to inside of window's base surface.
8744 : // This ignores 2-D heat transfer effects.
8745 826 : int BaseSurfNum = state.dataSurface->Surface(SurfNum).BaseSurf;
8746 826 : state.dataSurface->SurfOpaqAI(BaseSurfNum) =
8747 826 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum2) / state.dataSurface->Surface(BaseSurfNum).Area;
8748 826 : state.dataSurface->SurfOpaqAO(BaseSurfNum) =
8749 826 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum2) / state.dataSurface->Surface(BaseSurfNum).Area;
8750 :
8751 : ////////////////////////////////////////////////////////////////////
8752 : // BEAM SOLAR ON EXTERIOR WINDOW TRANSMITTED AS BEAM AND/OR DIFFUSE
8753 : ////////////////////////////////////////////////////////////////////
8754 826 : Real64 TBm = TBmBm;
8755 : // Correction for beam absorbed by inside reveal
8756 : Real64 TBmDenom =
8757 826 : SunLitFract * CosInc * state.dataSurface->Surface(SurfNum).Area * window.InOutProjSLFracMult(state.dataGlobal->HourOfDay);
8758 826 : if (TBmDenom != 0.0) { // when =0.0, no correction
8759 490 : TBm -= state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) / TBmDenom;
8760 : }
8761 :
8762 826 : TBm = max(0.0, TBm);
8763 :
8764 826 : int NumOfBackSurf = state.dataShadowComb->ShadowComb(BaseSurfNum).NumBackSurf;
8765 :
8766 826 : if (state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::FullInteriorExterior) {
8767 1792 : for (int IBack = 1; IBack <= NumOfBackSurf; ++IBack) {
8768 :
8769 : int const BackSurfNum =
8770 1792 : state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
8771 :
8772 1792 : if (BackSurfNum == 0) break; // No more irradiated back surfaces for this exterior window
8773 966 : int ConstrNumBack = state.dataSurface->Surface(BackSurfNum).Construction;
8774 : // NBackGlass = Construct( ConstrNumBack ).TotGlassLayers;
8775 : // Irradiated (overlap) area for this back surface, projected onto window plane
8776 : // (includes effect of shadowing on exterior window)
8777 966 : Real64 AOverlap = state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, IBack, SurfNum);
8778 966 : Real64 BOverlap = TBm * AOverlap * CosInc; //[m2]
8779 :
8780 966 : if (state.dataConstruction->Construct(ConstrNumBack).TransDiff <= 0.0) {
8781 : // Back surface is opaque interior or exterior wall
8782 :
8783 966 : Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(BackSurfNum);
8784 966 : state.dataSurface->SurfOpaqAI(BackSurfNum) += BOverlap * AbsIntSurf / state.dataSurface->Surface(BackSurfNum).Area; //[-]
8785 966 : BABSZone += BOverlap * AbsIntSurf; //[m2]
8786 : }
8787 : }
8788 : } else {
8789 0 : for (int const FloorNum : thisEnclosure.SurfacePtr) {
8790 : // In following, ISABSF is zero except for nominal floor surfaces
8791 0 : if (!state.dataSurface->Surface(FloorNum).HeatTransSurf) continue;
8792 0 : if (state.dataSolarShading->SurfIntAbsFac(FloorNum) <= 0.0 || FloorNum == SurfNum) continue; // Keep only floor surfaces
8793 :
8794 0 : Real64 BTOTWinZone = TBm * SunLitFract * state.dataSurface->Surface(SurfNum).Area * CosInc *
8795 0 : window.InOutProjSLFracMult(state.dataGlobal->HourOfDay); //[m2]
8796 :
8797 0 : if (state.dataConstruction->Construct(state.dataSurface->Surface(FloorNum).Construction).TransDiff <= 0.0) {
8798 : // Opaque surface
8799 0 : state.dataSurface->SurfOpaqAI(FloorNum) +=
8800 0 : BTOTWinZone * state.dataSolarShading->SurfIntAbsFac(FloorNum) / state.dataSurface->Surface(FloorNum).Area; //[-]
8801 : }
8802 : }
8803 : }
8804 826 : state.dataHeatBal->ZoneTransSolar(enclosureNum) += state.dataSurface->SurfWinTransSolar(SurfNum); //[W]
8805 826 : state.dataHeatBal->ZoneTransSolarEnergy(enclosureNum) =
8806 826 : state.dataHeatBal->ZoneTransSolar(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8807 826 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinBmSolar(SurfNum);
8808 826 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) += state.dataSurface->SurfWinDifSolar(SurfNum);
8809 826 : state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclosureNum) =
8810 826 : state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8811 826 : state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclosureNum) =
8812 826 : state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec; //[J]
8813 : }
8814 826 : state.dataHeatBal->EnclSolDB(enclosureNum) = BTOTZone - BABSZone;
8815 : }
8816 826 : }
8817 :
8818 36688 : int WindowScheduledSolarAbs(EnergyPlusData &state,
8819 : int const SurfNum, // Surface number
8820 : int const ConstNum // Construction number
8821 : )
8822 : {
8823 : // SUBROUTINE INFORMATION:
8824 : // AUTHOR Simon Vidanovic
8825 : // DATE WRITTEN June 2013
8826 :
8827 : // PURPOSE OF THIS SUBROUTINE:
8828 : // Returns scheduled surface gain object for given surface-construction combination
8829 :
8830 : // Return value
8831 : int WindowScheduledSolarAbs;
8832 :
8833 36688 : WindowScheduledSolarAbs = 0;
8834 :
8835 36688 : for (int i = 1; i <= state.dataSurface->TotFenLayAbsSSG; ++i) {
8836 253 : if ((state.dataSurface->FenLayAbsSSG(i).SurfPtr == SurfNum) && (state.dataSurface->FenLayAbsSSG(i).ConstrPtr == ConstNum)) {
8837 253 : WindowScheduledSolarAbs = i;
8838 253 : return WindowScheduledSolarAbs;
8839 : }
8840 : }
8841 :
8842 36435 : return WindowScheduledSolarAbs;
8843 : }
8844 :
8845 43433138 : int SurfaceScheduledSolarInc(EnergyPlusData &state,
8846 : int const SurfNum, // Surface number
8847 : int const ConstNum // Construction number
8848 : )
8849 : {
8850 : // SUBROUTINE INFORMATION:
8851 : // AUTHOR Simon Vidanovic
8852 : // DATE WRITTEN June 2013
8853 :
8854 : // PURPOSE OF THIS SUBROUTINE:
8855 : // Returns scheduled surface gain pointer for given surface-construction combination
8856 :
8857 : // Return value
8858 : int SurfaceScheduledSolarInc;
8859 :
8860 43433138 : SurfaceScheduledSolarInc = 0;
8861 :
8862 43434959 : for (int i = 1; i <= state.dataSurface->TotSurfIncSolSSG; ++i) {
8863 2415 : if ((state.dataSurface->SurfIncSolSSG(i).SurfPtr == SurfNum) && (state.dataSurface->SurfIncSolSSG(i).ConstrPtr == ConstNum)) {
8864 594 : SurfaceScheduledSolarInc = i;
8865 594 : return SurfaceScheduledSolarInc;
8866 : }
8867 : }
8868 :
8869 43432544 : return SurfaceScheduledSolarInc;
8870 : }
8871 :
8872 31444 : void PerformSolarCalculations(EnergyPlusData &state)
8873 : {
8874 :
8875 : // SUBROUTINE INFORMATION:
8876 : // AUTHOR Linda K. Lawrie
8877 : // DATE WRITTEN July 1999
8878 : // MODIFIED Sept 2003, FCW: add calls to CalcBeamSolDiffuseReflFactors and
8879 : // CalcBeamSolSpecularReflFactors
8880 : // Jan 2004, FCW: call CalcDayltgCoefficients if storm window status on
8881 : // any window has changed
8882 : // RE-ENGINEERED na
8883 :
8884 : // PURPOSE OF THIS SUBROUTINE:
8885 : // This subroutine determines if new solar/shading calculations need
8886 : // to be performed and calls the proper routines to do the job.
8887 :
8888 : // METHODOLOGY EMPLOYED:
8889 : // Users are allowed to enter a value for number of days in each period that
8890 : // will be used for calculating solar. (Later, this could be more complicated as
8891 : // in allowing a number of days in a month or something). Using this value or the
8892 : // default (20 days) if nothing is entered by the user, the routine will use the
8893 : // number of days left to determine if a new set of calculations should be done.
8894 : // The calculations use the average of "equation of time" and "solar declination"
8895 : // to perform the calculations.
8896 :
8897 : // REFERENCES:
8898 : // na
8899 :
8900 : // Using/Aliasing
8901 : using DaylightingManager::CalcDayltgCoefficients;
8902 : // Locals
8903 : // SUBROUTINE ARGUMENT DEFINITIONS:
8904 : // na
8905 :
8906 : // SUBROUTINE PARAMETER DEFINITIONS:
8907 : // na
8908 :
8909 : // INTERFACE BLOCK SPECIFICATIONS
8910 : // na
8911 :
8912 : // DERIVED TYPE DEFINITIONS
8913 : // na
8914 :
8915 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8916 : Real64 SumDec;
8917 : Real64 SumET;
8918 : Real64 AvgEqOfTime;
8919 : Real64 AvgSinSolarDeclin;
8920 : Real64 AvgCosSolarDeclin;
8921 : int PerDayOfYear;
8922 : int Count;
8923 : Real64 SinDec;
8924 : Real64 EqTime;
8925 : // not used INTEGER SurfNum
8926 :
8927 : // Calculate sky diffuse shading
8928 :
8929 31444 : if (state.dataGlobal->BeginSimFlag) {
8930 771 : state.dataSolarShading->CalcSkyDifShading = true;
8931 771 : SkyDifSolarShading(state); // Calculate factors for shading of sky diffuse solar
8932 771 : state.dataSolarShading->CalcSkyDifShading = false;
8933 : }
8934 :
8935 31444 : if (state.dataGlobal->BeginEnvrnFlag) {
8936 6218 : state.dataSolarShading->ShadowingDaysLeft = 0;
8937 : }
8938 :
8939 31444 : if (state.dataSolarShading->ShadowingDaysLeft <= 0 || state.dataSysVars->DetailedSolarTimestepIntegration) {
8940 :
8941 14330 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
8942 : // Perform calculations.
8943 6236 : state.dataSolarShading->ShadowingDaysLeft = state.dataSolarShading->ShadowingCalcFrequency;
8944 6236 : if (state.dataGlobal->DayOfSim + state.dataSolarShading->ShadowingDaysLeft > state.dataGlobal->NumOfDayInEnvrn) {
8945 5757 : state.dataSolarShading->ShadowingDaysLeft = state.dataGlobal->NumOfDayInEnvrn - state.dataGlobal->DayOfSim + 1;
8946 : }
8947 :
8948 : // Calculate average Equation of Time, Declination Angle for this period
8949 :
8950 6236 : if (!state.dataGlobal->WarmupFlag) {
8951 36 : if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
8952 36 : DisplayString(state, "Updating Shadowing Calculations, Start Date=" + state.dataEnvrn->CurMnDyYr);
8953 : } else {
8954 0 : DisplayString(state, "Updating Shadowing Calculations, Start Date=" + state.dataEnvrn->CurMnDy);
8955 : }
8956 36 : state.dataReportFlag->DisplayPerfSimulationFlag = true;
8957 : }
8958 :
8959 6236 : PerDayOfYear = state.dataEnvrn->DayOfYear;
8960 6236 : SumDec = 0.0;
8961 6236 : SumET = 0.0;
8962 22563 : for (Count = 1; Count <= state.dataSolarShading->ShadowingDaysLeft; ++Count) {
8963 16327 : SUN3(PerDayOfYear, SinDec, EqTime);
8964 16327 : SumDec += SinDec;
8965 16327 : SumET += EqTime;
8966 16327 : ++PerDayOfYear;
8967 : }
8968 :
8969 : // Compute Period Values
8970 6236 : AvgSinSolarDeclin = SumDec / double(state.dataSolarShading->ShadowingDaysLeft);
8971 6236 : AvgCosSolarDeclin = std::sqrt(1.0 - pow_2(AvgSinSolarDeclin));
8972 6236 : AvgEqOfTime = SumET / double(state.dataSolarShading->ShadowingDaysLeft);
8973 : } else {
8974 8094 : SUN3(state.dataEnvrn->DayOfYear, AvgSinSolarDeclin, AvgEqOfTime);
8975 8094 : AvgCosSolarDeclin = std::sqrt(1.0 - pow_2(AvgSinSolarDeclin));
8976 : // trigger display of progress in the simulation every two weeks
8977 8094 : if (!state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag && (state.dataGlobal->DayOfSim % 14 == 0)) {
8978 0 : state.dataReportFlag->DisplayPerfSimulationFlag = true;
8979 : }
8980 : }
8981 :
8982 14330 : CalcPerSolarBeam(state, AvgEqOfTime, AvgSinSolarDeclin, AvgCosSolarDeclin);
8983 :
8984 : // Calculate factors for solar reflection
8985 14330 : if (state.dataSurface->CalcSolRefl) {
8986 54 : CalcBeamSolDiffuseReflFactors(state);
8987 54 : CalcBeamSolSpecularReflFactors(state);
8988 54 : if (state.dataGlobal->BeginSimFlag) CalcSkySolDiffuseReflFactors(state);
8989 : }
8990 : // Calculate daylighting coefficients
8991 14330 : CalcDayltgCoefficients(state);
8992 : }
8993 :
8994 31444 : if (!state.dataGlobal->WarmupFlag) {
8995 4468 : --state.dataSolarShading->ShadowingDaysLeft;
8996 : }
8997 :
8998 : // Recalculate daylighting coefficients if storm window has been added
8999 : // or removed from one or more windows at beginning of day
9000 66275 : if (state.dataDaylightingManager->TotWindowsWithDayl > 0 && !state.dataGlobal->BeginSimFlag && !state.dataGlobal->BeginEnvrnFlag &&
9001 33084 : !state.dataGlobal->WarmupFlag && state.dataSurface->TotStormWin > 0 && state.dataHeatBal->StormWinChangeThisDay) {
9002 0 : CalcDayltgCoefficients(state);
9003 : }
9004 31444 : }
9005 :
9006 1284477 : void SHDRVL(EnergyPlusData &state,
9007 : int const HTSS, // Heat transfer surface number of the subsurface
9008 : int const SBSNR, // Subsurface number
9009 : int const Hour,
9010 : int const TS)
9011 : {
9012 :
9013 : // SUBROUTINE INFORMATION:
9014 : // AUTHOR Legacy Code
9015 : // DATE WRITTEN
9016 : // MODIFIED May 2002 (FCW): allow triangular windows to have reveal.
9017 : // RE-ENGINEERED Lawrie, Oct 2000
9018 :
9019 : // PURPOSE OF THIS SUBROUTINE:
9020 : // This subroutine computes the shadowing from a reveal onto a subsurface.
9021 :
9022 : // REFERENCES:
9023 : // BLAST/IBLAST code, original author George Walton
9024 :
9025 : int NVS; // Number of verticies
9026 :
9027 1284477 : int constexpr None(0); // for use with RevealStatus
9028 1284477 : int constexpr EntireWindowShadedByReveal(1); // for use with RevealStatus
9029 1284477 : int constexpr WindowShadedOnlyByReveal(2); // for use with RevealStatus
9030 :
9031 : Real64 A; // Area
9032 : Real64 R; // Depth of the reveal (m)
9033 : int I; // Loop control
9034 : int N; // Vertex number
9035 : int NS1; // Locations in homogeneous coordinate array
9036 : int NS2;
9037 : // note, below dimensions not changed because subsurface still max 4
9038 2568954 : Array1D<Real64> XVT(5); // Projected X coordinates of vertices
9039 2568954 : Array1D<Real64> YVT(5); // Projected Y coordinates of vertices
9040 : bool RevealStatusSet; // Used to control flow through this subroutine.
9041 : // Certain operations performed only if reveal status not yet set.
9042 : int RevealStatus; // Status of the reveal, takes the parameter values above
9043 :
9044 1284477 : RevealStatus = None;
9045 1284477 : RevealStatusSet = false;
9046 :
9047 1284477 : if (!state.dataSolarShading->CalcSkyDifShading) {
9048 855794 : state.dataSolarShading->SurfWinRevealStatus(Hour, TS, SBSNR) = None;
9049 : }
9050 :
9051 1284477 : R = state.dataSurface->Surface(SBSNR).Reveal;
9052 1284477 : if (R <= 0.0) {
9053 1266602 : RevealStatus = None;
9054 1266602 : RevealStatusSet = true;
9055 : }
9056 :
9057 1284477 : if (!RevealStatusSet) {
9058 :
9059 17875 : state.dataSolarShading->FRVLHC = state.dataSolarShading->LOCHCA + 1;
9060 17875 : ++state.dataSolarShading->LOCHCA;
9061 17875 : NVS = state.dataSurface->Surface(SBSNR).Sides;
9062 :
9063 : // Currently (06May02) windows are either rectangles (NVS=4) or triangles (NVS=3)
9064 :
9065 17875 : if (NVS == 4) { // Rectangular subsurface
9066 :
9067 : // Determine vertices of reveal.
9068 : // Project the subsurface up to the plane of the wall.
9069 :
9070 17875 : XVT(1) = state.dataSurface->ShadeV(SBSNR).XV(1) + R * max(state.dataSolarShading->XShadowProjection, 0.0);
9071 17875 : XVT(2) = state.dataSurface->ShadeV(SBSNR).XV(2) + R * max(state.dataSolarShading->XShadowProjection, 0.0);
9072 17875 : XVT(3) = state.dataSurface->ShadeV(SBSNR).XV(3) + R * min(state.dataSolarShading->XShadowProjection, 0.0);
9073 17875 : XVT(4) = state.dataSurface->ShadeV(SBSNR).XV(4) + R * min(state.dataSolarShading->XShadowProjection, 0.0);
9074 17875 : YVT(1) = state.dataSurface->ShadeV(SBSNR).YV(1) + R * min(state.dataSolarShading->YShadowProjection, 0.0);
9075 17875 : YVT(2) = state.dataSurface->ShadeV(SBSNR).YV(2) + R * max(state.dataSolarShading->YShadowProjection, 0.0);
9076 17875 : YVT(3) = state.dataSurface->ShadeV(SBSNR).YV(3) + R * max(state.dataSolarShading->YShadowProjection, 0.0);
9077 17875 : YVT(4) = state.dataSurface->ShadeV(SBSNR).YV(4) + R * min(state.dataSolarShading->YShadowProjection, 0.0);
9078 :
9079 : // Check for complete shadowing.
9080 :
9081 17875 : if ((XVT(2) >= XVT(3)) || (YVT(2) >= YVT(1))) {
9082 :
9083 564 : RevealStatus = EntireWindowShadedByReveal;
9084 564 : RevealStatusSet = true;
9085 :
9086 : } else {
9087 : // Re-order vertices to clockwise.
9088 :
9089 86555 : for (N = 1; N <= NVS; ++N) {
9090 69244 : state.dataSolarShading->XVS(N) = XVT(NVS + 1 - N);
9091 69244 : state.dataSolarShading->YVS(N) = YVT(NVS + 1 - N);
9092 : }
9093 :
9094 : // Transform to homogeneous coordinates
9095 :
9096 17311 : HTRANS1(state, state.dataSolarShading->FRVLHC, NVS);
9097 17311 : state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC) = -state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC);
9098 17311 : state.dataSolarShading->HCT(state.dataSolarShading->FRVLHC) = 1.0;
9099 :
9100 17311 : if (state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC) <= 0.0) {
9101 0 : RevealStatus = EntireWindowShadedByReveal;
9102 0 : RevealStatusSet = true;
9103 : }
9104 : }
9105 :
9106 0 : } else if (NVS == 3) { // Triangular window
9107 :
9108 : // Project window to outside plane of parent surface
9109 :
9110 0 : for (N = 1; N <= 3; ++N) {
9111 0 : XVT(N) = state.dataSurface->ShadeV(SBSNR).XV(N) + R * state.dataSolarShading->XShadowProjection;
9112 0 : YVT(N) = state.dataSurface->ShadeV(SBSNR).YV(N) + R * state.dataSolarShading->YShadowProjection;
9113 : }
9114 :
9115 : // Find the overlap between the original window and the projected window
9116 : // Put XVT,YVT in clockwise order
9117 :
9118 0 : for (N = 1; N <= NVS; ++N) {
9119 0 : state.dataSolarShading->XVS(N) = XVT(NVS + 1 - N);
9120 0 : state.dataSolarShading->YVS(N) = YVT(NVS + 1 - N);
9121 : }
9122 :
9123 : // Transform to homogeneous coordinates
9124 :
9125 0 : NS1 = state.dataSolarShading->LOCHCA + 1;
9126 0 : state.dataSolarShading->LOCHCA = NS1;
9127 0 : HTRANS1(state, NS1, NVS);
9128 :
9129 : // Put XV,YV in clockwise order
9130 :
9131 0 : for (N = 1; N <= NVS; ++N) {
9132 0 : state.dataSolarShading->XVS(N) = state.dataSurface->ShadeV(SBSNR).XV(NVS + 1 - N);
9133 0 : state.dataSolarShading->YVS(N) = state.dataSurface->ShadeV(SBSNR).YV(NVS + 1 - N);
9134 : }
9135 :
9136 : // Transform to homogenous coordinates
9137 :
9138 0 : NS2 = state.dataSolarShading->LOCHCA + 1;
9139 0 : state.dataSolarShading->LOCHCA = NS2;
9140 0 : HTRANS1(state, NS2, NVS);
9141 0 : state.dataSolarShading->HCT(state.dataSolarShading->FRVLHC) = 1.0;
9142 :
9143 : // Find overlap
9144 :
9145 0 : DeterminePolygonOverlap(state, NS1, NS2, state.dataSolarShading->FRVLHC);
9146 0 : if (state.dataSolarShading->OverlapStatus == NoOverlap) {
9147 0 : RevealStatus = EntireWindowShadedByReveal;
9148 0 : RevealStatusSet = true;
9149 : }
9150 : }
9151 : }
9152 :
9153 1284477 : if (!RevealStatusSet) {
9154 :
9155 : // Check for no shadows on window.
9156 :
9157 17311 : if (state.dataSolarShading->NSBSHC <= 1) {
9158 7797 : RevealStatus = WindowShadedOnlyByReveal;
9159 7797 : RevealStatusSet = true;
9160 : } else {
9161 : // Reduce all previous shadows to size of reveal opening.
9162 9514 : state.dataSolarShading->LOCHCA = state.dataSolarShading->FRVLHC;
9163 9514 : MULTOL(state, state.dataSolarShading->LOCHCA, state.dataSolarShading->FSBSHC, state.dataSolarShading->NSBSHC - 1);
9164 9514 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures)) {
9165 0 : RevealStatus = None;
9166 0 : RevealStatusSet = true;
9167 : } else {
9168 9514 : state.dataSolarShading->NRVLHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FRVLHC + 1;
9169 9514 : if (state.dataSolarShading->NRVLHC <= 1) {
9170 52 : RevealStatus = WindowShadedOnlyByReveal;
9171 52 : RevealStatusSet = true;
9172 : }
9173 : }
9174 : }
9175 : }
9176 :
9177 1284477 : if (!RevealStatusSet) {
9178 : // Compute sunlit area.
9179 9462 : A = state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC);
9180 25271 : for (I = 2; I <= state.dataSolarShading->NRVLHC; ++I) {
9181 31618 : A += state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC - 1 + I) *
9182 15809 : (1.0 - state.dataSolarShading->HCT(state.dataSolarShading->FRVLHC - 1 + I));
9183 : }
9184 9462 : state.dataSolarShading->SurfSunlitArea(HTSS) = A;
9185 : }
9186 :
9187 1284477 : if ((RevealStatus == EntireWindowShadedByReveal) || (state.dataSolarShading->SurfSunlitArea(HTSS) < 0.0)) {
9188 594 : state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0; // Window entirely shaded by reveal.
9189 1283883 : } else if (RevealStatus == WindowShadedOnlyByReveal) {
9190 7849 : state.dataSolarShading->SurfSunlitArea(HTSS) =
9191 7849 : state.dataSolarShading->HCAREA(state.dataSolarShading->FRVLHC); // Window shaded only by reveal.
9192 : }
9193 :
9194 1284477 : if (!state.dataSolarShading->CalcSkyDifShading) {
9195 855794 : state.dataSolarShading->SurfWinRevealStatus(Hour, TS, SBSNR) = RevealStatus;
9196 : }
9197 1284477 : }
9198 :
9199 3220462 : void SHDSBS(EnergyPlusData &state,
9200 : int const iHour, // Hour Index
9201 : int const CurSurf,
9202 : int const NBKS, // Number of back surfaces
9203 : int const NSBS, // Number of subsurfaces
9204 : int const HTS, // Heat transfer surface number of the general receiving surf
9205 : int const TS // Time step Index
9206 : )
9207 : {
9208 :
9209 : // SUBROUTINE INFORMATION:
9210 : // AUTHOR Legacy Code
9211 : // DATE WRITTEN
9212 : // MODIFIED FCW, Oct 2002: Surface%Area --> Surface%Area + SurfaceWindow%DividerArea
9213 : // in calculation of SunlitFracWithoutReveal (i.e., use full window area, not
9214 : // just glass area.
9215 : // TH, May 2009: Bug fixed to address part of CR 7596 - inside reveals
9216 : // causing high cooling loads
9217 : // RE-ENGINEERED Lawrie, Oct 2000
9218 :
9219 : // PURPOSE OF THIS SUBROUTINE:
9220 : // This subroutine determines the shadowing on subsurfaces and
9221 : // revises the base surface area accordingly. It also computes
9222 : // the effect of transparent subsurfaces.
9223 :
9224 : // REFERENCES:
9225 : // BLAST/IBLAST code, original author George Walton
9226 :
9227 : Real64 A; // Area
9228 : int I; // Loop control
9229 : int J; // Loop control
9230 : int K; // Window construction number
9231 : int N; // Vertex number
9232 : Real64 SurfArea; // Surface area. For walls, includes all window frame areas.
9233 : // For windows, includes divider area
9234 : // REAL(r64) FrameAreaAdd ! Additional frame area sunlit
9235 : // REAL(r64) DividerAreaAdd ! Additional frame area sunlit
9236 : int HTSS; // Heat transfer surface number of the subsurface
9237 : int SBSNR; // Subsurface number
9238 :
9239 3220462 : if (NSBS > 0) { // Action taken only if subsurfaces present
9240 :
9241 1610411 : state.dataSolarShading->FSBSHC = state.dataSolarShading->LOCHCA + 1;
9242 :
9243 4132113 : for (I = 1; I <= NSBS; ++I) { // Do for all subsurfaces (sbs).
9244 :
9245 2521702 : SBSNR = state.dataShadowComb->ShadowComb(CurSurf).SubSurf(I);
9246 :
9247 2521702 : HTSS = SBSNR;
9248 :
9249 2521702 : K = state.dataSurface->Surface(SBSNR).Construction;
9250 :
9251 2521702 : if (!state.dataSolarShading->penumbra) {
9252 5033366 : if ((state.dataSolarShading->OverlapStatus != TooManyVertices) && (state.dataSolarShading->OverlapStatus != TooManyFigures) &&
9253 2516683 : (state.dataSolarShading->SurfSunlitArea(HTS) > 0.0)) {
9254 :
9255 : // Re-order vertices to clockwise sequential; compute homogeneous coordinates.
9256 1327134 : state.dataSolarShading->NVS = state.dataSurface->Surface(SBSNR).Sides;
9257 6635320 : for (N = 1; N <= state.dataSolarShading->NVS; ++N) {
9258 5308186 : state.dataSolarShading->XVS(N) = state.dataSurface->ShadeV(SBSNR).XV(state.dataSolarShading->NVS + 1 - N);
9259 5308186 : state.dataSolarShading->YVS(N) = state.dataSurface->ShadeV(SBSNR).YV(state.dataSolarShading->NVS + 1 - N);
9260 : }
9261 1327134 : state.dataSolarShading->LOCHCA = state.dataSolarShading->FSBSHC;
9262 1327134 : HTRANS1(state, state.dataSolarShading->LOCHCA, state.dataSolarShading->NVS);
9263 1327134 : state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA) = -state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
9264 1327134 : state.dataSolarShading->HCT(state.dataSolarShading->LOCHCA) = 1.0;
9265 1327134 : state.dataSolarShading->NSBSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FSBSHC + 1;
9266 :
9267 : // Determine sunlit area of subsurface due to shadows on general receiving surface.
9268 1327134 : if (state.dataSolarShading->NGSSHC > 0) {
9269 255778 : MULTOL(state, state.dataSolarShading->LOCHCA, state.dataSolarShading->FGSSHC - 1, state.dataSolarShading->NGSSHC);
9270 255778 : if ((state.dataSolarShading->OverlapStatus != TooManyVertices) && (state.dataSolarShading->OverlapStatus != TooManyFigures))
9271 255778 : state.dataSolarShading->NSBSHC = state.dataSolarShading->LOCHCA - state.dataSolarShading->FSBSHC + 1;
9272 : }
9273 : }
9274 :
9275 5033366 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures) ||
9276 2516683 : (state.dataSolarShading->SurfSunlitArea(HTS) <= 0.0)) { // General receiving surface totally shaded.
9277 :
9278 1189549 : state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
9279 :
9280 1189549 : if (iHour > 0 && TS > 0) state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) = 0.0;
9281 :
9282 1327134 : } else if ((state.dataSolarShading->NGSSHC <= 0) || (state.dataSolarShading->NSBSHC == 1)) { // No shadows.
9283 :
9284 1133689 : state.dataSolarShading->SurfSunlitArea(HTSS) = state.dataSolarShading->HCAREA(state.dataSolarShading->FSBSHC);
9285 1133689 : state.dataSolarShading->SurfSunlitArea(HTS) -=
9286 1133689 : state.dataSolarShading->SurfSunlitArea(HTSS); // Revise sunlit area of general receiving surface.
9287 :
9288 : // TH. This is a bug. SunLitFracWithoutReveal should be a ratio of area
9289 : // IF(IHour > 0 .AND. TS > 0) SunLitFracWithoutReveal(HTSS,IHour,TS) = &
9290 : // Surface(HTSS)%NetAreaShadowCalc
9291 :
9292 : // new code fixed part of CR 7596. TH 5/29/2009
9293 1133689 : if (iHour > 0 && TS > 0)
9294 749358 : state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) =
9295 749358 : state.dataSolarShading->SurfSunlitArea(HTSS) / state.dataSurface->Surface(HTSS).NetAreaShadowCalc;
9296 :
9297 1133689 : SHDRVL(state, HTSS, SBSNR, iHour, TS); // Determine shadowing from reveal.
9298 :
9299 1133689 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
9300 0 : state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
9301 :
9302 : } else { // Compute area.
9303 :
9304 193445 : A = state.dataSolarShading->HCAREA(state.dataSolarShading->FSBSHC);
9305 457523 : for (J = 2; J <= state.dataSolarShading->NSBSHC; ++J) {
9306 528156 : A += state.dataSolarShading->HCAREA(state.dataSolarShading->FSBSHC - 1 + J) *
9307 264078 : (1.0 - state.dataSolarShading->HCT(state.dataSolarShading->FSBSHC - 1 + J));
9308 : }
9309 193445 : state.dataSolarShading->SurfSunlitArea(HTSS) = A;
9310 193445 : if (state.dataSolarShading->SurfSunlitArea(HTSS) > 0.0) {
9311 :
9312 150788 : state.dataSolarShading->SurfSunlitArea(HTS) -=
9313 150788 : state.dataSolarShading->SurfSunlitArea(HTSS); // Revise sunlit area of general receiving surface.
9314 :
9315 150788 : if (iHour > 0 && TS > 0)
9316 106436 : state.dataHeatBal->SurfSunlitFracWithoutReveal(iHour, TS, HTSS) =
9317 106436 : state.dataSolarShading->SurfSunlitArea(HTSS) / state.dataSurface->Surface(HTSS).Area;
9318 :
9319 150788 : SHDRVL(state, HTSS, SBSNR, iHour, TS); // Determine shadowing from reveal.
9320 :
9321 150788 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
9322 0 : state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
9323 :
9324 : } else { // General receiving surface totally shaded.
9325 :
9326 42657 : state.dataSolarShading->SurfSunlitArea(HTSS) = 0.0;
9327 : }
9328 : }
9329 : }
9330 :
9331 : // Determine transmittance and absorptances of sunlit window.
9332 2521702 : if (state.dataConstruction->Construct(K).TransDiff > 0.0) {
9333 :
9334 2392140 : if (!state.dataSolarShading->CalcSkyDifShading) { // Overlaps calculation is only done for beam solar
9335 : // shading, not for sky diffuse solar shading
9336 :
9337 1534620 : CalcInteriorSolarOverlaps(state, iHour, NBKS, HTSS, CurSurf, TS);
9338 : }
9339 : }
9340 :
9341 : // Error checking.
9342 2521702 : SurfArea = state.dataSurface->Surface(SBSNR).NetAreaShadowCalc;
9343 2521702 : state.dataSolarShading->SurfSunlitArea(HTSS) = max(0.0, state.dataSolarShading->SurfSunlitArea(HTSS));
9344 :
9345 2521702 : state.dataSolarShading->SurfSunlitArea(HTSS) = min(state.dataSolarShading->SurfSunlitArea(HTSS), SurfArea);
9346 :
9347 : } // End of subsurface loop
9348 : }
9349 3220462 : }
9350 :
9351 24421 : void SUN3(int const JulianDayOfYear, // Julian Day Of Year
9352 : Real64 &SineOfSolarDeclination, // Sine of Solar Declination
9353 : Real64 &EquationOfTime // Equation of Time (Degrees)
9354 : )
9355 : {
9356 :
9357 : // SUBROUTINE INFORMATION:
9358 : // AUTHOR Legacy Code
9359 : // DATE WRITTEN
9360 : // MODIFIED na
9361 : // RE-ENGINEERED Linda K. Lawrie
9362 :
9363 : // PURPOSE OF THIS SUBROUTINE:
9364 : // This subroutine computes the coefficients for determining
9365 : // the solar position.
9366 :
9367 : // METHODOLOGY EMPLOYED:
9368 : // The expressions are based on least-squares fits of data on p.316 of 'Thermal
9369 : // Environmental Engineering' by Threlkeld and on p.387 of the ASHRAE Handbook
9370 : // of Fundamentals (need date of ASHRAE HOF).
9371 :
9372 : // REFERENCES:
9373 : // BLAST/IBLAST code, original author George Walton
9374 :
9375 : // Fitted coefficients of Fourier series | Sine of declination coefficients
9376 : static constexpr std::array<Real64, 9> SineSolDeclCoef = {
9377 : 0.00561800, 0.0657911, -0.392779, 0.00064440, -0.00618495, -0.00010101, -0.00007951, -0.00011691, 0.00002096};
9378 : // Fitted coefficients of Fourier Series | Equation of Time coefficients
9379 : static constexpr std::array<Real64, 9> EqOfTimeCoef = {
9380 : 0.00021971, -0.122649, 0.00762856, -0.156308, -0.0530028, -0.00388702, -0.00123978, -0.00270502, -0.00167992};
9381 :
9382 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9383 : Real64 X; // Day of Year in Radians (Computed from Input JulianDayOfYear)
9384 : Real64 CosX; // COS(X)
9385 : Real64 SineX; // SIN(X)
9386 :
9387 24421 : X = 0.017167 * JulianDayOfYear; // Convert julian date to angle X
9388 :
9389 : // Calculate sines and cosines of X
9390 24421 : SineX = std::sin(X);
9391 24421 : CosX = std::cos(X);
9392 :
9393 73263 : SineOfSolarDeclination = SineSolDeclCoef[0] + SineSolDeclCoef[1] * SineX + SineSolDeclCoef[2] * CosX + SineSolDeclCoef[3] * (SineX * CosX * 2.0) +
9394 48842 : SineSolDeclCoef[4] * (pow_2(CosX) - pow_2(SineX)) +
9395 48842 : SineSolDeclCoef[5] * (SineX * (pow_2(CosX) - pow_2(SineX)) + CosX * (SineX * CosX * 2.0)) +
9396 48842 : SineSolDeclCoef[6] * (CosX * (pow_2(CosX) - pow_2(SineX)) - SineX * (SineX * CosX * 2.0)) +
9397 48842 : SineSolDeclCoef[7] * (2.0 * (SineX * CosX * 2.0) * (pow_2(CosX) - pow_2(SineX))) +
9398 24421 : SineSolDeclCoef[8] * (pow_2(pow_2(CosX) - pow_2(SineX)) - pow_2(SineX * CosX * 2.0));
9399 :
9400 73263 : EquationOfTime = EqOfTimeCoef[0] + EqOfTimeCoef[1] * SineX + EqOfTimeCoef[2] * CosX + EqOfTimeCoef[3] * (SineX * CosX * 2.0) +
9401 48842 : EqOfTimeCoef[4] * (pow_2(CosX) - pow_2(SineX)) +
9402 48842 : EqOfTimeCoef[5] * (SineX * (pow_2(CosX) - pow_2(SineX)) + CosX * (SineX * CosX * 2.0)) +
9403 48842 : EqOfTimeCoef[6] * (CosX * (pow_2(CosX) - pow_2(SineX)) - SineX * (SineX * CosX * 2.0)) +
9404 48842 : EqOfTimeCoef[7] * (2.0 * (SineX * CosX * 2.0) * (pow_2(CosX) - pow_2(SineX))) +
9405 24421 : EqOfTimeCoef[8] * (pow_2(pow_2(CosX) - pow_2(SineX)) - pow_2(SineX * CosX * 2.0));
9406 24421 : }
9407 :
9408 344400 : void SUN4(EnergyPlusData &state,
9409 : Real64 const CurrentTime, // Time to use in shadowing calculations
9410 : Real64 const EqOfTime, // Equation of time for current day
9411 : Real64 const SinSolarDeclin, // Sine of the Solar declination (current day)
9412 : Real64 const CosSolarDeclin // Cosine of the Solar declination (current day)
9413 : )
9414 : {
9415 :
9416 : // SUBROUTINE INFORMATION:
9417 : // AUTHOR Legacy Code
9418 : // DATE WRITTEN
9419 : // MODIFIED na
9420 : // RE-ENGINEERED Lawrie, Oct 2000
9421 :
9422 : // PURPOSE OF THIS SUBROUTINE:
9423 : // This subroutine computes solar direction cosines for a given hour. These
9424 : // cosines are used in the shadowing calculations.
9425 : // REFERENCES:
9426 : // BLAST/IBLAST code, original author George Walton
9427 :
9428 : Real64 H; // Hour angle (before noon = +) (in radians)
9429 : Real64 HrAngle; // Basic hour angle
9430 :
9431 : // Compute the hour angle
9432 344400 : HrAngle = (15.0 * (12.0 - (CurrentTime + EqOfTime)) + (state.dataEnvrn->TimeZoneMeridian - state.dataEnvrn->Longitude));
9433 344400 : H = HrAngle * DataGlobalConstants::DegToRadians;
9434 :
9435 : // Compute the cosine of the solar zenith angle.
9436 344400 : state.dataSolarShading->SUNCOS(3) = SinSolarDeclin * state.dataEnvrn->SinLatitude + CosSolarDeclin * state.dataEnvrn->CosLatitude * std::cos(H);
9437 344400 : state.dataSolarShading->SUNCOS(2) = 0.0;
9438 344400 : state.dataSolarShading->SUNCOS(1) = 0.0;
9439 :
9440 344400 : if (state.dataSolarShading->SUNCOS(3) < DataEnvironment::SunIsUpValue) return; // Return if sun not above horizon.
9441 :
9442 : // Compute other direction cosines.
9443 173403 : state.dataSolarShading->SUNCOS(2) = SinSolarDeclin * state.dataEnvrn->CosLatitude - CosSolarDeclin * state.dataEnvrn->SinLatitude * std::cos(H);
9444 173403 : state.dataSolarShading->SUNCOS(1) = CosSolarDeclin * std::sin(H);
9445 : }
9446 :
9447 2568509 : void WindowShadingManager(EnergyPlusData &state)
9448 : {
9449 :
9450 : // SUBROUTINE INFORMATION:
9451 : // AUTHOR Fred Winkelmann
9452 : // DATE WRITTEN December 1998
9453 : // MODIFIED November 1999 (FW)
9454 : // Aug 2001 (FW): change shading control names, change approach
9455 : // to scheduling and glare control, add movable
9456 : // insulation controls (mainly for heating reduction)
9457 : // Dec 2001 (FW): add slat angle control for blinds
9458 : // Aug 2002 (FW): add four new control types:
9459 : // OnIfHighOutsideAirTempAndHighSolarOnWindow
9460 : // OnIfHighOutsideAirTempAndHighHorizontalSolar
9461 : // OnIfHighZoneAirTempAndHighSolarOnWindow
9462 : // OnIfHighZoneAirTempAndHighHorizontalSolar
9463 : // Dec 2002 (FW): add between-glass shade/blind
9464 : // Mar 2003 (FW): allow GlareControlIsActive = .TRUE. only for daylit zones
9465 : // Apr 2003 (FW): use SNLoadCoolRate or SNLoadHeatRate only if not first time step
9466 : // (fixes problem when used first time thru and not allocated)
9467 : // May 2006 (RR): add exterior window screen
9468 : // May 2009 (BG): add EMS actuator override for shade flag and slat angle
9469 : // RE-ENGINEERED na
9470 :
9471 : // PURPOSE OF THIS SUBROUTINE:
9472 : // For windows with shading, selects the shaded construction
9473 : // that is used in the heat balance calculation, and sets
9474 : // the window shading flag, which is:
9475 : // -1: if window has no shading device
9476 : // 0: if shading device is off
9477 : // 1: if interior shade is on
9478 : // 2: if glazing is switched to darker state
9479 : // 3: if exterior shade is on
9480 : // 6: if interior blind is on
9481 : // 7: if exterior blind is on
9482 : // 8: if between-glass shade is on
9483 : // 9: if between-glass blind is on
9484 : // 10: window has interior shade that is off but may be triggered on later
9485 : // to control daylight glare
9486 : // 20: window has switchable glazing that is unswitched but may be switched later
9487 : // to control daylight glare or daylight illuminance
9488 : // 30: window has exterior shade that is off but may be triggered on later
9489 : // to control daylight glare or daylight illuminance
9490 : // 60: window has interior blind that is off but may be triggered on later
9491 : // to control daylight glare or daylight illuminance
9492 : // 70: window has exterior blind that is off but may be triggered on later
9493 : // to control daylight glare or daylight illuminance
9494 : // 80: window has between-glass shade that is off but may be triggered on later
9495 : // to control daylight glare or daylight illuminance
9496 : // 90: window has between-glass blind that is off but may be triggered on later
9497 : // to control daylight glare or daylight illuminance
9498 : // A "shading device" may be an exterior, interior or between-glass shade or blind,
9499 : // or the lower-transmitting (dark) state of switchable glazing (e.g., electrochromic).
9500 : // In all cases, the unshaded condition is represented
9501 : // by the construction given by window's Surface()%Construction and
9502 : // the shaded condition is represented by the construction given by
9503 : // the window's Surface()%ShadedConstruction
9504 : // REFERENCES:
9505 : // na
9506 :
9507 : // Using/Aliasing
9508 : using General::POLYF;
9509 : using ScheduleManager::GetCurrentScheduleValue;
9510 :
9511 : static Real64 const DeltaAng(DataGlobalConstants::Pi / (double(MaxSlatAngs) - 1.0));
9512 : static Real64 const DeltaAng_inv(1.0 / DeltaAng);
9513 : static Real64 const DeltaProfAng(DataGlobalConstants::Pi / 36.0);
9514 : int IConst; // Construction
9515 :
9516 21015074 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
9517 36909306 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
9518 18462741 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
9519 18462741 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
9520 18462741 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
9521 40474011 : for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) {
9522 22011270 : state.dataSurface->SurfWinExtIntShadePrevTS(ISurf) = state.dataSurface->SurfWinShadingFlag(ISurf);
9523 :
9524 22011270 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::NoShade;
9525 22011270 : state.dataSurface->SurfWinFracTimeShadingDeviceOn(ISurf) = 0.0;
9526 22011270 : if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::EQL) {
9527 8109 : int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction).EQLConsPtr;
9528 8109 : if (state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr > 0) {
9529 0 : if (state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).CNTRL ==
9530 0 : state.dataWindowEquivalentLayer->lscNONE) {
9531 0 : state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) =
9532 0 : state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).PHI_DEG;
9533 : } else {
9534 0 : state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0;
9535 : }
9536 : }
9537 : }
9538 :
9539 : // Initialization of complex fenestration shading device
9540 22011270 : if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::BSDF) {
9541 39540 : auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction));
9542 39540 : auto &surface_window(state.dataSurface->SurfaceWindow(ISurf));
9543 39540 : int TotLayers = construction.TotLayers;
9544 219672 : for (auto Lay = 1; Lay <= TotLayers; ++Lay) {
9545 180132 : const int LayPtr = construction.LayerPoint(Lay);
9546 180132 : auto &material(state.dataMaterial->Material(LayPtr));
9547 180132 : const bool isShading = material.Group == DataHeatBalance::MaterialGroup::ComplexWindowShade;
9548 180132 : if (isShading && Lay == 1) {
9549 10143 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShade;
9550 : }
9551 180132 : if (isShading && Lay == TotLayers) {
9552 15894 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShade;
9553 : }
9554 : }
9555 39540 : if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntShade) {
9556 15894 : auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction));
9557 15894 : const int TotLay = construction.TotLayers;
9558 15894 : int ShadingLayerPtr = construction.LayerPoint(TotLay);
9559 15894 : ShadingLayerPtr = state.dataMaterial->Material(ShadingLayerPtr).ComplexShadePtr;
9560 15894 : auto &complexShade = state.dataHeatBal->ComplexShade(ShadingLayerPtr);
9561 15894 : auto TauShadeIR = complexShade.IRTransmittance;
9562 15894 : auto EpsShadeIR = complexShade.BackEmissivity;
9563 15894 : auto RhoShadeIR = max(0.0, 1.0 - TauShadeIR - EpsShadeIR);
9564 : // Get properties of glass next to inside shading layer
9565 15894 : int GlassLayPtr = construction.LayerPoint(TotLay - 2);
9566 15894 : auto EpsGlassIR = state.dataMaterial->Material(GlassLayPtr).AbsorpThermalBack;
9567 15894 : auto RhoGlassIR = 1 - EpsGlassIR;
9568 :
9569 15894 : auto EffShBlEmiss = EpsShadeIR * (1.0 + RhoGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR));
9570 15894 : surface_window.EffShBlindEmiss[0] = EffShBlEmiss;
9571 15894 : auto EffGlEmiss = EpsGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR);
9572 15894 : surface_window.EffGlassEmiss[0] = EffGlEmiss;
9573 : }
9574 : }
9575 :
9576 22011270 : if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue;
9577 21984078 : if (!state.dataSurface->Surface(ISurf).HasShadeControl) {
9578 21494751 : continue;
9579 : } else {
9580 : //
9581 : }
9582 :
9583 : // Initialize switching factor (applicable only to switchable glazing) to unswitched
9584 489327 : state.dataSurface->SurfWinSwitchingFactor(ISurf) = 0.0;
9585 :
9586 489327 : IConst = state.dataSurface->Surface(ISurf).Construction;
9587 : // Vis trans at normal incidence of unswitched glass. Counting the GlazedFrac
9588 489327 : if (IConst > 0)
9589 489327 : state.dataSurface->SurfWinVisTransSelected(ISurf) =
9590 489327 : POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf);
9591 :
9592 : // Window has shading control
9593 : // select the active window shading control and corresponding contructions
9594 489327 : size_t indexWindowShadingControl = selectActiveWindowShadingControlIndex(state, ISurf);
9595 978654 : if (!state.dataSurface->Surface(ISurf).windowShadingControlList.empty() &&
9596 489327 : indexWindowShadingControl <= state.dataSurface->Surface(ISurf).windowShadingControlList.size() - 1) {
9597 489327 : state.dataSurface->Surface(ISurf).activeWindowShadingControl =
9598 489327 : state.dataSurface->Surface(ISurf).windowShadingControlList[indexWindowShadingControl];
9599 : }
9600 489327 : state.dataSurface->Surface(ISurf).activeShadedConstructionPrev = state.dataSurface->Surface(ISurf).activeShadedConstruction;
9601 978654 : if (!state.dataSurface->Surface(ISurf).shadedConstructionList.empty() &&
9602 489327 : indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedConstructionList.size() - 1) {
9603 489327 : state.dataSurface->Surface(ISurf).activeShadedConstruction =
9604 489327 : state.dataSurface->Surface(ISurf).shadedConstructionList[indexWindowShadingControl];
9605 : }
9606 489327 : state.dataSurface->SurfWinActiveShadedConstruction(ISurf) = state.dataSurface->Surface(ISurf).activeShadedConstruction;
9607 489327 : if (!state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.empty() &&
9608 0 : indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.size() - 1) {
9609 0 : if (state.dataSurface->SurfWinStormWinFlag(ISurf) == 1) {
9610 0 : state.dataSurface->SurfWinActiveShadedConstruction(ISurf) =
9611 0 : state.dataSurface->Surface(ISurf).shadedStormWinConstructionList[indexWindowShadingControl];
9612 : }
9613 : }
9614 :
9615 489327 : int IShadingCtrl = state.dataSurface->Surface(ISurf).activeWindowShadingControl;
9616 489327 : int IZone = state.dataSurface->Surface(ISurf).Zone;
9617 : // Setpoint for shading
9618 489327 : Real64 SetPoint = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint; // Control setpoint
9619 489327 : Real64 SetPoint2 = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint2; // Second control setpoint
9620 :
9621 489327 : bool SchedAllowsControl = true; // True if control schedule is not specified or is specified and schedule value = 1
9622 489327 : int SchedulePtr = state.dataSurface->WindowShadingControl(IShadingCtrl).Schedule;
9623 489327 : if (SchedulePtr != 0) {
9624 261924 : if (state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingControlIsScheduled &&
9625 130962 : GetCurrentScheduleValue(state, SchedulePtr) <= 0.0)
9626 121860 : SchedAllowsControl = false;
9627 : }
9628 :
9629 : Real64 GlareControlIsActive =
9630 579586 : (state.dataDaylightingData->ZoneDaylight(IZone).totRefPts > 0 && state.dataEnvrn->SunIsUp &&
9631 579586 : state.dataSurface->WindowShadingControl(IShadingCtrl).GlareControlIsActive); // True if glare control is active
9632 :
9633 489327 : Real64 SolarOnWindow = 0.0; // Direct plus diffuse solar intensity on window (W/m2)
9634 489327 : Real64 BeamSolarOnWindow = 0.0; // Direct solar intensity on window (W/m2)
9635 489327 : Real64 HorizSolar = 0.0; // Horizontal direct plus diffuse solar intensity
9636 489327 : if (state.dataEnvrn->SunIsUp) {
9637 248965 : Real64 SkySolarOnWindow = state.dataSolarShading->SurfAnisoSkyMult(ISurf) *
9638 248965 : state.dataEnvrn->DifSolarRad; // Sky diffuse solar intensity on window (W/m2)
9639 746895 : BeamSolarOnWindow = state.dataEnvrn->BeamSolarRad *
9640 248965 : state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf) *
9641 248965 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf);
9642 248965 : SolarOnWindow =
9643 248965 : BeamSolarOnWindow + SkySolarOnWindow + state.dataEnvrn->GndSolarRad * state.dataSurface->Surface(ISurf).ViewFactorGround;
9644 248965 : HorizSolar = state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad;
9645 : }
9646 :
9647 : // Determine whether to deploy shading depending on type of control
9648 489327 : auto &thisIZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(IZone);
9649 :
9650 489327 : bool shadingOn = false;
9651 489327 : bool shadingOffButGlareControlOn = false;
9652 489327 : switch (state.dataSurface->WindowShadingControl(IShadingCtrl).shadingControlType) {
9653 20907 : case WindowShadingControlType::AlwaysOn: // 'ALWAYSON'
9654 20907 : shadingOn = true;
9655 20907 : break;
9656 0 : case WindowShadingControlType::AlwaysOff: // 'ALWAYSOFF'
9657 0 : break;
9658 122880 : case WindowShadingControlType::OnIfScheduled: // 'ONIFSCHEDULEALLOWS'
9659 122880 : if (SchedAllowsControl) shadingOn = true;
9660 122880 : break;
9661 173658 : case WindowShadingControlType::HiSolar: // 'ONIFHIGHSOLARONWINDOW'
9662 : // ! Direct plus diffuse solar intensity on window
9663 173658 : if (state.dataEnvrn->SunIsUp) {
9664 85955 : if (SolarOnWindow > SetPoint && SchedAllowsControl) {
9665 44140 : shadingOn = true;
9666 41815 : } else if (GlareControlIsActive) {
9667 3192 : shadingOffButGlareControlOn = true;
9668 : }
9669 : }
9670 173658 : break;
9671 :
9672 0 : case WindowShadingControlType::HiHorzSolar: // 'ONIFHIGHHORIZONTALSOLAR' ! Direct plus diffuse exterior horizontal solar intensity
9673 0 : if (state.dataEnvrn->SunIsUp) {
9674 0 : if (HorizSolar > SetPoint && SchedAllowsControl) {
9675 0 : shadingOn = true;
9676 0 : } else if (GlareControlIsActive) {
9677 0 : shadingOffButGlareControlOn = true;
9678 : }
9679 : }
9680 0 : break;
9681 :
9682 0 : case WindowShadingControlType::HiOutAirTemp: // 'OnIfHighOutdoorAirTemperature'
9683 0 : if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SchedAllowsControl) {
9684 0 : shadingOn = true;
9685 0 : } else if (GlareControlIsActive) {
9686 0 : shadingOffButGlareControlOn = true;
9687 : }
9688 0 : break;
9689 :
9690 0 : case WindowShadingControlType::HiZoneAirTemp: // 'OnIfHighZoneAirTemperature' ! Previous time step zone air temperature
9691 0 : if (thisIZoneHB.MAT > SetPoint && SchedAllowsControl) {
9692 0 : shadingOn = true;
9693 0 : } else if (GlareControlIsActive) {
9694 0 : shadingOffButGlareControlOn = true;
9695 : }
9696 0 : break;
9697 :
9698 0 : case WindowShadingControlType::OnHiOutTemp_HiSolarWindow: // 'OnIfHighOutdoorAirTempAndHighSolarOnWindow' ! Outside air temp and
9699 : // solar on window
9700 0 : if (state.dataEnvrn->SunIsUp) {
9701 0 : if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) {
9702 0 : shadingOn = true;
9703 0 : } else if (GlareControlIsActive) {
9704 0 : shadingOffButGlareControlOn = true;
9705 : }
9706 : }
9707 0 : break;
9708 :
9709 0 : case WindowShadingControlType::OnHiOutTemp_HiHorzSolar: // 'OnIfHighOutdoorAirTempAndHighHorizontalSolar' ! Outside air temp and
9710 : // horizontal solar
9711 0 : if (state.dataEnvrn->SunIsUp) {
9712 0 : if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) {
9713 0 : shadingOn = true;
9714 0 : } else if (GlareControlIsActive) {
9715 0 : shadingOffButGlareControlOn = true;
9716 : }
9717 : }
9718 0 : break;
9719 :
9720 0 : case WindowShadingControlType::OnHiZoneTemp_HiSolarWindow: // 'ONIFHIGHZONEAIRTEMPANDHIGHSOLARONWINDOW' ! Zone air temp and solar on
9721 : // window
9722 0 : if (state.dataEnvrn->SunIsUp) {
9723 0 : if (thisIZoneHB.MAT > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) {
9724 0 : shadingOn = true;
9725 0 : } else if (GlareControlIsActive) {
9726 0 : shadingOffButGlareControlOn = true;
9727 : }
9728 : }
9729 0 : break;
9730 :
9731 0 : case WindowShadingControlType::OnHiZoneTemp_HiHorzSolar: // 'ONIFHIGHZONEAIRTEMPANDHIGHHORIZONTALSOLAR' ! Zone air temp and
9732 : // horizontal solar
9733 0 : if (state.dataEnvrn->SunIsUp) {
9734 0 : if (thisIZoneHB.MAT > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) {
9735 0 : shadingOn = true;
9736 0 : } else if (GlareControlIsActive) {
9737 0 : shadingOffButGlareControlOn = true;
9738 : }
9739 : }
9740 0 : break;
9741 :
9742 0 : case WindowShadingControlType::HiZoneCooling:
9743 : // 'ONIFHIGHZONECOOLING' ! Previous time step zone sensible cooling rate [W]
9744 : // In the following, the check on BeginSimFlag is needed since SNLoadCoolRate (and SNLoadHeatRate,
9745 : // used in other CASEs) are not allocated at this point for the first time step of the simulation.
9746 0 : if (!state.dataGlobal->BeginSimFlag) {
9747 0 : if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > SetPoint && SchedAllowsControl) {
9748 0 : shadingOn = true;
9749 0 : } else if (GlareControlIsActive) {
9750 0 : shadingOffButGlareControlOn = true;
9751 : }
9752 : }
9753 0 : break;
9754 :
9755 166458 : case WindowShadingControlType::HiGlare:
9756 : // 'ONIFHIGHGLARE' ! Daylight glare index at first reference point in the zone.
9757 : // This type of shading control is done in DayltgInteriorIllum. Glare control is not affected
9758 : // by control schedule.
9759 166458 : if (state.dataEnvrn->SunIsUp) {
9760 83609 : shadingOffButGlareControlOn = true;
9761 : }
9762 166458 : break;
9763 :
9764 2712 : case WindowShadingControlType::MeetDaylIlumSetp:
9765 : // 'MEETDAYLIGHTILLUMINANCESETPOINT') ! Daylight illuminance test is done in DayltgInteriorIllum
9766 : // Only switchable glazing does daylight illuminance control
9767 2712 : if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
9768 1330 : shadingOffButGlareControlOn = true;
9769 : }
9770 2712 : break;
9771 :
9772 2712 : case WindowShadingControlType::HiSolar_HiLumin_OffMidNight:
9773 : // 'OnIfHighSolarOrHighLuminanceTillMidnight'
9774 : // if shade is already on, then keep it on until midnight, otherwise check thresholds
9775 2712 : if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) {
9776 978 : shadingOn = true;
9777 1734 : } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
9778 630 : if (SolarOnWindow > SetPoint) {
9779 14 : shadingOn = true;
9780 : } else {
9781 : // pass to DayltgInteriorIllum to check for luminance
9782 616 : shadingOn = false;
9783 616 : shadingOffButGlareControlOn = true;
9784 : }
9785 : }
9786 : // if it is the beginning of the day, then shades off
9787 2712 : if (state.dataGlobal->BeginDayFlag) {
9788 36 : shadingOn = false;
9789 36 : shadingOffButGlareControlOn = false;
9790 : }
9791 2712 : break;
9792 :
9793 0 : case WindowShadingControlType::HiSolar_HiLumin_OffSunset:
9794 : // 'OnIfHighSolarOrHighLuminanceTillSunset'
9795 : // if shade is already on, then keep it on until sunset, otherwise check thresholds
9796 0 : if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) {
9797 0 : shadingOn = true;
9798 0 : } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
9799 0 : if (SolarOnWindow > SetPoint) {
9800 0 : shadingOn = true;
9801 : } else {
9802 : // pass to DayltgInteriorIllum to check for luminance
9803 0 : shadingOn = false;
9804 0 : shadingOffButGlareControlOn = true;
9805 : }
9806 : }
9807 : // if sunset, then shades off
9808 0 : if (!state.dataEnvrn->SunIsUp) {
9809 0 : shadingOn = false;
9810 0 : shadingOffButGlareControlOn = false;
9811 : }
9812 0 : break;
9813 :
9814 0 : case WindowShadingControlType::HiSolar_HiLumin_OffNextMorning:
9815 : // 'OnIfHighSolarOrHighLuminanceTillNextMorning'
9816 : // if shade is already on, then keep it on until next day when sun is up, otherwise check thresholds
9817 0 : if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) {
9818 0 : shadingOn = true;
9819 0 : } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) {
9820 0 : if (SolarOnWindow > SetPoint) {
9821 0 : shadingOn = true;
9822 : } else {
9823 : // pass to DayltgInteriorIllum to check for luminance
9824 0 : shadingOn = false;
9825 0 : shadingOffButGlareControlOn = true;
9826 : }
9827 : }
9828 : // if next morning (identified by sun is not up in previous time step and is up now), then shades off
9829 0 : if (!state.dataEnvrn->SunIsUpPrevTS && state.dataEnvrn->SunIsUp) {
9830 0 : shadingOn = false;
9831 0 : shadingOffButGlareControlOn = false;
9832 : }
9833 0 : break;
9834 :
9835 0 : case WindowShadingControlType::OnNightLoOutTemp_OffDay: // 'OnNightIfLowOutdoorTempAndOffDay'
9836 0 : if (!state.dataEnvrn->SunIsUp && state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) {
9837 0 : shadingOn = true;
9838 0 : } else if (GlareControlIsActive) {
9839 0 : shadingOffButGlareControlOn = true;
9840 : }
9841 0 : break;
9842 :
9843 0 : case WindowShadingControlType::OnNightLoInTemp_OffDay: // 'OnNightIfLowInsideTempAndOffDay')
9844 0 : if (!state.dataEnvrn->SunIsUp && thisIZoneHB.MAT < SetPoint && SchedAllowsControl) {
9845 0 : shadingOn = true;
9846 0 : } else if (GlareControlIsActive) {
9847 0 : shadingOffButGlareControlOn = true;
9848 : }
9849 0 : break;
9850 :
9851 0 : case WindowShadingControlType::OnNightIfHeating_OffDay: // 'OnNightIfHeatingAndOffDay'
9852 0 : if (!state.dataGlobal->BeginSimFlag) {
9853 0 : if (!state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadHeatRate > SetPoint &&
9854 : SchedAllowsControl) {
9855 0 : shadingOn = true;
9856 0 : } else if (GlareControlIsActive) {
9857 0 : shadingOffButGlareControlOn = true;
9858 : }
9859 : }
9860 0 : break;
9861 :
9862 0 : case WindowShadingControlType::OnNightLoOutTemp_OnDayCooling: // 'OnNightIfLowOutdoorTempAndOnDayIfCooling'
9863 0 : if (!state.dataGlobal->BeginSimFlag) {
9864 0 : if (!state.dataEnvrn->SunIsUp) { // Night
9865 0 : if (state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) shadingOn = true;
9866 : } else { // Day
9867 0 : if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && SchedAllowsControl) {
9868 0 : shadingOn = true;
9869 0 : } else if (GlareControlIsActive) {
9870 0 : shadingOffButGlareControlOn = true;
9871 : }
9872 : }
9873 : }
9874 0 : break;
9875 :
9876 0 : case WindowShadingControlType::OnNightIfHeating_OnDayCooling: // 'OnNightIfHeatingAndOnDayIfCooling'
9877 0 : if (!state.dataGlobal->BeginSimFlag) {
9878 0 : if (!state.dataEnvrn->SunIsUp) { // Night
9879 0 : if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadHeatRate > SetPoint && SchedAllowsControl)
9880 0 : shadingOn = true;
9881 : } else { // Day
9882 0 : if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && SchedAllowsControl) {
9883 0 : shadingOn = true;
9884 0 : } else if (GlareControlIsActive) {
9885 0 : shadingOffButGlareControlOn = true;
9886 : }
9887 : }
9888 : }
9889 0 : break;
9890 :
9891 0 : case WindowShadingControlType::OffNight_OnDay_HiSolarWindow: // 'OffNightAndOnDayIfCoolingAndHighSolarOnWindow'
9892 0 : if (!state.dataGlobal->BeginSimFlag) {
9893 0 : if (state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 &&
9894 : SchedAllowsControl) {
9895 0 : if (SolarOnWindow > SetPoint) shadingOn = true;
9896 0 : } else if (GlareControlIsActive) {
9897 0 : shadingOffButGlareControlOn = true;
9898 : }
9899 : }
9900 0 : break;
9901 :
9902 0 : case WindowShadingControlType::OnNight_OnDay_HiSolarWindow: // 'OnNightAndOnDayIfCoolingAndHighSolarOnWindow'
9903 0 : if (!state.dataGlobal->BeginSimFlag) {
9904 0 : if (state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 &&
9905 : SchedAllowsControl) {
9906 0 : if (SolarOnWindow > SetPoint) shadingOn = true;
9907 0 : } else if (!state.dataEnvrn->SunIsUp && SchedAllowsControl) {
9908 0 : shadingOn = true;
9909 0 : } else if (GlareControlIsActive) {
9910 0 : shadingOffButGlareControlOn = true;
9911 : }
9912 : }
9913 0 : break;
9914 0 : default:
9915 0 : ShowWarningError(state, "Invalid Selection of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name);
9916 : }
9917 :
9918 489327 : WinShadingType ShType = state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingType;
9919 :
9920 489327 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ShadeOff; // Initialize shading flag to off
9921 :
9922 489327 : if (IS_SHADED(ShType)) {
9923 489327 : if (shadingOn) {
9924 71475 : state.dataSurface->SurfWinShadingFlag(ISurf) = ShType;
9925 417852 : } else if (shadingOffButGlareControlOn) {
9926 88747 : if (ShType == WinShadingType::SwitchableGlazing)
9927 84939 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::GlassConditionallyLightened;
9928 3808 : else if (ShType == WinShadingType::IntShade)
9929 616 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShadeConditionallyOff;
9930 3192 : else if (ShType == WinShadingType::ExtShade)
9931 3192 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShadeConditionallyOff;
9932 0 : else if (ShType == WinShadingType::IntBlind)
9933 0 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntBlindConditionallyOff;
9934 0 : else if (ShType == WinShadingType::ExtBlind)
9935 0 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtBlindConditionallyOff;
9936 0 : else if (ShType == WinShadingType::BGShade)
9937 0 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGShadeConditionallyOff;
9938 0 : else if (ShType == WinShadingType::BGBlind)
9939 0 : state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGBlindConditionallyOff;
9940 : }
9941 : }
9942 :
9943 : // Set switching factor to fully switched if ShadingFlag = 2
9944 489327 : if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::SwitchableGlazing) {
9945 0 : state.dataSurface->SurfWinSwitchingFactor(ISurf) = 1.0;
9946 :
9947 : // Added TH 1/20/2010
9948 : // Vis trans at normal incidence of fully switched glass
9949 0 : IConst = state.dataSurface->Surface(ISurf).activeShadedConstruction;
9950 0 : state.dataSurface->SurfWinVisTransSelected(ISurf) =
9951 0 : POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf);
9952 : }
9953 :
9954 : // Slat angle control for blinds
9955 :
9956 489327 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = 0.0;
9957 489327 : state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0;
9958 489327 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = false;
9959 1439673 : if (ANY_BLIND(state.dataSurface->SurfWinShadingFlag(ISurf)) ||
9960 922038 : state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntBlindConditionallyOff ||
9961 1411365 : state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtBlindConditionallyOff ||
9962 461019 : state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::BGBlindConditionallyOff) {
9963 : // Blind in place or may be in place due to glare control
9964 28308 : int BlNum = state.dataSurface->SurfWinBlindNumber(ISurf);
9965 28308 : if (BlNum > 0) {
9966 28308 : Real64 InputSlatAngle = state.dataHeatBal->Blind(BlNum).SlatAngle *
9967 28308 : DataGlobalConstants::DegToRadians; // Slat angle of associated Material:WindowBlind (rad)
9968 : Real64 ProfAng; // Solar profile angle (rad)
9969 : Real64 SlatAng; // Slat angle this time step (rad)
9970 : Real64 PermeabilityA; // Intermediate variables in blind permeability calc
9971 : Real64 PermeabilityB;
9972 : Real64 ThetaBase; // Intermediate slat angle variable (rad)
9973 : Real64 ThetaBlock1; // Slat angles that just block beam solar (rad)
9974 : Real64 ThetaBlock2;
9975 :
9976 56616 : DaylightingManager::ProfileAngle(state,
9977 : ISurf,
9978 28308 : state.dataEnvrn->SOLCOS,
9979 28308 : state.dataHeatBal->Blind(BlNum).SlatOrientation,
9980 28308 : state.dataSurface->SurfWinProfileAng(ISurf));
9981 28308 : ProfAng = state.dataSurface->SurfWinProfileAng(ISurf);
9982 28308 : if (ProfAng > DataGlobalConstants::PiOvr2 || ProfAng < -DataGlobalConstants::PiOvr2) {
9983 0 : ProfAng = min(max(ProfAng, -DataGlobalConstants::PiOvr2), DataGlobalConstants::PiOvr2);
9984 : }
9985 28308 : int ProfAngIndex = int((ProfAng + DataGlobalConstants::PiOvr2) / DeltaProfAng) + 1;
9986 28308 : state.dataSurface->SurfWinProfAngIndex(ISurf) = ProfAngIndex;
9987 28308 : state.dataSurface->SurfWinProfAngInterpFac(ISurf) =
9988 28308 : (ProfAng + DataGlobalConstants::PiOvr2 - (ProfAngIndex - 1) * DeltaProfAng) / DeltaProfAng;
9989 :
9990 28308 : if (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) {
9991 13090 : ProfAng = state.dataSurface->SurfWinProfileAng(ISurf);
9992 26180 : Real64 ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation /
9993 26180 : state.dataHeatBal->Blind(BlNum).SlatWidth);
9994 : // There are two solutions for the slat angle that just blocks beam radiation
9995 13090 : ThetaBlock1 = ProfAng + ThetaBase;
9996 13090 : ThetaBlock2 = ProfAng + DataGlobalConstants::Pi - ThetaBase;
9997 13090 : state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2);
9998 13090 : state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2);
9999 13090 : state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians;
10000 13090 : state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians;
10001 : }
10002 :
10003 : // TH 5/20/2010, CR 8064: Slat Width <= Slat Separation
10004 28308 : if (state.dataHeatBal->Blind(BlNum).SlatWidth <= state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) {
10005 0 : if (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl == SlatAngleControl::BlockBeamSolar) {
10006 0 : ProfAng = state.dataSurface->SurfWinProfileAng(ISurf);
10007 0 : if (std::abs(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation /
10008 0 : state.dataHeatBal->Blind(BlNum).SlatWidth) <= 1.0) {
10009 : // set to block 100% of beam solar, not necessarily to block maximum solar (beam + diffuse)
10010 0 : ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation /
10011 0 : state.dataHeatBal->Blind(BlNum).SlatWidth);
10012 0 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10013 : } else {
10014 : // cannot block 100% of beam solar, turn slats to be perpendicular to sun beam to block maximal beam solar
10015 0 : ThetaBase = 0.0;
10016 : }
10017 :
10018 : // There are two solutions for the slat angle that just blocks beam radiation
10019 0 : ThetaBlock1 = ProfAng + ThetaBase;
10020 0 : ThetaBlock2 = ProfAng - ThetaBase + DataGlobalConstants::Pi;
10021 :
10022 0 : state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2);
10023 0 : state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2);
10024 0 : state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians;
10025 0 : state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians;
10026 : }
10027 : }
10028 :
10029 28308 : switch (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl) {
10030 25177 : case SlatAngleControl::Fixed: { // 'FIXEDSLATANGLE'
10031 25177 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle;
10032 55834 : if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall ||
10033 30494 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) &&
10034 75205 : (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) &&
10035 : (BeamSolarOnWindow > 0.0))
10036 11991 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10037 25177 : } break;
10038 0 : case SlatAngleControl::Scheduled: { // 'SCHEDULEDSLATANGLE'
10039 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) =
10040 0 : GetCurrentScheduleValue(state, state.dataSurface->WindowShadingControl(IShadingCtrl).SlatAngleSchedule);
10041 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) =
10042 0 : max(state.dataHeatBal->Blind(BlNum).MinSlatAngle,
10043 0 : min(state.dataSurface->SurfWinSlatAngThisTS(ISurf), state.dataHeatBal->Blind(BlNum).MaxSlatAngle)) *
10044 : DataGlobalConstants::DegToRadians;
10045 0 : if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall ||
10046 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) &&
10047 0 : (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) &&
10048 : (BeamSolarOnWindow > 0.0))
10049 0 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10050 0 : } break;
10051 3131 : case SlatAngleControl::BlockBeamSolar: { // 'BLOCKBEAMSOLAR'
10052 3131 : if (BeamSolarOnWindow > 0.0) {
10053 1092 : if (state.dataHeatBal->Blind(BlNum).SlatSeparation >= state.dataHeatBal->Blind(BlNum).SlatWidth) {
10054 : // TH 5/20/2010. CR 8064.
10055 : // The following line of code assumes slats are always vertical/closed to minimize solar penetration
10056 : // The slat angle can however change if the only goal is to block maximum amount of direct beam solar
10057 : // SurfaceWindow(ISurf)%SlatAngThisTS = 0.0 ! Allows beam penetration but minimizes it
10058 :
10059 0 : if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin &&
10060 0 : state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) {
10061 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall;
10062 0 : } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin &&
10063 0 : state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) {
10064 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig;
10065 0 : } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin &&
10066 0 : state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) {
10067 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
10068 0 : } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax &&
10069 0 : state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) {
10070 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax;
10071 : } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition)
10072 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
10073 : }
10074 :
10075 : } else { // Usual case -- slat width greater than slat separation
10076 2184 : if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin &&
10077 1092 : state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) {
10078 1071 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall;
10079 1071 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10080 42 : } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin &&
10081 21 : state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) {
10082 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig;
10083 0 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10084 21 : } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin &&
10085 0 : state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) {
10086 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
10087 0 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10088 42 : } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax &&
10089 21 : state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) {
10090 21 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax;
10091 21 : state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true;
10092 : } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition)
10093 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin;
10094 : }
10095 : }
10096 : } else {
10097 2039 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle;
10098 : }
10099 3131 : } break;
10100 0 : default:
10101 0 : break;
10102 : }
10103 :
10104 28308 : state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) =
10105 28308 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) / DataGlobalConstants::DegToRadians;
10106 28308 : if (state.dataSurface->SurfWinSlatAngThisTSDegEMSon(ISurf)) {
10107 0 : state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = state.dataSurface->SurfWinSlatAngThisTSDegEMSValue(ISurf);
10108 0 : state.dataSurface->SurfWinSlatAngThisTS(ISurf) =
10109 0 : DataGlobalConstants::DegToRadians * state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf);
10110 : }
10111 : // Air flow permeability for calculation of convective air flow between blind and glass
10112 28308 : SlatAng = state.dataSurface->SurfWinSlatAngThisTS(ISurf);
10113 28308 : PermeabilityA =
10114 28308 : std::sin(SlatAng) - state.dataHeatBal->Blind(BlNum).SlatThickness / state.dataHeatBal->Blind(BlNum).SlatSeparation;
10115 84924 : PermeabilityB = 1.0 - (std::abs(state.dataHeatBal->Blind(BlNum).SlatWidth * std::cos(SlatAng)) +
10116 56616 : state.dataHeatBal->Blind(BlNum).SlatThickness * std::sin(SlatAng)) /
10117 28308 : state.dataHeatBal->Blind(BlNum).SlatSeparation;
10118 28308 : state.dataSurface->SurfWinBlindAirFlowPermeability(ISurf) = min(1.0, max(0.0, PermeabilityA, PermeabilityB));
10119 84924 : state.dataSurface->SurfWinBlindBmBmTrans(ISurf) = General::BlindBeamBeamTrans(ProfAng,
10120 : SlatAng,
10121 28308 : state.dataHeatBal->Blind(BlNum).SlatWidth,
10122 28308 : state.dataHeatBal->Blind(BlNum).SlatSeparation,
10123 28308 : state.dataHeatBal->Blind(BlNum).SlatThickness);
10124 : // Calculate blind interpolation factors and indices.
10125 28308 : if (state.dataSurface->SurfWinMovableSlats(ISurf)) {
10126 3131 : if (SlatAng > DataGlobalConstants::Pi || SlatAng < 0.0) {
10127 0 : SlatAng = min(max(SlatAng, 0.0), DataGlobalConstants::Pi);
10128 : }
10129 3131 : Real64 SlatsAngIndex = 1 + int(SlatAng * DeltaAng_inv);
10130 3131 : state.dataSurface->SurfWinSlatsAngIndex(ISurf) = SlatsAngIndex;
10131 3131 : state.dataSurface->SurfWinSlatsAngInterpFac(ISurf) = (SlatAng - DeltaAng * (SlatsAngIndex - 1)) * DeltaAng_inv;
10132 : }
10133 : }
10134 : } // End of check if interior or exterior or between glass blind in place
10135 :
10136 : // CALL CalcScreenTransmittance to intialized all screens prior to HB calc's
10137 489327 : if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtScreen && state.dataEnvrn->SunIsUp) {
10138 3248 : CalcScreenTransmittance(state, ISurf);
10139 : }
10140 :
10141 : // EMS Actuator Point: override setting if ems flag on
10142 489327 : if (state.dataSurface->SurfWinShadingFlagEMSOn(ISurf)) {
10143 48400 : WinShadingType SurfWinShadingFlagEMS = findValueInEnumeration(state.dataSurface->SurfWinShadingFlagEMSValue(ISurf));
10144 48400 : if (SurfWinShadingFlagEMS != WinShadingType::Invalid) {
10145 48400 : state.dataSurface->SurfWinShadingFlag(ISurf) = SurfWinShadingFlagEMS;
10146 : } else {
10147 0 : ShowWarningError(state,
10148 0 : "Invalid EMS value of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name);
10149 : }
10150 : }
10151 : } // End of surface loop
10152 : }
10153 : }
10154 2568509 : }
10155 :
10156 2568509 : void CheckGlazingShadingStatusChange(EnergyPlusData &state)
10157 : {
10158 2568509 : if (state.dataGlobal->BeginSimFlag) {
10159 771 : if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
10160 2 : state.dataHeatBal->EnclRadAlwaysReCalc = true;
10161 : } else {
10162 5581 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
10163 9628 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
10164 4816 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
10165 46998 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
10166 84367 : if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TCFlag == 1 ||
10167 42183 : state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) {
10168 2 : state.dataHeatBal->EnclRadAlwaysReCalc = true;
10169 2 : break;
10170 : }
10171 : }
10172 : }
10173 : }
10174 : }
10175 771 : if (state.dataHeatBal->EnclRadAlwaysReCalc) {
10176 13 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
10177 9 : state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = true;
10178 : }
10179 13 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
10180 9 : state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = true;
10181 : }
10182 : }
10183 : }
10184 2568509 : if (state.dataHeatBal->EnclRadAlwaysReCalc) return;
10185 :
10186 2559053 : if (state.dataGlobal->BeginEnvrnFlag || state.dataGlobal->AnyConstrOverridesInModel || state.dataGlobal->AnySurfPropOverridesInModel) {
10187 94718 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
10188 82476 : state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = true;
10189 : }
10190 94718 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
10191 82476 : state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = true;
10192 : }
10193 12242 : return;
10194 : }
10195 20869059 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
10196 18322248 : state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = false;
10197 : }
10198 20869059 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
10199 18322248 : state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = false;
10200 : }
10201 2546811 : if (!state.dataGlobal->AndShadingControlInModel) return;
10202 818524 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
10203 6719931 : for (int const SurfNum : state.dataViewFactor->EnclRadInfo(enclosureNum).SurfacePtr) {
10204 : bool surfShadingStatusChange =
10205 12145755 : state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) != state.dataSurface->SurfWinShadingFlag(SurfNum) ||
10206 12145755 : state.dataSurface->Surface(SurfNum).activeShadedConstruction != state.dataSurface->Surface(SurfNum).activeShadedConstructionPrev ||
10207 12145755 : state.dataSurface->SurfWinMovableSlats(SurfNum);
10208 6093056 : if (surfShadingStatusChange) {
10209 46389 : state.dataViewFactor->EnclSolInfo(enclosureNum).radReCalc = true;
10210 46389 : state.dataViewFactor->EnclRadInfo(enclosureNum).radReCalc = true;
10211 46389 : break;
10212 : }
10213 : }
10214 : }
10215 : }
10216 :
10217 48400 : DataSurfaces::WinShadingType findValueInEnumeration(Real64 controlValue)
10218 : {
10219 : // This is a workaround to translate EMS Shading control numerical values
10220 : // EMS control of window shading devices involves setting the control values for shading control actuators with
10221 : // one of these values. The variable names can be used or replaced, it is the whole number values that trigger
10222 : // changes in the modeling.
10223 : // Shades and Blinds are either fully on or fully off, partial positions require multiple windows.
10224 : // the window shading control flag values follow
10225 : // -1: if window has no shading device
10226 : // 0: if shading device is off
10227 : // 1: if interior shade is on
10228 : // 2: if glazing is switched to darker state
10229 : // 3: if exterior shade is on
10230 : // 4: if exterior screen is on
10231 : // 6: if interior blind is on
10232 : // 7: if exterior blind is on
10233 : // 8: if between-glass shade is on
10234 : // 9: if between-glass blind is on
10235 : // 10: window has interior shade that is off but may be triggered on later to control daylight glare
10236 : // 20: window has switchable glazing that is unswitched but may be switched later to control daylight glare or
10237 : // daylight illuminance 30: window has exterior shade that is off but may be triggered on later to control
10238 : // daylight glare or daylight illuminance 60: window has interior blind that is off but may be triggered on later
10239 : // to control daylight glare or daylight illuminance 70: window has exterior blind that is off but may be
10240 : // triggered on later to control daylight glare or daylight illuminance 80: window has between-glass shade that is
10241 : // off but may be triggered on later to control daylight glare or daylight illuminance 90: window has
10242 : // between-glass blind that is off but may be triggered on later to control daylight glare or daylight illuminance
10243 48400 : if (controlValue == -1.0) return WinShadingType::NoShade;
10244 48400 : if (controlValue == 0.0) return WinShadingType::ShadeOff;
10245 16204 : if (controlValue == 1.0) return WinShadingType::IntShade;
10246 16204 : if (controlValue == 2.0) return WinShadingType::SwitchableGlazing;
10247 16204 : if (controlValue == 3.0) return WinShadingType::ExtShade;
10248 16204 : if (controlValue == 4.0) return WinShadingType::ExtScreen;
10249 16204 : if (controlValue == 6.0) return WinShadingType::IntBlind;
10250 0 : if (controlValue == 7.0) return WinShadingType::ExtBlind;
10251 0 : if (controlValue == 8.0) return WinShadingType::BGShade;
10252 0 : if (controlValue == 9.0) return WinShadingType::BGBlind;
10253 0 : if (controlValue == 10.0) return WinShadingType::IntShadeConditionallyOff;
10254 0 : if (controlValue == 20.0) return WinShadingType::GlassConditionallyLightened;
10255 0 : if (controlValue == 30.0) return WinShadingType::ExtShadeConditionallyOff;
10256 0 : if (controlValue == 60.0) return WinShadingType::IntBlindConditionallyOff;
10257 0 : if (controlValue == 70.0) return WinShadingType::ExtBlindConditionallyOff;
10258 0 : if (controlValue == 80.0) return WinShadingType::BGShadeConditionallyOff;
10259 0 : if (controlValue == 90.0) return WinShadingType::BGBlindConditionallyOff;
10260 0 : return WinShadingType::Invalid;
10261 : }
10262 :
10263 489327 : int selectActiveWindowShadingControlIndex(EnergyPlusData &state, int curSurface)
10264 : {
10265 : // For a given surface, determine based on the schedules which index to the window shading control list vector
10266 : // should be active
10267 489327 : int selected = 0; // presume it is the first shading control - even if it is not active it needs to be some
10268 : // shading control which is then turned off in the WindowShadingManager
10269 489327 : if (state.dataSurface->Surface(curSurface).windowShadingControlList.size() > 1) {
10270 10476 : for (std::size_t listIndex = 0; listIndex < state.dataSurface->Surface(curSurface).windowShadingControlList.size(); ++listIndex) {
10271 6996 : int wsc = state.dataSurface->Surface(curSurface).windowShadingControlList[listIndex];
10272 : // pick the first WindowShadingControl that has a non-zero schedule value
10273 6996 : if (ScheduleManager::GetCurrentScheduleValue(state, state.dataSurface->WindowShadingControl(wsc).Schedule) > 0.0) {
10274 24 : selected = listIndex;
10275 24 : break;
10276 : }
10277 : }
10278 : }
10279 489327 : return (selected);
10280 : }
10281 :
10282 4044 : void WindowGapAirflowControl(EnergyPlusData &state)
10283 : {
10284 :
10285 : // SUBROUTINE INFORMATION:
10286 : // AUTHOR Fred Winkelmann
10287 : // DATE WRITTEN February 2003
10288 : // MODIFIED June 2003, FCW: add fatal error for illegal schedule value
10289 : // RE-ENGINEERED na
10290 :
10291 : // PURPOSE OF THIS SUBROUTINE:
10292 : // For airflow windows, determines the airflow in the gap of
10293 : // double glazing and in the inner gap of triple glazing.
10294 :
10295 : // REFERENCES:
10296 : // na
10297 :
10298 : // Using/Aliasing
10299 : using ScheduleManager::GetCurrentScheduleValue;
10300 :
10301 16176 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
10302 24264 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
10303 12132 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
10304 12132 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
10305 12132 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
10306 44484 : for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) {
10307 :
10308 32352 : state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0;
10309 32352 : if (state.dataSurface->SurfWinMaxAirflow(ISurf) == 0.0) continue;
10310 16176 : if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue;
10311 16176 : switch (state.dataSurface->SurfWinAirflowControlType(ISurf)) {
10312 16176 : case WindowAirFlowControlType::MaxFlow: {
10313 16176 : state.dataSurface->SurfWinAirflowThisTS(ISurf) = state.dataSurface->SurfWinMaxAirflow(ISurf);
10314 16176 : } break;
10315 0 : case WindowAirFlowControlType::AlwaysOff: {
10316 0 : state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0;
10317 0 : } break;
10318 0 : case WindowAirFlowControlType::Schedule: {
10319 0 : if (state.dataSurface->SurfWinAirflowHasSchedule(ISurf)) {
10320 0 : int SchedulePtr = state.dataSurface->SurfWinAirflowSchedulePtr(ISurf); // Schedule pointer
10321 0 : Real64 ScheduleMult = GetCurrentScheduleValue(state, SchedulePtr); // Multiplier value from schedule
10322 0 : if (ScheduleMult < 0.0 || ScheduleMult > 1.0) {
10323 0 : ShowFatalError(state,
10324 0 : "Airflow schedule has a value outside the range 0.0 to 1.0 for window=" +
10325 0 : state.dataSurface->Surface(ISurf).Name);
10326 : }
10327 0 : state.dataSurface->SurfWinAirflowThisTS(ISurf) = ScheduleMult * state.dataSurface->SurfWinMaxAirflow(ISurf);
10328 : }
10329 0 : } break;
10330 0 : default:
10331 0 : break;
10332 : }
10333 : } // End of surface loop
10334 : } // End of space loop
10335 : } // End of zone loop
10336 4044 : }
10337 :
10338 771 : void SkyDifSolarShading(EnergyPlusData &state)
10339 : {
10340 :
10341 : // SUBROUTINE INFORMATION:
10342 : // AUTHOR Fred Winkelmann
10343 : // DATE WRITTEN May 1999
10344 : // MODIFIED Sep 2000, FCW: add IR view factor calc
10345 : // Sep 2002, FCW: correct error in expression for ground IR view factor.
10346 : // Affects only non-vertical surfaces that are shadowed. For these surfaces
10347 : // error caused underestimate of IR from ground and shadowing surfaces.
10348 : // Dec 2002; LKL: Sky Radiance Distribution now only anisotropic
10349 : // Nov 2003: FCW: modify to do sky solar shading of shadowing surfaces
10350 : // RE-ENGINEERED na
10351 :
10352 : // PURPOSE OF THIS SUBROUTINE:
10353 : // Calculates factors that account for shading of sky diffuse
10354 : // solar radiation by shadowing surfaces such as overhangs and detached
10355 : // shades.
10356 : // Called by PerformSolarCalculations
10357 : // For each exterior heat transfer surface calculates the following
10358 : // ratio (called DifShdgRatioIsoSky in this subroutine):
10359 : // R1 = (Diffuse solar from sky dome on surface, with shading)/
10360 : // (Diffuse solar from sky dome on surface, without shading)
10361 : // To calculate the incident diffuse radiation on a surface the sky
10362 : // hemisphere is divided into source elements ("patches"). Each patch
10363 : // is assumed to have the same radiance, i.e. the sky radiance is isotropic.
10364 : // The irradiance from each patch on a surface is calculated. Then these
10365 : // irradiances are summed to get the net irradiance on a surface, which
10366 : // the denominator of R1.
10367 : // To get the numerator of R1 the same summation is done, but for each surface
10368 : // and each patch the Shadow subroutine is called to determine how much
10369 : // radiation from a patch is blocked by shading surfaces.
10370 : // Also calculated is the following ratio (called DifShdgRatioHoriz in this routine):
10371 : // R2 = (Diffuse solar from sky horizon band on surface, with shading)/
10372 : // (Diffuse solar from sky horizon band on surface, without shading)
10373 : // For this ratio only a band of sky just above the horizon is considered.
10374 : // R1 and R2 are used in SUBROUTINE AnisoSkyViewFactors, which determines the
10375 : // sky diffuse solar irradiance on each exterior heat transfer surface each
10376 : // time step. In that routine the sky radiance distribution is a superposition
10377 : // of an isotropic distribution,
10378 : // a horizon brightening distribution and a circumsolar brightening distribution,
10379 : // where the proportion of each distribution depends
10380 : // on cloud cover, sun position and other factors. R1 multiplies the irradiance
10381 : // due to the isotropic component and R2 multiplies the irradiance due to the
10382 : // horizon brightening component.
10383 : // Calculates sky and ground IR view factors assuming sky IR is isotropic and
10384 : // shadowing surfaces are opaque to IR.
10385 :
10386 : // Using/Aliasing
10387 :
10388 : Real64 Fac1WoShdg; // Intermediate calculation factor, without shading
10389 : Real64 FracIlluminated; // Fraction of surface area illuminated by a sky patch
10390 : Real64 Fac1WithShdg; // Intermediate calculation factor, with shading
10391 : Real64 SurfArea; // Surface area (m2)
10392 : // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WithShdgIsoSky ! Diffuse solar irradiance from isotropic
10393 : // ! sky on surface, with shading
10394 : // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgIsoSky ! Diffuse solar from isotropic
10395 : // ! sky on surface, without shading
10396 : // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WithShdgHoriz ! Diffuse solar irradiance from horizon portion
10397 : // of
10398 : // ! sky on surface, with shading
10399 : // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgHoriz ! Diffuse solar irradiance from horizon portion
10400 : // of
10401 : // ! sky on surface, without shading
10402 : // INTEGER iHour,iTS
10403 :
10404 : // Initialize Surfaces Arrays
10405 771 : bool detailedShading = state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
10406 771 : state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal;
10407 771 : state.dataSolarShading->SurfSunlitArea = 0.0;
10408 771 : state.dataSolarShading->SurfWithShdgIsoSky.dimension(state.dataSurface->TotSurfaces, 0.0);
10409 771 : state.dataSolarShading->SurfWoShdgIsoSky.dimension(state.dataSurface->TotSurfaces, 0.0);
10410 771 : state.dataSolarShading->SurfWithShdgHoriz.dimension(state.dataSurface->TotSurfaces, 0.0);
10411 771 : state.dataSolarShading->SurfWoShdgHoriz.dimension(state.dataSurface->TotSurfaces, 0.0);
10412 771 : state.dataSolarShading->SurfDifShdgRatioIsoSky.allocate(state.dataSurface->TotSurfaces);
10413 771 : state.dataSolarShading->SurfDifShdgRatioHoriz.allocate(state.dataSurface->TotSurfaces);
10414 : // initialized as no shading
10415 771 : state.dataSolarShading->SurfDifShdgRatioIsoSky = 1.0;
10416 771 : state.dataSolarShading->SurfDifShdgRatioHoriz = 1.0;
10417 771 : if (detailedShading) {
10418 0 : state.dataSolarShading->SurfCurDifShdgRatioIsoSky.dimension(state.dataSurface->TotSurfaces, 1.0);
10419 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, state.dataSurface->TotSurfaces);
10420 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS = 1.0;
10421 0 : state.dataSolarShading->SurfDifShdgRatioHorizHRTS.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, state.dataSurface->TotSurfaces);
10422 0 : state.dataSolarShading->SurfDifShdgRatioHorizHRTS = 1.0;
10423 : }
10424 :
10425 19152 : for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
10426 :
10427 : // CurrentModuleObject='Surfaces'
10428 18381 : if (detailedShading) {
10429 0 : SetupOutputVariable(state,
10430 : "Debug Surface Solar Shading Model DifShdgRatioIsoSky",
10431 : OutputProcessor::Unit::None,
10432 0 : state.dataSolarShading->SurfCurDifShdgRatioIsoSky(SurfNum),
10433 : OutputProcessor::SOVTimeStepType::Zone,
10434 : OutputProcessor::SOVStoreType::Average,
10435 0 : state.dataSurface->Surface(SurfNum).Name);
10436 : } else {
10437 55143 : SetupOutputVariable(state,
10438 : "Debug Surface Solar Shading Model DifShdgRatioIsoSky",
10439 : OutputProcessor::Unit::None,
10440 18381 : state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum),
10441 : OutputProcessor::SOVTimeStepType::Zone,
10442 : OutputProcessor::SOVStoreType::Average,
10443 36762 : state.dataSurface->Surface(SurfNum).Name);
10444 : }
10445 55143 : SetupOutputVariable(state,
10446 : "Debug Surface Solar Shading Model DifShdgRatioHoriz",
10447 : OutputProcessor::Unit::None,
10448 18381 : state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum),
10449 : OutputProcessor::SOVTimeStepType::Zone,
10450 : OutputProcessor::SOVStoreType::Average,
10451 36762 : state.dataSurface->Surface(SurfNum).Name);
10452 55143 : SetupOutputVariable(state,
10453 : "Debug Surface Solar Shading Model WithShdgIsoSky",
10454 : OutputProcessor::Unit::None,
10455 18381 : state.dataSolarShading->SurfWithShdgIsoSky(SurfNum),
10456 : OutputProcessor::SOVTimeStepType::Zone,
10457 : OutputProcessor::SOVStoreType::Average,
10458 36762 : state.dataSurface->Surface(SurfNum).Name);
10459 55143 : SetupOutputVariable(state,
10460 : "Debug Surface Solar Shading Model WoShdgIsoSky",
10461 : OutputProcessor::Unit::None,
10462 18381 : state.dataSolarShading->SurfWoShdgIsoSky(SurfNum),
10463 : OutputProcessor::SOVTimeStepType::Zone,
10464 : OutputProcessor::SOVStoreType::Average,
10465 36762 : state.dataSurface->Surface(SurfNum).Name);
10466 : }
10467 :
10468 5397 : for (int IPhi = 0; IPhi < NPhi; ++IPhi) { // Loop over patch altitude values
10469 4626 : state.dataSolarShading->SUNCOS(3) = state.dataSolarShading->sin_Phi[IPhi];
10470 :
10471 115650 : for (int ITheta = 0; ITheta < NTheta; ++ITheta) { // Loop over patch azimuth values
10472 111024 : state.dataSolarShading->SUNCOS(1) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->cos_Theta[ITheta];
10473 111024 : state.dataSolarShading->SUNCOS(2) = state.dataSolarShading->cos_Phi[IPhi] * state.dataSolarShading->sin_Theta[ITheta];
10474 :
10475 2775744 : for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
10476 : // Cosine of angle of incidence on surface of solar radiation from patch
10477 2664720 : state.dataSolarShading->SurfSunCosTheta(SurfNum) =
10478 5329440 : state.dataSolarShading->SUNCOS(1) * state.dataSurface->Surface(SurfNum).OutNormVec(1) +
10479 5329440 : state.dataSolarShading->SUNCOS(2) * state.dataSurface->Surface(SurfNum).OutNormVec(2) +
10480 2664720 : state.dataSolarShading->SUNCOS(3) * state.dataSurface->Surface(SurfNum).OutNormVec(3);
10481 : }
10482 :
10483 111024 : SHADOW(state, 24, 0);
10484 :
10485 2775744 : for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
10486 :
10487 2664720 : if (state.dataSolarShading->SurfSunCosTheta(SurfNum) < 0.0) continue;
10488 :
10489 1530123 : Fac1WoShdg = state.dataSolarShading->cos_Phi[IPhi] * DThetaDPhi * state.dataSolarShading->SurfSunCosTheta(SurfNum);
10490 1530123 : SurfArea = state.dataSurface->Surface(SurfNum).NetAreaShadowCalc;
10491 1530123 : if (SurfArea > Eps) {
10492 1530123 : FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / SurfArea;
10493 : } else {
10494 0 : FracIlluminated = state.dataSolarShading->SurfSunlitArea(SurfNum) / (SurfArea + Eps);
10495 : }
10496 1530123 : Fac1WithShdg = Fac1WoShdg * FracIlluminated;
10497 1530123 : state.dataSolarShading->SurfWithShdgIsoSky(SurfNum) += Fac1WithShdg;
10498 1530123 : state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) += Fac1WoShdg;
10499 :
10500 : // Horizon region
10501 1530123 : if (IPhi == 0) {
10502 253154 : state.dataSolarShading->SurfWithShdgHoriz(SurfNum) += Fac1WithShdg;
10503 253154 : state.dataSolarShading->SurfWoShdgHoriz(SurfNum) += Fac1WoShdg;
10504 : }
10505 : } // End of surface loop
10506 : } // End of Theta loop
10507 : } // End of Phi loop
10508 :
10509 19276 : for (int SurfNum : state.dataSurface->AllExtSolAndShadingSurfaceList) {
10510 :
10511 18505 : if (std::abs(state.dataSolarShading->SurfWoShdgIsoSky(SurfNum)) > Eps) {
10512 17831 : state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum) =
10513 17831 : (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum));
10514 : } else {
10515 674 : state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum) =
10516 674 : (state.dataSolarShading->SurfWithShdgIsoSky(SurfNum)) / (state.dataSolarShading->SurfWoShdgIsoSky(SurfNum) + Eps);
10517 : }
10518 18505 : if (std::abs(state.dataSolarShading->SurfWoShdgHoriz(SurfNum)) > Eps) {
10519 17831 : state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum) =
10520 17831 : (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum));
10521 : } else {
10522 674 : state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum) =
10523 674 : (state.dataSolarShading->SurfWithShdgHoriz(SurfNum)) / (state.dataSolarShading->SurfWoShdgHoriz(SurfNum) + Eps);
10524 : }
10525 : }
10526 :
10527 : // Get IR view factors. An exterior surface can receive IR radiation from
10528 : // sky, ground or shadowing surfaces. Assume shadowing surfaces have same
10529 : // temperature as outside air (and therefore same temperature as ground),
10530 : // so that the view factor to these shadowing surfaces can be included in
10531 : // the ground view factor. Sky IR is assumed to be isotropic and shadowing
10532 : // surfaces are assumed to be opaque to IR so they totally "shade" IR from
10533 : // sky or ground.
10534 :
10535 44533 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
10536 43762 : if (!state.dataSysVars->DetailedSkyDiffuseAlgorithm || !state.dataSurface->ShadingTransmittanceVaries ||
10537 0 : state.dataHeatBal->SolarDistribution == DataHeatBalance::Shadowing::Minimal) {
10538 43762 : state.dataSurface->Surface(SurfNum).ViewFactorSkyIR *= state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum);
10539 : } else {
10540 0 : state.dataSurface->Surface(SurfNum).ViewFactorSkyIR *= state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS(1, 1, SurfNum);
10541 : }
10542 43762 : state.dataSurface->Surface(SurfNum).ViewFactorGroundIR = 1.0 - state.dataSurface->Surface(SurfNum).ViewFactorSkyIR;
10543 :
10544 43762 : if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
10545 6 : Real64 SrdSurfsViewFactor = 0.0;
10546 6 : int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
10547 6 : auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
10548 20 : for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
10549 14 : SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
10550 : }
10551 6 : state.dataSurface->Surface(SurfNum).ViewFactorGroundIR = 1.0 - state.dataSurface->Surface(SurfNum).ViewFactorSkyIR - SrdSurfsViewFactor;
10552 : }
10553 : }
10554 :
10555 : // DEALLOCATE(WithShdgIsoSky)
10556 : // DEALLOCATE(WoShdgIsoSky)
10557 : // DEALLOCATE(WithShdgHoriz)
10558 : // DEALLOCATE(WoShdgHoriz)
10559 :
10560 771 : if (state.dataSysVars->DetailedSkyDiffuseAlgorithm && state.dataSurface->ShadingTransmittanceVaries &&
10561 0 : state.dataHeatBal->SolarDistribution != DataHeatBalance::Shadowing::Minimal) {
10562 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
10563 0 : state.dataSolarShading->SurfDifShdgRatioIsoSkyHRTS({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}, SurfNum) =
10564 0 : state.dataSolarShading->SurfDifShdgRatioIsoSky(SurfNum);
10565 0 : state.dataSolarShading->SurfDifShdgRatioHorizHRTS({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}, SurfNum) =
10566 0 : state.dataSolarShading->SurfDifShdgRatioHoriz(SurfNum);
10567 : }
10568 : }
10569 771 : }
10570 :
10571 822103 : void CalcWindowProfileAngles(EnergyPlusData &state)
10572 : {
10573 :
10574 : // SUBROUTINE INFORMATION:
10575 : // AUTHOR Fred Winkelmann
10576 : // DATE WRITTEN April 2002
10577 : // MODIFIED na
10578 : // RE-ENGINEERED na
10579 : // PURPOSE OF THIS SUBROUTINE:
10580 : // Called by CalcPerSolarBeam for wholly or partially sunlit exterior windows
10581 : // Calculates horizontal and vertical beam solar profile angles
10582 :
10583 : Real64 ElevSun; // Sun elevation; angle between sun and horizontal
10584 : Real64 ElevWin; // Window elevation: angle between window outward normal and horizontal
10585 : Real64 AzimWin; // Window azimuth (radians)
10586 : Real64 AzimSun; // Sun azimuth (radians)
10587 : Real64 ProfileAngHor; // Solar profile angle (radians) for horizontally oriented window elements
10588 : // such as the top and bottom of a frame.
10589 : // This is the incidence angle in a plane that is normal to the window
10590 : // and parallel to the Y-axis of the window (the axis along
10591 : // which the height of the window is measured).
10592 : Real64 ProfileAngVert; // Solar profile angle (radians) for vertically oriented elements
10593 : // such as the sides of a frame.
10594 : // This is the incidence angle in a plane that is normal to the window
10595 : // and parallel to the X-axis of the window (the axis along
10596 : // which the width of the window is measured).
10597 1644206 : Vector3<Real64> WinNorm; // Unit vector normal to window
10598 1644206 : Vector3<Real64> WinNormCrossBase; // Cross product of WinNorm and vector along window baseline
10599 1644206 : Vector3<Real64> SunPrime; // Projection of sun vector onto plane (perpendicular to
10600 1644206 : Vector3<Real64> const SolCosVec(state.dataEnvrn->SOLCOS); // Local Vector3 copy for speed (until SOLCOS mig to Vector3)
10601 : // window plane) determined by WinNorm and vector along
10602 : // baseline of window
10603 : Real64 ThWin; // Azimuth angle of WinNorm (radians)
10604 : Real64 dot1;
10605 : Real64 dot2;
10606 : Real64 dot3;
10607 :
10608 822103 : ElevSun = DataGlobalConstants::PiOvr2 - std::acos(SolCosVec.z);
10609 822103 : AzimSun = std::atan2(SolCosVec.x, SolCosVec.y);
10610 :
10611 822103 : Real64 const cos_ElevSun = std::cos(ElevSun);
10612 822103 : Real64 const sin_ElevSun = std::sin(ElevSun);
10613 :
10614 6670327 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
10615 11701404 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
10616 5853180 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
10617 5853180 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
10618 5853180 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
10619 12978939 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
10620 :
10621 7134269 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment &&
10622 8510 : state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt)
10623 8510 : continue;
10624 :
10625 7117249 : state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
10626 7117249 : state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
10627 7117249 : if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue;
10628 :
10629 3852155 : ElevWin = DataGlobalConstants::PiOvr2 - state.dataSurface->Surface(SurfNum).Tilt * DataGlobalConstants::DegToRadians;
10630 3852155 : AzimWin = state.dataSurface->Surface(SurfNum).Azimuth * DataGlobalConstants::DegToRadians;
10631 :
10632 3852155 : ProfileAngHor = std::atan(sin_ElevSun / std::abs(cos_ElevSun * std::cos(AzimWin - AzimSun))) - ElevWin;
10633 :
10634 : // CR9280 - were having negative profile angles on west sides. commenting out previous code
10635 : // (original code) for vertical windows
10636 : // IF(ABS(ElevWin) < 0.1d0) THEN ! Near-vertical window
10637 : // ProfileAngVert = ABS(AzimWin-AzimSun)
10638 : // ELSE
10639 3852155 : WinNorm = state.dataSurface->Surface(SurfNum).OutNormVec;
10640 3852155 : ThWin = AzimWin - DataGlobalConstants::PiOvr2;
10641 3852155 : Real64 const sin_Elevwin(std::sin(ElevWin));
10642 3852155 : WinNormCrossBase.x = -(sin_Elevwin * std::cos(ThWin));
10643 3852155 : WinNormCrossBase.y = sin_Elevwin * std::sin(ThWin);
10644 3852155 : WinNormCrossBase.z = std::cos(ElevWin);
10645 3852155 : SunPrime = SolCosVec - WinNormCrossBase * dot(SolCosVec, WinNormCrossBase);
10646 3852155 : dot1 = dot(WinNorm, SunPrime);
10647 3852155 : dot2 = SunPrime.magnitude();
10648 3852155 : dot3 = dot1 / dot2;
10649 3852155 : if (dot3 > 1.0) {
10650 0 : dot3 = 1.0;
10651 3852155 : } else if (dot3 < -1.0) {
10652 0 : dot3 = -1.0;
10653 : }
10654 : // ProfileAngVert =
10655 : // ABS(ACOS(DOT_PRODUCT(WinNorm,SunPrime)/SQRT(DOT_PRODUCT(SunPrime,SunPrime))))
10656 3852155 : ProfileAngVert = std::abs(std::acos(dot3));
10657 : // END IF
10658 : // Constrain to 0 to pi
10659 3852155 : if (ProfileAngVert > DataGlobalConstants::Pi) ProfileAngVert = DataGlobalConstants::TwoPi - ProfileAngVert;
10660 :
10661 3852155 : state.dataSurface->SurfWinProfileAngHor(SurfNum) = ProfileAngHor / DataGlobalConstants::DegToRadians;
10662 3852155 : state.dataSurface->SurfWinProfileAngVert(SurfNum) = ProfileAngVert / DataGlobalConstants::DegToRadians;
10663 3852155 : state.dataSurface->SurfWinTanProfileAngHor(SurfNum) = std::abs(std::tan(ProfileAngHor));
10664 3852155 : state.dataSurface->SurfWinTanProfileAngVert(SurfNum) = std::abs(std::tan(ProfileAngVert));
10665 : }
10666 : }
10667 : }
10668 822103 : }
10669 :
10670 68875 : void CalcFrameDividerShadow(EnergyPlusData &state,
10671 : int const SurfNum, // Surface number
10672 : int const FrDivNum, // Frame/divider number
10673 : int const HourNum // Hour number
10674 : )
10675 : {
10676 :
10677 : // SUBROUTINE INFORMATION:
10678 : // AUTHOR Fred Winkelmann
10679 : // DATE WRITTEN June 2000
10680 : // MODIFIED Aug 2000, FW: add effective shadowing by inside
10681 : // projections
10682 : // RE-ENGINEERED na
10683 :
10684 : // PURPOSE OF THIS SUBROUTINE:
10685 : // Called by CalcPerSolarBeam for wholly or partially sunlit exterior windows
10686 : // with a frame and/or divider. Using beam solar profile angles,
10687 : // calculates fraction of glass shaded by exterior frame and divider projections,
10688 : // The frame and divider profiles are assumed to be rectangular.
10689 : // A similar shadowing approach is used to calculate the fraction of glass area
10690 : // that produces beam solar illumination on interior frame and divider projections.
10691 : // This fraction is used in CalcWinFrameAndDividerTemps to determine the
10692 : // beam solar absorbed by inside projections. Beam solar reflected by inside projections
10693 : // is assumed to stay in the zone (as beam solar) although in actuality roughly
10694 : // half of this is reflected back onto the glass and the half that is reflected
10695 : // into the zone is diffuse.
10696 : // For multipane glazing the effect of solar absorbed by the exposed portion of
10697 : // frame or divider between the panes is not calculated. Beam solar incident on
10698 : // these portions is assumed to be transmitted into the zone unchanged.
10699 : // The shadowing of diffuse solar radiation by projections is not considered.
10700 :
10701 : Real64 ElevSun; // Sun elevation; angle between sun and horizontal
10702 : Real64 ElevWin; // Window elevation: angle between window outward normal and horizontal
10703 : Real64 AzimWin; // Window azimuth (radians)
10704 : Real64 AzimSun; // Sun azimuth (radians)
10705 : Real64 ProfileAngHor; // Solar profile angle (radians) for horizontally oriented projections
10706 : // such as the top and bottom of a frame or horizontal dividers.
10707 : // This is the incidence angle in a plane that is normal to the window
10708 : // and parallel to the Y-axis of the window (the axis along
10709 : // which the height of the window is measured).
10710 : Real64 ProfileAngVert; // Solar profile angle (radians) for vertically oriented projections
10711 : // such as the top and bottom of a frame or horizontal dividers.
10712 : // This is the incidence angle in a plane that is normal to the window
10713 : // and parallel to the X-axis of the window (the axis along
10714 : // which the width of the window is measured).
10715 : Real64 TanProfileAngHor; // Tangent of ProfileAngHor
10716 : Real64 TanProfileAngVert; // Tangent of ProfileAngVert
10717 : Real64 FrWidth; // Frame width (m)
10718 : Real64 DivWidth; // Divider width (m)
10719 : Real64 FrProjOut; // Outside frame projection (m)
10720 : Real64 DivProjOut; // Outside divider projection (m)
10721 : Real64 FrProjIn; // Inside frame projection (m)
10722 : Real64 DivProjIn; // Inside divider projection (m)
10723 : int NHorDiv; // Number of horizontal dividers
10724 : int NVertDiv; // Number of vertical dividers
10725 : Real64 GlArea; // Glazed area (m2)
10726 : Real64 Arealite; // Area of a single lite of glass (m2); glazed area, GlArea,
10727 : // if there is no divider (in which case there is only one lite).
10728 : Real64 ArealiteCol; // Area of a vertical column of lites (m2)
10729 : Real64 ArealiteRow; // Area of a horizontal row of lites (m2)
10730 : Real64 AshVDout; // Shaded area from all vertical divider outside projections (m2)
10731 : Real64 AshVDin; // Shaded area from all vertical divider inside projections (m2)
10732 : Real64 AshHDout; // Shaded area from all horizontal divider outside projections (m2)
10733 : Real64 AshHDin; // Shaded area from all horizontal divider inside projections (m2)
10734 : Real64 AshVFout; // Shaded area from outside projection of vertical sides of frame (m2)
10735 : Real64 AshVFin; // Shaded area from inside projection of vertical sides of frame (m2)
10736 : Real64 AshHFout; // Shaded area from outside projection of horizontal sides
10737 : // (top) of frame (m2)
10738 : Real64 AshHFin; // Shaded area from inside projection of horizontal sides
10739 : // (top) of frame (m2)
10740 : Real64 AshDDover; // Divider/divider shadow overlap area (m2)
10741 : Real64 AshFFover; // Frame/frame shadow overlap area (m2)
10742 : Real64 AshFVDover; // Frame/vertical divider overlap area (m2)
10743 : Real64 AshFHDover; // Frame/horizontal divider overlap area (m2)
10744 : Real64 AshFDtotOut; // Total outside projection shadow area (m2)
10745 : Real64 AshFDtotIn; // Total inside projection shadow area (m2)
10746 : Real64 FracShFDOut; // Fraction of glazing shadowed by frame and divider
10747 : // outside projections
10748 : Real64 FracShFDin; // Fraction of glazing that illuminates frame and divider
10749 : // inside projections with beam radiation
10750 :
10751 99923 : Vector3<Real64> WinNorm(3); // Window outward normal unit vector
10752 : Real64 ThWin; // Azimuth angle of WinNorm
10753 99923 : Vector3<Real64> SunPrime(3); // Projection of sun vector onto plane (perpendicular to
10754 : // window plane) determined by WinNorm and vector along
10755 : // baseline of window
10756 99923 : Vector3<Real64> WinNormCrossBase(3); // Cross product of WinNorm and vector along window baseline
10757 :
10758 213404 : if (state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut == 0.0 && state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn == 0.0 &&
10759 144529 : state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut == 0.0 && state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn == 0.0)
10760 37827 : return;
10761 :
10762 31048 : FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut;
10763 31048 : FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
10764 31048 : DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
10765 31048 : DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
10766 :
10767 31048 : GlArea = state.dataSurface->Surface(SurfNum).Area;
10768 31048 : ElevWin = DataGlobalConstants::PiOvr2 - state.dataSurface->Surface(SurfNum).Tilt * DataGlobalConstants::DegToRadians;
10769 31048 : ElevSun = DataGlobalConstants::PiOvr2 - std::acos(state.dataSolarShading->SUNCOS(3));
10770 31048 : AzimWin = state.dataSurface->Surface(SurfNum).Azimuth * DataGlobalConstants::DegToRadians;
10771 31048 : AzimSun = std::atan2(state.dataSolarShading->SUNCOS(1), state.dataSolarShading->SUNCOS(2));
10772 :
10773 31048 : ProfileAngHor = std::atan(std::sin(ElevSun) / std::abs(std::cos(ElevSun) * std::cos(AzimWin - AzimSun))) - ElevWin;
10774 31048 : if (std::abs(ElevWin) < 0.1) { // Near-vertical window
10775 11473 : ProfileAngVert = std::abs(AzimWin - AzimSun);
10776 : } else {
10777 19575 : WinNorm = state.dataSurface->Surface(SurfNum).OutNormVec;
10778 19575 : ThWin = AzimWin - DataGlobalConstants::PiOvr2;
10779 19575 : WinNormCrossBase(1) = -std::sin(ElevWin) * std::cos(ThWin);
10780 19575 : WinNormCrossBase(2) = std::sin(ElevWin) * std::sin(ThWin);
10781 19575 : WinNormCrossBase(3) = std::cos(ElevWin);
10782 19575 : SunPrime = state.dataSolarShading->SUNCOS - WinNormCrossBase * dot(state.dataSolarShading->SUNCOS, WinNormCrossBase);
10783 19575 : ProfileAngVert = std::abs(std::acos(dot(WinNorm, SunPrime) / magnitude(SunPrime)));
10784 : }
10785 : // Constrain to 0 to pi
10786 31048 : if (ProfileAngVert > DataGlobalConstants::Pi) ProfileAngVert = 2 * DataGlobalConstants::Pi - ProfileAngVert;
10787 31048 : TanProfileAngHor = std::abs(std::tan(ProfileAngHor));
10788 31048 : TanProfileAngVert = std::abs(std::tan(ProfileAngVert));
10789 :
10790 31048 : NHorDiv = state.dataSurface->FrameDivider(FrDivNum).HorDividers;
10791 31048 : NVertDiv = state.dataSurface->FrameDivider(FrDivNum).VertDividers;
10792 31048 : FrWidth = state.dataSurface->FrameDivider(FrDivNum).FrameWidth;
10793 31048 : DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
10794 :
10795 62096 : Arealite = (state.dataSurface->Surface(SurfNum).Height / (NHorDiv + 1.0) - DivWidth / 2.0) *
10796 31048 : (state.dataSurface->Surface(SurfNum).Width / (NVertDiv + 1.0) - DivWidth / 2.0);
10797 31048 : if (DivProjOut > 0.0 || DivProjIn > 0.0) {
10798 10547 : ArealiteCol = (NHorDiv + 1) * Arealite;
10799 10547 : ArealiteRow = (NVertDiv + 1) * Arealite;
10800 : } else {
10801 20501 : ArealiteCol = GlArea;
10802 20501 : ArealiteRow = GlArea;
10803 : }
10804 31048 : AshVDout = 0.0;
10805 31048 : AshVDin = 0.0;
10806 31048 : AshHDout = 0.0;
10807 31048 : AshHDin = 0.0;
10808 31048 : AshVFout = 0.0;
10809 31048 : AshVFin = 0.0;
10810 31048 : AshHFout = 0.0;
10811 31048 : AshHFin = 0.0;
10812 31048 : AshDDover = 0.0;
10813 31048 : AshFFover = 0.0;
10814 31048 : AshFVDover = 0.0;
10815 31048 : AshFHDover = 0.0;
10816 :
10817 31048 : if (DivProjOut > 0.0 || DivProjIn > 0.0) {
10818 :
10819 : // Shaded area from all vertical dividers
10820 10547 : AshVDout = NVertDiv * min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * DivProjOut * TanProfileAngVert, ArealiteCol);
10821 10547 : AshVDin = NVertDiv * min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * DivProjIn * TanProfileAngVert, ArealiteCol);
10822 :
10823 : // Shaded area from all horizontal dividers
10824 10547 : AshHDout = NHorDiv * min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * DivProjOut * TanProfileAngHor, ArealiteRow);
10825 10547 : AshHDin = NHorDiv * min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * DivProjIn * TanProfileAngHor, ArealiteRow);
10826 :
10827 : // Horizontal divider/vertical divider shadow overlap
10828 10547 : AshDDover = min(DivProjOut * TanProfileAngHor * DivProjOut * TanProfileAngVert, Arealite) * NHorDiv * NVertDiv;
10829 : }
10830 :
10831 31048 : if (FrProjOut > 0.0 || FrProjIn > 0.0) {
10832 :
10833 : // Shaded area from sides of frame; to avoid complications from possible overlaps between
10834 : // shadow from side of frame and shadow from vertical divider the shaded area from side of
10835 : // frame is restricted to the area of one column of lites.
10836 31048 : AshVFout = min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * FrProjOut * TanProfileAngVert, ArealiteCol);
10837 31048 : AshVFin = min((state.dataSurface->Surface(SurfNum).Height - NHorDiv * DivWidth) * FrProjIn * TanProfileAngVert, ArealiteCol);
10838 :
10839 : // Shaded area from top or bottom of frame; to avoid complications from possible overlaps
10840 : // between shadow from top or bottom of frame and shadow from horizontal divider, the shaded
10841 : // area from the top or bottom of frame is restricted to the area of one row of lites.
10842 31048 : AshHFout = min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * FrProjOut * TanProfileAngHor, ArealiteRow);
10843 31048 : AshHFin = min((state.dataSurface->Surface(SurfNum).Width - NVertDiv * DivWidth) * FrProjIn * TanProfileAngHor, ArealiteRow);
10844 :
10845 : // Top/bottom of frame/side of frame shadow overlap
10846 31048 : AshFFover = min(FrProjOut * TanProfileAngHor * FrProjOut * TanProfileAngVert, Arealite);
10847 31048 : if (DivProjOut > 0.0) {
10848 : // Frame/vertical divider shadow overlap
10849 10547 : AshFVDover = min(FrProjOut * DivProjOut * TanProfileAngHor * TanProfileAngVert, Arealite) * NVertDiv;
10850 : // Frame/horizontal divider shadow overlap
10851 10547 : AshFHDover = min(FrProjOut * DivProjOut * TanProfileAngHor * TanProfileAngVert, Arealite) * NHorDiv;
10852 : }
10853 : }
10854 :
10855 31048 : AshFDtotOut = AshVDout + AshHDout + AshVFout + AshHFout - (AshDDover + AshFFover + AshFVDover + AshFHDover);
10856 62096 : AshFDtotIn = (AshVDin + AshHDin) * state.dataSurface->FrameDivider(FrDivNum).DividerSolAbsorp +
10857 31048 : (AshVFin + AshHFin) * state.dataSurface->FrameDivider(FrDivNum).FrameSolAbsorp;
10858 :
10859 : // Divide by the glazed area of the window
10860 31048 : FracShFDOut = AshFDtotOut / GlArea;
10861 31048 : FracShFDin = AshFDtotIn / GlArea;
10862 31048 : state.dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult(HourNum) = 1.0 - FracShFDOut;
10863 31048 : state.dataSurface->SurfaceWindow(SurfNum).InOutProjSLFracMult(HourNum) = 1.0 - (FracShFDin + FracShFDOut);
10864 : }
10865 :
10866 0 : void CalcBeamSolarOnWinRevealSurface(EnergyPlusData &state)
10867 : {
10868 :
10869 : // SUBROUTINE INFORMATION:
10870 : // AUTHOR F. Winkelmann
10871 : // DATE WRITTEN April 2002
10872 : // MODIFIED:na
10873 : // RE-ENGINEERED:na
10874 :
10875 : // PURPOSE OF THIS SUBROUTINE
10876 : // Called by InitHeatGains when the sun is up.
10877 : // Calculates beam solar radiation absorbed and reflected by top, bottom,
10878 : // right and left sides of outside and inside window reveal surfaces.
10879 : // In doing this calculation, the shadowing on a reveal surface by other reveal surfaces
10880 : // is determined using the orientation of the reveal surfaces and the sun position.
10881 : // It is assumed that:
10882 : // (1) The window is an exterior window and is rectangular.
10883 : // (2) The reveal surfaces are perpendicular to the window plane.
10884 : // (3) If an exterior shade or blind is in place, there is no beam solar on
10885 : // on exterior or interior reveal surfaces.
10886 : // (3) If an interior shade or blind is in place, there is no beam solar on
10887 : // interior reveal surfaces.
10888 : // (4) The effect of window divider, if present, is ignored, including shadowing
10889 : // of divider on inside reveal surfaces.
10890 :
10891 : // In the variable names, the "subscript" 1 = outside reveal, 2 = inside reveal
10892 : // The outside reveal surfaces (top, bottom, left, right) are assumed to have the same depth
10893 : // (given by Surface%Reveal and determined from vertices of window and vertices of parent
10894 : // wall) and the same solar absorptance. The inside reveal surfaces are divided into
10895 : // two categories: (1) the bottom reveal surface, called here the "inside sill;" and
10896 : // the other reveal surfaces (left, right and top). The left, right and top inside reveal
10897 : // surfaces are assumed to have the same depth and solar absorptance.
10898 : // The depth of the outside reveal is measured from the outside surface of the glazing;
10899 : // The depth of the inside sill and the other reveal surfaces is measured from the inside
10900 : // surface of the glazing. The inside sill is
10901 : // allowed to have depth and solar absorptance values that are different from the corresponding
10902 : // values for the other inside reveal surfaces. The inside sill depth is required to be
10903 : // greater than or equal to the depth of the other inside reveal surfaces. If the inside sill
10904 : // depth is greater than zero the depth of the other inside reveal surfaces is required to
10905 : // to be greater than zero.
10906 : // The reflection of beam solar radiation from all reveal surfaces is assumed to be isotropic
10907 : // diffuse; there is no specular component. Half of the beam solar reflected from outside
10908 : // reveal surfaces is assumed to go towards the window; the other half is assumed to go back
10909 : // to the exterior environment (i.e., reflection of this outward-going component from
10910 : // other outside reveal surfaces is not considered). The half that goes towards the window
10911 : // is added to the other radiation incident on the window.
10912 : // Correspondingly, half of the beam solar reflected from inside reveal surfaces is assumed
10913 : // to go towards the window, with the other half going into the zone (this half, and the portion
10914 : // going towards the window that is reflected) is added in CalcInteriorSolarDistribution
10915 : // to the variable BTOTzone, which is the total beam solar entering the zone as beam or diffuse.
10916 : // The portion going towards the window that is not reflected is absorbed in the glazing or
10917 : // transmitted back out into the exterior environment.
10918 : // The beam solar that is absorbed by outside reveal surfaces is added to the solar absorbed
10919 : // by the outside surface of the window's parent wall; similarly, the beam solar absorbed
10920 : // by the inside reveal surfaces is added to the solar absorbed by the inside surface of the
10921 : // parent wall (and is subtracted from BTOTzone).
10922 : // The net effect of beam solar reflected from outside reveal surfaces is to INCREASE the
10923 : // the heat gain to the zone, whereas the effect of beam solar reflected from interior reveal
10924 : // surfaces is to DECREASE the heat gain to the zone since part of this reflected solar is
10925 : // transmitted back out the window.
10926 : // If the window has a frame, the absorption of reflected beam solar by the inside and outside
10927 : // surfaces of the frame is considered. The shadowing of the frame onto interior reveal
10928 : // surfaces is also considered.
10929 :
10930 : // The total glazing thickness is taken to be the sum of the thickness of the glass layers
10931 : // and between-glass gas layers. If the window has an exterior, movable, storm window glass layer
10932 : // the presence of this layer and its adjacent air gap is considered in calculating the glazing
10933 : // properties (solar transmittance, etc.). But the storm window glass is assumed to be close
10934 : // enough to the rest of the glazing that its effect on total glazing thickness and outside
10935 : // reveal depth can be ignored.
10936 :
10937 : // METHODOLOGY EMPLOYED
10938 : // na
10939 :
10940 : // REFERENCES
10941 : // na
10942 :
10943 : // USE STATEMENTS
10944 : // Using/Aliasing
10945 : using General::InterpSw;
10946 : using General::POLYF;
10947 :
10948 : // Locals
10949 : // SUBROUTINE ARGUMENT DEFINITIONS:na
10950 :
10951 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS
10952 :
10953 : int ConstrNum; // Construction number
10954 : int ConstrNumSh; // Shaded construction number
10955 : Real64 CosBetaBottom; // Cosine of beam solar angle of incidence on bottom reveal
10956 : Real64 CosBetaLeft; // Cosine of beam solar angle of incidence on left reveal
10957 : Real64 CosBeta; // ABS of CosBetaBottom or CosBetaLeft
10958 : Real64 d1; // Depth of outside reveal + half of glazing thickness (m)
10959 : Real64 d2; // Depth of inside sill or of inside reveal plus half of glazing thickness (m)
10960 : Real64 d2prime; // Depth of shadow cast on a reveal surface by opposite reveal (m)
10961 : Real64 d2prime2; // Depth of shadow cast by frame onto inside reveal (m)
10962 : Real64 d12; // d12 = d1 + d2 - d2prime (m)
10963 : Real64 TanAlpha; // Tangent of horizontal or vertical profile angle
10964 : Real64 TanGamma; // Tangent of vertical or horizontal profile angle
10965 : Real64 H; // Window height, width (m)
10966 : Real64 W;
10967 : Real64 L; // Window height or width (m)
10968 : Real64 A1sh; // Shadowed area of outside horizontal or vertical reveal (m2)
10969 : Real64 A2sh; // Shadowed area of inside horizontal or vertical reveal (m2)
10970 : Real64 A1ill; // Illuminated area of outside horizontal or vertical reveal (m2)
10971 : Real64 A2ill; // Illuminated area of inside horizontal or vertical reveal (m2)
10972 : Real64 SolTransGlass; // Beam solar transmittance of glazing
10973 : Real64 SolTransGlassSh; // For switchable glazing, beam solar trans in switched state
10974 : Real64 DiffReflGlass; // Diffuse back reflectance of glazing
10975 : Real64 DiffReflGlassSh; // For switchable glazing, diffuse back refl in switched state
10976 : int HorVertReveal; // Index: 1 = horizontal reveal, 2 = vertical reveal
10977 : Real64 OutsReveal; // Depth of outside reveal (from outside glazing plane to outside wall plane) (m)
10978 : Real64 InsReveal; // Depth of inside reveal (from inside glazing plane to inside wall plane (m)
10979 : Real64 InsSillDepth; // Depth of inside sill, measured from innermost face of glazing (m)
10980 : Real64 GlazingThickness; // Thickness of glazing, measured from innermost face to outermost face (m)
10981 : Real64 InsideRevealSolAbs; // Solar absorptance of inside reveal or inside sill
10982 : Real64 BmSolRefldOutsReveal; // Multiplied by beam solar gives beam solar reflected by horiz or vertical
10983 : // outside reveal surface (m2)
10984 : Real64 BmSolRefldInsReveal; // Multiplied by beam solar gives beam solar reflected by horiz or vertical
10985 : // inside reveal surface (m2)
10986 : WinShadingType ShadeFlag; // Shading flag
10987 : int FrameDivNum; // Frame/Divider number
10988 : Real64 FrameWidth; // Frame width (m)
10989 : Real64 P1; // Frame outside/inside projection plus half of glazing thickness (m)
10990 : Real64 P2;
10991 : Real64 f1; // f1=d1-P1, f2=d2-P2 (m)
10992 : Real64 f2;
10993 : Real64 L1; // Average distance of outside/inside illuminated area to frame;
10994 : Real64 L2;
10995 : // used in calculating view factor to frame (m)
10996 : Real64 FracToGlassOuts; // View factor from outside horizontal or vertical reveal to glass
10997 : Real64 FracToGlassIns; // View factor from inside horizontal or vertical reveal to glass
10998 : Real64 TanProfileAngVert; // Tangent of vertical profile angle (the profile angle appropriate for
10999 : // vertical reveal surfaces.
11000 : Real64 TanProfileAngHor; // Tangent of horizontal profile angle (the profile angle appropriate for
11001 : // horizontal reveal surfaces.
11002 :
11003 : Real64 tmp_SunlitFracWithoutReveal; // Temporary variable
11004 :
11005 0 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
11006 0 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
11007 0 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
11008 0 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
11009 0 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
11010 0 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
11011 : // Added TH for initialization. CR 7596 inside reveal causing high cooling loads
11012 : // for outside reveals
11013 0 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
11014 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
11015 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
11016 0 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
11017 0 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
11018 : // for inside reveals
11019 0 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
11020 0 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
11021 0 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
11022 0 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
11023 0 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
11024 0 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
11025 0 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
11026 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
11027 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
11028 0 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
11029 0 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
11030 :
11031 0 : if ((state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment &&
11032 0 : state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt))
11033 0 : continue;
11034 0 : if (state.dataSurface->Surface(SurfNum).Reveal == 0.0 && state.dataSurface->SurfWinInsideReveal(SurfNum) == 0.0 &&
11035 0 : state.dataSurface->SurfWinInsideSillDepth(SurfNum) == 0.0)
11036 0 : continue;
11037 0 : if (state.dataSurface->Surface(SurfNum).Sides != 4) continue;
11038 0 : if (state.dataSurface->SurfWinInsideSillDepth(SurfNum) < state.dataSurface->SurfWinInsideReveal(SurfNum)) continue;
11039 :
11040 0 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
11041 0 : if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::ExtShade) | BITF(WinShadingType::ExtBlind))) continue;
11042 :
11043 0 : if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue;
11044 :
11045 0 : tmp_SunlitFracWithoutReveal =
11046 0 : state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
11047 :
11048 : // Calculate cosine of angle of incidence of beam solar on reveal surfaces,
11049 : // assumed to be perpendicular to window plane
11050 :
11051 0 : CosBetaBottom =
11052 0 : -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).SinAzim * state.dataSurface->Surface(SurfNum).CosTilt -
11053 0 : state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).CosAzim * state.dataSurface->Surface(SurfNum).CosTilt +
11054 0 : state.dataEnvrn->SOLCOS(3) * state.dataSurface->Surface(SurfNum).SinTilt;
11055 :
11056 0 : CosBetaLeft = -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).CosAzim -
11057 0 : state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).SinAzim;
11058 :
11059 : // Note: CosBetaTop = -CosBetaBottom, CosBetaRight = -CosBetaLeft
11060 :
11061 0 : OutsReveal = state.dataSurface->Surface(SurfNum).Reveal;
11062 0 : InsReveal = state.dataSurface->SurfWinInsideReveal(SurfNum);
11063 0 : InsideRevealSolAbs = 0.0;
11064 0 : GlazingThickness = state.dataSurface->SurfWinTotGlazingThickness(SurfNum);
11065 0 : H = state.dataSurface->Surface(SurfNum).Height;
11066 0 : W = state.dataSurface->Surface(SurfNum).Width;
11067 0 : d1 = OutsReveal + 0.5 * GlazingThickness;
11068 0 : ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
11069 0 : ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
11070 :
11071 0 : SolTransGlass = POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum),
11072 0 : state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
11073 0 : TanProfileAngVert = state.dataSurface->SurfWinTanProfileAngVert(SurfNum);
11074 0 : TanProfileAngHor = state.dataSurface->SurfWinTanProfileAngHor(SurfNum);
11075 0 : FrameDivNum = state.dataSurface->Surface(SurfNum).FrameDivider;
11076 0 : FrameWidth = 0.0;
11077 0 : if (FrameDivNum != 0) {
11078 0 : FrameWidth = state.dataSurface->FrameDivider(FrameDivNum).FrameWidth;
11079 0 : if (FrameWidth > 0.0) {
11080 0 : P1 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionOut + 0.5 * GlazingThickness;
11081 0 : P2 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionIn + 0.5 * GlazingThickness;
11082 0 : if (OutsReveal + 0.5 * GlazingThickness <= P1) d1 = P1 + 0.001;
11083 : }
11084 : }
11085 : // Loop over vertical and horizontal reveal surfaces
11086 0 : for (HorVertReveal = 1; HorVertReveal <= 2; ++HorVertReveal) {
11087 :
11088 0 : FracToGlassOuts = 0.5;
11089 0 : FracToGlassIns = 0.5;
11090 0 : BmSolRefldOutsReveal = 0.0;
11091 0 : BmSolRefldInsReveal = 0.0;
11092 0 : A1ill = 0.0;
11093 0 : A2ill = 0.0;
11094 :
11095 : // Added TH. 5/27/2009
11096 0 : A1sh = 0.0;
11097 0 : A2sh = 0.0;
11098 :
11099 0 : if (HorVertReveal == 1) { // Vertical reveal
11100 0 : TanAlpha = TanProfileAngHor;
11101 0 : TanGamma = TanProfileAngVert;
11102 0 : CosBeta = std::abs(CosBetaLeft);
11103 0 : L = state.dataSurface->Surface(SurfNum).Height;
11104 0 : d2 = InsReveal + 0.5 * GlazingThickness;
11105 0 : d2prime = d1 + d2 - W / TanGamma;
11106 0 : InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum);
11107 : } else { // Horizontal reveal
11108 0 : InsSillDepth = state.dataSurface->SurfWinInsideSillDepth(SurfNum);
11109 0 : TanAlpha = TanProfileAngVert;
11110 0 : TanGamma = TanProfileAngHor;
11111 0 : CosBeta = std::abs(CosBetaBottom);
11112 0 : L = state.dataSurface->Surface(SurfNum).Width;
11113 0 : if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated
11114 0 : d2 = InsSillDepth + 0.5 * GlazingThickness;
11115 0 : InsideRevealSolAbs = state.dataSurface->SurfWinInsideSillSolAbs(SurfNum);
11116 : } else { // Top reveal surfaces may be illuminated
11117 0 : d2 = InsReveal + 0.5 * GlazingThickness;
11118 0 : InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum);
11119 : }
11120 0 : d2prime = d1 + d2 - H / TanGamma;
11121 : }
11122 0 : if (d2prime < 0.0) d2prime = 0.0; // No shadow from opposing reveal
11123 0 : d12 = d1 + d2 - d2prime;
11124 :
11125 0 : if (FrameWidth <= 0.001) {
11126 : // Window without frame
11127 :
11128 : // Find inside and outside shadowed area of vertical or horizontal reveal surfaces
11129 : // that can be illuminated by beam solar; shadowing is by other reveal surfaces.
11130 :
11131 0 : if (d2prime <= d2) {
11132 0 : if (d12 * TanAlpha <= L) {
11133 0 : A1sh = 0.5 * TanAlpha * pow_2(d1);
11134 0 : A2sh = d2prime * L + 0.5 * TanAlpha * pow_2(d12) - A1sh;
11135 : } else { // d12*TanAlpha > L
11136 0 : if (d1 * TanAlpha <= L) {
11137 0 : A1sh = 0.5 * TanAlpha * pow_2(d1);
11138 0 : A2sh = d2 * L - 0.5 * TanAlpha * pow_2(L / TanAlpha - d1);
11139 : } else { // d1*TanAlpha > L
11140 0 : A1sh = d1 * L - (0.5 / TanAlpha) * pow_2(L);
11141 0 : A2sh = d2 * L;
11142 : }
11143 : }
11144 : } else { // d2prime > d2
11145 0 : A2sh = d2 * L;
11146 0 : if (d2prime < d1 + d2) {
11147 0 : if (d12 * TanAlpha <= L) {
11148 0 : A1sh = L * (d2prime - d2) + 0.5 * TanAlpha * pow_2(d12);
11149 : } else { // d12*TanAlpha > L
11150 0 : A1sh = d1 * L - 0.5 * pow_2(L) / TanAlpha;
11151 : }
11152 : } else { // d2prime >= d1+d2
11153 0 : A1sh = d1 * L;
11154 : }
11155 : }
11156 :
11157 : // Added TH. 5/27/2009
11158 0 : if (A1sh < 0.0) A1sh = 0.0;
11159 0 : if (A2sh < 0.0) A2sh = 0.0;
11160 :
11161 0 : if (OutsReveal >= 0.001) A1ill = d1 * L - A1sh; // A1ill = 0.0 if OutsReveal < 0.001
11162 0 : if (InsReveal >= 0.001) A2ill = d2 * L - A2sh; // A2ill = 0.0 if InsReveal < 0.001
11163 :
11164 : } else { // Window with frame; take into account shadowing
11165 : // of inside reveal surfaces by frame
11166 0 : f1 = d1 - P1;
11167 0 : f2 = d2 - P2;
11168 0 : d2prime2 = FrameWidth / TanGamma;
11169 0 : if (HorVertReveal == 1) { // Vertical reveal
11170 0 : if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001;
11171 : } else { // Horizontal
11172 0 : if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated
11173 0 : if (InsSillDepth + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001;
11174 : } else { // Top reveal surfaces may be illuminated
11175 0 : if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001;
11176 : }
11177 : }
11178 :
11179 0 : if (d2prime <= f2) { // Shadow from opposing reveal does not go beyond inside surface of frame
11180 :
11181 0 : if (d12 * TanAlpha <= L) {
11182 0 : A1sh = 0.5 * TanAlpha * pow_2(f1);
11183 0 : L1 = f1 * (f1 * TanAlpha / (6.0 * L) + 0.5);
11184 0 : if (d2 - (d2prime + d2prime2 + P2) >= 0.0) {
11185 0 : A2sh = (d2prime + d2prime2) * L + 0.5 * TanAlpha * (pow_2(d1 + d2 - d2prime) - pow_2(d1 + P2 + d2prime2));
11186 0 : L2 = d2prime2 + 0.5 * (d2 - (d2prime + d2prime2 + P2));
11187 : } else { // d2-(d2prime+d2prime2+P2) < 0. ! Inside reveal is fully shadowed by
11188 : // frame and/or opposing reveal
11189 0 : A2sh = f2 * L;
11190 0 : L2 = f2;
11191 : }
11192 : } else { // d12*TanAlpha >= L
11193 0 : if ((d1 + P2) * TanAlpha <= L) {
11194 0 : A1sh = 0.5 * TanAlpha * pow_2(f1);
11195 0 : L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5);
11196 0 : if ((d1 + P2 + d2prime2) * TanAlpha >= L) {
11197 0 : A2sh = f2 * L;
11198 0 : L2 = f2;
11199 : } else { // (d1+P2+d2prime2)*TanAlpha < L
11200 0 : A2sh = f2 * L - 0.5 * pow_2(L - (d1 + P2) * TanAlpha) / TanAlpha +
11201 0 : d2prime2 * (L - (d1 + P2 + d2prime2 / 2.0) * TanAlpha);
11202 0 : L2 = d2prime2 + (L / TanAlpha - (d1 + P2 + d2prime2)) / 3.0;
11203 : }
11204 : } else { // (d1+P2)*TanAlpha > L
11205 0 : L2 = f2;
11206 0 : A2sh = f2 * L;
11207 0 : if (f1 * TanAlpha <= L) {
11208 0 : A1sh = 0.5 * TanAlpha * pow_2(f1);
11209 0 : L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5);
11210 : } else { // f1*TanAlpha > L
11211 0 : A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha;
11212 0 : L1 = f1 - (L / TanAlpha) / 3.0;
11213 : }
11214 : }
11215 : }
11216 :
11217 : } else { // d2prime > f2 ! Shadow from opposing reveal goes beyond inside of frame
11218 :
11219 0 : A2sh = f2 * L;
11220 0 : L2 = f2;
11221 0 : if (d2prime >= d1 + d2) {
11222 0 : A1sh = 0.0;
11223 0 : L1 = f1;
11224 : } else { // d2prime < d1+d2
11225 0 : if (d2prime <= d2 + P1) {
11226 0 : if (f1 * TanAlpha <= L) {
11227 0 : A1sh = 0.5 * TanAlpha * pow_2(f1);
11228 0 : L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5);
11229 : } else { // f1*TanAlpha > L
11230 0 : A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha;
11231 0 : L1 = f1 - (L / TanAlpha) / 3.0;
11232 : }
11233 : } else { // d2prime > d2+P1
11234 0 : if (d12 * TanAlpha <= L) {
11235 0 : A1sh = L * (d2prime - (d2 + P1)) + 0.5 * TanAlpha * pow_2(d12);
11236 0 : L1 = (L * (f1 - d12 / 2.0) - d12 * TanAlpha * (f1 / 2 - d12 / 3.0)) / (L - d12 * TanAlpha / 2.0);
11237 : } else { // d12*TanAlpha > L
11238 0 : A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha;
11239 0 : L1 = f1 - (L / TanAlpha) / 3.0;
11240 : }
11241 : }
11242 : }
11243 : }
11244 :
11245 : // Added TH. 5/27/2009
11246 0 : if (A1sh < 0.0) A1sh = 0.0;
11247 0 : if (A2sh < 0.0) A2sh = 0.0;
11248 :
11249 0 : if (OutsReveal >= P1 + 0.5 * GlazingThickness + 0.001) A1ill = L * f1 - A1sh;
11250 0 : if (InsReveal >= P2 + 0.5 * GlazingThickness + 0.001) A2ill = L * f2 - A2sh;
11251 0 : if (L1 == 0.0) {
11252 0 : FracToGlassOuts = 0.0;
11253 : } else {
11254 0 : FracToGlassOuts = 0.5 * (1.0 - std::atan(FrameWidth / L1) / DataGlobalConstants::PiOvr2);
11255 : }
11256 0 : if (L2 == 0.0) {
11257 0 : FracToGlassIns = 0.0;
11258 : } else {
11259 0 : FracToGlassIns = 0.5 * (1.0 - std::atan(FrameWidth / L2) / DataGlobalConstants::PiOvr2);
11260 : }
11261 : } // End of check if window has frame
11262 :
11263 : // Added TH. 5/27/2009
11264 0 : if (A1ill < 0.0) A1ill = 0.0;
11265 0 : if (A2ill < 0.0) A2ill = 0.0;
11266 :
11267 : // Quantities related to outside reveal
11268 0 : if (A1ill > 1.0e-6) {
11269 :
11270 0 : state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) +=
11271 0 : A1ill * state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum) * CosBeta * tmp_SunlitFracWithoutReveal;
11272 :
11273 0 : BmSolRefldOutsReveal =
11274 0 : A1ill * (1.0 - state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum)) * CosBeta * tmp_SunlitFracWithoutReveal;
11275 :
11276 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) += state.dataEnvrn->BeamSolarRad * BmSolRefldOutsReveal;
11277 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) =
11278 0 : state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
11279 :
11280 : // Reflected solar from outside horizontal and vertical reveal incident on glazing
11281 0 : state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) +=
11282 0 : FracToGlassOuts * BmSolRefldOutsReveal / state.dataSurface->Surface(SurfNum).Area;
11283 :
11284 0 : if (FrameWidth > 0.0) {
11285 : // Reflected solar from outside horizontal and vertical reveal incident on frame
11286 0 : state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) +=
11287 0 : (0.5 - FracToGlassOuts) * BmSolRefldOutsReveal / state.dataSurface->SurfWinFrameArea(SurfNum);
11288 : }
11289 :
11290 : } // End of check if A1ill > 0.0 (actually 10^-6)
11291 :
11292 : // Quantities related to inside reveal; inside reveal reflection/absorption is assumed
11293 : // to occur only if an interior shade or blind is not in place.
11294 :
11295 0 : if (NOT_SHADED(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) {
11296 :
11297 0 : if (A2ill > 1.0e-6) {
11298 :
11299 0 : DiffReflGlass = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
11300 0 : if (ShadeFlag == WinShadingType::SwitchableGlazing) {
11301 0 : SolTransGlassSh =
11302 0 : POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum),
11303 0 : state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef);
11304 0 : SolTransGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), SolTransGlass, SolTransGlassSh);
11305 0 : DiffReflGlassSh = state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack;
11306 0 : DiffReflGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), DiffReflGlass, DiffReflGlassSh);
11307 : }
11308 :
11309 : // Calc beam solar sbsorbed (m2)
11310 0 : state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) +=
11311 0 : A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal;
11312 :
11313 : // Added TH 5/26/2009 for reporting purpose - Beam solar absorbed by the inside reveal
11314 : // (W)
11315 0 : state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) +=
11316 0 : state.dataEnvrn->BeamSolarRad * A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal;
11317 :
11318 : // in m2 = Area * solar transmitted fraction * inside reveal reflection fraction
11319 0 : BmSolRefldInsReveal = A2ill * SolTransGlass * (1.0 - InsideRevealSolAbs) * CosBeta * tmp_SunlitFracWithoutReveal;
11320 :
11321 0 : state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) += BmSolRefldInsReveal;
11322 :
11323 0 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) +=
11324 0 : state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal; // W, BeamSolarRad in W/m2
11325 0 : state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) =
11326 0 : state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
11327 :
11328 : // Reflected solar from inside horizontal and vertical reveal incident on glazing
11329 0 : state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) +=
11330 0 : FracToGlassIns * BmSolRefldInsReveal / state.dataSurface->Surface(SurfNum).Area;
11331 :
11332 : // Added TH 5/26/2009 for reporting purpose - diffuse on window glass from inside
11333 : // reveal (W)
11334 0 : state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) +=
11335 0 : state.dataEnvrn->BeamSolarRad * FracToGlassIns * BmSolRefldInsReveal;
11336 :
11337 : // Reflected solar from inside horizontal and vertical reveal incident on frame
11338 0 : if (FrameWidth > 0.0) {
11339 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) +=
11340 0 : (0.5 - FracToGlassIns) * BmSolRefldInsReveal / state.dataSurface->SurfWinFrameArea(SurfNum);
11341 :
11342 : // Added TH 5/26/2009 for reporting purpose - diffuse on window frame from inside
11343 : // reveal (W)
11344 0 : state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) +=
11345 0 : state.dataEnvrn->BeamSolarRad * (0.5 - FracToGlassIns) * BmSolRefldInsReveal;
11346 : }
11347 :
11348 : // Reflected solar from inside reveal going directly into zone and reflected from
11349 : // glass. Assumes half of solar reflected from inside reveal goes as diffuse radiation
11350 : // into the zone and half goes as diffuse radiation towards window.
11351 0 : state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) += BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns);
11352 :
11353 : // Added TH 5/26/2009 for reporting purpose - diffuse into zone from inside reveal (W)
11354 0 : state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) +=
11355 0 : state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns);
11356 :
11357 : } // End of check if A2ill > 0.0 (actually 10^-6)
11358 :
11359 : } // End of check if interior shade or blind is in place
11360 :
11361 : } // End of loop over vertical and horizontal reveal
11362 :
11363 : } // End of surface loop
11364 : }
11365 : }
11366 0 : }
11367 :
11368 2568313 : void ReportSurfaceShading(EnergyPlusData &state)
11369 : {
11370 :
11371 : // SUBROUTINE INFORMATION:
11372 : // AUTHOR Linda Lawrie
11373 : // DATE WRITTEN April 2000
11374 : // MODIFIED na
11375 : // RE-ENGINEERED na
11376 :
11377 : // PURPOSE OF THIS SUBROUTINE:
11378 : // This subroutine uses the internal variables used in the Shading
11379 : // calculations and prepares them for reporting (at timestep level).
11380 :
11381 : // METHODOLOGY EMPLOYED:
11382 : // Because all of the calculations are done on a "daily" basis in this
11383 : // module, it is difficult to formulate the values that might be useful
11384 : // for reporting. SunlitFrac was the first of these two arrays to be
11385 : // made into "two dimensions". It is not clear that both have to be
11386 : // two dimensions.
11387 :
11388 : // REFERENCES:
11389 : // na
11390 :
11391 : // Using/Aliasing
11392 : using namespace OutputReportPredefined;
11393 :
11394 : // Locals
11395 : // SUBROUTINE ARGUMENT DEFINITIONS:
11396 : // na
11397 :
11398 : // SUBROUTINE PARAMETER DEFINITIONS:
11399 : // na
11400 :
11401 : // INTERFACE BLOCK SPECIFICATIONS
11402 : // na
11403 :
11404 : // DERIVED TYPE DEFINITIONS
11405 : // na
11406 :
11407 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11408 : int SurfNum; // Loop Counter
11409 : int RepCol; // the column of the predefined report
11410 :
11411 166705567 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
11412 164137254 : state.dataSurface->SurfSunlitFrac(SurfNum) =
11413 164137254 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
11414 164137254 : state.dataSurface->SurfSunlitArea(SurfNum) =
11415 328274508 : state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
11416 164137254 : state.dataSurface->Surface(SurfNum).Area;
11417 : }
11418 : // added for predefined reporting
11419 2568313 : RepCol = 0;
11420 2568313 : if (state.dataEnvrn->Month == 3 && state.dataEnvrn->DayOfMonth == 21) {
11421 1881 : if ((state.dataGlobal->HourOfDay == 9) && (state.dataGlobal->TimeStep == 4)) {
11422 16 : RepCol = state.dataOutRptPredefined->pdchSlfMar21_9;
11423 1865 : } else if ((state.dataGlobal->HourOfDay == 12) && (state.dataGlobal->TimeStep == 4)) {
11424 16 : RepCol = state.dataOutRptPredefined->pdchSlfMar21_12;
11425 1849 : } else if ((state.dataGlobal->HourOfDay == 15) && (state.dataGlobal->TimeStep == 4)) {
11426 16 : RepCol = state.dataOutRptPredefined->pdchSlfMar21_15;
11427 : }
11428 2566432 : } else if (state.dataEnvrn->Month == 6 && state.dataEnvrn->DayOfMonth == 21) {
11429 1881 : if ((state.dataGlobal->HourOfDay == 9) && (state.dataGlobal->TimeStep == 4)) {
11430 16 : RepCol = state.dataOutRptPredefined->pdchSlfJun21_9;
11431 1865 : } else if ((state.dataGlobal->HourOfDay == 12) && (state.dataGlobal->TimeStep == 4)) {
11432 16 : RepCol = state.dataOutRptPredefined->pdchSlfJun21_12;
11433 1849 : } else if ((state.dataGlobal->HourOfDay == 15) && (state.dataGlobal->TimeStep == 4)) {
11434 16 : RepCol = state.dataOutRptPredefined->pdchSlfJun21_15;
11435 : }
11436 2564551 : } else if (state.dataEnvrn->Month == 12 && state.dataEnvrn->DayOfMonth == 21) {
11437 172863 : if ((state.dataGlobal->HourOfDay == 9) && (state.dataGlobal->TimeStep == 4)) {
11438 1335 : RepCol = state.dataOutRptPredefined->pdchSlfDec21_9;
11439 171528 : } else if ((state.dataGlobal->HourOfDay == 12) && (state.dataGlobal->TimeStep == 4)) {
11440 1335 : RepCol = state.dataOutRptPredefined->pdchSlfDec21_12;
11441 170193 : } else if ((state.dataGlobal->HourOfDay == 15) && (state.dataGlobal->TimeStep == 4)) {
11442 1335 : RepCol = state.dataOutRptPredefined->pdchSlfDec21_15;
11443 : }
11444 : }
11445 2568313 : if (RepCol != 0) {
11446 423456 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
11447 419355 : if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) {
11448 62388 : PreDefTableEntry(state, RepCol, state.dataSurface->Surface(SurfNum).Name, state.dataSurface->SurfSunlitFrac(SurfNum));
11449 : }
11450 : }
11451 : }
11452 2568313 : }
11453 :
11454 771 : void ReportSurfaceErrors(EnergyPlusData &state)
11455 : {
11456 :
11457 : // SUBROUTINE INFORMATION:
11458 : // AUTHOR Linda Lawrie
11459 : // DATE WRITTEN November 2004
11460 : // MODIFIED na
11461 : // RE-ENGINEERED na
11462 :
11463 : // PURPOSE OF THIS SUBROUTINE:
11464 : // This subroutine reports some recurring type errors that can get mixed up with more important
11465 : // errors in the error file.
11466 :
11467 : using namespace DataErrorTracking; // for error tracking
11468 :
11469 771 : static Array1D_string const MSG(4, {"misses", "", "within", "overlaps"});
11470 :
11471 : int Loop1;
11472 : int Loop2;
11473 : int Count;
11474 : int TotCount;
11475 1542 : Array1D_bool SurfErrorReported;
11476 1542 : Array1D_bool SurfErrorReported2;
11477 :
11478 771 : if (state.dataSolarShading->NumTooManyFigures + state.dataSolarShading->NumTooManyVertices + state.dataSolarShading->NumBaseSubSurround > 0) {
11479 0 : ShowMessage(state, "");
11480 0 : ShowMessage(state, "===== Recurring Surface Error Summary =====");
11481 0 : ShowMessage(state, "The following surface error messages occurred.");
11482 0 : ShowMessage(state, "");
11483 :
11484 0 : if (state.dataSolarShading->NumBaseSubSurround > 0) {
11485 0 : ShowMessage(state, "Base Surface does not surround subsurface errors occurring...");
11486 0 : ShowMessage(state,
11487 : "Check that the GlobalGeometryRules object is expressing the proper starting corner and "
11488 : "direction [CounterClockwise/Clockwise]");
11489 0 : ShowMessage(state, "");
11490 : }
11491 :
11492 0 : SurfErrorReported.dimension(state.dataSurface->TotSurfaces, false);
11493 0 : TotCount = 0;
11494 0 : for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumBaseSubSurround; ++Loop1) {
11495 0 : Count = 0;
11496 0 : if (SurfErrorReported(state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1)) continue;
11497 0 : for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumBaseSubSurround; ++Loop2) {
11498 0 : if (state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1 ==
11499 0 : state.dataSolarShading->TrackBaseSubSurround(Loop2).SurfIndex1 &&
11500 0 : state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex == state.dataSolarShading->TrackBaseSubSurround(Loop2).MiscIndex) {
11501 0 : ++Count;
11502 : }
11503 : }
11504 0 : TotCount += Count;
11505 0 : state.dataErrTracking->TotalWarningErrors += Count - 1;
11506 0 : ShowWarningError(state,
11507 0 : "Base surface does not surround subsurface (CHKSBS), Overlap Status=" +
11508 0 : state.dataSolarShading->cOverLapStatus(state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex));
11509 0 : ShowContinueError(state, format(" The base surround errors occurred {} times.", Count));
11510 0 : for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumBaseSubSurround; ++Loop2) {
11511 0 : if (state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1 ==
11512 0 : state.dataSolarShading->TrackBaseSubSurround(Loop2).SurfIndex1 &&
11513 0 : state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex == state.dataSolarShading->TrackBaseSubSurround(Loop2).MiscIndex) {
11514 0 : ShowContinueError(state,
11515 0 : "Surface \"" + state.dataSurface->Surface(state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1).Name +
11516 0 : "\" " + MSG(state.dataSolarShading->TrackBaseSubSurround(Loop1).MiscIndex) + " SubSurface \"" +
11517 0 : state.dataSurface->Surface(state.dataSolarShading->TrackBaseSubSurround(Loop2).SurfIndex2).Name + "\"");
11518 : }
11519 : }
11520 0 : SurfErrorReported(state.dataSolarShading->TrackBaseSubSurround(Loop1).SurfIndex1) = true;
11521 : }
11522 0 : if (TotCount > 0) {
11523 0 : ShowMessage(state, "");
11524 0 : ShowContinueError(state, format(" The base surround errors occurred {} times (total).", TotCount));
11525 0 : ShowMessage(state, "");
11526 : }
11527 :
11528 0 : SurfErrorReported2.allocate(state.dataSurface->TotSurfaces);
11529 0 : SurfErrorReported = false;
11530 0 : TotCount = 0;
11531 0 : if (state.dataSolarShading->NumTooManyVertices > 0) {
11532 0 : ShowMessage(state, format("Too many vertices [>={}] in shadow overlap errors occurring...", state.dataSolarShading->MaxHCV));
11533 0 : ShowMessage(state,
11534 : "These occur throughout the year and may occur several times for the same surfaces. You "
11535 : "may be able to reduce them by "
11536 : "adding Output:Diagnostics,DoNotMirrorDetachedShading;");
11537 : }
11538 0 : for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumTooManyVertices; ++Loop1) {
11539 0 : Count = 0;
11540 0 : SurfErrorReported2 = false;
11541 0 : if (SurfErrorReported(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1)) continue;
11542 0 : for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyVertices; ++Loop2) {
11543 0 : if (state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1 ==
11544 0 : state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex1) {
11545 0 : ++Count;
11546 : }
11547 : }
11548 0 : TotCount += Count;
11549 0 : state.dataErrTracking->TotalWarningErrors += Count - 1;
11550 0 : ShowMessage(state, "");
11551 0 : ShowWarningError(state, format("Too many vertices [>={}] in a shadow overlap", state.dataSolarShading->MaxHCV));
11552 0 : ShowContinueError(
11553 : state,
11554 0 : "Overlapping figure=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1).Name +
11555 0 : ", Surface Class=[" +
11556 0 : cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1).Class) + ']');
11557 0 : ShowContinueError(state, format(" This error occurred {} times.", Count));
11558 0 : for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyVertices; ++Loop2) {
11559 0 : if (state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1 ==
11560 0 : state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex1) {
11561 0 : if (SurfErrorReported2(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2)) continue;
11562 0 : ShowContinueError(
11563 : state,
11564 0 : "Figure being Overlapped=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2).Name +
11565 0 : ", Surface Class=[" +
11566 0 : cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2).Class) + ']');
11567 0 : SurfErrorReported2(state.dataSolarShading->TrackTooManyVertices(Loop2).SurfIndex2) = true;
11568 : }
11569 : }
11570 0 : SurfErrorReported(state.dataSolarShading->TrackTooManyVertices(Loop1).SurfIndex1) = true;
11571 : }
11572 0 : if (TotCount > 0) {
11573 0 : ShowMessage(state, "");
11574 0 : ShowContinueError(state, format(" The too many vertices errors occurred {} times (total).", TotCount));
11575 0 : ShowMessage(state, "");
11576 : }
11577 :
11578 0 : SurfErrorReported = false;
11579 0 : TotCount = 0;
11580 0 : if (state.dataSolarShading->NumTooManyFigures > 0) {
11581 0 : ShowMessage(state, format("Too many figures [>={}] in shadow overlap errors occurring...", state.dataSolarShading->MaxHCS));
11582 0 : ShowMessage(state,
11583 : "These occur throughout the year and may occur several times for the same surfaces. You "
11584 : "may be able to reduce them by "
11585 : "adding OutputDiagnostics,DoNotMirrorDetachedShading;");
11586 : }
11587 0 : for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumTooManyFigures; ++Loop1) {
11588 0 : Count = 0;
11589 0 : SurfErrorReported2 = false;
11590 0 : if (SurfErrorReported(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1)) continue;
11591 0 : for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyFigures; ++Loop2) {
11592 0 : if (state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1 == state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex1) {
11593 0 : ++Count;
11594 : }
11595 : }
11596 0 : TotCount += Count;
11597 0 : state.dataErrTracking->TotalWarningErrors += Count - 1;
11598 0 : ShowMessage(state, "");
11599 0 : ShowWarningError(state, format("Too many figures [>={}] in a shadow overlap", state.dataSolarShading->MaxHCS));
11600 0 : ShowContinueError(state,
11601 0 : "Overlapping figure=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1).Name +
11602 0 : ", Surface Class=[" +
11603 0 : cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1).Class) +
11604 : ']');
11605 0 : ShowContinueError(state, format(" This error occurred {} times.", Count));
11606 0 : for (Loop2 = 1; Loop2 <= state.dataSolarShading->NumTooManyFigures; ++Loop2) {
11607 0 : if (state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1 == state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex1) {
11608 0 : if (SurfErrorReported2(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2)) continue;
11609 0 : ShowContinueError(
11610 : state,
11611 0 : "Figure being Overlapped=" + state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2).Name +
11612 0 : ", Surface Class=[" +
11613 0 : cSurfaceClass(state.dataSurface->Surface(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2).Class) + ']');
11614 0 : SurfErrorReported2(state.dataSolarShading->TrackTooManyFigures(Loop2).SurfIndex2) = true;
11615 : }
11616 : }
11617 0 : SurfErrorReported(state.dataSolarShading->TrackTooManyFigures(Loop1).SurfIndex1) = true;
11618 : }
11619 0 : if (TotCount > 0) {
11620 0 : ShowMessage(state, "");
11621 0 : ShowContinueError(state, format(" The too many figures errors occurred {} times (total).", TotCount));
11622 0 : ShowMessage(state, "");
11623 : }
11624 0 : SurfErrorReported.deallocate();
11625 0 : SurfErrorReported2.deallocate();
11626 : }
11627 771 : }
11628 :
11629 771 : void ComputeWinShadeAbsorpFactors(EnergyPlusData &state)
11630 : {
11631 :
11632 : // SUBROUTINE INFORMATION:
11633 : // AUTHOR Fred Winkelmann
11634 : // DATE WRITTEN Mar 2001
11635 : // MODIFIED Oct 2002,FCW: change ConstrNumSh =
11636 : // WindowShadingControl(WinShadeCtrlNum)%ShadedConstruction
11637 : // to Surface(SurfNum)%ShadedConstruction
11638 : // RE-ENGINEERED na
11639 :
11640 : // PURPOSE OF THIS SUBROUTINE:
11641 : // Called by InitSolarCalculations. Finds fractions that apportion radiation absorbed by a
11642 : // window shade to the two faces of the shade. For radiation incident from the left,
11643 : // ShadeAbsFacFace(1) is the fraction of radiation absorbed in the left-hand half of the
11644 : // of the shade and ShadeAbsFacFace(2) is the fraction absorbed in the right-hand half.
11645 : // The shade is assumed to be homogeneous.
11646 :
11647 : // REFERENCES: See EnergyPlus engineering documentation
11648 : // USE STATEMENTS: na
11649 :
11650 5585 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
11651 9632 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
11652 4818 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
11653 4818 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
11654 4818 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
11655 10792 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
11656 5974 : if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window && state.dataSurface->Surface(SurfNum).HasShadeControl) {
11657 143 : int WinShadeCtrlNum = state.dataSurface->Surface(SurfNum).activeWindowShadingControl; // Window shading control number
11658 :
11659 143 : int MatNumSh = 0; // Shade layer material number
11660 143 : Real64 AbsorpEff = 0.0; // Effective absorptance of isolated shade layer (fraction of
11661 : // of incident radiation remaining after reflected portion is
11662 : // removed that is absorbed
11663 143 : if (ANY_SHADE(state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType)) {
11664 71 : int const ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction; // Window construction number with shade
11665 71 : int TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers; // Total layers in a construction
11666 :
11667 71 : if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::IntShade) {
11668 49 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay); // Interior shade
11669 22 : } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::ExtShade) {
11670 18 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1); // Exterior shade
11671 4 : } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::BGShade) {
11672 4 : if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) {
11673 : // Double pane with between-glass shade
11674 2 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3);
11675 : } else {
11676 : // Triple pane with between-glass shade
11677 2 : MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5);
11678 : }
11679 : }
11680 142 : AbsorpEff = state.dataMaterial->Material(MatNumSh).AbsorpSolar /
11681 71 : (state.dataMaterial->Material(MatNumSh).AbsorpSolar + state.dataMaterial->Material(MatNumSh).Trans + 0.0001);
11682 71 : AbsorpEff = min(max(AbsorpEff, 0.0001),
11683 : 0.999); // Constrain to avoid problems with following log eval
11684 71 : state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum) = (1.0 - std::exp(0.5 * std::log(1.0 - AbsorpEff))) / AbsorpEff;
11685 71 : state.dataSurface->SurfWinShadeAbsFacFace2(SurfNum) = 1.0 - state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum);
11686 : }
11687 : }
11688 : }
11689 : }
11690 : }
11691 771 : }
11692 :
11693 821277 : void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state)
11694 : {
11695 :
11696 : // SUBROUTINE INFORMATION:
11697 : // AUTHOR Rob Hitchcock
11698 : // DATE WRITTEN July 2007
11699 : // MODIFIED N/A
11700 : // RE-ENGINEERED N/A
11701 :
11702 : // PURPOSE OF THIS SUBROUTINE:
11703 : // This subroutine calculates the initial distribution
11704 : // of diffuse solar transmitted through exterior windows
11705 : // to individual heat transfer surfaces in each zone(or enclosure).
11706 :
11707 : // METHODOLOGY EMPLOYED:
11708 : // Apportions diffuse solar transmitted through each exterior window
11709 : // that is then absorbed, reflected, and/or transmitted
11710 : // by other heat transfer surfaces in the zone.
11711 : // Calculations use:
11712 : // 1. WinDifSolar calculated in SUBROUTINE CalcInteriorSolarDistribution,
11713 : // 2. view factors between each exterior window and
11714 : // other heat transfer surfaces in a zone
11715 : // calculated in SUBROUTINE CalcApproximateViewFactors, and
11716 : // 3. surface absorptances, reflectances, and transmittances
11717 : // determined here using revised code from SUBROUTINE InitIntSolarDistribution
11718 :
11719 : // Using/Aliasing
11720 : using General::InterpSw;
11721 : using ScheduleManager::GetCurrentScheduleValue;
11722 : using namespace DataViewFactorInformation;
11723 : using namespace DataWindowEquivalentLayer;
11724 :
11725 : Real64 AbsInt; // Tmp var for Inside surface short-wave absorptance
11726 : Real64 InsideDifAbsorptance; // Inside diffuse solar absorptance of a surface
11727 : Real64 InsideDifReflectance; // Inside diffuse solar reflectance of a surface
11728 : int BlNum; // Blind number
11729 : Real64 BlAbsDiffBk; // Glass layer back diffuse solar absorptance when blind in place
11730 : Real64 AbsDiffBkBl; // Blind diffuse back solar absorptance as part of glazing system
11731 :
11732 : // REAL(r64) :: DividerSolAbs ! Window divider solar absorptance
11733 : // REAL(r64) :: DividerSolRefl ! Window divider solar reflectance
11734 : // INTEGER :: MatNumGl ! Glass layer material number
11735 : // INTEGER :: MatNumSh ! Shade layer material number
11736 : // REAL(r64) :: TransGl,ReflGl,AbsGl ! Glass layer solar transmittance, reflectance, absorptance
11737 :
11738 : Real64 ViewFactor; // temp var for view factor
11739 : // Real64 ViewFactorTotal; // debug var for view factor total
11740 : Real64 WinDifSolarTrans; // debug var for WinDifSolar() [W]
11741 : // Real64 WinDifSolarDistTotl; // debug var for window total
11742 : // distributed diffuse solar [W] Real64 WinDifSolarDistAbsorbedTotl; // debug
11743 : // var for individual exterior window total distributed
11744 : // diffuse solar absorbed [W]
11745 : // Real64 WinDifSolarDistReflectedTotl; // debug var for individual exterior window total distributed
11746 : // diffuse solar reflected [W]
11747 : // Real64 WinDifSolarDistTransmittedTotl; // debug var for individual exterior window total distributed
11748 : // diffuse solar transmitted [W]
11749 : Real64 WinDifSolLayAbsW; // temp var for diffuse solar absorbed by individual glass layer [W]
11750 : // Real64 ZoneDifSolarTrans; // debug var for WinDifSolar() [W]
11751 : // Real64 ZoneDifSolarDistTotl; // debug var for zone total
11752 : // distributed diffuse solar [W] Real64 ZoneDifSolarDistAbsorbedTotl; //
11753 : // debug var for zone total distributed diffuse solar absorbed [W] Real64
11754 : // ZoneDifSolarDistReflectedTotl; // debug var for zone total distributed
11755 : // diffuse solar reflected [W] Real64 ZoneDifSolarDistTransmittedTotl; //
11756 : // debug var for zone total distributed diffuse solar transmitted [W]
11757 :
11758 : Real64 DifSolarAbsW; // temp var for diffuse solar absorbed by surface [W]
11759 : Real64 DifSolarAbs; // temp var for diffuse solar absorbed by surface [W/m2]
11760 : Real64 DifSolarReflW; // temp var for diffuse solar reflected by surface [W]
11761 : Real64 DifSolarTransW; // temp var for diffuse solar transmitted through interior window surface [W]
11762 : Real64 ShBlDifSolarAbsW; // temp var for diffuse solar absorbed by shade/blind [W]
11763 :
11764 1642554 : Array2D<Real64> SurfWinAbsSolBeamEQL(2, CFSMAXNL + 1); // absorbed exterior beam radiation by layers fraction
11765 : Array2D<Real64> SurfWinAbsSolDiffEQL(2,
11766 1642554 : CFSMAXNL + 1); // absorbed exterior diffuse radiation by layers fraction
11767 1642554 : Array2D<Real64> SurfWinAbsSolBeamBackEQL(2, CFSMAXNL + 1); // absorbed interior beam radiation by layers fraction from back
11768 1642554 : Array2D<Real64> AbsSolDiffBackEQL(2, CFSMAXNL + 1); // absorbed exterior diffuse radiation by layers fraction from back
11769 : int EQLNum; // equivalent layer fenestration index
11770 : int Lay; // equivalent layer fenestration layer index
11771 :
11772 : // Init accumulators for absorbed diffuse solar for all surfaces for later heat balance calcs
11773 821277 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs = 0.0;
11774 821277 : state.dataHeatBal->SurfWinInitialDifSolwinAbs = 0.0;
11775 :
11776 : // Init accumulator for total reflected diffuse solar within each zone for interreflection calcs
11777 821277 : state.dataHeatBal->EnclSolInitialDifSolReflW = 0.0;
11778 :
11779 : // Init accumulator for transmitted diffuse solar for all surfaces for reporting
11780 821277 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans = 0.0;
11781 :
11782 : // Loop over all zones doing initial distribution of diffuse solar to interior heat transfer surfaces
11783 6664958 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfRadiantEnclosures; ++enclosureNum) {
11784 5843681 : auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(enclosureNum));
11785 : // Init Zone accumulators for debugging
11786 : // ZoneDifSolarTrans = 0.0;
11787 : // ZoneDifSolarDistAbsorbedTotl = 0.0;
11788 : // ZoneDifSolarDistReflectedTotl = 0.0;
11789 : // ZoneDifSolarDistTransmittedTotl = 0.0;
11790 : // Loop over all diffuse solar transmitting surfaces (i.e., exterior windows and TDDs) in the current zone
11791 56358052 : for (int const DifTransSurfNum : thisEnclosure.SurfacePtr) {
11792 : // Skip surfaces that are not exterior, except for TDD_Diffusers
11793 131969342 : if (((state.dataSurface->Surface(DifTransSurfNum).ExtBoundCond != ExternalEnvironment) &&
11794 81419494 : (state.dataSurface->Surface(DifTransSurfNum).ExtBoundCond != OtherSideCondModeledExt)) &&
11795 30905123 : state.dataSurface->SurfWinOriginalClass(DifTransSurfNum) != SurfaceClass::TDD_Diffuser)
11796 30905123 : continue;
11797 :
11798 : // Do I need to do anything special for TDDs?
11799 : // if ( SurfaceWindow( DifTransSurfNum ).OriginalClass == SurfaceClass::TDD_Diffuser )
11800 : // {
11801 : // }
11802 :
11803 : // Skip surfaces that are not exterior windows or TDD diffusers
11804 32102073 : if (state.dataSurface->Surface(DifTransSurfNum).Class != SurfaceClass::Window &&
11805 12492825 : state.dataSurface->SurfWinOriginalClass(DifTransSurfNum) != SurfaceClass::TDD_Diffuser)
11806 12492825 : continue;
11807 :
11808 : //----------------------------------------------------------------------------------------------------------
11809 : // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH EXTERIOR WINDOWS AND TDDS TO INTERIOR HEAT TRANSFER
11810 : // SURFACES
11811 : //----------------------------------------------------------------------------------------------------------
11812 :
11813 : // Init transmitted solar debug vars
11814 : // ViewFactorTotal = 0.0;
11815 7116423 : WinDifSolarTrans = state.dataSurface->SurfWinDifSolar(DifTransSurfNum);
11816 : // ZoneDifSolarTrans += WinDifSolarTrans;
11817 :
11818 : // Init Exterior Window accumulators for debugging
11819 : // WinDifSolarDistAbsorbedTotl = 0.0;
11820 : // WinDifSolarDistReflectedTotl = 0.0;
11821 : // WinDifSolarDistTransmittedTotl = 0.0;
11822 :
11823 : // Loop over all heat transfer surfaces in the current zone that might receive diffuse solar
11824 102738319 : for (int const HeatTransSurfNum : thisEnclosure.SurfacePtr) {
11825 : // Skip surfaces that are not heat transfer surfaces
11826 : // Skip tubular daylighting device domes
11827 95621896 : if (state.dataSurface->Surface(HeatTransSurfNum).Class == SurfaceClass::TDD_Dome) continue;
11828 :
11829 : // View factor from current (sending) window DifTransSurfNum to current (receiving) surface
11830 : // HeatTransSurfNum
11831 : int const HTenclosureSurfNum =
11832 95621896 : state.dataSurface->Surface(HeatTransSurfNum).SolarEnclSurfIndex; // HT surface index for EnclSolInfo.SurfacePtr and F arrays
11833 95621896 : int const enclosureNum = state.dataSurface->Surface(HeatTransSurfNum).SolarEnclIndex; // index for EnclSolInfo
11834 : int const DTenclSurfNum =
11835 95621896 : state.dataSurface->Surface(DifTransSurfNum).SolarEnclSurfIndex; // Window surface index for EnclSolInfo.SurfacePtr and F arrays
11836 :
11837 95621896 : ViewFactor = state.dataViewFactor->EnclSolInfo(enclosureNum).F(HTenclosureSurfNum, DTenclSurfNum);
11838 : // debug ViewFactorTotal
11839 : // ViewFactorTotal += ViewFactor; // debug
11840 :
11841 : // Skip receiving surfaces with 0.0 view factor
11842 95621896 : if (ViewFactor <= 0.0) continue;
11843 :
11844 54777008 : Real64 const WinDifSolarTrans_Factor(WinDifSolarTrans * ViewFactor);
11845 54777008 : Real64 const win_SwitchingFactor(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum));
11846 54777008 : Real64 const per_HTSurfaceArea(1.0 / state.dataSurface->Surface(HeatTransSurfNum).Area);
11847 :
11848 : // Calculate diffuse solar from current exterior window absorbed and reflected by current heat
11849 : // transfer surface And calculate transmitted diffuse solar to adjacent zones through interior
11850 : // windows
11851 54777008 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(HeatTransSurfNum);
11852 54777008 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Interior Opaque Surface
11853 :
11854 : // Determine the inside (back) diffuse solar absorptance
11855 : // and reflectance of the current heat transfer surface
11856 47748963 : InsideDifAbsorptance = state.dataHeatBalSurf->SurfAbsSolarInt(HeatTransSurfNum);
11857 : // Inside (back) diffuse solar reflectance is assumed to be 1 - absorptance
11858 47748963 : InsideDifReflectance = 1.0 - InsideDifAbsorptance;
11859 :
11860 : // Absorbed diffuse solar [W] = current window transmitted diffuse solar [W]
11861 : // * view factor from current (sending) window DifTransSurfNum to current (receiving)
11862 : // surface HeatTransSurfNum
11863 : // * current surface inside solar absorptance
11864 47748963 : DifSolarAbsW = WinDifSolarTrans_Factor * InsideDifAbsorptance; // [W]
11865 :
11866 : // Absorbed diffuse solar [W/m2] = Absorbed diffuse solar [W]
11867 : // / current surface net area
11868 47748963 : DifSolarAbs = DifSolarAbsW * per_HTSurfaceArea;
11869 :
11870 : // Accumulate absorbed diffuse solar [W/m2] on this surface for heat balance calcs
11871 47748963 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(HeatTransSurfNum) += DifSolarAbs;
11872 :
11873 : // Reflected diffuse solar [W] = current window transmitted diffuse solar
11874 : // * view factor from current (sending) window DifTransSurfNum to current (receiving)
11875 : // surface HeatTransSurfNum
11876 : // * current window inside solar reflectance
11877 47748963 : DifSolarReflW = WinDifSolarTrans_Factor * InsideDifReflectance;
11878 :
11879 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
11880 : // interreflection calcs
11881 47748963 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
11882 :
11883 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of
11884 : // energy For opaque surfaces all incident diffuse is either absorbed or reflected
11885 :
11886 : } else { // Exterior or Interior Window
11887 7028045 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(HeatTransSurfNum);
11888 7028045 : int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
11889 7028045 : WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(HeatTransSurfNum);
11890 :
11891 7028045 : if (state.dataSurface->SurfWinWindowModelType(HeatTransSurfNum) != WindowModel::EQL) {
11892 7024765 : if (NOT_SHADED(ShadeFlag)) { // No window shading
11893 : // Init accumulator for transmittance calc below
11894 6938132 : DifSolarAbsW = 0.0;
11895 :
11896 : // Calc diffuse solar absorbed by all window glass layers
11897 : // Note: I am assuming here that individual glass layer absorptances have been
11898 : // corrected
11899 : // to account for layer by layer transmittance and reflection effects.
11900 16041662 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
11901 : // Calc diffuse solar absorbed from the inside by each window glass layer [W]
11902 9103530 : AbsInt = state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
11903 9103530 : WinDifSolLayAbsW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
11904 :
11905 : // Accumulate distributed diffuse solar absorbed [W] by overall window for
11906 : // transmittance calc below
11907 9103530 : DifSolarAbsW += WinDifSolLayAbsW;
11908 :
11909 : // Accumulate diffuse solar absorbed from the inside by each window glass layer
11910 : // [W/m2] for heat balance calcs
11911 9103530 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea;
11912 : }
11913 :
11914 : // Calc diffuse solar reflected back to zone
11915 : // I don't really care if this is a window or opaque surface since I am just
11916 : // accumulating all reflected diffuse solar in a zone bucket for "interreflected"
11917 : // distribution Reflected diffuse solar [W] = current window transmitted diffuse solar
11918 : // * view factor from current (sending) window DifTransSurfNum to current
11919 : // (receiving) surface HeatTransSurfNum
11920 : // * current window inside solar reflectance
11921 6938132 : InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
11922 6938132 : DifSolarReflW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
11923 :
11924 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
11925 : // interreflection calcs
11926 6938132 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
11927 :
11928 : //------------------------------------------------------------------------------
11929 : // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO ADJACENT ZONE
11930 : //------------------------------------------------------------------------------
11931 :
11932 : // If this receiving window surface (HeatTransSurfNum) is an interior window,
11933 : // calc distributed solar transmitted to adjacent zone [W]
11934 : // NOTE: This calc is here because interior windows are currently assumed to have no
11935 : // shading
11936 :
11937 : // Get the adjacent surface number for this receiving window surface
11938 6938132 : int AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond;
11939 : // If the adjacent surface number is > 0, this is an interior window
11940 6938132 : if (AdjSurfNum > 0) { // this is an interior window surface
11941 :
11942 : // Calc diffuse solar from current exterior window
11943 : // transmitted through this interior window to adjacent zone [W]
11944 : // Transmitted diffuse solar [W] = current exterior window transmitted diffuse
11945 : // solar
11946 : // * view factor from current (sending) window DifTransSurfNum to current
11947 : // (receiving) surface HeatTransSurfNum
11948 : // - diffuse absorbed by this interior window
11949 : // - diffuse reflected by this interior window
11950 7495 : DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
11951 : // HERE 8/15/07 Note Construct(AdjConstrNum)%TransDiff could be used here since
11952 : // the "front" transmittance for an interior window in the adjacent zone is the
11953 : // correct direction as long as I use the Construct() of the Surface in the
11954 : // adjacent zone. However, the above calculation better conserves energy, although
11955 : // possibly at the expense of less accurate transmittance calcs. Preliminary tests
11956 : // showed fairly good agreement between the two DifSolarTransW calculation
11957 : // methods, but for consistency I stuck with the above. int AdjConstrNum =
11958 : // Surface(AdjSurfNum).Construction;
11959 : // DifSolarTransW = WinDifSolar(DifTransSurfNum) &
11960 : // * ViewFactor &
11961 : // * Construct(AdjConstrNum)%TransDiff
11962 :
11963 : // Get the adjacent zone index
11964 7495 : int const adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
11965 :
11966 : // Call routine to distribute diffuse solar transmitted through this interior
11967 : // window into adjacent zone
11968 7495 : CalcInteriorWinTransDifSolInitialDistribution(state, adjEnclosureNum, AdjSurfNum, DifSolarTransW);
11969 :
11970 : } else { // this is an exterior window surface
11971 :
11972 : // Calc transmitted Window and Zone total distributed diffuse solar to check for
11973 : // conservation of energy This is not very effective since it assigns whatever
11974 : // distributed diffuse solar has not been absorbed or reflected to transmitted.
11975 6930637 : DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
11976 :
11977 : } // this is an interior window surface
11978 :
11979 : // Accumulate transmitted diffuse solar for reporting
11980 6938132 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
11981 :
11982 86633 : } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing
11983 : // Init accumulator for transmittance calc below
11984 2226 : DifSolarAbsW = 0.0;
11985 :
11986 2226 : auto const &construct(state.dataConstruction->Construct(ConstrNum));
11987 2226 : auto const &construct_AbsDiffBack(construct.AbsDiffBack);
11988 2226 : auto const &construct_sh(state.dataConstruction->Construct(ConstrNumSh));
11989 2226 : auto const &construct_sh_AbsDiffBack(construct_sh.AbsDiffBack);
11990 6678 : for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
11991 : // Calc diffuse solar absorbed in each window glass layer
11992 4452 : WinDifSolLayAbsW = WinDifSolarTrans_Factor *
11993 4452 : InterpSw(win_SwitchingFactor, construct_AbsDiffBack(IGlass), construct_sh_AbsDiffBack(IGlass));
11994 :
11995 : // Accumulate distributed diffuse solar absorbed [W] by overall window for
11996 : // transmittance calc below
11997 4452 : DifSolarAbsW += WinDifSolLayAbsW;
11998 :
11999 : // Accumulate diffuse solar absorbed from the inside by each window glass layer
12000 : // [W/m2] for heat balance calcs
12001 4452 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea;
12002 : }
12003 :
12004 : // Calc diffuse solar reflected back to zone
12005 2226 : DifSolarReflW = WinDifSolarTrans_Factor *
12006 2226 : InterpSw(win_SwitchingFactor, construct.ReflectSolDiffBack, construct_sh.ReflectSolDiffBack);
12007 :
12008 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
12009 : // interreflection calcs
12010 2226 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
12011 :
12012 : // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
12013 : // conservation of energy This is not very effective since it assigns whatever
12014 : // distributed diffuse solar has not been absorbed or reflected to transmitted.
12015 2226 : DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
12016 :
12017 : // Accumulate transmitted diffuse solar for reporting
12018 2226 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
12019 :
12020 84407 : } else if (ConstrNumSh != 0) {
12021 : // Interior, exterior or between-glass shade, screen or blind in place
12022 :
12023 : // Init accumulator for transmittance calc below
12024 70547 : DifSolarAbsW = 0.0;
12025 70547 : WinDifSolLayAbsW = 0.0;
12026 :
12027 : // First calc diffuse solar absorbed by each glass layer in this window with
12028 : // shade/blind in place
12029 70547 : auto const &construct_sh(state.dataConstruction->Construct(ConstrNumSh));
12030 70547 : auto const &construct_sh_AbsDiffBack(construct_sh.AbsDiffBack);
12031 70547 : auto const &construct_sh_BlAbsDiffBack(construct_sh.BlAbsDiffBack);
12032 :
12033 70547 : int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(HeatTransSurfNum);
12034 70547 : Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(HeatTransSurfNum);
12035 :
12036 182098 : for (int IGlass = 1; IGlass <= construct_sh.TotGlassLayers; ++IGlass) {
12037 111551 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
12038 : // Calc diffuse solar absorbed in each window glass layer and shade
12039 110424 : WinDifSolLayAbsW = WinDifSolarTrans_Factor * construct_sh_AbsDiffBack(IGlass);
12040 1127 : } else if (ANY_BLIND(ShadeFlag)) {
12041 1127 : if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
12042 0 : BlAbsDiffBk = General::InterpGeneral(
12043 0 : construct_sh_BlAbsDiffBack(SurfWinSlatsAngIndex, IGlass),
12044 0 : construct_sh_BlAbsDiffBack(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), IGlass),
12045 : SurfWinSlatsAngInterpFac);
12046 : } else {
12047 1127 : BlAbsDiffBk = construct_sh_BlAbsDiffBack(1, IGlass);
12048 : }
12049 : // Calc diffuse solar absorbed in each window glass layer and shade
12050 1127 : WinDifSolLayAbsW = WinDifSolarTrans_Factor * BlAbsDiffBk;
12051 : }
12052 :
12053 : // Accumulate distributed diffuse solar absorbed [W] by overall window for
12054 : // transmittance calc below
12055 111551 : DifSolarAbsW += WinDifSolLayAbsW;
12056 :
12057 : // Accumulate diffuse solar absorbed from the inside by each window glass layer
12058 : // [W/m2] for heat balance calcs
12059 111551 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea;
12060 : }
12061 :
12062 : // Next calc diffuse solar reflected back to zone from window with shade or blind on
12063 : // Diffuse back solar reflectance, bare glass or shade on
12064 70547 : InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
12065 70547 : if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::IntBlind) | BITF(WinShadingType::ExtBlind))) {
12066 : // Diffuse back solar reflectance, blind present, vs. slat angle
12067 1127 : if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
12068 0 : InsideDifReflectance = General::InterpGeneral(
12069 0 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(SurfWinSlatsAngIndex),
12070 0 : state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(
12071 0 : std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
12072 : SurfWinSlatsAngInterpFac);
12073 : } else {
12074 1127 : InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).BlReflectSolDiffBack(1);
12075 : }
12076 : }
12077 70547 : DifSolarReflW = WinDifSolarTrans_Factor * InsideDifReflectance;
12078 :
12079 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
12080 : // interreflection calcs
12081 70547 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
12082 :
12083 : // Now calc diffuse solar absorbed by shade/blind itself
12084 70547 : BlNum = state.dataSurface->SurfWinBlindNumber(HeatTransSurfNum);
12085 70547 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
12086 : // Calc diffuse solar absorbed by shade or screen [W]
12087 69420 : ShBlDifSolarAbsW = WinDifSolarTrans_Factor * construct_sh.AbsDiffBackShade;
12088 1127 : } else if (ANY_BLIND(ShadeFlag)) {
12089 : // Calc diffuse solar absorbed by blind [W]
12090 1127 : if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
12091 0 : AbsDiffBkBl =
12092 0 : General::InterpGeneral(construct_sh.AbsDiffBackBlind(SurfWinSlatsAngIndex),
12093 0 : construct_sh.AbsDiffBackBlind(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
12094 : SurfWinSlatsAngInterpFac);
12095 : } else {
12096 1127 : AbsDiffBkBl = construct_sh.AbsDiffBackBlind(1);
12097 : }
12098 1127 : ShBlDifSolarAbsW = WinDifSolarTrans_Factor * AbsDiffBkBl;
12099 : }
12100 : // Correct for divider shadowing
12101 70547 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
12102 29838 : ShBlDifSolarAbsW *= state.dataSurface->SurfWinGlazedFrac(HeatTransSurfNum);
12103 : }
12104 :
12105 : // Accumulate diffuse solar absorbed by shade or screen [W/m2] for heat balance calcs
12106 70547 : state.dataSurface->SurfWinInitialDifSolAbsByShade(HeatTransSurfNum) += ShBlDifSolarAbsW * per_HTSurfaceArea;
12107 :
12108 : // Accumulate distributed diffuse solar absorbed [W] by overall window for
12109 : // transmittance calc below
12110 70547 : DifSolarAbsW += ShBlDifSolarAbsW;
12111 :
12112 : // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
12113 : // conservation of energy This is not very effective since it assigns whatever
12114 : // distributed diffuse solar has not been absorbed or reflected to transmitted.
12115 70547 : DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW;
12116 :
12117 : // Accumulate transmitted diffuse solar for reporting
12118 70547 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
12119 : } // End of shading flag check
12120 :
12121 : } else {
12122 : // SurfaceWindow(HeatTransSurfNum)%WindowModelType == WindowModel:: EQL
12123 : // ConstrNum=Surface(HeatTransSurfNum)%Construction
12124 : // call the ASHWAT fenestration model for diffuse radiation here
12125 3280 : WindowEquivalentLayer::CalcEQLOpticalProperty(state, HeatTransSurfNum, SolarArrays::DIFF, AbsSolDiffBackEQL);
12126 :
12127 3280 : EQLNum = state.dataConstruction->Construct(ConstrNum).EQLConsPtr;
12128 17262 : for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
12129 :
12130 : // Calc diffuse solar absorbed from the inside by each layer of EQL model [W]
12131 : // WinDifSolLayAbsW = WinDifSolar(DifTransSurfNum)* ViewFactor *
12132 : // Construct(ConstrNum)%AbsDiffBack(Lay)
12133 13982 : WinDifSolLayAbsW = WinDifSolarTrans_Factor * AbsSolDiffBackEQL(2, Lay);
12134 :
12135 : // Accumulate distributed diffuse solar absorbed [W] by overall window for
12136 : // transmittance calc below
12137 13982 : DifSolarAbsW += WinDifSolLayAbsW;
12138 :
12139 : // Accumulate diffuse solar absorbed from the inside by each window layer [W/m2] for
12140 : // heat balance calcs
12141 13982 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, Lay) += WinDifSolLayAbsW * per_HTSurfaceArea;
12142 :
12143 : // ASHWAT equivalent layer model may require not the individual layer absorption but
12144 : // the flux InitialDifSolwinEQL(HeatTransSurfNum) = WinDifSolar(DifTransSurfNum)*
12145 : // ViewFactor
12146 : }
12147 :
12148 : // Calc diffuse solar reflected back to zone
12149 : // I don't really care if this is a window or opaque surface since I am just
12150 : // accumulating all reflected diffuse solar in a zone bucket for "interreflected"
12151 : // distribution Reflected diffuse solar [W] = current window transmitted diffuse solar
12152 : // * view factor from current (sending) window DifTransSurfNum to current (receiving)
12153 : // surface HeatTransSurfNum
12154 : // * current window inside solar reflectance
12155 3280 : InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
12156 3280 : DifSolarReflW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
12157 :
12158 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
12159 : // interreflection calcs
12160 3280 : state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W]
12161 :
12162 : //------------------------------------------------------------------------------
12163 : // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO ADJACENT ZONE
12164 : //------------------------------------------------------------------------------
12165 :
12166 : // If this receiving window surface (HeatTransSurfNum) is an interior window,
12167 : // calc distributed solar transmitted to adjacent zone [W]
12168 : // NOTE: This calc is here because interior windows are currently assumed to have no
12169 : // shading
12170 :
12171 : // Get the adjacent surface number for this receiving window surface
12172 3280 : int const AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond;
12173 : // If the adjacent surface number is > 0, this is an interior window
12174 3280 : if (AdjSurfNum > 0) { // this is an interior window surface
12175 :
12176 : // Calc diffuse solar from current exterior window
12177 : // transmitted through this interior window to adjacent zone [W]
12178 : // Transmitted diffuse solar [W] = current exterior window transmitted diffuse solar
12179 : // * view factor from current (sending) window DifTransSurfNum to current
12180 : // (receiving) surface HeatTransSurfNum
12181 0 : DifSolarTransW = AbsSolDiffBackEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1) * ViewFactor;
12182 : // int AdjConstrNum = Surface(AdjSurfNum).Construction;
12183 : // Get the adjacent zone index
12184 0 : int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex;
12185 : // Call routine to distribute diffuse solar transmitted through this interior window
12186 : // into adjacent zone
12187 0 : CalcInteriorWinTransDifSolInitialDistribution(state, adjEnclosureNum, AdjSurfNum, DifSolarTransW);
12188 :
12189 : } else { // this is an exterior window surface
12190 :
12191 : // Calc transmitted Window and Zone total distributed diffuse solar to check for
12192 : // conservation of energy This is not very effective since it assigns whatever
12193 : // distributed diffuse solar has not been absorbed or reflected to transmitted.
12194 3280 : DifSolarTransW = AbsSolDiffBackEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1) * ViewFactor;
12195 :
12196 : } // this is an interior window surface
12197 :
12198 : // Accumulate transmitted diffuse solar for reporting
12199 3280 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += DifSolarTransW * per_HTSurfaceArea;
12200 :
12201 : } // IF (SurfaceWindow(HeatTransSurfNum)%WindowModelType /= WindowModel:: EQL) THEN
12202 :
12203 : // HERE 8/14/07 Ignore absorptance and reflectance of Frames and Dividers for now.
12204 : // I would need revised view factors that included these surface types.
12205 : // By ignoring them here, the diffuse solar is accounted for on the other surfaces
12206 :
12207 : // IF(SurfaceWindow(HeatTransSurfNum)%FrameArea > 0.0) THEN ! Window has a frame
12208 : // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
12209 : // END IF
12210 :
12211 : // IF(SurfaceWindow(HeatTransSurfNum)%DividerArea > 0.0) THEN ! Window has dividers
12212 : // DividerSolAbs = SurfaceWindow(HeatTransSurfNum)%DividerSolAbsorp
12213 : // IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended
12214 : // divider; account for inside glass
12215 : // MatNumGl = Construct(ConstrNum)%LayerPoint(Construct(ConstrNum)%TotLayers)
12216 : // TransGl = dataMaterial.Material(MatNumGl)%Trans
12217 : // ReflGl = dataMaterial.Material(MatNumGl)%ReflectSolDiffBack
12218 : // AbsGl = 1.0d0-TransGl-ReflGl
12219 : // DividerSolRefl = 1.0d0-DividerSolAbs
12220 : // DividerSolAbs = AbsGl + TransGl*(DividerSolAbs +
12221 : // DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl)
12222 : // END IF
12223 : // Correct for interior shade transmittance
12224 : // IF(ShadeFlag == IntShadeOn) THEN
12225 : // MatNumSh = Construct(ConstrNumSh)%LayerPoint(Construct(ConstrNumSh)%TotLayers)
12226 : // DividerSolAbs = DividerSolAbs * dataMaterial.Material(MatNumSh)%Trans
12227 : // ELSE IF(ShadeFlag == WinShadingType::IntBlind) THEN
12228 : // DividerSolAbs = DividerSolAbs *
12229 : // InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, &
12230 : // SurfaceWindow(HeatTransSurfNum)%MovableSlats,Blind(BlNum)%SolBackDiffDiffTrans)
12231 : // END IF
12232 : // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
12233 :
12234 : // END IF ! Window has dividers
12235 :
12236 : } // opaque or window heat transfer surface
12237 :
12238 : } // HeatTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast
12239 :
12240 : // Check debug var for view factors here
12241 : // ViewFactorTotal
12242 : // Check debug vars for individual transmitting surfaces here
12243 : // WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl +
12244 : // WinDifSolarDistTransmittedTotl;
12245 : // WinDifSolarTrans
12246 :
12247 : } // DifTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast
12248 :
12249 : // Check debug vars for zone totals here
12250 : // ZoneDifSolarDistTotl = ZoneDifSolarDistAbsorbedTotl + ZoneDifSolarDistReflectedTotl +
12251 : // ZoneDifSolarDistTransmittedTotl;
12252 : // ZoneDifSolarTrans
12253 : // ZoneDifSolarDistAbsorbedTotl
12254 : // ZoneDifSolarDistReflectedTotl
12255 : // ZoneDifSolarDistTransmittedTotl
12256 : // CALL DisplayString('Diffuse Solar Distribution Zone Totals')
12257 :
12258 : } // ZoneNum = 1, NumOfZones
12259 821277 : }
12260 7495 : void CalcInteriorWinTransDifSolInitialDistribution(EnergyPlusData &state,
12261 : int const IntWinEnclosureNum, // Interior Window Enclosure index number
12262 : int const IntWinSurfNum, // Interior Window Surface number
12263 : Real64 const IntWinDifSolarTransW // Diffuse Solar transmitted through Interior Window
12264 : // IntWinSurfNum from adjacent enclosure [W]
12265 : )
12266 : {
12267 :
12268 : // SUBROUTINE INFORMATION:
12269 : // AUTHOR Rob Hitchcock
12270 : // DATE WRITTEN August 2007
12271 : // MODIFIED N/A
12272 : // RE-ENGINEERED N/A
12273 :
12274 : // PURPOSE OF THIS SUBROUTINE:
12275 : // This subroutine calculates the initial distribution
12276 : // of diffuse solar transmitted through the given interior window
12277 : // to individual heat transfer surfaces in the given enclosure.
12278 : // Diffuse solar transmitted through interior windows in this enclosure
12279 : // to adjacent enclosures, is added to the EnclSolInitialDifSolReflW
12280 : // of the adjacent enclosure for subsequent interreflection calcs
12281 :
12282 : // METHODOLOGY EMPLOYED:
12283 : // Similar to method used in CalcWinTransDifSolInitialDistribution.
12284 : // Apportions diffuse solar transmitted through an interior window
12285 : // that is then absorbed, reflected, and/or transmitted
12286 : // by other heat transfer surfaces in the given enclosure.
12287 : // Calculations use:
12288 : // 1. DifSolarTransW calculated in SUBROUTINE CalcWinTransDifSolInitialDistribution,
12289 : // 2. view factors between the interior window and
12290 : // other heat transfer surfaces in the given enclosure
12291 : // calculated in SUBROUTINE CalcApproximateViewFactors, and
12292 : // 3. surface absorptances, reflectances, and transmittances
12293 : // determined here using revised code from SUBROUTINE InitIntSolarDistribution
12294 :
12295 : // Using/Aliasing
12296 : using General::InterpSw;
12297 : using ScheduleManager::GetCurrentScheduleValue;
12298 : using namespace DataViewFactorInformation;
12299 :
12300 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12301 : int IGlass; // Glass layer counter
12302 : int TotGlassLayers; // Number of glass layers in a window construction
12303 : WinShadingType ShadeFlag; // Shading flag
12304 : Real64 AbsInt; // Tmp var for Inside surface short-wave absorptance
12305 : Real64 InsideDifAbsorptance; // Inside diffuse solar absorptance of a surface
12306 : Real64 InsideDifReflectance; // Inside diffuse solar reflectance of a surface
12307 : int BlNum; // Blind number
12308 : Real64 BlAbsDiffBk; // Glass layer back diffuse solar absorptance when blind in place
12309 : Real64 AbsDiffBkBl; // Blind diffuse back solar absorptance as part of glazing system
12310 :
12311 : // REAL(r64) :: DividerSolAbs ! Window divider solar absorptance
12312 : // REAL(r64) :: DividerSolRefl ! Window divider solar reflectance
12313 : // INTEGER :: MatNumGl ! Glass layer material number
12314 : // INTEGER :: MatNumSh ! Shade layer material number
12315 : // REAL(r64) :: TransGl,ReflGl,AbsGl ! Glass layer solar transmittance, reflectance, absorptance
12316 :
12317 : Real64 ViewFactor; // temp var for view factor
12318 : Real64 ViewFactorTotal; // debug var for view factor total
12319 : Real64 WinDifSolarTrans; // debug var for WinDifSolar() [W]
12320 : // Real64 WinDifSolarDistTotl; // debug var for window total distributed
12321 : // diffuse solar [W] Real64 WinDifSolarDistAbsorbedTotl( 0.0 ); // debug var
12322 : // for individual exterior window total
12323 : // distributed
12324 : // diffuse solar absorbed [W]
12325 : // Real64 WinDifSolarDistReflectedTotl( 0.0 ); // debug var for individual exterior window total
12326 : // distributed
12327 : // diffuse solar reflected [W]
12328 : // Real64 WinDifSolarDistTransmittedTotl( 0.0 ); // debug var for individual exterior window total
12329 : // distributed
12330 : // diffuse solar transmitted [W]
12331 : Real64 WinDifSolLayAbsW; // temp var for diffuse solar absorbed by individual glass layer [W]
12332 : // Real64 ZoneDifSolarTrans( 0.0 ); // debug var for WinDifSolar() [W]
12333 : // REAL(r64) :: ZoneDifSolarDistTotl ! debug var for zone total distributed diffuse solar [W]
12334 : // Real64 ZoneDifSolarDistAbsorbedTotl( 0.0 ); // debug var for zone total distributed diffuse solar
12335 : // absorbed [W] Real64 ZoneDifSolarDistReflectedTotl( 0.0 ); // debug var for zone total distributed
12336 : // diffuse solar reflected [W] Real64 ZoneDifSolarDistTransmittedTotl( 0.0 ); // debug var for zone
12337 : // total distributed diffuse solar transmitted [W]
12338 :
12339 : Real64 DifSolarAbsW; // temp var for diffuse solar absorbed by surface [W]
12340 : Real64 DifSolarAbs; // temp var for diffuse solar absorbed by surface [W/m2]
12341 : Real64 DifSolarReflW; // temp var for diffuse solar reflected by surface [W]
12342 : Real64 DifSolarTransW; // temp var for diffuse solar transmitted through interior window surface [W]
12343 : Real64 ShBlDifSolarAbsW; // temp var for diffuse solar absorbed by shade/blind [W]
12344 :
12345 : //-------------------------------------------------------------------------------------------------
12346 : // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO INTERIOR HEAT TRANSFER SURFACES
12347 : //-------------------------------------------------------------------------------------------------
12348 :
12349 : // Init debug vars
12350 7495 : ViewFactorTotal = 0.0;
12351 7495 : WinDifSolarTrans = IntWinDifSolarTransW;
12352 :
12353 7495 : auto &thisEnclosure(state.dataViewFactor->EnclSolInfo(IntWinEnclosureNum));
12354 : // Loop over all heat transfer surfaces in the current zone that might receive diffuse solar
12355 7495 : Real64 InitialZoneDifSolReflW_zone(0.0);
12356 70152 : for (int const HeatTransSurfNum : thisEnclosure.SurfacePtr) {
12357 : // Skip surfaces that are not heat transfer surfaces
12358 62657 : if (!state.dataSurface->Surface(HeatTransSurfNum).HeatTransSurf) continue;
12359 : // Skip tubular daylighting device domes
12360 62657 : if (state.dataSurface->Surface(HeatTransSurfNum).Class == SurfaceClass::TDD_Dome) continue;
12361 :
12362 : // View factor from current (sending) window IntWinSurfNum to current (receiving) surface HeatTransSurfNum
12363 : int HTenclosureSurfNum =
12364 62657 : state.dataSurface->Surface(HeatTransSurfNum).SolarEnclSurfIndex; // HT surface index for EnclSolInfo.SurfacePtr and F arrays
12365 62657 : int enclosureNum = state.dataSurface->Surface(HeatTransSurfNum).SolarEnclIndex; // index for EnclSolInfo
12366 : int IntWinEnclSurfNum =
12367 62657 : state.dataSurface->Surface(IntWinSurfNum).SolarEnclSurfIndex; // Window surface index for EnclSolInfo.SurfacePtr and F arrays
12368 :
12369 62657 : ViewFactor = state.dataViewFactor->EnclSolInfo(enclosureNum).F(HTenclosureSurfNum, IntWinEnclSurfNum);
12370 : // debug ViewFactorTotal
12371 62657 : ViewFactorTotal += ViewFactor; // debug
12372 :
12373 : // Skip receiving surfaces with 0.0 view factor
12374 62657 : if (ViewFactor <= 0.0) continue;
12375 43955 : Real64 const SolarTrans_ViewFactor(IntWinDifSolarTransW * ViewFactor);
12376 :
12377 : // Calculate diffuse solar from current interior window absorbed and reflected by current heat transfer
12378 : // surface And calculate transmitted diffuse solar to adjacent zones through interior windows
12379 43955 : int const ConstrNum = state.dataSurface->SurfActiveConstruction(HeatTransSurfNum);
12380 43955 : if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Interior Opaque Surface
12381 :
12382 : // Determine the inside (back) diffuse solar absorptance
12383 : // and reflectance of the current heat transfer surface
12384 37475 : InsideDifAbsorptance = state.dataHeatBalSurf->SurfAbsSolarInt(HeatTransSurfNum);
12385 : // Inside (back) diffuse solar reflectance is assumed to be 1 - absorptance
12386 37475 : InsideDifReflectance = 1.0 - InsideDifAbsorptance;
12387 :
12388 : // Absorbed diffuse solar [W] = current window transmitted diffuse solar [W]
12389 : // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface
12390 : // HeatTransSurfNum
12391 : // * current surface inside solar absorptance
12392 37475 : DifSolarAbsW = SolarTrans_ViewFactor * InsideDifAbsorptance; // [W]
12393 :
12394 : // Absorbed diffuse solar [W/m2] = Absorbed diffuse solar [W]
12395 : // / current surface net area
12396 37475 : DifSolarAbs = DifSolarAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area;
12397 :
12398 : // Accumulate absorbed diffuse solar [W/m2] on this surface for heat balance calcs
12399 37475 : state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(HeatTransSurfNum) += DifSolarAbs;
12400 :
12401 : // Reflected diffuse solar [W] = current window transmitted diffuse solar
12402 : // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface
12403 : // HeatTransSurfNum
12404 : // * current window inside solar reflectance
12405 37475 : DifSolarReflW = SolarTrans_ViewFactor * InsideDifReflectance;
12406 :
12407 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection
12408 : // calcs
12409 37475 : InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
12410 :
12411 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12412 : // For opaque surfaces all incident diffuse is either absorbed or reflected
12413 : // WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug [W]
12414 : // WinDifSolarDistReflectedTotl += DifSolarReflW; // debug [W]
12415 : // ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug [W]
12416 : // ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug [W]
12417 :
12418 : } else { // Exterior or Interior Window
12419 :
12420 6480 : int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(HeatTransSurfNum);
12421 :
12422 6480 : TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
12423 6480 : ShadeFlag = state.dataSurface->SurfWinShadingFlag(HeatTransSurfNum);
12424 :
12425 6480 : if (NOT_SHADED(ShadeFlag)) { // No window shading
12426 : // Init accumulator for transmittance calc below
12427 6480 : DifSolarAbsW = 0.0;
12428 :
12429 : // Calc diffuse solar absorbed by all window glass layers
12430 : // Note: I am assuming here that individual glass layer absorptances have been corrected
12431 : // to account for layer by layer transmittance and reflection effects.
12432 12960 : for (IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
12433 : // Calc diffuse solar absorbed from the inside by each window glass layer [W]
12434 6480 : AbsInt = state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
12435 6480 : WinDifSolLayAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
12436 :
12437 : // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
12438 : // below
12439 6480 : DifSolarAbsW += WinDifSolLayAbsW;
12440 :
12441 : // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for
12442 : // heat balance calcs
12443 6480 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) +=
12444 6480 : (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12445 : }
12446 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12447 : // WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
12448 : // ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
12449 :
12450 : // Calc diffuse solar reflected back to zone
12451 : // I don't really care if this is a window or opaque surface since I am just
12452 : // accumulating all reflected diffuse solar in a zone bucket for "interreflected" distribution
12453 : // Reflected diffuse solar [W] = current window transmitted diffuse solar
12454 : // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface
12455 : // HeatTransSurfNum
12456 : // * current window inside solar reflectance
12457 6480 : DifSolarReflW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
12458 :
12459 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
12460 : // interreflection calcs
12461 6480 : InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
12462 :
12463 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12464 :
12465 : // WinDifSolarDistReflectedTotl += DifSolarReflW; // debug
12466 : // ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug
12467 :
12468 : // Calc transmitted Window and Zone total distributed diffuse solar to check for conservation of
12469 : // energy This is not very effective since it assigns whatever distributed diffuse solar has not
12470 : // been absorbed or reflected to transmitted.
12471 6480 : DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW;
12472 :
12473 : // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
12474 : // conservation of energy
12475 : // WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
12476 : // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
12477 :
12478 : // Accumulate transmitted diffuse solar for reporting
12479 6480 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) +=
12480 6480 : (DifSolarTransW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12481 :
12482 : //-----------------------------------------------------------------------------------
12483 : // ADD TRANSMITTED DIFFUSE SOLAR THROUGH INTERIOR WINDOW TO ADJACENT ZONE
12484 : // TOTAL REFLECTED DIFFUSE SOLAR FOR SUBSEQUENT INTERREFLECTION CALCS
12485 : //-----------------------------------------------------------------------------------
12486 :
12487 : // If this receiving window surface (HeatTransSurfNum) is an interior window,
12488 : // add transmitted diffuse solar to adjacent zone total reflected distributed
12489 : // diffuse solar for subsequent interreflection calcs
12490 : // NOTE: This calc is here because interior windows are currently assumed to have no shading
12491 :
12492 : // Get the adjacent surface number for this receiving window surface
12493 6480 : int const AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond;
12494 : // If the adjacent surface number is > 0, this is an interior window
12495 6480 : if (AdjSurfNum > 0) { // this is an interior window surface
12496 :
12497 : // Get the adjacent zone/enclosure index
12498 : // Add transmitted diffuse solar to total reflected distributed diffuse solar for each zone
12499 : // for subsequent interreflection calcs
12500 0 : state.dataHeatBal->EnclSolInitialDifSolReflW(state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex) += DifSolarTransW; // [W]
12501 : }
12502 :
12503 0 : } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing
12504 : // Init accumulator for transmittance calc below
12505 0 : DifSolarAbsW = 0.0;
12506 :
12507 0 : for (IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
12508 : // Calc diffuse solar absorbed in each window glass layer
12509 0 : WinDifSolLayAbsW = SolarTrans_ViewFactor * InterpSw(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum),
12510 0 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass),
12511 0 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass));
12512 :
12513 : // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
12514 : // below
12515 0 : DifSolarAbsW += WinDifSolLayAbsW;
12516 :
12517 : // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for
12518 : // heat balance calcs
12519 0 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) +=
12520 0 : (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12521 : }
12522 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12523 : // WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
12524 : // ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
12525 :
12526 : // Calc diffuse solar reflected back to zone
12527 0 : DifSolarReflW = SolarTrans_ViewFactor * InterpSw(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum),
12528 0 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack,
12529 0 : state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack);
12530 :
12531 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
12532 : // interreflection calcs
12533 0 : InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
12534 :
12535 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12536 : // WinDifSolarDistReflectedTotl += DifSolarReflW; // debug
12537 : // ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug
12538 :
12539 : // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
12540 : // conservation of energy This is not very effective since it assigns whatever distributed diffuse
12541 : // solar has not been absorbed or reflected to transmitted.
12542 0 : DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW;
12543 : // WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
12544 : // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug
12545 : //[W]
12546 :
12547 : // Accumulate transmitted diffuse solar for reporting
12548 0 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) +=
12549 0 : (DifSolarTransW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12550 :
12551 : } else {
12552 : // Interior, exterior or between-glass shade, screen or blind in place
12553 :
12554 : // Init accumulator for transmittance calc below
12555 0 : DifSolarAbsW = 0.0;
12556 0 : WinDifSolLayAbsW = 0.0;
12557 0 : int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(HeatTransSurfNum);
12558 0 : Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(HeatTransSurfNum);
12559 :
12560 : // First calc diffuse solar absorbed by each glass layer in this window with shade/blind in place
12561 0 : for (IGlass = 1; IGlass <= state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; ++IGlass) {
12562 0 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
12563 : // Calc diffuse solar absorbed in each window glass layer and shade
12564 0 : WinDifSolLayAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass);
12565 0 : } else if (ANY_BLIND(ShadeFlag)) {
12566 0 : if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
12567 0 : BlAbsDiffBk = General::InterpGeneral(
12568 0 : state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(SurfWinSlatsAngIndex, IGlass),
12569 0 : state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), IGlass),
12570 : SurfWinSlatsAngInterpFac);
12571 : } else {
12572 0 : BlAbsDiffBk = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(1, IGlass);
12573 : }
12574 : // Calc diffuse solar absorbed in each window glass layer and shade
12575 0 : WinDifSolLayAbsW = SolarTrans_ViewFactor * BlAbsDiffBk;
12576 : }
12577 :
12578 : // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
12579 : // below
12580 0 : DifSolarAbsW += WinDifSolLayAbsW;
12581 :
12582 : // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for
12583 : // heat balance calcs
12584 0 : state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) +=
12585 0 : (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12586 : }
12587 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12588 : // WinDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
12589 : // ZoneDifSolarDistAbsorbedTotl += DifSolarAbsW; // debug
12590 :
12591 : // Next calc diffuse solar reflected back to zone from window with shade or blind on
12592 : // Diffuse back solar reflectance, bare glass or shade on
12593 0 : InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack;
12594 0 : if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::IntBlind) | BITF(WinShadingType::ExtBlind))) {
12595 : // Diffuse back solar reflectance, blind present, vs. slat angle
12596 0 : if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
12597 0 : InsideDifReflectance = General::InterpGeneral(
12598 0 : state.dataConstruction->Construct(ConstrNumSh).BlReflectSolDiffBack(SurfWinSlatsAngIndex),
12599 0 : state.dataConstruction->Construct(ConstrNumSh).BlReflectSolDiffBack(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
12600 : SurfWinSlatsAngInterpFac);
12601 : } else {
12602 0 : InsideDifReflectance = state.dataConstruction->Construct(ConstrNumSh).BlReflectSolDiffBack(1);
12603 : }
12604 : }
12605 0 : DifSolarReflW = SolarTrans_ViewFactor * InsideDifReflectance;
12606 :
12607 : // Accumulate total reflected distributed diffuse solar for each zone for subsequent
12608 : // interreflection calcs
12609 0 : InitialZoneDifSolReflW_zone += DifSolarReflW; // [W]
12610 :
12611 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12612 : // WinDifSolarDistReflectedTotl += DifSolarReflW; // debug
12613 : // ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug
12614 :
12615 : // Now calc diffuse solar absorbed by shade/blind itself
12616 0 : BlNum = state.dataSurface->SurfWinBlindNumber(HeatTransSurfNum);
12617 0 : if (ANY_SHADE_SCREEN(ShadeFlag)) {
12618 : // Calc diffuse solar absorbed by shade or screen [W]
12619 0 : ShBlDifSolarAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackShade;
12620 0 : } else if (ANY_BLIND(ShadeFlag)) {
12621 : // Calc diffuse solar absorbed by blind [W]
12622 0 : if (state.dataSurface->SurfWinMovableSlats(HeatTransSurfNum)) {
12623 0 : AbsDiffBkBl = General::InterpGeneral(
12624 0 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(SurfWinSlatsAngIndex),
12625 0 : state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)),
12626 : SurfWinSlatsAngInterpFac);
12627 : } else {
12628 0 : AbsDiffBkBl = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(1);
12629 : }
12630 0 : ShBlDifSolarAbsW = SolarTrans_ViewFactor * AbsDiffBkBl;
12631 : }
12632 : // Correct for divider shadowing
12633 0 : if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
12634 0 : ShBlDifSolarAbsW *= state.dataSurface->SurfWinGlazedFrac(HeatTransSurfNum);
12635 : }
12636 :
12637 : // Accumulate diffuse solar absorbed by shade or screen [W/m2] for heat balance calcs
12638 0 : state.dataSurface->SurfWinInitialDifSolAbsByShade(HeatTransSurfNum) +=
12639 0 : (ShBlDifSolarAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12640 :
12641 : // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc
12642 : // below
12643 0 : DifSolarAbsW += ShBlDifSolarAbsW;
12644 :
12645 : // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy
12646 : // WinDifSolarDistAbsorbedTotl += ShBlDifSolarAbsW; // debug
12647 : // ZoneDifSolarDistAbsorbedTotl += ShBlDifSolarAbsW; // debug
12648 :
12649 : // Accumulate transmitted Window and Zone total distributed diffuse solar to check for
12650 : // conservation of energy This is not very effective since it assigns whatever distributed diffuse
12651 : // solar has not been absorbed or reflected to transmitted.
12652 0 : DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW;
12653 : // WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
12654 : // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W]
12655 :
12656 : // Accumulate transmitted diffuse solar for reporting
12657 0 : state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) +=
12658 0 : (DifSolarTransW / state.dataSurface->Surface(HeatTransSurfNum).Area);
12659 :
12660 : } // End of shading flag check
12661 :
12662 : // HERE 8/14/07 Ignore absorptance and reflectance of Frames and Dividers for now.
12663 : // I would need revised view factors that included these surface types.
12664 : // By ignoring them here, the diffuse solar is accounted for on the other surfaces
12665 :
12666 : // IF(SurfaceWindow(HeatTransSurfNum)%FrameArea > 0.0) THEN ! Window has a frame
12667 : // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
12668 : // END IF
12669 :
12670 : // IF(SurfaceWindow(HeatTransSurfNum)%DividerArea > 0.0) THEN ! Window has dividers
12671 : // DividerSolAbs = SurfaceWindow(HeatTransSurfNum)%DividerSolAbsorp
12672 : // IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended divider;
12673 : // account for inside glass
12674 : // MatNumGl = Construct(ConstrNum)%LayerPoint(Construct(ConstrNum)%TotLayers)
12675 : // TransGl = dataMaterial.Material(MatNumGl)%Trans
12676 : // ReflGl = dataMaterial.Material(MatNumGl)%ReflectSolDiffBack
12677 : // AbsGl = 1.0d0-TransGl-ReflGl
12678 : // DividerSolRefl = 1.0d0-DividerSolAbs
12679 : // DividerSolAbs = AbsGl + TransGl*(DividerSolAbs +
12680 : // DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl)
12681 : // END IF
12682 : // Correct for interior shade transmittance
12683 : // IF(ShadeFlag == IntShadeOn) THEN
12684 : // MatNumSh = Construct(ConstrNumSh)%LayerPoint(Construct(ConstrNumSh)%TotLayers)
12685 : // DividerSolAbs = DividerSolAbs * dataMaterial.Material(MatNumSh)%Trans
12686 : // ELSE IF(ShadeFlag == WinShadingType::IntBlind) THEN
12687 : // DividerSolAbs = DividerSolAbs *
12688 : // InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, &
12689 : // SurfaceWindow(HeatTransSurfNum)%MovableSlats,Blind(BlNum)%SolBackDiffDiffTrans)
12690 : // END IF
12691 : // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
12692 :
12693 : // END IF ! Window has dividers
12694 : } // opaque or window heat transfer surface
12695 :
12696 : } // HeatTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast
12697 7495 : state.dataHeatBal->EnclSolInitialDifSolReflW(IntWinEnclosureNum) += InitialZoneDifSolReflW_zone;
12698 :
12699 : // Check debug var for view factors here
12700 : // ViewFactorTotal
12701 : // Check debug vars for individual transmitting surfaces here
12702 : // WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl +
12703 : // WinDifSolarDistTransmittedTotl; //Debug
12704 : // WinDifSolarTrans
12705 7495 : }
12706 :
12707 24 : void CalcComplexWindowOverlap(EnergyPlusData &state,
12708 : BSDFGeomDescr &Geom, // State Geometry
12709 : BSDFWindowGeomDescr const &Window, // Window Geometry
12710 : int const ISurf // Surface number of the complex fenestration
12711 : )
12712 : {
12713 : // SUBROUTINE INFORMATION:
12714 : // AUTHOR Simon Vidanovic
12715 : // DATE WRITTEN May 2012
12716 : // MODIFIED Simon Vidanovic (May 2013) - added overlaps calculations for daylighting
12717 : // RE-ENGINEERED na
12718 :
12719 : // PURPOSE OF THIS SUBROUTINE:
12720 : // For each of basis directions on back surface of the window calculates
12721 : // overlap areas. It also calculates overlap areas and reflectances for daylighting calculations
12722 :
12723 : using namespace Vectors;
12724 :
12725 : Real64 XShadowProjection; // temporary buffer
12726 : Real64 YShadowProjection; // temporary buffer
12727 :
12728 : Real64 XSp; // for calc BSDF projection direction
12729 : Real64 YSp; // for calc BSDF projection direction
12730 : Real64 ZSp; // for calc BSDF projection direction
12731 : Real64 SdotX; // temporary variable for manipulating .dot. product
12732 : Real64 SdotY; // temporary variable for manipulating .dot. product
12733 : Real64 SdotZ; // temporary variable for manipulating .dot. product
12734 : int BackSurfaceNumber; // current back surface number
12735 : int NVT; // Number of vertices of back surface
12736 : int NS1; // Number of the figure being overlapped
12737 : int NS2; // Number of the figure doing overlapping
12738 : int NS3; // Location to place results of overlap
12739 : int IRay; // Current ray of BSDF direction
12740 : int KBkSurf; // Current back surface
12741 : int N;
12742 :
12743 : // Daylighting
12744 : int IConst; // Construction number of back surface
12745 : int InsideConLay; // Construction's inside material layer number
12746 : Real64 VisibleReflectance; // Visible reflectance for inside surface material
12747 : Real64 TotAOverlap; // Total overlap area for given outgoing direction
12748 : Real64 TotARhoVisOverlap; // Total overlap area time reflectance for given outgoing direction
12749 :
12750 24 : state.dataSolarShading->XVertex.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
12751 24 : state.dataSolarShading->YVertex.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
12752 24 : state.dataSolarShading->ZVertex.dimension(state.dataSurface->MaxVerticesPerSurface + 1, 0.0);
12753 :
12754 24 : Geom.AOverlap.dimension(Window.NBkSurf, Geom.Trn.NBasis, 0.0);
12755 24 : Geom.ARhoVisOverlap.dimension(Window.NBkSurf, Geom.Trn.NBasis, 0.0);
12756 24 : Geom.AveRhoVisOverlap.dimension(Geom.Trn.NBasis, 0.0);
12757 :
12758 : // First to calculate and store coordinates of the window surface
12759 24 : state.dataSolarShading->LOCHCA = 1;
12760 24 : int BaseSurf = state.dataSurface->Surface(ISurf).BaseSurf; // Base surface number
12761 :
12762 : // Base surface contains current window surface (ISurf).
12763 : // Since that is case, below transformation should always return ZVT = 0.0
12764 : // for every possible transformation
12765 24 : CTRANS(state, ISurf, BaseSurf, NVT, state.dataSolarShading->XVertex, state.dataSolarShading->YVertex, state.dataSolarShading->ZVertex);
12766 :
12767 : // HTRANS routine is using coordinates stored in XVS and YVS in order to calculate
12768 : // surface area. Since both projections are equal to zero, then simply
12769 : // compy these values into XVS and YVS arrays
12770 120 : for (N = 1; N <= NVT; ++N) {
12771 96 : state.dataSolarShading->XVS(N) = state.dataSolarShading->XVertex(N);
12772 96 : state.dataSolarShading->YVS(N) = state.dataSolarShading->YVertex(N);
12773 : }
12774 :
12775 : // This calculates the area stored in XVS and YVS
12776 24 : HTRANS1(state, state.dataSolarShading->LOCHCA, NVT);
12777 :
12778 : // Calculation of overlap areas for each outgoing basis direction
12779 1944 : for (IRay = 1; IRay <= Geom.Trn.NBasis; ++IRay) { // basis directions loop (on back surface)
12780 : // For current basis direction calculate dot product between window surface
12781 : // and basis direction. This will be used to calculate projection of each
12782 : // of the back surfaces to window surface for given basis direciton
12783 1920 : SdotX = dot(state.dataSurface->Surface(ISurf).lcsx, Geom.sTrn(IRay));
12784 1920 : SdotY = dot(state.dataSurface->Surface(ISurf).lcsy, Geom.sTrn(IRay));
12785 1920 : SdotZ = dot(state.dataSurface->Surface(ISurf).lcsz, Geom.sTrn(IRay));
12786 1920 : XSp = -SdotX;
12787 1920 : YSp = -SdotY;
12788 1920 : ZSp = -SdotZ;
12789 :
12790 : // Projection of shadows for current basis direciton
12791 1920 : if (std::abs(ZSp) > 1.e-4) {
12792 1920 : XShadowProjection = XSp / ZSp;
12793 1920 : YShadowProjection = YSp / ZSp;
12794 1920 : if (std::abs(XShadowProjection) < 1.e-8) XShadowProjection = 0.0;
12795 1920 : if (std::abs(YShadowProjection) < 1.e-8) YShadowProjection = 0.0;
12796 : } else {
12797 0 : XShadowProjection = 0.0;
12798 0 : YShadowProjection = 0.0;
12799 : }
12800 :
12801 14244 : for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop
12802 : // BaseSurf = Surface(ISurf).BaseSurf
12803 12324 : BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(KBkSurf);
12804 :
12805 : // Transform coordinates of back surface from general system to the
12806 : // plane of the receiving surface
12807 36972 : CTRANS(state,
12808 : BackSurfaceNumber,
12809 : BaseSurf,
12810 : NVT,
12811 12324 : state.dataSolarShading->XVertex,
12812 12324 : state.dataSolarShading->YVertex,
12813 12324 : state.dataSolarShading->ZVertex);
12814 :
12815 : // Project "shadow" from back surface along sun's rays to receiving surface. Back surface vertices
12816 : // become clockwise sequential.
12817 :
12818 61620 : for (N = 1; N <= NVT; ++N) {
12819 49296 : state.dataSolarShading->YVS(N) = state.dataSolarShading->YVertex(N) - YShadowProjection * state.dataSolarShading->ZVertex(N);
12820 49296 : state.dataSolarShading->XVS(N) = state.dataSolarShading->XVertex(N) - XShadowProjection * state.dataSolarShading->ZVertex(N);
12821 : }
12822 :
12823 : // Transform to the homogeneous coordinate system.
12824 :
12825 12324 : NS3 = state.dataSolarShading->LOCHCA + 1;
12826 12324 : state.dataSolarShading->HCT(NS3) = 0.0;
12827 12324 : HTRANS1(state, NS3, NVT);
12828 :
12829 : // Determine area of overlap of projected back surface and receiving surface.
12830 :
12831 12324 : NS1 = 1;
12832 12324 : NS2 = NS3;
12833 12324 : state.dataSolarShading->HCT(NS3) = 1.0;
12834 12324 : DeterminePolygonOverlap(state, NS1, NS2, NS3);
12835 :
12836 12324 : if (state.dataSolarShading->OverlapStatus == NoOverlap) continue; // to next back surface
12837 4624 : if ((state.dataSolarShading->OverlapStatus == TooManyVertices) || (state.dataSolarShading->OverlapStatus == TooManyFigures))
12838 0 : break; // back surfaces DO loop
12839 :
12840 4624 : state.dataSolarShading->LOCHCA = NS3;
12841 4624 : state.dataSolarShading->HCNS(state.dataSolarShading->LOCHCA) = BackSurfaceNumber;
12842 4624 : state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA) = -state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
12843 :
12844 4624 : Geom.AOverlap(KBkSurf, IRay) = state.dataSolarShading->HCAREA(state.dataSolarShading->LOCHCA);
12845 : } // DO KBkSurf = 1 , NBkSurf
12846 :
12847 : // If some of back surfaces is contained in base surface, then need to substract shadow of subsurface
12848 : // from shadow on base surface. Reson is that above shadowing algorithm is calculating shadow wihtout
12849 : // influence of subsurfaces
12850 14244 : for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop
12851 12324 : BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(KBkSurf);
12852 : // CurBaseSurf is Current base surface number for shadow overlap calcualtions
12853 12324 : int CurBaseSurf = state.dataSurface->Surface(BackSurfaceNumber).BaseSurf;
12854 12324 : if (CurBaseSurf != BackSurfaceNumber) {
12855 : // Search if that base surface in list of back surfaces for current window
12856 : // CurBackSurface is Current back surface number for base surface
12857 2724 : int CurBackSurface = 0;
12858 5366 : for (N = 1; N <= Window.NBkSurf; ++N) {
12859 5366 : if (state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(N) == CurBaseSurf) {
12860 2724 : CurBackSurface = N;
12861 2724 : break;
12862 : }
12863 : }
12864 2724 : if (CurBackSurface != 0) {
12865 2724 : Geom.AOverlap(CurBackSurface, IRay) -= Geom.AOverlap(KBkSurf, IRay);
12866 : }
12867 : }
12868 : }
12869 :
12870 : // Calculate overlap area times reflectance. This is necessary for complex fenestration daylighting
12871 : // calculations
12872 1920 : TotAOverlap = 0.0;
12873 1920 : TotARhoVisOverlap = 0.0;
12874 14244 : for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop
12875 12324 : BackSurfaceNumber = state.dataShadowComb->ShadowComb(BaseSurf).BackSurf(KBkSurf);
12876 12324 : IConst = state.dataSurface->Surface(BackSurfaceNumber).Construction;
12877 12324 : InsideConLay = state.dataConstruction->Construct(IConst).TotLayers;
12878 12324 : if (state.dataSurface->SurfWinWindowModelType(BackSurfaceNumber) == WindowModel::BSDF) {
12879 2724 : VisibleReflectance = state.dataConstruction->Construct(IConst).ReflectVisDiffBack;
12880 : } else {
12881 9600 : VisibleReflectance = (1.0 - state.dataMaterial->Material(InsideConLay).AbsorpVisible);
12882 : }
12883 12324 : Geom.ARhoVisOverlap(KBkSurf, IRay) = Geom.AOverlap(KBkSurf, IRay) * VisibleReflectance;
12884 12324 : TotAOverlap += Geom.AOverlap(KBkSurf, IRay);
12885 12324 : TotARhoVisOverlap += Geom.ARhoVisOverlap(KBkSurf, IRay);
12886 : }
12887 :
12888 1920 : if (TotAOverlap != 0.0) {
12889 1920 : Geom.AveRhoVisOverlap(IRay) = TotARhoVisOverlap / TotAOverlap;
12890 : }
12891 :
12892 : } // DO IRay = 1, Geom%Trn%NBasis
12893 :
12894 : // Reset back shadowing counter since complex windows do not need it anymore
12895 24 : state.dataSolarShading->LOCHCA = 1;
12896 24 : }
12897 :
12898 2568509 : void TimestepInitComplexFenestration(EnergyPlusData &state)
12899 : {
12900 : // SUBROUTINE INFORMATION:
12901 : // AUTHOR Simon Vidanovic
12902 : // DATE WRITTEN May 2012
12903 : // MODIFIED May 2012 (Initialize complex fenestration in case of EMS)
12904 : // RE-ENGINEERED na
12905 :
12906 : // PURPOSE OF THIS SUBROUTINE:
12907 : // Performs initialization of complex fenestration. It also performs check if current surface containing
12908 : // complex fenestration have construction changed (by EMS) in which case performs addition of current states
12909 : // into complex fenestration array
12910 :
12911 : using WindowComplexManager::CheckCFSStates;
12912 :
12913 : // Locals
12914 : int iSurf; // Current surface number
12915 : int iState; // current state number
12916 : int NumOfStates; // number of states for current window
12917 :
12918 166715563 : for (iSurf = 1; iSurf <= state.dataSurface->TotSurfaces; ++iSurf) {
12919 164147054 : if (state.dataSurface->SurfWinWindowModelType(iSurf) == WindowModel::BSDF) {
12920 : // This will check complex fenestrations state and add new one if necessary (EMS case)
12921 39540 : CheckCFSStates(state, iSurf);
12922 :
12923 39540 : NumOfStates = state.dataBSDFWindow->ComplexWind(iSurf).NumStates;
12924 :
12925 : // Check for overlap areas and initialize if necessary
12926 79080 : for (iState = 1; iState <= NumOfStates; ++iState) {
12927 : // do initialization only once
12928 39540 : if (state.dataBSDFWindow->ComplexWind(iSurf).Geom(iState).InitState) {
12929 24 : CalcComplexWindowOverlap(
12930 24 : state, state.dataBSDFWindow->ComplexWind(iSurf).Geom(iState), state.dataBSDFWindow->ComplexWind(iSurf), iSurf);
12931 24 : state.dataBSDFWindow->ComplexWind(iSurf).Geom(iState).InitState = false;
12932 : }
12933 : }
12934 : }
12935 : }
12936 2568509 : }
12937 :
12938 2313 : } // namespace EnergyPlus::SolarShading
|