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 : // ObjexxFCL Headers
49 : #include <ObjexxFCL/Array1D.hh>
50 :
51 : // EnergyPlus Headers
52 : #include <EnergyPlus/Data/EnergyPlusData.hh>
53 : #include <EnergyPlus/DataGlobals.hh>
54 : #include <EnergyPlus/TARCOGCommon.hh>
55 : #include <EnergyPlus/TARCOGParams.hh>
56 :
57 : namespace EnergyPlus {
58 :
59 : namespace TARCOGCommon {
60 :
61 : // MODULE INFORMATION:
62 : // AUTHOR Simon Vidanovic
63 : // DATE WRITTEN June/22/2010
64 : // MODIFIED na
65 : // RE-ENGINEERED na
66 : // Revision: 6.0.36 (June/22/2010)
67 : // - Initial setup, extracted from TARCOG.for
68 :
69 : // PURPOSE OF THIS MODULE:
70 : // A module which contains common TARCOG functions and subroutines
71 :
72 0 : Real64 LDSumMax(Real64 const Width, Real64 const Height)
73 : {
74 : // LDSumMax function calculates sum part of equation for maximum deflection
75 : // Width - glazing system width
76 : // Height - glazing system height
77 :
78 : // Using/Aliasing
79 : using namespace TARCOGParams;
80 :
81 : // Return value
82 : Real64 LDSumMax;
83 :
84 : // Locals
85 : int i;
86 : int j;
87 :
88 0 : LDSumMax = 0.0;
89 0 : for (i = 1; i <= TARCOGParams::MMax; i += 2) {
90 0 : Real64 const sin_i(std::sin(i * Constant::PiOvr2));
91 0 : Real64 const pow_i_W(pow_2(i / Width));
92 0 : for (j = 1; j <= TARCOGParams::NMax; j += 2) {
93 0 : LDSumMax += (sin_i * std::sin(j * Constant::PiOvr2)) / (i * j * pow_2(pow_i_W + pow_2(j / Height)));
94 : } // do j = 1, DeflectionParameters::NMax, 2
95 : } // do i = 1, DeflectionParameters::MMax, 2
96 :
97 0 : return LDSumMax;
98 : }
99 :
100 0 : Real64 LDSumMean(Real64 const Width, Real64 const Height)
101 : {
102 : // LDSumMean function calculates sum part of equation for mean deflection
103 : // Width - glazing system width
104 : // Height - glazing system height
105 :
106 : // Using/Aliasing
107 : using namespace TARCOGParams;
108 :
109 : // Return value
110 : Real64 LDSumMean;
111 :
112 : // Locals
113 0 : Real64 constexpr Pi_squared(Constant::Pi * Constant::Pi);
114 : int i;
115 : int j;
116 :
117 0 : LDSumMean = 0.0;
118 0 : for (i = 1; i <= TARCOGParams::MMax; i += 2) {
119 0 : Real64 const pow_i_Pi_2(i * i * Pi_squared);
120 0 : Real64 const pow_i_W(pow_2(i / Width));
121 0 : for (j = 1; j <= TARCOGParams::NMax; j += 2) {
122 0 : LDSumMean += 4.0 / (pow_i_Pi_2 * pow_2(j) * pow_2(pow_i_W + pow_2(j / Height)));
123 : } // do j = 1, DeflectionParameters::NMax, 2
124 : } // do i = 1, MMax, 2
125 :
126 0 : return LDSumMean;
127 : }
128 :
129 0 : void modifyHcGap(Array1D<Real64> const &hcgap, // Convective coefficient for gap
130 : Array1D<Real64> const &qv, // Heat flow from ventilation [W/m2]
131 : Array1D<Real64> const &hcv, // Convective heat flow coefficient due to ventilation
132 : Array1D<Real64> &hcgapMod, // Modified heat flow coefficient for gap
133 : int const nlayer, // Number of layers
134 : Real64 const edgeGlCorFac // Edge of glass correction factor
135 : )
136 : {
137 0 : for (int i = 1; i <= nlayer + 1; ++i) {
138 0 : if (qv(i) != 0) {
139 0 : hcgapMod(i) = 0.5 * hcv(i);
140 : } else {
141 0 : hcgapMod(i) = hcgap(i) * edgeGlCorFac;
142 : }
143 : }
144 0 : }
145 :
146 0 : void matrixQBalance(int const nlayer,
147 : Array2<Real64> &a,
148 : Array1D<Real64> &b,
149 : Array1D<Real64> const &sconScaled, // Solid layer coduction coefficient divided by thickness
150 : Array1D<Real64> const &hcgas,
151 : Array1D<Real64> &hcgapMod, // Modified heat flow coefficient for gap
152 : Array1D<Real64> const &asol,
153 : Array1D<Real64> const &qv,
154 : Array1D<Real64> const &hcv, // Convective heat flow coefficient due to ventilation
155 : Real64 const Tin,
156 : Real64 const Tout,
157 : Real64 const Gin,
158 : Real64 const Gout,
159 : Array1D<Real64> const &theta,
160 : Array1D<Real64> const &tir,
161 : Array1D<Real64> const &rir,
162 : Array1D<Real64> const &emis,
163 : Real64 const edgeGlCorrFac // Edge of glass correction factor
164 : )
165 : {
166 :
167 : // Using/Aliasing
168 : using namespace TARCOGParams;
169 :
170 : // Locals
171 : // local variables
172 : int i;
173 : int j;
174 : int k;
175 : int front;
176 : int back;
177 : int vent;
178 :
179 0 : for (i = 1; i <= 4 * nlayer; ++i) {
180 0 : b(i) = 0.0;
181 0 : for (j = 1; j <= 4 * nlayer; ++j) {
182 0 : a(j, i) = 0.0;
183 : }
184 : }
185 :
186 0 : modifyHcGap(hcgas, qv, hcv, hcgapMod, nlayer, edgeGlCorrFac);
187 :
188 : //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
189 : //!!!!!!!!!!!!!!!!!!!! build matrix a !!!!!!!!!!!!!!!!!!!!!!!!!
190 : //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
191 :
192 0 : for (i = 1; i <= nlayer; ++i) {
193 0 : k = 4 * i - 3;
194 0 : front = 2 * i - 1;
195 0 : back = 2 * i;
196 :
197 : // first row
198 0 : if (i != 1) {
199 0 : a(k - 1, k) = -hcgapMod(i);
200 0 : a(k - 2, k) = tir(front) - 1.0;
201 : }
202 0 : a(k, k) = hcgapMod(i) + sconScaled(i);
203 0 : a(k + 1, k) = 1.0;
204 0 : a(k + 3, k) = -sconScaled(i);
205 0 : if (i != nlayer) {
206 0 : a(k + 5, k) = -tir(back);
207 : }
208 :
209 : // second row
210 0 : a(k, k + 1) = emis(front) * Constant::StefanBoltzmann * pow_3(theta(front));
211 0 : a(k + 1, k + 1) = -1.0;
212 0 : if (i != 1) {
213 0 : a(k - 2, k + 1) = rir(front);
214 : }
215 0 : if (i != nlayer) {
216 0 : a(k + 5, k + 1) = tir(back);
217 : }
218 :
219 : // third row
220 0 : a(k + 2, k + 2) = -1.0;
221 0 : a(k + 3, k + 2) = emis(back) * Constant::StefanBoltzmann * pow_3(theta(back));
222 0 : if (i != 1) {
223 0 : a(k - 2, k + 2) = tir(front);
224 : }
225 0 : if (i != nlayer) {
226 0 : a(k + 5, k + 2) = rir(back);
227 : }
228 :
229 : // fourth row
230 0 : a(k, k + 3) = sconScaled(i);
231 0 : a(k + 2, k + 3) = -1.0;
232 0 : a(k + 3, k + 3) = -hcgapMod(i + 1) - sconScaled(i);
233 0 : if (i != 1) {
234 0 : a(k - 2, k + 3) = tir(front);
235 : }
236 0 : if (i != nlayer) {
237 0 : a(k + 4, k + 3) = hcgapMod(i + 1);
238 0 : a(k + 5, k + 3) = 1.0 - tir(back);
239 : }
240 : }
241 :
242 : // build matrix b
243 :
244 0 : for (i = 1; i <= nlayer; ++i) {
245 0 : k = 4 * i - 3;
246 0 : front = 2 * i - 1;
247 0 : back = 2 * i;
248 0 : vent = i + 1;
249 :
250 0 : b(k) = 0.5 * asol(i) + 0.5 * qv(vent - 1);
251 0 : b(k + 3) = -0.5 * asol(i) - 0.5 * qv(vent);
252 :
253 0 : if (i == 1) {
254 0 : b(k) = b(k) + hcgapMod(i) * Tout + Gout - tir(front) * Gout;
255 0 : b(k + 1) = b(k + 1) - rir(front) * Gout;
256 0 : b(k + 2) = b(k + 2) - tir(front) * Gout;
257 0 : b(k + 3) = b(k + 3) - tir(front) * Gout;
258 : }
259 :
260 0 : if (i == nlayer) {
261 0 : b(k) = b(k) + tir(back) * Gin;
262 0 : b(k + 1) = b(k + 1) - tir(back) * Gin;
263 0 : b(k + 2) = b(k + 2) - rir(back) * Gin;
264 0 : b(k + 3) = b(k + 3) - Gin - hcgapMod(i + 1) * Tin + tir(back) * Gin;
265 : }
266 : }
267 0 : }
268 :
269 0 : void EquationsSolver(EnergyPlusData &state, Array2<Real64> &a, Array1D<Real64> &b, int const n, int &nperr, std::string &ErrorMessage)
270 : {
271 : //***********************************************************************
272 : // Purpose: solves the main system of energy balance equations
273 : //***********************************************************************
274 : // Input:
275 : // a - matrix, radiositied
276 : // b - vector of known quantities
277 : // n - ???
278 : // Output:
279 : // b - solutions
280 : // nperr - error code
281 :
282 : // Using/Aliasing
283 : using namespace TARCOGParams;
284 :
285 : // Locals
286 0 : Array1D_int indx(n);
287 : Real64 d;
288 :
289 0 : ludcmp(state, a, n, indx, d, nperr, ErrorMessage);
290 :
291 : // Exit on error
292 0 : if ((nperr > 0) && (nperr <= 1000)) return;
293 :
294 0 : lubksb(a, n, indx, b);
295 0 : }
296 :
297 0 : void ludcmp(EnergyPlusData &state, Array2<Real64> &a, int const n, Array1D_int &indx, Real64 &d, int &nperr, std::string &ErrorMessage)
298 : {
299 :
300 : // Locals
301 0 : Real64 constexpr TINY(1.0e-20);
302 :
303 : int i;
304 : int imax;
305 : int j;
306 : int k;
307 : Real64 aamax;
308 : Real64 dum;
309 : Real64 sum;
310 :
311 0 : d = 1.0;
312 0 : for (i = 1; i <= n; ++i) {
313 0 : aamax = 0.0;
314 0 : for (j = 1; j <= n; ++j) {
315 0 : if (std::abs(a(j, i)) > aamax) aamax = std::abs(a(j, i));
316 : } // j
317 0 : if (aamax == 0.0) {
318 0 : nperr = 13;
319 0 : ErrorMessage = "Singular matrix in ludcmp.";
320 0 : return;
321 : }
322 0 : state.dataTARCOGCommon->vv(i) = 1.0 / aamax;
323 : } // i
324 :
325 0 : for (j = 1; j <= n; ++j) {
326 0 : for (i = 1; i <= j - 1; ++i) {
327 0 : sum = a(j, i);
328 0 : for (k = 1; k <= i - 1; ++k) {
329 0 : sum -= a(k, i) * a(j, k);
330 : } // k
331 0 : a(j, i) = sum;
332 : } // i
333 0 : aamax = 0.0;
334 0 : for (i = j; i <= n; ++i) {
335 0 : sum = a(j, i);
336 0 : for (k = 1; k <= j - 1; ++k) {
337 0 : sum -= a(k, i) * a(j, k);
338 : } // k
339 0 : a(j, i) = sum;
340 0 : dum = state.dataTARCOGCommon->vv(i) * std::abs(sum);
341 0 : if (dum >= aamax) {
342 0 : imax = i;
343 0 : aamax = dum;
344 : }
345 : } // i
346 0 : if (j != imax) {
347 0 : for (k = 1; k <= n; ++k) {
348 0 : dum = a(k, imax);
349 0 : a(k, imax) = a(k, j);
350 0 : a(k, j) = dum;
351 : } // k
352 0 : d = -d;
353 0 : state.dataTARCOGCommon->vv(imax) = state.dataTARCOGCommon->vv(j);
354 : }
355 0 : indx(j) = imax;
356 0 : if (a(j, j) == 0.0) a(j, j) = TINY;
357 0 : if (j != n) {
358 0 : dum = 1.0 / a(j, j);
359 0 : for (i = j + 1; i <= n; ++i) {
360 0 : a(j, i) *= dum;
361 : } // i
362 : }
363 : } // j
364 : }
365 :
366 0 : void lubksb(Array2A<Real64> const a, int const n, const Array1D_int &indx, Array1D<Real64> &b)
367 : {
368 : // Argument array dimensioning
369 0 : a.dim(n, n);
370 0 : EP_SIZE_CHECK(indx, n);
371 0 : EP_SIZE_CHECK(b, n);
372 :
373 : // Locals
374 : int i;
375 : int ii;
376 : int j;
377 : int ll;
378 : Real64 sum;
379 :
380 0 : ii = 0;
381 0 : for (i = 1; i <= n; ++i) {
382 0 : ll = indx(i);
383 0 : sum = b(ll);
384 0 : b(ll) = b(i);
385 0 : if (ii != 0) {
386 0 : for (j = ii; j <= i - 1; ++j) {
387 0 : sum -= a(j, i) * b(j);
388 : } // j
389 0 : } else if (sum != 0.0) {
390 0 : ii = i;
391 : }
392 0 : b(i) = sum;
393 : } // i
394 :
395 0 : for (i = n; i >= 1; --i) {
396 0 : sum = b(i);
397 0 : for (j = i + 1; j <= n; ++j) {
398 0 : sum -= a(j, i) * b(j);
399 : } // j
400 0 : b(i) = sum / a(i, i);
401 : } // i
402 0 : }
403 :
404 0 : Real64 pos(Real64 const x)
405 : {
406 0 : return (x + std::abs(x)) / 2.0;
407 : }
408 :
409 : } // namespace TARCOGCommon
410 :
411 : } // namespace EnergyPlus
|