Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef Construction_hh_INCLUDED
49 : #define Construction_hh_INCLUDED
50 :
51 : // EnergyPlus Headers
52 : #include <EnergyPlus/Data/BaseData.hh>
53 : #include <EnergyPlus/DataBSDFWindow.hh>
54 : #include <EnergyPlus/DataHeatBalance.hh>
55 : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
56 : #include <EnergyPlus/EnergyPlus.hh>
57 : #include <EnergyPlus/Material.hh>
58 : #include <EnergyPlus/WindowManager.hh>
59 :
60 : namespace EnergyPlus {
61 :
62 : // Forward declarations
63 : struct EnergyPlusData;
64 :
65 : namespace Construction {
66 :
67 : int constexpr MaxLayersInConstruct(11); // Maximum number of layers allowed in a single construction
68 : int constexpr MaxCTFTerms(19); // Maximum number of CTF terms allowed to still allow stability
69 : // Note Sync with SurfaceGroundHeatExchanger::local::MaxCTFTerms
70 : // ** has to be big enough to hold no matter what window model
71 : // each window model should validate layers individually
72 :
73 : // Nested one-field structs just to keep overall structure
74 : // consistent with Material::BlindTAR. See Material.hh for
75 : // discussion of this approach.
76 : struct BlindSolVis
77 : {
78 : struct
79 : {
80 : struct
81 : {
82 : Material::BlindDfTARGS Df;
83 : } Ft;
84 : struct
85 : {
86 : Material::BlindDfTAR Df;
87 : } Bk;
88 : } Sol;
89 : struct
90 : {
91 : struct
92 : {
93 : Material::BlindDfTAR Df;
94 : } Ft;
95 : struct
96 : {
97 : Material::BlindDfTAR Df;
98 : } Bk;
99 : } Vis;
100 : };
101 :
102 : // Nested one-field structs keep overall structure consistent with Material::BlindTAR
103 : struct BlindSolDfAbs
104 : {
105 : struct
106 : {
107 : struct
108 : {
109 : struct
110 : {
111 : Real64 Abs = 0.0;
112 : Real64 AbsGnd = 0.0;
113 : Real64 AbsSky = 0.0;
114 : } Df;
115 : } Ft; // Front
116 :
117 : struct
118 : {
119 : struct
120 : {
121 : Real64 Abs = 0.0;
122 : } Df;
123 : } Bk; // Back
124 : } Sol;
125 : };
126 :
127 : struct TCLayer
128 : {
129 : int constrNum;
130 : Real64 specTemp;
131 : };
132 :
133 : // This needs to get broken up too
134 : struct ConstructionProps
135 : {
136 : // Members
137 : std::string Name; // Name of construction
138 : int TotLayers = 0; // Total number of layers for the construction; for windows
139 : // this is the total of the glass, gas and shade layers
140 : int TotSolidLayers = 0; // Total number of solid (glass or shade) layers (windows only)
141 : int TotGlassLayers = 0; // Total number of glass layers (windows only)
142 : Array1D_int LayerPoint; // Pointer array which refers back to
143 : // the Material structure; LayerPoint(i)=j->Material(j)%Name,etc
144 : bool IsUsed = false; // Marked true when the construction is used
145 : bool IsUsedCTF = false; // Mark true when the construction is used for a surface with CTF calculations
146 : Real64 InsideAbsorpVis = 0.0; // Inside Layer visible absorptance of an opaque surface; not used for windows.
147 : Real64 OutsideAbsorpVis = 0.0; // Outside Layer visible absorptance of an opaque surface; not used for windows.
148 : Real64 InsideAbsorpSolar = 0.0; // Inside Layer solar absorptance of an opaque surface; not used for windows.
149 : Real64 OutsideAbsorpSolar = 0.0; // Outside Layer solar absorptance of an opaque surface; not used for windows.
150 : Real64 InsideAbsorpThermal = 0.0; // Inside Layer Thermal absorptance for opaque surfaces or windows;
151 : // for windows, applies to innermost glass layer
152 : Real64 OutsideAbsorpThermal = 0.0; // Outside Layer Thermal absorptance
153 : Material::SurfaceRoughness OutsideRoughness = Material::SurfaceRoughness::Invalid; // Outside Surface roughness index
154 : int DayltPropPtr = 0; // Pointer to Daylight Construction Properties
155 : int W5FrameDivider = 0; // FrameDivider number for window construction from Window5 data file;
156 : // zero is construction not from Window5 file or Window5 construction has no frame.
157 : // Conductive properties for the construction
158 : std::array<Real64, MaxCTFTerms> CTFCross{}; // Cross or Y terms of the CTF equation
159 : std::array<Real64, MaxCTFTerms> CTFFlux{}; // Flux history terms of the CTF equation
160 : std::array<Real64, MaxCTFTerms> CTFInside{}; // Inside or Z terms of the CTF equation
161 : std::array<Real64, MaxCTFTerms> CTFOutside{}; // Outside or X terms of the CTF equation
162 : std::array<Real64, MaxCTFTerms> CTFSourceIn{}; // Heat source/sink inside terms of CTF equation
163 : std::array<Real64, MaxCTFTerms> CTFSourceOut{}; // Heat source/sink outside terms of CTF equation
164 : Real64 CTFTimeStep = 0.0; // Time increment for stable simulation of construct (could be greater than TimeStep)
165 : // The next three series of terms are used to calculate the temperature at the location of a source/sink
166 : // in the QTF formulation. This calculation is necessary to allow the proper simulation of a
167 : // radiant system.
168 : std::array<Real64, MaxCTFTerms> CTFTSourceOut{}; // Outside terms of the CTF equation for interior temp
169 : // calc@source location
170 : std::array<Real64, MaxCTFTerms> CTFTSourceIn{}; // Inside terms of the CTF equation for interior temp
171 : // calc@source location
172 : std::array<Real64, MaxCTFTerms> CTFTSourceQ{}; // Source/sink terms of the CTF equation for interior temp
173 : // calc@source location
174 : // The next three series of terms are used to calculate the temperature at a location specified by the user.
175 : // This location must be between two layers and is intended to allow the user to evaluate whether or not
176 : // condensation is a possibility between material layers.
177 : std::array<Real64, MaxCTFTerms> CTFTUserOut{}; // Outside terms of the CTF equation for interior temp
178 : // calc@user location
179 : std::array<Real64, MaxCTFTerms> CTFTUserIn{}; // Inside terms of the CTF equation for interior temp
180 : // calc@user location
181 : std::array<Real64, MaxCTFTerms> CTFTUserSource{}; // Source/sink terms of the CTF equation for interior temp
182 : // calc@user location
183 : int NumHistories = 0; // CTFTimeStep/TimeStepZone or the number of temp/flux history series
184 : // for the construction
185 : int NumCTFTerms = 0; // Number of CTF terms for this construction (not including terms at current time)
186 : Real64 UValue = 0.0; // Overall heat transfer coefficient for the construction
187 : int SolutionDimensions = 0; // Number of dimensions in the solution (1 for normal constructions,
188 : // 1 or 2 for constructions with sources or sinks)-->may allow 3-D later?
189 : int SourceAfterLayer = 0; // Source/sink is present after this layer in the construction
190 : int TempAfterLayer = 0; // User is requesting a temperature calculation after this layer in the construction
191 : // This location is also the position of a temperature on the interior of a slab
192 : // that could be used to control a low temperature radiant system
193 : Real64 ThicknessPerpend = 0.0; // Thickness between planes of symmetry in the direction
194 : // perpendicular to the main direction of heat transfer
195 : // (same as half the distance between tubes)
196 : Real64 userTemperatureLocationPerpendicular = 0.0; // Location of the source perpendicular to the main direction
197 : // of heat transfer. Used in conjunction with the TempAfterLayer
198 : // term to provide specific location of user defined temperature.
199 : // This value is only used when SolutionDimension = 2.
200 : // Moisture Transfer Functions term belong here as well
201 : // BLAST detailed solar model parameters
202 : Real64 AbsDiffIn = 0.0; // Inner absorptance coefficient for diffuse radiation
203 : Real64 AbsDiffOut = 0.0; // Outer absorptance coefficient for diffuse radiation
204 : // Variables for window constructions
205 : Array1D<Real64> AbsDiff; // Diffuse solar absorptance for each glass layer,
206 : // bare glass or shade on
207 :
208 : std::array<Real64, Material::MaxSlatAngs> effShadeBlindEmi;
209 : std::array<Real64, Material::MaxSlatAngs> effGlassEmi;
210 :
211 : std::array<BlindSolVis, Material::MaxSlatAngs> blindTARs;
212 :
213 : // Sol diffuse absorptance per glass layer with blind on
214 : Array1D<std::array<BlindSolDfAbs, Material::MaxSlatAngs>> layerSlatBlindDfAbs;
215 :
216 : Array1D<Real64> AbsDiffBack; // Diffuse back solar absorptance for each glass layer
217 : Real64 AbsDiffShade = 0.0; // Diffuse solar absorptance for shade
218 : Real64 AbsDiffBackShade = 0.0; // Diffuse back solar absorptance for shade
219 : Real64 ShadeAbsorpThermal = 0.0; // Diffuse back thermal absorptance of shade
220 : Array1D<std::array<Real64, Window::maxPolyCoef>> AbsBeamCoef; // Coefficients of incidence-angle polynomial for solar
221 : // absorptance for each solid glazing layer
222 : Array1D<std::array<Real64, Window::maxPolyCoef>> AbsBeamBackCoef; // As for AbsBeamCoef but for back-incident solar
223 : std::array<Real64, Window::maxPolyCoef> AbsBeamShadeCoef = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // Shade abs inc-angle coefs
224 : Real64 TransDiff = 0.0; // Diffuse solar transmittance, bare glass or shade on
225 : Real64 TransDiffVis; // Diffuse visible transmittance, bare glass or shade on
226 : Real64 ReflectSolDiffBack = 0.0; // Diffuse back solar reflectance, bare glass or shade on
227 : Real64 ReflectSolDiffFront = 0.0; // Diffuse front solar reflectance, bare glass or shade on
228 : Real64 ReflectVisDiffBack = 0.0; // Diffuse back visible reflectance, bare glass or shade on
229 : Real64 ReflectVisDiffFront = 0.0; // Diffuse front visible reflectance, bare glass or shade on
230 : std::array<Real64, Window::maxPolyCoef> TransSolBeamCoef = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // beam sol trans inc-angle coefs
231 : std::array<Real64, Window::maxPolyCoef> TransVisBeamCoef = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // beam vis trans inc-angle coefs
232 : std::array<Real64, Window::maxPolyCoef> ReflSolBeamFrontCoef = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // beam sol ref front inc-angle coefs
233 : std::array<Real64, Window::maxPolyCoef> ReflSolBeamBackCoef = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // beam sol ref back inc-angle coefs
234 : Array1D<std::array<Real64, Window::maxPolyCoef>> tBareSolCoef; // Isolated glass solar transmittance coeffs of inc. angle polynomial
235 : Array1D<std::array<Real64, Window::maxPolyCoef>> tBareVisCoef; // Isolated glass visible transmittance coeffs of inc. angle polynomial
236 : Array1D<std::array<Real64, Window::maxPolyCoef>> rfBareSolCoef; // Isolated glass front solar reflectance coeffs of inc. angle polynomial
237 : Array1D<std::array<Real64, Window::maxPolyCoef>> rfBareVisCoef; // Isolated glass front visible reflectance coeffs of inc. angle polynomial
238 : Array1D<std::array<Real64, Window::maxPolyCoef>> rbBareSolCoef; // Isolated glass back solar reflectance coeffs of inc. angle polynomial
239 : Array1D<std::array<Real64, Window::maxPolyCoef>> rbBareVisCoef; // Isolated glass back visible reflectance coeffs of inc. angle polynomial
240 : Array1D<std::array<Real64, Window::maxPolyCoef>> afBareSolCoef; // Isolated glass front solar absorptance coeffs of inc. angle polynomial
241 : Array1D<std::array<Real64, Window::maxPolyCoef>> abBareSolCoef; // Isolated glass back solar absorptance coeffs of inc. angle polynomial
242 : Array1D<Real64> tBareSolDiff; // Isolated glass diffuse solar transmittance
243 : Array1D<Real64> tBareVisDiff; // Isolated glass diffuse visible transmittance
244 : Array1D<Real64> rfBareSolDiff; // Isolated glass diffuse solar front reflectance
245 : Array1D<Real64> rfBareVisDiff; // Isolated glass diffuse visible front reflectance
246 : Array1D<Real64> rbBareSolDiff; // Isolated glass diffuse solar back reflectance
247 : Array1D<Real64> rbBareVisDiff; // Isolated glass diffuse visible back reflectance
248 : Array1D<Real64> afBareSolDiff; // Isolated glass diffuse solar front absorptance
249 : Array1D<Real64> abBareSolDiff; // Isolated glass diffuse solar back absorptance
250 : bool FromWindow5DataFile = false; // True if this is a window construction extracted from the Window5 data file
251 : Real64 W5FileMullionWidth = 0.0; // Width of mullion for construction from Window5 data file (m)
252 : DataWindowEquivalentLayer::Orientation W5FileMullionOrientation =
253 : DataWindowEquivalentLayer::Orientation::Invalid; // Orientation of mullion, if present, for Window5 data file construction,
254 : Real64 W5FileGlazingSysWidth = 0.0; // Glass width for construction from Window5 data file (m)
255 : Real64 W5FileGlazingSysHeight = 0.0; // Glass height for construction form Window5 data file (m)
256 : Real64 SummerSHGC = 0.0; // Calculated ASHRAE SHGC for summer conditions
257 : Real64 VisTransNorm = 0.0; // The normal visible transmittance
258 : Real64 SolTransNorm = 0.0; // the normal solar transmittance
259 : bool SourceSinkPresent = false; // .TRUE. if there is a source/sink within this construction
260 : bool TypeIsWindow = false; // True if a window construction, false otherwise
261 : bool WindowTypeBSDF = false; // True for complex window, false otherwise
262 : bool TypeIsEcoRoof = false; // -- true for construction with ecoRoof outside, the flag
263 : //-- is turned on when the outside layer is of type EcoRoof
264 : bool TypeIsIRT = false; // -- true for construction with IRT material
265 : bool TypeIsCfactorWall = false; // -- true for construction with Construction:CfactorUndergroundWall
266 : bool TypeIsFfactorFloor = false; // -- true for construction with Construction:FfactorGroundFloor
267 :
268 : // Added TH 12/22/2008 for thermochromic windows
269 : bool isTCWindow = false;
270 : bool isTCMaster = false;
271 : int TCMasterConstrNum = 0; // The master TC construction referenced by its slave constructions
272 : int TCMasterMatNum = 0; // The master TC material
273 : int TCLayerNum = 0; // Which material layer is the TC glazing, counting all material layers.
274 : int TCGlassNum = 0; // Which glass layer is the TC glazing, counting from glass layers only.
275 : int numTCChildConstrs;
276 : Array1D<TCLayer> TCChildConstrs;
277 : Real64 specTemp;
278 :
279 : // For CFactor underground walls
280 : Real64 CFactor = 0.0;
281 : Real64 Height = 0.0;
282 : // For FFactor slabs-on-grade or underground floors
283 : Real64 FFactor = 0.0;
284 : Real64 Area = 0.0;
285 : Real64 PerimeterExposed = 0.0;
286 : bool ReverseConstructionNumLayersWarning = false;
287 : bool ReverseConstructionLayersOrderWarning = false;
288 : // Complex Fenestration
289 : DataBSDFWindow::BSDFWindowInputStruct BSDFInput; // nest structure with user input for complex fenestration
290 : // EquivalentLayer Window
291 : bool WindowTypeEQL = false; // True for equivalent layer window, false otherwise
292 : int EQLConsPtr = 0; // Pointer to equivalent Layer window construction
293 : Array1D<Real64> AbsDiffFrontEQL; // Diffuse layer system front absorptance for EQL window
294 : Array1D<Real64> AbsDiffBackEQL; // Diffuse layer system back absorptance for EQL window
295 : Real64 TransDiffFrontEQL = 0.0; // Diffuse system front transmittance for EQL window
296 : Real64 TransDiffBackEQL = 0.0; // Diffuse system back transmittance for EQL window
297 : // Air boundary
298 : bool TypeIsAirBoundary = false; // true for Construction:AirBoundary
299 : bool TypeIsAirBoundaryMixing = false; // true for Construction:AirBoundary with SimpleMixing for air exchange
300 : Real64 AirBoundaryACH = 0.0; // Air boundary simple mixing air changes per hour [1/hr]
301 : Sched::Schedule *airBoundaryMixingSched = nullptr; // Air boundary simple mixing schedule index
302 :
303 : int rcmax = 0; // Total number of nodes in the construct (<= MaxTotNodes)
304 : Array2D<Real64> AExp; // Exponential of AMat
305 : Array2D<Real64> AInv; // Inverse of AMat
306 : Array2D<Real64> AMat; // "A" matrix from Seem's dissertation (constant coefficients of linear system)
307 : Array1D<Real64> BMat; // "B" matrix of state space method (non-zero elements)
308 : Array1D<Real64> CMat; // "C" matrix of state space method (non-zero elements)
309 : Array1D<Real64> DMat; // "D" matrix of state space method (non-zero elements)
310 : Array1D<Real64> e; // Coefficients for the surface flux history term
311 : Array2D<Real64> Gamma1; // Intermediate calculation array corresponding to a term in Seem's dissertation
312 : Array2D<Real64> Gamma2; // Intermediate calculation array corresponding to a term in Seem's dissertation
313 : Array3D<Real64> s; // Coefficients for the surface temperature history terms
314 : Array2D<Real64> s0; // Coefficients for the current surface temperature terms
315 : Array2D<Real64> IdenMatrix; // Identity Matrix
316 : int NumOfPerpendNodes = 7; // Number of nodes in the direction
317 : // perpendicular to the main direction of heat transfer. This is only used
318 : // when a two-dimensional solution has been requested for a construction
319 : // with a heat source/sink.
320 : int NodeSource = 0; // Node at which a source or sink is present
321 : int NodeUserTemp = 0; // Node where user wishes to calculate a temperature (for constructions with sources/sinks only)
322 :
323 : // Default Constructor
324 891 : ConstructionProps()
325 1782 : : LayerPoint(MaxLayersInConstruct, 0), TransDiffVis(0.0), tBareSolDiff(5, 0.0), tBareVisDiff(5, 0.0), rfBareSolDiff(5, 0.0),
326 891 : rfBareVisDiff(5, 0.0), rbBareSolDiff(5, 0.0), rbBareVisDiff(5, 0.0), afBareSolDiff(5, 0.0), abBareSolDiff(5, 0.0),
327 2673 : AbsDiffFrontEQL(DataWindowEquivalentLayer::CFSMAXNL, 0.0), AbsDiffBackEQL(DataWindowEquivalentLayer::CFSMAXNL, 0.0)
328 : {
329 891 : BMat.allocate(3);
330 891 : CMat.allocate(2);
331 891 : DMat.allocate(2);
332 891 : s0.allocate(3, 4);
333 891 : }
334 :
335 : void calculateTransferFunction(EnergyPlusData &state, bool &ErrorsFound, bool &DoCTFErrorReport);
336 :
337 : void calculateExponentialMatrix(); // Time step of the resulting CTFs
338 :
339 : void calculateInverseMatrix();
340 :
341 : void calculateGammas();
342 :
343 : void calculateFinalCoefficients();
344 :
345 : void reportTransferFunction(EnergyPlusData &state, int cCounter);
346 :
347 : void reportLayers(EnergyPlusData &state);
348 :
349 : bool isGlazingConstruction(EnergyPlusData &state) const;
350 :
351 : Real64 setThicknessPerpendicular(EnergyPlusData &state, Real64 userValue);
352 :
353 : Real64 setUserTemperatureLocationPerpendicular(EnergyPlusData &state, Real64 userValue);
354 :
355 : void setNodeSourceAndUserTemp(Array1D_int &Nodes);
356 :
357 : void setArraysBasedOnMaxSolidWinLayers(EnergyPlusData &state);
358 : };
359 : } // namespace Construction
360 :
361 : struct ConstructionData : BaseGlobalStruct
362 : {
363 : Array1D<Construction::ConstructionProps> Construct;
364 : Array1D_int LayerPoint = Array1D<int>(Construction::MaxLayersInConstruct, 0);
365 :
366 2126 : void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
367 : {
368 2126 : }
369 :
370 1152 : void init_state([[maybe_unused]] EnergyPlusData &state) override
371 : {
372 1152 : }
373 :
374 2100 : void clear_state() override
375 : {
376 2100 : new (this) ConstructionData();
377 2100 : }
378 : };
379 :
380 : } // namespace EnergyPlus
381 :
382 : #endif
|