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