Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Fmath.hh>
53 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/Data/EnergyPlusData.hh>
56 : #include <EnergyPlus/DataEnvironment.hh>
57 : #include <EnergyPlus/DataHVACGlobals.hh>
58 : #include <EnergyPlus/DataHeatBalSurface.hh>
59 : #include <EnergyPlus/DataHeatBalance.hh>
60 : #include <EnergyPlus/DataIPShortCuts.hh>
61 : #include <EnergyPlus/DataSurfaces.hh>
62 : #include <EnergyPlus/EMSManager.hh>
63 : #include <EnergyPlus/General.hh>
64 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
65 : #include <EnergyPlus/OutputProcessor.hh>
66 : #include <EnergyPlus/Psychrometrics.hh>
67 : #include <EnergyPlus/ScheduleManager.hh>
68 : #include <EnergyPlus/ThermalChimney.hh>
69 : #include <EnergyPlus/UtilityRoutines.hh>
70 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
71 :
72 : namespace EnergyPlus {
73 :
74 : namespace ThermalChimney {
75 : // Module containing the data for Thermal Chimney system
76 :
77 : // MODULE INFORMATION:
78 : // AUTHOR Kwang Ho Lee
79 : // DATE WRITTEN April 2008
80 : // MODIFIED na
81 : // RE-ENGINEERED na
82 :
83 : // PURPOSE OF THIS MODULE:
84 : // To encapsulate the data and algorithyms required to manage the ThermalChimney System Component
85 :
86 : // METHODOLOGY EMPLOYED:
87 : // na
88 :
89 : // REFERENCES:
90 : // 1. N. K. Bansal, R. Mathur and M. S. Bhandari, "Solar Chimney for Enhanced Stack Ventilation",
91 : // Building and Environment, 28, pp. 373-377, 1993
92 : // 2. K. S. Ong, "A Mathematical Model of a Solar Chimney", Renewable Energy, 28, pp. 1047-1060, 2003
93 : // 3. J. Marti-Herrero and M. R. Heras-Celemin, "Dynamic Physical Model for a Solar Chimney",
94 : // Solar Energy, 81, pp. 614-622, 2007
95 :
96 : // OTHER NOTES: none
97 :
98 : // Using/Aliasing
99 : using namespace DataEnvironment;
100 : using namespace DataHeatBalance;
101 : using namespace DataSurfaces;
102 : using namespace DataHeatBalSurface;
103 :
104 : // Use statements for access to subroutines in other modules
105 : using namespace Psychrometrics;
106 :
107 3728073 : void ManageThermalChimney(EnergyPlusData &state)
108 : {
109 :
110 : // SUBROUTINE INFORMATION:
111 : // AUTHOR Kwang Ho Lee
112 : // DATE WRITTEN April 2008
113 : // MODIFIED na
114 : // RE-ENGINEERED na
115 :
116 : // PURPOSE OF THIS SUBROUTINE:
117 : // This subroutine manages the simulation of ThermalChimney unit.
118 : // This driver manages the calls to all of
119 : // the other drivers and simulation algorithms.
120 :
121 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
122 3728073 : bool ErrorsFound(false);
123 :
124 : // Obtains and Allocates heat balance related parameters from input file
125 3728073 : if (state.dataThermalChimneys->ThermalChimneyGetInputFlag) {
126 763 : GetThermalChimney(state, ErrorsFound);
127 763 : state.dataThermalChimneys->ThermalChimneyGetInputFlag = false;
128 : }
129 :
130 3728073 : if (state.dataThermalChimneys->TotThermalChimney == 0) return;
131 :
132 8280 : CalcThermalChimney(state);
133 :
134 8280 : ReportThermalChimney(state);
135 : }
136 :
137 763 : void GetThermalChimney(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
138 : {
139 :
140 : // SUBROUTINE INFORMATION:
141 : // AUTHOR Kwang Ho Lee
142 : // DATE WRITTEN April 2008
143 : // MODIFIED na
144 : // RE-ENGINEERED na
145 :
146 : // PURPOSE OF THIS SUBROUTINE:
147 : // This subroutine obtains input data for ThermalChimney units and
148 : // stores it in the ThermalChimney data structure.
149 :
150 : // Using/Aliasing
151 :
152 : using ScheduleManager::GetScheduleIndex;
153 :
154 : // SUBROUTINE PARAMETER DEFINITIONS:
155 763 : Real64 constexpr FlowFractionTolerance(0.0001); // Smallest deviation from unity for the sum of all fractions
156 :
157 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
158 : int NumAlpha;
159 : int NumNumber;
160 : Real64 AllRatiosSummed;
161 : int TCZoneNum; // Thermal chimney zone counter
162 : int TCZoneNum1; // Thermal chimney zone counter
163 : int IOStat;
164 : int Loop;
165 : int Loop1;
166 763 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
167 :
168 : // Following used for reporting
169 763 : state.dataThermalChimneys->ZnRptThermChim.allocate(state.dataGlobal->NumOfZones);
170 :
171 763 : cCurrentModuleObject = "ZoneThermalChimney";
172 763 : state.dataThermalChimneys->TotThermalChimney = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
173 :
174 763 : state.dataThermalChimneys->ThermalChimneySys.allocate(state.dataThermalChimneys->TotThermalChimney);
175 763 : state.dataThermalChimneys->ThermalChimneyReport.allocate(state.dataThermalChimneys->TotThermalChimney);
176 :
177 765 : for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
178 :
179 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
180 : cCurrentModuleObject,
181 : Loop,
182 2 : state.dataIPShortCut->cAlphaArgs,
183 : NumAlpha,
184 2 : state.dataIPShortCut->rNumericArgs,
185 : NumNumber,
186 : IOStat,
187 2 : state.dataIPShortCut->lNumericFieldBlanks,
188 2 : state.dataIPShortCut->lAlphaFieldBlanks,
189 2 : state.dataIPShortCut->cAlphaFieldNames,
190 2 : state.dataIPShortCut->cNumericFieldNames);
191 2 : if (Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) {
192 0 : continue;
193 : }
194 :
195 : // First Alpha is Thermal Chimney Name
196 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
197 :
198 : // Second Alpha is Zone Name
199 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr =
200 2 : Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataHeatBal->Zone);
201 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr == 0) {
202 0 : ShowSevereError(state, format("{}=\"{} invalid Zone", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
203 0 : ShowContinueError(
204 0 : state, format("invalid - not found {}=\"{}\".", state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2)));
205 0 : ErrorsFound = true;
206 2 : } else if (!state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr).HasWindow) {
207 0 : ShowSevereError(state, format("{}=\"{} invalid Zone", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
208 0 : ShowContinueError(state,
209 0 : format("...invalid - no window(s) in {}=\"{}\".",
210 0 : state.dataIPShortCut->cAlphaFieldNames(2),
211 0 : state.dataIPShortCut->cAlphaArgs(2)));
212 0 : ShowContinueError(state, "...thermal chimney zones must have window(s).");
213 0 : ErrorsFound = true;
214 : }
215 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).RealZoneName = state.dataIPShortCut->cAlphaArgs(2);
216 :
217 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).SchedName = state.dataIPShortCut->cAlphaArgs(3);
218 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
219 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr = ScheduleManager::ScheduleAlwaysOn;
220 : } else {
221 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
222 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr == 0) {
223 0 : ShowSevereError(state, format("{}=\"{} invalid data", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
224 0 : ShowContinueError(
225 : state,
226 0 : format("Invalid-not found {}=\"{}\".", state.dataIPShortCut->cAlphaFieldNames(3), state.dataIPShortCut->cAlphaArgs(3)));
227 0 : ErrorsFound = true;
228 : }
229 : }
230 :
231 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth = state.dataIPShortCut->rNumericArgs(1);
232 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth < 0.0) {
233 0 : ShowSevereError(state,
234 0 : format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
235 : cCurrentModuleObject,
236 0 : state.dataIPShortCut->cAlphaArgs(1),
237 0 : state.dataIPShortCut->cNumericFieldNames(1),
238 0 : state.dataIPShortCut->rNumericArgs(1)));
239 0 : ErrorsFound = true;
240 : }
241 :
242 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea = state.dataIPShortCut->rNumericArgs(2);
243 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea < 0.0) {
244 0 : ShowSevereError(state,
245 0 : format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
246 : cCurrentModuleObject,
247 0 : state.dataIPShortCut->cAlphaArgs(1),
248 0 : state.dataIPShortCut->cNumericFieldNames(2),
249 0 : state.dataIPShortCut->rNumericArgs(2)));
250 0 : ErrorsFound = true;
251 : }
252 :
253 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff = state.dataIPShortCut->rNumericArgs(3);
254 4 : if ((state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff <= 0.0) ||
255 2 : (state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff > 1.0)) {
256 0 : ShowSevereError(state,
257 0 : format("{}=\"{} invalid {} must be > 0 and <=1.0, entered value=[{:.2R}].",
258 : cCurrentModuleObject,
259 0 : state.dataIPShortCut->cAlphaArgs(1),
260 0 : state.dataIPShortCut->cNumericFieldNames(3),
261 0 : state.dataIPShortCut->rNumericArgs(3)));
262 0 : ErrorsFound = true;
263 : }
264 :
265 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib = NumAlpha - 3;
266 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
267 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
268 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
269 4 : state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet.allocate(
270 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
271 4 : state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow.allocate(
272 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
273 4 : state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea.allocate(
274 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
275 :
276 2 : AllRatiosSummed = 0.0;
277 4 : for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
278 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) = state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3);
279 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) =
280 2 : Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3), state.dataHeatBal->Zone);
281 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) == 0) {
282 0 : int spaceNum = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3), state.dataHeatBal->space);
283 0 : if (spaceNum > 0) {
284 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum) = spaceNum;
285 0 : int zoneNum = state.dataHeatBal->space(spaceNum).zoneNum;
286 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) = zoneNum;
287 : }
288 : }
289 :
290 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) =
291 2 : state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 1);
292 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) =
293 2 : state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 2);
294 2 : if (state.dataIPShortCut->lNumericFieldBlanks(3 * TCZoneNum + 2))
295 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) = 1.0;
296 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum) =
297 2 : state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 3);
298 :
299 : //!! Error trap for zones that do not exist or zones not in the zone the thermal chimney is in
300 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) == 0) {
301 0 : ShowSevereError(state,
302 0 : format("{}=\"{} invalid {}=\"{}\" not found.",
303 : cCurrentModuleObject,
304 0 : state.dataIPShortCut->cAlphaArgs(1),
305 0 : state.dataIPShortCut->cAlphaFieldNames(TCZoneNum + 3),
306 0 : state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3)));
307 0 : ErrorsFound = true;
308 2 : } else if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
309 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr) {
310 0 : ShowSevereError(state,
311 0 : format("{}=\"{} invalid reference {}=\"{}",
312 : cCurrentModuleObject,
313 0 : state.dataIPShortCut->cAlphaArgs(1),
314 0 : state.dataIPShortCut->cAlphaFieldNames(2),
315 0 : state.dataIPShortCut->cAlphaArgs(2)));
316 0 : ShowContinueError(state,
317 0 : format("...must not have same zone as reference= {}=\"{}\".",
318 0 : state.dataIPShortCut->cAlphaFieldNames(TCZoneNum + 3),
319 0 : state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3)));
320 0 : ErrorsFound = true;
321 : }
322 :
323 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) < 0.0) {
324 0 : ShowSevereError(state,
325 0 : format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
326 : cCurrentModuleObject,
327 0 : state.dataIPShortCut->cAlphaArgs(1),
328 0 : state.dataIPShortCut->cNumericFieldNames(3 * TCZoneNum + 1),
329 0 : state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 1)));
330 0 : ErrorsFound = true;
331 : }
332 :
333 4 : if ((state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) <= 0.0) ||
334 2 : (state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) > 1.0)) {
335 0 : ShowSevereError(state,
336 0 : format("{}=\"{} invalid {} must be > 0 and <=1.0, entered value=[{:.2R}].",
337 : cCurrentModuleObject,
338 0 : state.dataIPShortCut->cAlphaArgs(1),
339 0 : state.dataIPShortCut->cNumericFieldNames(3 * TCZoneNum + 2),
340 0 : state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 2)));
341 0 : ErrorsFound = true;
342 : }
343 :
344 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum) < 0.0) {
345 0 : ShowSevereError(state,
346 0 : format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
347 : cCurrentModuleObject,
348 0 : state.dataIPShortCut->cAlphaArgs(1),
349 0 : state.dataIPShortCut->cNumericFieldNames(3 * TCZoneNum + 3),
350 0 : state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 3)));
351 0 : ErrorsFound = true;
352 : }
353 :
354 2 : AllRatiosSummed += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum);
355 :
356 : } // DO TCZoneNum = 1, ThermalChimneySys(Loop)%TotZoneToDistrib
357 :
358 : // Error trap if the sum of fractions is not equal to 1.0
359 2 : if (std::abs(AllRatiosSummed - 1.0) > FlowFractionTolerance) {
360 0 : ShowSevereError(state,
361 0 : format("{}=\"{} invalid sum of fractions, must be =1.0, entered value (summed from entries)=[{:.4R}].",
362 : cCurrentModuleObject,
363 0 : state.dataIPShortCut->cAlphaArgs(1),
364 : AllRatiosSummed));
365 0 : ErrorsFound = true;
366 : }
367 :
368 : } // DO Loop=1, TotThermalChimney
369 :
370 : // check infiltration output
371 : // setup zone-level infiltration reports
372 763 : Array1D_bool RepVarSet;
373 763 : RepVarSet.dimension(state.dataGlobal->NumOfZones, true);
374 4284 : for (Loop = 1; Loop <= state.dataHeatBal->TotInfiltration; ++Loop) {
375 3521 : int zoneNum = state.dataHeatBal->Infiltration(Loop).ZonePtr;
376 3521 : if (zoneNum > 0 && !state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) {
377 3520 : RepVarSet(zoneNum) = false;
378 : }
379 : }
380 : // Set up the output variables for thermal chimneys
381 765 : for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
382 4 : SetupOutputVariable(state,
383 : "Zone Thermal Chimney Current Density Air Volume Flow Rate",
384 : Constant::Units::m3_s,
385 2 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow,
386 : OutputProcessor::TimeStepType::System,
387 : OutputProcessor::StoreType::Average,
388 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
389 4 : SetupOutputVariable(state,
390 : "Zone Thermal Chimney Standard Density Air Volume Flow Rate",
391 : Constant::Units::m3_s,
392 2 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd,
393 : OutputProcessor::TimeStepType::System,
394 : OutputProcessor::StoreType::Average,
395 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
396 4 : SetupOutputVariable(state,
397 : "Zone Thermal Chimney Mass Flow Rate",
398 : Constant::Units::kg_s,
399 2 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow,
400 : OutputProcessor::TimeStepType::System,
401 : OutputProcessor::StoreType::Average,
402 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
403 4 : SetupOutputVariable(state,
404 : "Zone Thermal Chimney Outlet Temperature",
405 : Constant::Units::C,
406 2 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim,
407 : OutputProcessor::TimeStepType::System,
408 : OutputProcessor::StoreType::Average,
409 2 : state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
410 :
411 2 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
412 0 : SetupEMSActuator(state,
413 : "Zone Thermal Chimney",
414 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).Name,
415 : "Air Exchange Flow Rate",
416 : "[m3/s]",
417 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).EMSOverrideOn,
418 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).EMSAirFlowRateValue);
419 : }
420 :
421 4 : for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
422 4 : SetupOutputVariable(state,
423 : "Zone Thermal Chimney Heat Loss Energy",
424 : Constant::Units::J,
425 2 : state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
426 2 : .ThermalChimneyHeatLoss,
427 : OutputProcessor::TimeStepType::System,
428 : OutputProcessor::StoreType::Sum,
429 2 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
430 4 : SetupOutputVariable(state,
431 : "Zone Thermal Chimney Heat Gain Energy",
432 : Constant::Units::J,
433 2 : state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
434 2 : .ThermalChimneyHeatGain,
435 : OutputProcessor::TimeStepType::System,
436 : OutputProcessor::StoreType::Sum,
437 2 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
438 4 : SetupOutputVariable(state,
439 : "Zone Thermal Chimney Volume",
440 : Constant::Units::m3,
441 2 : state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
442 2 : .ThermalChimneyVolume,
443 : OutputProcessor::TimeStepType::System,
444 : OutputProcessor::StoreType::Sum,
445 2 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
446 4 : SetupOutputVariable(state,
447 : "Zone Thermal Chimney Mass",
448 : Constant::Units::kg,
449 2 : state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
450 2 : .ThermalChimneyMass,
451 : OutputProcessor::TimeStepType::System,
452 : OutputProcessor::StoreType::Sum,
453 2 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
454 2 : if (RepVarSet(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))) {
455 0 : SetupOutputVariable(
456 : state,
457 : "Zone Infiltration Sensible Heat Loss Energy",
458 : Constant::Units::J,
459 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilHeatLoss,
460 : OutputProcessor::TimeStepType::System,
461 : OutputProcessor::StoreType::Sum,
462 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
463 0 : SetupOutputVariable(
464 : state,
465 : "Zone Infiltration Sensible Heat Gain Energy",
466 : Constant::Units::J,
467 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilHeatGain,
468 : OutputProcessor::TimeStepType::System,
469 : OutputProcessor::StoreType::Sum,
470 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
471 0 : SetupOutputVariable(
472 : state,
473 : "Zone Infiltration Latent Heat Loss Energy",
474 : Constant::Units::J,
475 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilLatentLoss,
476 : OutputProcessor::TimeStepType::System,
477 : OutputProcessor::StoreType::Sum,
478 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
479 0 : SetupOutputVariable(
480 : state,
481 : "Zone Infiltration Latent Heat Gain Energy",
482 : Constant::Units::J,
483 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilLatentGain,
484 : OutputProcessor::TimeStepType::System,
485 : OutputProcessor::StoreType::Sum,
486 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
487 0 : SetupOutputVariable(
488 : state,
489 : "Zone Infiltration Total Heat Loss Energy",
490 : Constant::Units::J,
491 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilTotalLoss,
492 : OutputProcessor::TimeStepType::System,
493 : OutputProcessor::StoreType::Sum,
494 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
495 0 : SetupOutputVariable(
496 : state,
497 : "Zone Infiltration Total Heat Gain Energy",
498 : Constant::Units::J,
499 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilTotalGain,
500 : OutputProcessor::TimeStepType::System,
501 : OutputProcessor::StoreType::Sum,
502 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
503 0 : SetupOutputVariable(
504 : state,
505 : "Zone Infiltration Current Density Volume Flow Rate",
506 : Constant::Units::m3_s,
507 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVdotCurDensity,
508 : OutputProcessor::TimeStepType::System,
509 : OutputProcessor::StoreType::Average,
510 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
511 0 : SetupOutputVariable(
512 : state,
513 : "Zone Infiltration Standard Density Volume Flow Rate",
514 : Constant::Units::m3_s,
515 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVdotStdDensity,
516 : OutputProcessor::TimeStepType::System,
517 : OutputProcessor::StoreType::Average,
518 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
519 0 : SetupOutputVariable(
520 : state,
521 : "Zone Infiltration Current Density Volume",
522 : Constant::Units::m3,
523 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVolumeCurDensity,
524 : OutputProcessor::TimeStepType::System,
525 : OutputProcessor::StoreType::Sum,
526 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
527 0 : SetupOutputVariable(
528 : state,
529 : "Zone Infiltration Standard Density Volume",
530 : Constant::Units::m3,
531 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVolumeStdDensity,
532 : OutputProcessor::TimeStepType::System,
533 : OutputProcessor::StoreType::Sum,
534 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
535 0 : SetupOutputVariable(state,
536 : "Zone Infiltration Mass",
537 : Constant::Units::kg,
538 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilMass,
539 : OutputProcessor::TimeStepType::System,
540 : OutputProcessor::StoreType::Sum,
541 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
542 0 : SetupOutputVariable(state,
543 : "Zone Infiltration Mass Flow Rate",
544 : Constant::Units::kg_s,
545 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilMdot,
546 : OutputProcessor::TimeStepType::System,
547 : OutputProcessor::StoreType::Average,
548 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
549 0 : SetupOutputVariable(
550 : state,
551 : "Zone Infiltration Air Change Rate",
552 : Constant::Units::ach,
553 0 : state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilAirChangeRate,
554 : OutputProcessor::TimeStepType::System,
555 : OutputProcessor::StoreType::Average,
556 0 : state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
557 0 : RepVarSet(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)) = false;
558 : }
559 : } // DO TCZoneNum = 1, ThermalChimneySys(Loop)%TotZoneToDistrib
560 : } // DO Loop=1, TotThermalChimney
561 :
562 : //! LKL-more renaming effort and code review might be possible here
563 : // Check to make sure there is only one thermal chimney statement per zone
564 765 : for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
565 2 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib > 1) {
566 0 : for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
567 :
568 0 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib >= (TCZoneNum + 1)) {
569 0 : for (TCZoneNum1 = TCZoneNum + 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib;
570 : ++TCZoneNum1) {
571 0 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
572 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum1)) {
573 0 : ShowSevereError(state,
574 0 : format("Only one ZoneThermalChimney object allowed per zone but zone {} has two ZoneThermalChimney "
575 : "objects associated with it",
576 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum)));
577 0 : ErrorsFound = true;
578 : }
579 : }
580 0 : for (TCZoneNum1 = 1; TCZoneNum1 <= TCZoneNum - 1; ++TCZoneNum1) {
581 0 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
582 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum1)) {
583 0 : ShowSevereError(state,
584 0 : format("Only one ZoneThermalChimney object allowed per zone but zone {} has two ZoneThermalChimney "
585 : "objects associated with it",
586 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum)));
587 0 : ErrorsFound = true;
588 : }
589 : }
590 : } else { // IF ( ThermalChimneySys(Loop)%TotZoneToDistrib >= (TCZoneNum+1) ) THEN
591 0 : for (TCZoneNum1 = 1; TCZoneNum1 <= TCZoneNum - 1; ++TCZoneNum1) {
592 0 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
593 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum1)) {
594 0 : ShowSevereError(state,
595 0 : format("Only one ZoneThermalChimney object allowed per zone but zone {} has two ZoneThermalChimney "
596 : "objects associated with it",
597 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum)));
598 0 : ErrorsFound = true;
599 : }
600 : }
601 : } // IF ( ThermalChimneySys(Loop)%TotZoneToDistrib >= (TCZoneNum+1) ) THEN
602 :
603 : } // DO TCZoneNum = 1, ThermalChimneySys(Loop)%TotZoneToDistrib
604 : } // IF (ThermalChimneySys(Loop)%TotZoneToDistrib > 1) THEN
605 : } // DO Loop = 1, TotThermalChimney
606 :
607 : // Check to make sure there is only one thermal chimney statement per zone
608 763 : if (state.dataThermalChimneys->TotThermalChimney > 1) {
609 3 : for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
610 :
611 2 : if (state.dataThermalChimneys->TotThermalChimney >= (Loop + 1)) {
612 2 : for (Loop1 = Loop + 1; Loop1 <= state.dataThermalChimneys->TotThermalChimney; ++Loop1) {
613 2 : for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
614 2 : for (TCZoneNum1 = 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop1).TotZoneToDistrib; ++TCZoneNum1) {
615 1 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
616 1 : state.dataThermalChimneys->ThermalChimneySys(Loop1).ZonePtr(TCZoneNum1)) {
617 0 : ShowSevereError(state,
618 0 : format("Only one ZoneThermalChimney object allowed per zone but zone {} has two "
619 : "ZoneThermalChimney objects associated with it",
620 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum)));
621 0 : ErrorsFound = true;
622 : }
623 : }
624 : }
625 : }
626 1 : for (Loop1 = 1; Loop1 <= Loop - 1; ++Loop1) {
627 0 : for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
628 0 : for (TCZoneNum1 = 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop1).TotZoneToDistrib; ++TCZoneNum1) {
629 0 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
630 0 : state.dataThermalChimneys->ThermalChimneySys(Loop1).ZonePtr(TCZoneNum1)) {
631 0 : ShowSevereError(state,
632 0 : format("Only one ZoneThermalChimney object allowed per zone but zone {} has two "
633 : "ZoneThermalChimney objects associated with it",
634 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum)));
635 0 : ErrorsFound = true;
636 : }
637 : }
638 : }
639 : }
640 : } else { // IF ( TotThermalChimney >= (Loop+1) ) THEN
641 2 : for (Loop1 = 1; Loop1 <= Loop - 1; ++Loop1) {
642 2 : for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
643 2 : for (TCZoneNum1 = 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop1).TotZoneToDistrib; ++TCZoneNum1) {
644 1 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
645 1 : state.dataThermalChimneys->ThermalChimneySys(Loop1).ZonePtr(TCZoneNum1)) {
646 0 : ShowSevereError(state,
647 0 : format("Only one ZoneThermalChimney object allowed per zone but zone {} has two "
648 : "ZoneThermalChimney objects associated with it",
649 0 : state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum)));
650 0 : ErrorsFound = true;
651 : }
652 : }
653 : }
654 : }
655 : } // IF ( TotThermalChimney >= (Loop+1) ) THEN
656 :
657 : } // DO Loop = 1, TotThermalChimney
658 : } // IF (TotThermalChimney > 1) THEN
659 :
660 763 : if (ErrorsFound) {
661 0 : ShowFatalError(state, format("{} Errors found in input. Preceding condition(s) cause termination.", cCurrentModuleObject));
662 : }
663 763 : }
664 :
665 8280 : void CalcThermalChimney(EnergyPlusData &state)
666 : {
667 :
668 : // SUBROUTINE INFORMATION:
669 : // AUTHOR Kwang Ho Lee
670 : // DATE WRITTEN April 2008
671 : // MODIFIED na
672 : // RE-ENGINEERED na
673 :
674 : // PURPOSE OF THIS SUBROUTINE:
675 : // This subroutine simulates the components making up the ThermalChimney.
676 :
677 : using ScheduleManager::GetCurrentScheduleValue;
678 :
679 8280 : int constexpr NTC(15); // Number of subregions in thermal chimney air channel for FINITE DIFFERENCE
680 :
681 : // To be obtained from other modules and subroutines
682 : Real64 SurfTempAbsorberWall; // Absorber wall surface temperature (K)
683 : Real64 SurfTempGlassCover; // Glass cover surface temperature (K)
684 : Real64 ConvTransCoeffWallFluid; // Absorber wall convection trasnfer coefficient
685 : Real64 ConvTransCoeffGlassFluid; // Glass cover convection trasnfer coefficient
686 :
687 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
688 : // Real local vaiables
689 : Real64 minorW; // width of enclosure (narrow dimension)
690 : Real64 majorW; // width of major surface
691 : Real64 TempmajorW;
692 :
693 : Real64 RoomAirTemp;
694 : Real64 AirSpecHeatThermalChim; // (J/kg*C) or (J/kg*K)
695 : Real64 AbsorberWallWidthTC;
696 : Real64 TCVolumeAirFlowRate; // (m^3/s)
697 : Real64 TCMassAirFlowRate; // (kg/s)
698 : Real64 DischargeCoeffTC;
699 : Real64 AirOutletCrossAreaTC;
700 : Real64 AirInletCrossArea;
701 : Real64 AirRelativeCrossArea;
702 : // REAL(r64) :: OutletAirTempThermalChim
703 : Real64 OverallThermalChimLength;
704 : Real64 ThermChimTolerance;
705 8280 : Array1D<Real64> TempTCMassAirFlowRate(10); // Temporary Value of Thermal Chimney Mass Flow Rate ()
706 8280 : Array1D<Real64> TempTCVolumeAirFlowRate(10); // Temporary Value of Thermal Chimney Volume Flow Rate ()
707 : int IterationLoop;
708 : Real64 Process1; // Temporary Variable Used in the Middle of the Calculation
709 : Real64 Process2; // Temporary Variable Used in the Middle of the Calculation
710 : Real64 Process3; // Temporary Variable Used in the Middle of the Calculation
711 : // unused1208 REAL(r64) :: Process4 ! Temporary Variable Used in the Middle of the Calculation
712 : Real64 AirDensityThermalChim; // (kg/m^3)
713 : Real64 AirDensity; // (kg/m^3)
714 : Real64 CpAir;
715 : Real64 TemporaryWallSurfTemp;
716 :
717 : Real64 DeltaL; // OverallThermalChimLength / NTC
718 : int ThermChimLoop1;
719 : int ThermChimLoop2;
720 16560 : Array2D<Real64> EquaCoef(NTC, NTC); // Coefficients in Linear Algebraic Euqation for FINITE DIFFERENCE
721 8280 : Array1D<Real64> EquaConst(NTC); // Constants in Linear Algebraic Equation for FINITE DIFFERENCE
722 8280 : Array1D<Real64> ThermChimSubTemp(NTC); // Air temperature of each thermal chimney air channel subregion
723 :
724 24840 : for (int Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
725 :
726 16560 : int ZoneNum = state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr;
727 16560 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
728 : // start off with first surface in zone widths
729 16560 : int firstSpaceHTSurfaceFirst = state.dataHeatBal->space(state.dataHeatBal->Zone(ZoneNum).spaceIndexes(1)).HTSurfaceFirst;
730 16560 : majorW = state.dataSurface->Surface(firstSpaceHTSurfaceFirst).Width;
731 16560 : minorW = majorW;
732 16560 : TempmajorW = 0.0;
733 16560 : TemporaryWallSurfTemp = -10000.0;
734 :
735 : // determine major width and minor width
736 33120 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
737 16560 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
738 149040 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
739 132480 : if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Wall) continue;
740 :
741 82800 : if (state.dataSurface->Surface(SurfNum).Width > majorW) {
742 0 : majorW = state.dataSurface->Surface(SurfNum).Width;
743 : }
744 :
745 82800 : if (state.dataSurface->Surface(SurfNum).Width < minorW) {
746 16560 : minorW = state.dataSurface->Surface(SurfNum).Width;
747 : }
748 : }
749 :
750 149040 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
751 132480 : if (state.dataSurface->Surface(SurfNum).Width == majorW) {
752 66240 : if (state.dataHeatBalSurf->SurfTempIn(SurfNum) > TemporaryWallSurfTemp) {
753 33221 : TemporaryWallSurfTemp = state.dataHeatBalSurf->SurfTempIn(SurfNum);
754 33221 : ConvTransCoeffWallFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
755 33221 : SurfTempAbsorberWall = state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin;
756 : }
757 : }
758 : }
759 :
760 149040 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
761 132480 : if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) {
762 16560 : if (state.dataSurface->Surface(SurfNum).Width > TempmajorW) {
763 16560 : TempmajorW = state.dataSurface->Surface(SurfNum).Width;
764 16560 : ConvTransCoeffGlassFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
765 16560 : SurfTempGlassCover = state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin;
766 : }
767 : }
768 : }
769 16560 : }
770 :
771 16560 : AbsorberWallWidthTC = majorW;
772 16560 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth != majorW) {
773 16560 : AbsorberWallWidthTC = state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth;
774 : }
775 :
776 16560 : AirDensityThermalChim = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRat);
777 16560 : AirSpecHeatThermalChim = PsyCpAirFnW(thisZoneHB.airHumRat);
778 16560 : AirOutletCrossAreaTC = state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea;
779 16560 : DischargeCoeffTC = state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff;
780 :
781 16560 : AirInletCrossArea = 0.0;
782 33120 : for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
783 16560 : AirInletCrossArea += state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum);
784 : }
785 :
786 16560 : RoomAirTemp = 0.0;
787 33120 : for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
788 16560 : int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum);
789 16560 : if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) {
790 0 : RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) *
791 0 : state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr).MAT;
792 : } else {
793 16560 : int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
794 16560 : RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) *
795 16560 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr).MAT;
796 : }
797 : }
798 16560 : RoomAirTemp += Constant::Kelvin;
799 :
800 16560 : Process1 = 0.0;
801 16560 : Process2 = 0.0;
802 33120 : for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
803 16560 : int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
804 16560 : auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr);
805 16560 : Real64 tcZoneMAT = thisTCZoneHB.MAT;
806 16560 : Real64 tcZoneHumRat = thisTCZoneHB.airHumRat;
807 16560 : int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum);
808 16560 : if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) {
809 0 : auto &thisTCspaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr);
810 0 : tcZoneMAT = thisTCspaceHB.MAT;
811 0 : tcZoneHumRat = thisTCspaceHB.airHumRat;
812 : }
813 16560 : Real64 tcZoneEnth = PsyHFnTdbW(tcZoneMAT, tcZoneHumRat);
814 16560 : Process1 += tcZoneEnth * state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) *
815 16560 : state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum);
816 16560 : Process2 += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * tcZoneEnth;
817 : }
818 16560 : OverallThermalChimLength = Process1 / Process2;
819 :
820 16560 : DeltaL = OverallThermalChimLength / NTC;
821 :
822 : // Starting the iteration for mass and volumetric flow rate calculation
823 16560 : ThermChimTolerance = 10000000.0; // An impossibly big tolerance
824 182160 : for (IterationLoop = 1; IterationLoop <= 10; ++IterationLoop) {
825 :
826 165600 : if (IterationLoop == 1) {
827 16560 : TempTCMassAirFlowRate(IterationLoop) = 0.05; // Inital Guess
828 :
829 : } else {
830 149040 : TempTCMassAirFlowRate(IterationLoop) = TempTCVolumeAirFlowRate(IterationLoop - 1) * AirDensityThermalChim;
831 :
832 149040 : if (std::abs(TempTCMassAirFlowRate(IterationLoop) - TempTCMassAirFlowRate(IterationLoop - 1)) < ThermChimTolerance) {
833 99602 : ThermChimTolerance = std::abs(TempTCMassAirFlowRate(IterationLoop) - TempTCMassAirFlowRate(IterationLoop - 1));
834 99602 : TCMassAirFlowRate = TempTCMassAirFlowRate(IterationLoop);
835 99602 : TCVolumeAirFlowRate = TempTCVolumeAirFlowRate(IterationLoop);
836 : }
837 :
838 : } // IF (IterationLoop == 1) THEN
839 :
840 : // Calculation of Thermal Chimney Discharge Air Temperature
841 331200 : Process1 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid -
842 165600 : 2.0 * TempTCMassAirFlowRate(IterationLoop) * AirSpecHeatThermalChim;
843 331200 : Process2 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid +
844 165600 : 2.0 * TempTCMassAirFlowRate(IterationLoop) * AirSpecHeatThermalChim;
845 165600 : Process3 = 2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid * SurfTempGlassCover +
846 165600 : 2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid * SurfTempAbsorberWall;
847 :
848 2649600 : for (ThermChimLoop1 = 1; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
849 39744000 : for (ThermChimLoop2 = 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
850 37260000 : EquaCoef(ThermChimLoop2, ThermChimLoop1) = 0.0;
851 : }
852 : }
853 :
854 165600 : EquaCoef(1, 1) = Process2;
855 165600 : EquaConst(1) = Process3 - Process1 * RoomAirTemp;
856 2484000 : for (ThermChimLoop1 = 2; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
857 2318400 : EquaCoef((ThermChimLoop1 - 1), ThermChimLoop1) = Process1;
858 2318400 : EquaCoef(ThermChimLoop1, ThermChimLoop1) = Process2;
859 2318400 : EquaConst(ThermChimLoop1) = Process3;
860 : }
861 :
862 165600 : GaussElimination(EquaCoef, EquaConst, ThermChimSubTemp, NTC);
863 :
864 165600 : AirRelativeCrossArea = AirOutletCrossAreaTC / AirInletCrossArea;
865 165600 : if (ThermChimSubTemp(NTC) <= RoomAirTemp) {
866 49530 : TempTCVolumeAirFlowRate(IterationLoop) = 0.0;
867 : } else {
868 116070 : TempTCVolumeAirFlowRate(IterationLoop) = DischargeCoeffTC * AirOutletCrossAreaTC *
869 232140 : std::sqrt(2.0 * ((ThermChimSubTemp(NTC) - RoomAirTemp) / RoomAirTemp) * 9.8 *
870 116070 : OverallThermalChimLength / pow_2(1.0 + AirRelativeCrossArea));
871 : }
872 :
873 : } // DO IterationLoop = 1,10
874 :
875 : // Calculation of Thermal Chimney Discharge Temperature
876 16560 : Process1 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid -
877 16560 : 2.0 * TCMassAirFlowRate * AirSpecHeatThermalChim;
878 16560 : Process2 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid +
879 16560 : 2.0 * TCMassAirFlowRate * AirSpecHeatThermalChim;
880 16560 : Process3 = 2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid * SurfTempGlassCover +
881 16560 : 2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid * SurfTempAbsorberWall;
882 :
883 264960 : for (ThermChimLoop1 = 1; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
884 3974400 : for (ThermChimLoop2 = 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
885 3726000 : EquaCoef(ThermChimLoop2, ThermChimLoop1) = 0.0;
886 : }
887 : }
888 :
889 16560 : EquaCoef(1, 1) = Process2;
890 16560 : EquaConst(1) = Process3 - Process1 * RoomAirTemp;
891 248400 : for (ThermChimLoop1 = 2; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
892 231840 : EquaCoef((ThermChimLoop1 - 1), ThermChimLoop1) = Process1;
893 231840 : EquaCoef(ThermChimLoop1, ThermChimLoop1) = Process2;
894 231840 : EquaConst(ThermChimLoop1) = Process3;
895 : }
896 :
897 16560 : GaussElimination(EquaCoef, EquaConst, ThermChimSubTemp, NTC);
898 :
899 16560 : AirRelativeCrossArea = AirOutletCrossAreaTC / AirInletCrossArea;
900 16560 : if (ThermChimSubTemp(NTC) <= RoomAirTemp) {
901 4953 : TCVolumeAirFlowRate = 0.0;
902 : } else {
903 23214 : TCVolumeAirFlowRate = DischargeCoeffTC * AirOutletCrossAreaTC *
904 11607 : std::sqrt(2.0 * ((ThermChimSubTemp(NTC) - RoomAirTemp) / RoomAirTemp) * 9.8 * OverallThermalChimLength /
905 11607 : pow_2(1.0 + AirRelativeCrossArea));
906 11607 : if (state.dataThermalChimneys->ThermalChimneySys(Loop).EMSOverrideOn) {
907 0 : TCVolumeAirFlowRate = state.dataThermalChimneys->ThermalChimneySys(Loop).EMSAirFlowRateValue;
908 : }
909 : }
910 :
911 : // Now assignment of the overall mass flow rate into each zone
912 33120 : for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
913 16560 : int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
914 16560 : auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr);
915 16560 : Real64 tcZoneMAT = thisTCZoneHB.MAT;
916 16560 : Real64 tcZoneHumRat = thisTCZoneHB.airHumRat;
917 16560 : int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum);
918 16560 : if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) {
919 0 : auto &thisTCSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr);
920 0 : tcZoneMAT = thisTCSpaceHB.MAT;
921 0 : tcZoneHumRat = thisTCSpaceHB.airHumRat;
922 : }
923 : // ToDo - Let this persist to avoid diffs, but should be local
924 16560 : AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, tcZoneMAT, tcZoneHumRat);
925 16560 : CpAir = PsyCpAirFnW(tcZoneHumRat);
926 : Real64 thisMCPThermChim =
927 16560 : TCVolumeAirFlowRate * AirDensity * CpAir * state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum);
928 16560 : if (thisMCPThermChim <= 0.0) {
929 4953 : thisMCPThermChim = 0.0;
930 : }
931 16560 : Real64 thisThermChimAMFL = thisMCPThermChim / CpAir;
932 16560 : Real64 thisMCPTThermChim = thisMCPThermChim * state.dataHeatBal->Zone(tcZonePtr).OutDryBulbTemp; // Only zones have an ODB temp value
933 16560 : thisTCZoneHB.MCPThermChim = thisMCPThermChim;
934 16560 : thisTCZoneHB.ThermChimAMFL = thisThermChimAMFL;
935 16560 : thisTCZoneHB.MCPTThermChim = thisMCPTThermChim;
936 16560 : if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) {
937 0 : auto &thisTCSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr);
938 0 : thisTCSpaceHB.MCPThermChim = thisMCPThermChim;
939 0 : thisTCSpaceHB.ThermChimAMFL = thisThermChimAMFL;
940 0 : thisTCSpaceHB.MCPTThermChim = thisMCPTThermChim;
941 : }
942 : }
943 :
944 : // ToDo - This should probably be using AirDensityThermalChim here instead of AirDensity which is leftover from the last inlet zone
945 16560 : thisZoneHB.MCPThermChim = TCVolumeAirFlowRate * AirDensity * CpAir;
946 16560 : if (thisZoneHB.MCPThermChim <= 0.0) {
947 4953 : thisZoneHB.MCPThermChim = 0.0;
948 : }
949 16560 : thisZoneHB.ThermChimAMFL = thisZoneHB.MCPThermChim / CpAir;
950 16560 : thisZoneHB.MCPTThermChim = thisZoneHB.MCPThermChim * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp;
951 :
952 16560 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow = TCVolumeAirFlowRate;
953 16560 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow = TCMassAirFlowRate;
954 16560 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd = TCMassAirFlowRate / state.dataEnvrn->StdRhoAir;
955 16560 : if (state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow != (TCVolumeAirFlowRate * AirDensityThermalChim)) {
956 5316 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow =
957 5316 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow * AirDensityThermalChim;
958 : }
959 16560 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim = ThermChimSubTemp(NTC) - Constant::Kelvin;
960 :
961 16560 : if (GetCurrentScheduleValue(state, state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr) <= 0.0) {
962 16560 : for (int TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
963 8280 : int tcZonePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
964 8280 : auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(tcZonePtr);
965 8280 : thisTCZoneHB.MCPThermChim = 0.0;
966 8280 : thisTCZoneHB.ThermChimAMFL = 0.0;
967 8280 : thisTCZoneHB.MCPTThermChim = 0.0;
968 8280 : int tcSpacePtr = state.dataThermalChimneys->ThermalChimneySys(Loop).spacePtr(TCZoneNum);
969 8280 : if ((state.dataHeatBal->doSpaceHeatBalance) && (tcSpacePtr > 0)) {
970 0 : auto &thisTCSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(tcSpacePtr);
971 0 : thisTCSpaceHB.MCPThermChim = 0.0;
972 0 : thisTCSpaceHB.ThermChimAMFL = 0.0;
973 0 : thisTCSpaceHB.MCPTThermChim = 0.0;
974 : }
975 : }
976 8280 : thisZoneHB.MCPThermChim = 0.0;
977 8280 : thisZoneHB.ThermChimAMFL = 0.0;
978 8280 : thisZoneHB.MCPTThermChim = 0.0;
979 8280 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow = 0.0;
980 8280 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd = 0.0;
981 8280 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow = 0.0;
982 8280 : state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim =
983 8280 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
984 : }
985 :
986 : } // DO Loop=1, TotThermalChimney
987 8280 : }
988 :
989 8280 : void ReportThermalChimney(EnergyPlusData &state)
990 : {
991 :
992 : // SUBROUTINE INFORMATION:
993 : // AUTHOR Kwang Ho Lee
994 : // DATE WRITTEN April 2008
995 : // MODIFIED na
996 : // RE-ENGINEERED na
997 :
998 : // PURPOSE OF THIS SUBROUTINE:
999 : // This subroutine fills remaining report variables.
1000 :
1001 8280 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1002 :
1003 : int ZoneLoop; // Counter for the # of zones (nz)
1004 : Real64 AirDensity;
1005 : Real64 CpAir;
1006 :
1007 41400 : for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ...
1008 33120 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop);
1009 :
1010 : // Break the infiltration load into heat gain and loss components.
1011 66240 : AirDensity = PsyRhoAirFnPbTdbW(
1012 33120 : state, state.dataEnvrn->OutBaroPress, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).MAT, thisZoneHB.airHumRat);
1013 33120 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
1014 33120 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyVolume =
1015 33120 : (thisZoneHB.MCPThermChim / CpAir / AirDensity) * TimeStepSysSec;
1016 33120 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyMass = (thisZoneHB.MCPThermChim / CpAir) * TimeStepSysSec;
1017 :
1018 33120 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = 0.0;
1019 33120 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = 0.0;
1020 :
1021 33120 : if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT > state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) {
1022 :
1023 26179 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss =
1024 52358 : thisZoneHB.MCPThermChim *
1025 26179 : (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT - state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) *
1026 : TimeStepSysSec;
1027 26179 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = 0.0;
1028 :
1029 6941 : } else if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT <= state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) {
1030 :
1031 6941 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain =
1032 13882 : thisZoneHB.MCPThermChim *
1033 6941 : (state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT) *
1034 : TimeStepSysSec;
1035 6941 : state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = 0.0;
1036 : }
1037 :
1038 : } // ... end of zone loads report variable update loop.
1039 8280 : }
1040 :
1041 182160 : void GaussElimination(Array2A<Real64> EquaCoef, Array1D<Real64> &EquaConst, Array1D<Real64> &ThermChimSubTemp, int const NTC)
1042 : {
1043 : // PURPOSE OF THIS SUBROUTINE:
1044 : // This subroutine sovles linear algebraic equations using Gauss Elimination Method.
1045 :
1046 182160 : EquaCoef.dim(NTC, NTC);
1047 182160 : EP_SIZE_CHECK(EquaConst, NTC);
1048 182160 : EP_SIZE_CHECK(ThermChimSubTemp, NTC);
1049 :
1050 182160 : Array1D<Real64> tempor(NTC);
1051 : Real64 tempb;
1052 : Real64 TCvalue;
1053 : Real64 TCcoefficient;
1054 : int pivot;
1055 : Real64 ThermalChimSum;
1056 : int ThermChimLoop1;
1057 : int ThermChimLoop2;
1058 : int ThermChimLoop3;
1059 :
1060 2914560 : for (ThermChimLoop1 = 1; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
1061 :
1062 2732400 : TCvalue = std::abs(EquaCoef(ThermChimLoop1, ThermChimLoop1));
1063 2732400 : pivot = ThermChimLoop1;
1064 21859200 : for (ThermChimLoop2 = ThermChimLoop1 + 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
1065 19126800 : if (std::abs(EquaCoef(ThermChimLoop1, ThermChimLoop2)) > TCvalue) {
1066 0 : TCvalue = std::abs(EquaCoef(ThermChimLoop1, ThermChimLoop2));
1067 0 : pivot = ThermChimLoop2;
1068 : }
1069 : }
1070 :
1071 2732400 : if (pivot != ThermChimLoop1) {
1072 0 : tempor({ThermChimLoop1, NTC}) = EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop1);
1073 0 : tempb = EquaConst(ThermChimLoop1);
1074 0 : EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop1) = EquaCoef({ThermChimLoop1, NTC}, pivot);
1075 0 : EquaConst(ThermChimLoop1) = EquaConst(pivot);
1076 0 : EquaCoef({ThermChimLoop1, NTC}, pivot) = tempor({ThermChimLoop1, NTC});
1077 0 : EquaConst(pivot) = tempb;
1078 : }
1079 :
1080 21859200 : for (ThermChimLoop2 = ThermChimLoop1 + 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
1081 19126800 : TCcoefficient = -EquaCoef(ThermChimLoop1, ThermChimLoop2) / EquaCoef(ThermChimLoop1, ThermChimLoop1);
1082 19126800 : EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop2) += TCcoefficient * EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop1);
1083 19126800 : EquaConst(ThermChimLoop2) += TCcoefficient * EquaConst(ThermChimLoop1);
1084 : }
1085 : }
1086 :
1087 182160 : ThermChimSubTemp(NTC) = EquaConst(NTC) / EquaCoef(NTC, NTC);
1088 2732400 : for (ThermChimLoop2 = NTC - 1; ThermChimLoop2 >= 1; --ThermChimLoop2) {
1089 2550240 : ThermalChimSum = 0.0;
1090 21677040 : for (ThermChimLoop3 = ThermChimLoop2 + 1; ThermChimLoop3 <= NTC; ++ThermChimLoop3) {
1091 19126800 : ThermalChimSum += EquaCoef(ThermChimLoop3, ThermChimLoop2) * ThermChimSubTemp(ThermChimLoop3);
1092 : }
1093 2550240 : ThermChimSubTemp(ThermChimLoop2) = (EquaConst(ThermChimLoop2) - ThermalChimSum) / EquaCoef(ThermChimLoop2, ThermChimLoop2);
1094 : }
1095 182160 : }
1096 :
1097 : // End of Module Subroutines for ThermalChimney
1098 :
1099 : //*****************************************************************************************
1100 :
1101 : } // namespace ThermalChimney
1102 :
1103 : } // namespace EnergyPlus
|