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/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Data/EnergyPlusData.hh>
57 : #include <EnergyPlus/DataEnvironment.hh>
58 : #include <EnergyPlus/DataHVACGlobals.hh>
59 : #include <EnergyPlus/DataHeatBalance.hh>
60 : #include <EnergyPlus/DataIPShortCuts.hh>
61 : #include <EnergyPlus/EarthTube.hh>
62 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
63 : #include <EnergyPlus/OutputProcessor.hh>
64 : #include <EnergyPlus/Psychrometrics.hh>
65 : #include <EnergyPlus/ScheduleManager.hh>
66 : #include <EnergyPlus/UtilityRoutines.hh>
67 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
68 :
69 : namespace EnergyPlus::EarthTube {
70 : // Module containing the data for Earth Tube system
71 :
72 : // MODULE INFORMATION:
73 : // AUTHOR Kwang Ho Lee
74 : // DATE WRITTEN November 2005
75 :
76 : // PURPOSE OF THIS MODULE:
77 : // To encapsulate the data and algorithyms required to manage the EarthTube System Component
78 :
79 : // REFERENCES:
80 : // 1. M. Krarti, "Analytical Model to Predict Annual Soil Surface Temperature Variation",
81 : // Journal of Solar Energy Engineering 117, 1995, pp 91-99
82 : // 2. K. Labs In: J. Cook, editor, "Passive Cooling",
83 : // Cambridge Massachusetts, MIT Press, 1989, pp 206-212
84 :
85 : // This is an interesting one. The actual members of the enum are never explicitly used
86 : // The enum is used in a getEnumerationValue call to determine what was found in GetInput
87 : // The value is then used as an array index to lookup thermal conductivity and such from some std::arrays
88 : // So the IDE thinks these are unused, and I'm not sure the best way to hint that they sorta aren't
89 : enum class SoilType
90 : {
91 : Invalid = -1,
92 : HeavyAndSat,
93 : HeavyAndDamp,
94 : HeavyAndDry,
95 : LightAndDry,
96 : Num
97 : };
98 :
99 : constexpr std::array<std::string_view, static_cast<int>(Ventilation::Num)> ventilationNamesUC = {"NATURAL", "INTAKE", "EXHAUST"};
100 : constexpr std::array<std::string_view, static_cast<int>(SoilType::Num)> soilTypeNamesUC = {
101 : "HEAVYANDSATURATED", "HEAVYANDDAMP", "HEAVYANDDRY", "LIGHTANDDRY"};
102 :
103 3479215 : void ManageEarthTube(EnergyPlusData &state)
104 : {
105 :
106 : // SUBROUTINE INFORMATION:
107 : // AUTHOR Kwang Ho Lee
108 : // DATE WRITTEN November 2005
109 :
110 : // PURPOSE OF THIS SUBROUTINE:
111 : // This subroutine manages the simulation of EarthTube unit.
112 : // This driver manages the calls to all of
113 : // the other drivers and simulation algorithms.
114 :
115 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
116 3479215 : bool ErrorsFound(false);
117 :
118 : // Obtains and Allocates heat balance related parameters from input file
119 3479215 : if (state.dataEarthTube->GetInputFlag) {
120 739 : GetEarthTube(state, ErrorsFound);
121 739 : state.dataEarthTube->GetInputFlag = false;
122 : }
123 :
124 3479215 : if (state.dataEarthTube->EarthTubeSys.empty()) return;
125 :
126 2106 : CalcEarthTube(state);
127 :
128 2106 : ReportEarthTube(state);
129 : }
130 :
131 739 : void GetEarthTube(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
132 : {
133 :
134 : // SUBROUTINE INFORMATION:
135 : // AUTHOR Kwang Ho Lee
136 : // DATE WRITTEN November 2005
137 :
138 : // PURPOSE OF THIS SUBROUTINE:
139 : // This subroutine obtains input data for EarthTube units and
140 : // stores it in the EarthTube data structure.
141 :
142 : // SUBROUTINE PARAMETER DEFINITIONS:
143 739 : Real64 constexpr EarthTubeTempLimit(100.0); // degrees Celsius
144 :
145 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
146 : int NumAlpha;
147 : int NumNumber;
148 : int IOStat;
149 : int Loop;
150 1478 : Array1D_bool RepVarSet;
151 :
152 739 : auto &Zone(state.dataHeatBal->Zone);
153 :
154 739 : RepVarSet.dimension(state.dataGlobal->NumOfZones, true);
155 :
156 : // Following used for reporting
157 739 : state.dataEarthTube->ZnRptET.allocate(state.dataGlobal->NumOfZones);
158 :
159 1478 : std::string cCurrentModuleObject = "ZoneEarthtube";
160 739 : int TotEarthTube = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
161 :
162 739 : state.dataEarthTube->EarthTubeSys.allocate(TotEarthTube);
163 :
164 742 : for (Loop = 1; Loop <= TotEarthTube; ++Loop) {
165 3 : auto &thisEarthTube = state.dataEarthTube->EarthTubeSys(Loop);
166 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
167 : cCurrentModuleObject,
168 : Loop,
169 3 : state.dataIPShortCut->cAlphaArgs,
170 : NumAlpha,
171 3 : state.dataIPShortCut->rNumericArgs,
172 : NumNumber,
173 : IOStat,
174 3 : state.dataIPShortCut->lNumericFieldBlanks,
175 3 : state.dataIPShortCut->lAlphaFieldBlanks,
176 3 : state.dataIPShortCut->cAlphaFieldNames,
177 3 : state.dataIPShortCut->cNumericFieldNames);
178 :
179 : // First Alpha is Zone Name
180 3 : thisEarthTube.ZonePtr = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(1), Zone);
181 3 : if (thisEarthTube.ZonePtr == 0) {
182 0 : ShowSevereError(
183 0 : state, cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(1) + " not found=" + state.dataIPShortCut->cAlphaArgs(1));
184 0 : ErrorsFound = true;
185 : }
186 :
187 : // Second Alpha is Schedule Name
188 3 : thisEarthTube.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
189 3 : if (thisEarthTube.SchedPtr == 0) {
190 0 : if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
191 0 : ShowSevereError(state,
192 0 : cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(2) + " is required, missing for " +
193 0 : state.dataIPShortCut->cAlphaFieldNames(1) + '=' + state.dataIPShortCut->cAlphaArgs(1));
194 : } else {
195 0 : ShowSevereError(state,
196 0 : cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(2) +
197 0 : " entered=" + state.dataIPShortCut->cAlphaArgs(2) + " for " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' +
198 0 : state.dataIPShortCut->cAlphaArgs(1));
199 : }
200 0 : ErrorsFound = true;
201 : }
202 :
203 : // Overall parameters and their limits
204 3 : thisEarthTube.DesignLevel = state.dataIPShortCut->rNumericArgs(1);
205 :
206 3 : thisEarthTube.MinTemperature = state.dataIPShortCut->rNumericArgs(2);
207 3 : if ((thisEarthTube.MinTemperature < -EarthTubeTempLimit) || (thisEarthTube.MinTemperature > EarthTubeTempLimit)) {
208 0 : ShowSevereError(state,
209 0 : format("{}: {}={} must have a minimum temperature between -{:.0R}C and {:.0R}C",
210 : cCurrentModuleObject,
211 0 : state.dataIPShortCut->cAlphaFieldNames(1),
212 0 : state.dataIPShortCut->cAlphaArgs(1),
213 : EarthTubeTempLimit,
214 0 : EarthTubeTempLimit));
215 0 : ShowContinueError(state, format("Entered value={:.0R}", thisEarthTube.MinTemperature));
216 0 : ErrorsFound = true;
217 : }
218 :
219 3 : thisEarthTube.MaxTemperature = state.dataIPShortCut->rNumericArgs(3);
220 3 : if ((thisEarthTube.MaxTemperature < -EarthTubeTempLimit) || (thisEarthTube.MaxTemperature > EarthTubeTempLimit)) {
221 0 : ShowSevereError(state,
222 0 : format("{}: {}={} must have a maximum temperature between -{:.0R}C and {:.0R}C",
223 : cCurrentModuleObject,
224 0 : state.dataIPShortCut->cAlphaFieldNames(1),
225 0 : state.dataIPShortCut->cAlphaArgs(1),
226 : EarthTubeTempLimit,
227 0 : EarthTubeTempLimit));
228 0 : ShowContinueError(state, format("Entered value={:.0R}", thisEarthTube.MaxTemperature));
229 0 : ErrorsFound = true;
230 : }
231 :
232 3 : thisEarthTube.DelTemperature = state.dataIPShortCut->rNumericArgs(4); // 3/12/03 Negative del temp now allowed COP
233 :
234 : // if we have a blank, then just set it to the Natural type, otherwise, search on it
235 3 : if (state.dataIPShortCut->cAlphaArgs(3).empty()) {
236 0 : thisEarthTube.FanType = Ventilation::Natural;
237 : } else {
238 3 : thisEarthTube.FanType = static_cast<Ventilation>(getEnumerationValue(ventilationNamesUC, state.dataIPShortCut->cAlphaArgs(3)));
239 3 : if (thisEarthTube.FanType == Ventilation::Invalid) {
240 0 : ShowSevereError(state,
241 0 : cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' + state.dataIPShortCut->cAlphaArgs(1) +
242 0 : ", " + state.dataIPShortCut->cAlphaFieldNames(3) + " invalid=" + state.dataIPShortCut->cAlphaArgs(3));
243 0 : ErrorsFound = true;
244 : }
245 : }
246 :
247 3 : thisEarthTube.FanPressure = state.dataIPShortCut->rNumericArgs(5);
248 3 : if (thisEarthTube.FanPressure < 0.0) {
249 0 : ShowSevereError(state,
250 0 : format("{}: {}={}, {} must be positive, entered value={:.2R}",
251 : cCurrentModuleObject,
252 0 : state.dataIPShortCut->cAlphaFieldNames(1),
253 0 : state.dataIPShortCut->cAlphaArgs(1),
254 0 : state.dataIPShortCut->cNumericFieldNames(5),
255 0 : thisEarthTube.FanPressure));
256 0 : ErrorsFound = true;
257 : }
258 :
259 3 : thisEarthTube.FanEfficiency = state.dataIPShortCut->rNumericArgs(6);
260 3 : if ((thisEarthTube.FanEfficiency <= 0.0) || (thisEarthTube.FanEfficiency > 1.0)) {
261 0 : ShowSevereError(state,
262 0 : format("{}: {}={}, {} must be greater than zero and less than or equal to one, entered value={:.2R}",
263 : cCurrentModuleObject,
264 0 : state.dataIPShortCut->cAlphaFieldNames(1),
265 0 : state.dataIPShortCut->cAlphaArgs(1),
266 0 : state.dataIPShortCut->cNumericFieldNames(6),
267 0 : thisEarthTube.FanEfficiency));
268 0 : ErrorsFound = true;
269 : }
270 :
271 3 : thisEarthTube.r1 = state.dataIPShortCut->rNumericArgs(7);
272 3 : if (thisEarthTube.r1 <= 0.0) {
273 0 : ShowSevereError(state,
274 0 : format("{}: {}={}, {} must be positive, entered value={:.2R}",
275 : cCurrentModuleObject,
276 0 : state.dataIPShortCut->cAlphaFieldNames(1),
277 0 : state.dataIPShortCut->cAlphaArgs(1),
278 0 : state.dataIPShortCut->cNumericFieldNames(7),
279 0 : thisEarthTube.r1));
280 0 : ErrorsFound = true;
281 : }
282 :
283 3 : thisEarthTube.r2 = state.dataIPShortCut->rNumericArgs(8);
284 3 : if (thisEarthTube.r2 <= 0.0) {
285 0 : ShowSevereError(state,
286 0 : format("{}: {}={}, {} must be positive, entered value={:.2R}",
287 : cCurrentModuleObject,
288 0 : state.dataIPShortCut->cAlphaFieldNames(1),
289 0 : state.dataIPShortCut->cAlphaArgs(1),
290 0 : state.dataIPShortCut->cNumericFieldNames(8),
291 0 : thisEarthTube.r2));
292 0 : ErrorsFound = true;
293 : }
294 :
295 3 : thisEarthTube.r3 = 2.0 * thisEarthTube.r1;
296 :
297 3 : thisEarthTube.PipeLength = state.dataIPShortCut->rNumericArgs(9);
298 3 : if (thisEarthTube.PipeLength <= 0.0) {
299 0 : ShowSevereError(state,
300 0 : format("{}: {}={}, {} must be positive, entered value={:.2R}",
301 : cCurrentModuleObject,
302 0 : state.dataIPShortCut->cAlphaFieldNames(1),
303 0 : state.dataIPShortCut->cAlphaArgs(1),
304 0 : state.dataIPShortCut->cNumericFieldNames(9),
305 0 : thisEarthTube.PipeLength));
306 0 : ErrorsFound = true;
307 : }
308 :
309 3 : thisEarthTube.PipeThermCond = state.dataIPShortCut->rNumericArgs(10);
310 3 : if (thisEarthTube.PipeThermCond <= 0.0) {
311 0 : ShowSevereError(state,
312 0 : format("{}: {}={}, {} must be positive, entered value={:.2R}",
313 : cCurrentModuleObject,
314 0 : state.dataIPShortCut->cAlphaFieldNames(1),
315 0 : state.dataIPShortCut->cAlphaArgs(1),
316 0 : state.dataIPShortCut->cNumericFieldNames(10),
317 0 : thisEarthTube.PipeThermCond));
318 0 : ErrorsFound = true;
319 : }
320 :
321 3 : thisEarthTube.z = state.dataIPShortCut->rNumericArgs(11);
322 3 : if (thisEarthTube.z <= 0.0) {
323 0 : ShowSevereError(state,
324 0 : format("{}: {}={}, {} must be positive, entered value={:.2R}",
325 : cCurrentModuleObject,
326 0 : state.dataIPShortCut->cAlphaFieldNames(1),
327 0 : state.dataIPShortCut->cAlphaArgs(1),
328 0 : state.dataIPShortCut->cNumericFieldNames(11),
329 0 : thisEarthTube.z));
330 0 : ErrorsFound = true;
331 : }
332 3 : if (thisEarthTube.z <= (thisEarthTube.r1 + thisEarthTube.r2 + thisEarthTube.r3)) {
333 0 : ShowSevereError(state,
334 0 : format("{}: {}={}, {} must be greater than 3*{} + {} entered value={:.2R} ref sum={:.2R}",
335 : cCurrentModuleObject,
336 0 : state.dataIPShortCut->cAlphaFieldNames(1),
337 0 : state.dataIPShortCut->cAlphaArgs(1),
338 0 : state.dataIPShortCut->cNumericFieldNames(11),
339 0 : state.dataIPShortCut->cNumericFieldNames(7),
340 0 : state.dataIPShortCut->cNumericFieldNames(8),
341 : thisEarthTube.z,
342 0 : thisEarthTube.r1 + thisEarthTube.r2 + thisEarthTube.r3));
343 0 : ErrorsFound = true;
344 : }
345 :
346 3 : auto soilType = static_cast<SoilType>(getEnumerationValue(soilTypeNamesUC, state.dataIPShortCut->cAlphaArgs(4)));
347 3 : constexpr std::array<Real64, static_cast<int>(SoilType::Num)> thermalDiffusivity = {0.0781056, 0.055728, 0.0445824, 0.024192};
348 3 : constexpr std::array<Real64, static_cast<int>(SoilType::Num)> thermalConductivity = {2.42, 1.3, 0.865, 0.346};
349 3 : if (soilType == SoilType::Invalid) {
350 0 : ShowSevereError(state,
351 0 : cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' + state.dataIPShortCut->cAlphaArgs(1) +
352 0 : ", " + state.dataIPShortCut->cAlphaFieldNames(4) + " invalid=" + state.dataIPShortCut->cAlphaArgs(4));
353 0 : ErrorsFound = true;
354 : } else {
355 3 : thisEarthTube.SoilThermDiff = thermalDiffusivity[static_cast<int>(soilType)];
356 3 : thisEarthTube.SoilThermCond = thermalConductivity[static_cast<int>(soilType)];
357 : }
358 :
359 3 : thisEarthTube.AverSoilSurTemp = state.dataIPShortCut->rNumericArgs(12);
360 3 : thisEarthTube.ApmlSoilSurTemp = state.dataIPShortCut->rNumericArgs(13);
361 3 : thisEarthTube.SoilSurPhaseConst = int(state.dataIPShortCut->rNumericArgs(14));
362 :
363 : // Override any user input for cases where natural ventilation is being used
364 3 : if (thisEarthTube.FanType == Ventilation::Natural) {
365 1 : thisEarthTube.FanPressure = 0.0;
366 1 : thisEarthTube.FanEfficiency = 1.0;
367 : }
368 :
369 3 : thisEarthTube.ConstantTermCoef = state.dataIPShortCut->rNumericArgs(15);
370 3 : thisEarthTube.TemperatureTermCoef = state.dataIPShortCut->rNumericArgs(16);
371 3 : thisEarthTube.VelocityTermCoef = state.dataIPShortCut->rNumericArgs(17);
372 3 : thisEarthTube.VelocitySQTermCoef = state.dataIPShortCut->rNumericArgs(18);
373 :
374 3 : if (thisEarthTube.ZonePtr > 0) {
375 3 : if (RepVarSet(thisEarthTube.ZonePtr)) {
376 3 : RepVarSet(thisEarthTube.ZonePtr) = false;
377 12 : SetupOutputVariable(state,
378 : "Earth Tube Zone Sensible Cooling Energy",
379 : OutputProcessor::Unit::J,
380 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatLoss,
381 : OutputProcessor::SOVTimeStepType::System,
382 : OutputProcessor::SOVStoreType::NonState,
383 6 : Zone(thisEarthTube.ZonePtr).Name);
384 12 : SetupOutputVariable(state,
385 : "Earth Tube Zone Sensible Cooling Rate",
386 : OutputProcessor::Unit::W,
387 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatLossRate,
388 : OutputProcessor::SOVTimeStepType::System,
389 : OutputProcessor::SOVStoreType::State,
390 6 : Zone(thisEarthTube.ZonePtr).Name);
391 12 : SetupOutputVariable(state,
392 : "Earth Tube Zone Sensible Heating Energy",
393 : OutputProcessor::Unit::J,
394 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatGain,
395 : OutputProcessor::SOVTimeStepType::System,
396 : OutputProcessor::SOVStoreType::NonState,
397 6 : Zone(thisEarthTube.ZonePtr).Name);
398 12 : SetupOutputVariable(state,
399 : "Earth Tube Zone Sensible Heating Rate",
400 : OutputProcessor::Unit::W,
401 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatGainRate,
402 : OutputProcessor::SOVTimeStepType::System,
403 : OutputProcessor::SOVStoreType::State,
404 6 : Zone(thisEarthTube.ZonePtr).Name);
405 12 : SetupOutputVariable(state,
406 : "Earth Tube Air Flow Volume",
407 : OutputProcessor::Unit::m3,
408 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeVolume,
409 : OutputProcessor::SOVTimeStepType::System,
410 : OutputProcessor::SOVStoreType::NonState,
411 6 : Zone(thisEarthTube.ZonePtr).Name);
412 12 : SetupOutputVariable(state,
413 : "Earth Tube Current Density Air Volume Flow Rate",
414 : OutputProcessor::Unit::m3_s,
415 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeVolFlowRate,
416 : OutputProcessor::SOVTimeStepType::System,
417 : OutputProcessor::SOVStoreType::State,
418 6 : Zone(thisEarthTube.ZonePtr).Name);
419 12 : SetupOutputVariable(state,
420 : "Earth Tube Standard Density Air Volume Flow Rate",
421 : OutputProcessor::Unit::m3_s,
422 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeVolFlowRateStd,
423 : OutputProcessor::SOVTimeStepType::System,
424 : OutputProcessor::SOVStoreType::State,
425 6 : Zone(thisEarthTube.ZonePtr).Name);
426 12 : SetupOutputVariable(state,
427 : "Earth Tube Air Flow Mass",
428 : OutputProcessor::Unit::kg,
429 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeMass,
430 : OutputProcessor::SOVTimeStepType::System,
431 : OutputProcessor::SOVStoreType::NonState,
432 6 : Zone(thisEarthTube.ZonePtr).Name);
433 12 : SetupOutputVariable(state,
434 : "Earth Tube Air Mass Flow Rate",
435 : OutputProcessor::Unit::kg_s,
436 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeMassFlowRate,
437 : OutputProcessor::SOVTimeStepType::System,
438 : OutputProcessor::SOVStoreType::State,
439 6 : Zone(thisEarthTube.ZonePtr).Name);
440 12 : SetupOutputVariable(state,
441 : "Earth Tube Water Mass Flow Rate",
442 : OutputProcessor::Unit::kg_s,
443 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeWaterMassFlowRate,
444 : OutputProcessor::SOVTimeStepType::System,
445 : OutputProcessor::SOVStoreType::State,
446 6 : Zone(thisEarthTube.ZonePtr).Name);
447 12 : SetupOutputVariable(state,
448 : "Earth Tube Fan Electricity Energy",
449 : OutputProcessor::Unit::J,
450 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeFanElec,
451 : OutputProcessor::SOVTimeStepType::System,
452 : OutputProcessor::SOVStoreType::NonState,
453 3 : Zone(thisEarthTube.ZonePtr).Name,
454 : _,
455 : "Electricity",
456 : _,
457 : _,
458 3 : "Building");
459 12 : SetupOutputVariable(state,
460 : "Earth Tube Fan Electricity Rate",
461 : OutputProcessor::Unit::W,
462 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeFanElecPower,
463 : OutputProcessor::SOVTimeStepType::System,
464 : OutputProcessor::SOVStoreType::State,
465 6 : Zone(thisEarthTube.ZonePtr).Name);
466 12 : SetupOutputVariable(state,
467 : "Earth Tube Zone Inlet Air Temperature",
468 : OutputProcessor::Unit::C,
469 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeAirTemp,
470 : OutputProcessor::SOVTimeStepType::System,
471 : OutputProcessor::SOVStoreType::State,
472 6 : Zone(thisEarthTube.ZonePtr).Name);
473 9 : SetupOutputVariable(state,
474 : "Earth Tube Ground Interface Temperature",
475 : OutputProcessor::Unit::C,
476 : thisEarthTube.GroundTempz1z2t,
477 : OutputProcessor::SOVTimeStepType::System,
478 : OutputProcessor::SOVStoreType::State,
479 6 : Zone(thisEarthTube.ZonePtr).Name);
480 12 : SetupOutputVariable(state,
481 : "Earth Tube Outdoor Air Heat Transfer Rate",
482 : OutputProcessor::Unit::W,
483 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeOATreatmentPower,
484 : OutputProcessor::SOVTimeStepType::System,
485 : OutputProcessor::SOVStoreType::State,
486 6 : Zone(thisEarthTube.ZonePtr).Name);
487 12 : SetupOutputVariable(state,
488 : "Earth Tube Zone Inlet Wet Bulb Temperature",
489 : OutputProcessor::Unit::C,
490 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeWetBulbTemp,
491 : OutputProcessor::SOVTimeStepType::System,
492 : OutputProcessor::SOVStoreType::State,
493 6 : Zone(thisEarthTube.ZonePtr).Name);
494 12 : SetupOutputVariable(state,
495 : "Earth Tube Zone Inlet Humidity Ratio",
496 : OutputProcessor::Unit::kgWater_kgDryAir,
497 3 : state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHumRat,
498 : OutputProcessor::SOVTimeStepType::System,
499 : OutputProcessor::SOVStoreType::State,
500 6 : Zone(thisEarthTube.ZonePtr).Name);
501 : }
502 : }
503 : }
504 :
505 739 : CheckEarthTubesInZones(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
506 :
507 739 : if (ErrorsFound) {
508 0 : ShowFatalError(state, cCurrentModuleObject + ": Errors getting input. Program terminates.");
509 : }
510 739 : }
511 :
512 739 : void CheckEarthTubesInZones(EnergyPlusData &state,
513 : std::string const &ZoneName, // name of zone for error reporting
514 : std::string_view FieldName, // name of earth tube in input
515 : bool &ErrorsFound // Found a problem
516 : )
517 : {
518 : // Check to make sure there is only one earth tube statement per zone
519 739 : int numEarthTubes = (int)state.dataEarthTube->EarthTubeSys.size();
520 741 : for (int Loop = 1; Loop <= numEarthTubes - 1; ++Loop) {
521 5 : for (int Loop1 = Loop + 1; Loop1 <= numEarthTubes; ++Loop1) {
522 3 : if (state.dataEarthTube->EarthTubeSys(Loop).ZonePtr == state.dataEarthTube->EarthTubeSys(Loop1).ZonePtr) {
523 0 : ShowSevereError(state, ZoneName + " has more than one " + std::string{FieldName} + " associated with it.");
524 0 : ShowContinueError(state,
525 0 : "Only one " + std::string{FieldName} + " is allowed per zone. Check the definitions of " + std::string{FieldName});
526 0 : ShowContinueError(state, "in your input file and make sure that there is only one defined for each zone.");
527 0 : ErrorsFound = true;
528 : }
529 : }
530 : }
531 739 : }
532 :
533 2106 : void CalcEarthTube(EnergyPlusData &state)
534 : {
535 :
536 : // SUBROUTINE INFORMATION:
537 : // AUTHOR Kwang Ho Lee
538 : // DATE WRITTEN November 2005
539 :
540 : // PURPOSE OF THIS SUBROUTINE:
541 : // This subroutine simulates the components making up the EarthTube unit.
542 :
543 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
544 : int Loop;
545 : Real64 Process1; // Variable Used in the Middle of the Calculation
546 : Real64 GroundTempz1z2t; // Average Ground Temperature between Depth z1 and z2 at time t
547 :
548 : Real64 AirThermCond; // Thermal Conductivity of Air (W/mC)
549 : Real64 AirKinemVisco; // Kinematic Viscosity of Air (m2/s)
550 : Real64 AirThermDiffus; // Thermal Diffusivity of Air (m2/s)
551 : Real64 Re; // Reynolds Number for Flow Inside Pipe
552 : Real64 Pr; // Prandtl Number for Flow Inside Pipe
553 : Real64 Nu; // Nusselt Number for Flow Inside Pipe
554 : Real64 fa; // Friction Factor of Pipe
555 : Real64 PipeHeatTransCoef; // Convective Heat Transfer Coefficient at Inner Pipe Surface
556 : Real64 Rc; // Thermal Resistance due to Convection between Air and Pipe Inner Surface
557 : Real64 Rp; // Thermal Resistance due to Conduction between Pipe Inner and Outer Surface
558 : Real64 Rs; // Thermal Resistance due to Conduction between Pipe Outer Surface and Soil
559 : Real64 Rt; // Total Thermal Resistance between Pipe Air and Soil
560 : Real64 OverallHeatTransCoef; // Overall Heat Transfer Coefficient of Earth Tube
561 : Real64 AverPipeAirVel; // Average Pipe Air Velocity (m/s)
562 : Real64 AirMassFlowRate; // Actual Mass Flow Rate of Air inside Pipe
563 : Real64 AirSpecHeat; // Specific Heat of Air
564 : Real64 AirDensity; // Density of Air
565 : Real64 EVF;
566 :
567 2106 : int numEarthTubes = (int)state.dataEarthTube->EarthTubeSys.size();
568 8424 : for (Loop = 1; Loop <= numEarthTubes; ++Loop) {
569 6318 : auto &thisEarthTube = state.dataEarthTube->EarthTubeSys(Loop);
570 6318 : int NZ = thisEarthTube.ZonePtr;
571 6318 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
572 6318 : thisZoneHB.MCPTE = 0.0;
573 6318 : thisZoneHB.MCPE = 0.0;
574 6318 : thisZoneHB.EAMFL = 0.0;
575 6318 : thisZoneHB.EAMFLxHumRat = 0.0;
576 6318 : thisEarthTube.FanPower = 0.0;
577 :
578 : // Skip this if the zone is below the minimum temperature limit
579 6318 : if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT < thisEarthTube.MinTemperature) continue;
580 : // Skip this if the zone is above the maximum temperature limit
581 6318 : if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT > thisEarthTube.MaxTemperature) continue;
582 : // Skip if below the temperature difference limit
583 6318 : if (std::abs(state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT - state.dataEnvrn->OutDryBulbTemp) < thisEarthTube.DelTemperature)
584 1492 : continue;
585 :
586 4826 : AirDensity =
587 9652 : Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
588 4826 : AirSpecHeat = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat);
589 4826 : EVF = thisEarthTube.DesignLevel * ScheduleManager::GetCurrentScheduleValue(state, thisEarthTube.SchedPtr);
590 4826 : thisZoneHB.MCPE =
591 9652 : EVF * AirDensity * AirSpecHeat *
592 9652 : (thisEarthTube.ConstantTermCoef +
593 9652 : std::abs(state.dataEnvrn->OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT) *
594 9652 : thisEarthTube.TemperatureTermCoef +
595 4826 : state.dataEnvrn->WindSpeed * (thisEarthTube.VelocityTermCoef + state.dataEnvrn->WindSpeed * thisEarthTube.VelocitySQTermCoef));
596 :
597 4826 : thisZoneHB.EAMFL = thisZoneHB.MCPE / AirSpecHeat;
598 4826 : if (thisEarthTube.FanEfficiency > 0.0) {
599 4826 : thisEarthTube.FanPower = thisZoneHB.EAMFL * thisEarthTube.FanPressure / (thisEarthTube.FanEfficiency * AirDensity);
600 : }
601 :
602 4826 : AverPipeAirVel = EVF / DataGlobalConstants::Pi / pow_2(thisEarthTube.r1);
603 4826 : AirMassFlowRate = EVF * AirDensity;
604 :
605 : // Calculation of Average Ground Temperature between Depth z1 and z2 at time t
606 9652 : GroundTempz1z2t = thisEarthTube.AverSoilSurTemp -
607 9652 : thisEarthTube.ApmlSoilSurTemp *
608 9652 : std::exp(-thisEarthTube.z * std::sqrt(DataGlobalConstants::Pi / 365.0 / thisEarthTube.SoilThermDiff)) *
609 4826 : std::cos(2.0 * DataGlobalConstants::Pi / 365.0 *
610 9652 : (state.dataEnvrn->DayOfYear - thisEarthTube.SoilSurPhaseConst -
611 4826 : thisEarthTube.z / 2.0 * std::sqrt(365.0 / DataGlobalConstants::Pi / thisEarthTube.SoilThermDiff)));
612 4826 : thisEarthTube.GroundTempz1z2t = GroundTempz1z2t;
613 :
614 : // Calculation of Convective Heat Transfer Coefficient at Inner Pipe Surface
615 4826 : AirThermCond = 0.02442 + 0.6992 * state.dataEnvrn->OutDryBulbTemp / 10000.0;
616 4826 : AirKinemVisco = (0.1335 + 0.000925 * state.dataEnvrn->OutDryBulbTemp) / 10000.0;
617 4826 : AirThermDiffus = (0.0014 * state.dataEnvrn->OutDryBulbTemp + 0.1872) / 10000.0;
618 4826 : Re = 2.0 * thisEarthTube.r1 * AverPipeAirVel / AirKinemVisco;
619 4826 : Pr = AirKinemVisco / AirThermDiffus;
620 4826 : if (Re <= 2300.0) {
621 0 : Nu = 3.66;
622 4826 : } else if (Re <= 4000.0) {
623 0 : fa = std::pow(1.58 * std::log(Re) - 3.28, -2);
624 0 : Process1 = (fa / 2.0) * (Re - 1000.0) * Pr / (1.0 + 12.7 * std::sqrt(fa / 2.0) * (std::pow(Pr, 2.0 / 3.0) - 1.0));
625 0 : Nu = (Process1 - 3.66) / (1700.0) * Re + (4000.0 * 3.66 - 2300.0 * Process1) / 1700.0;
626 : } else {
627 4826 : fa = std::pow(1.58 * std::log(Re) - 3.28, -2);
628 4826 : Nu = (fa / 2.0) * (Re - 1000.0) * Pr / (1.0 + 12.7 * std::sqrt(fa / 2.0) * (std::pow(Pr, 2.0 / 3.0) - 1.0));
629 : }
630 4826 : PipeHeatTransCoef = Nu * AirThermCond / 2.0 / thisEarthTube.r1;
631 :
632 : // Calculation of Thermal Resistance and Overall Heat Transfer Coefficient
633 4826 : Rc = 1.0 / 2.0 / DataGlobalConstants::Pi / thisEarthTube.r1 / PipeHeatTransCoef;
634 4826 : Rp = std::log((thisEarthTube.r1 + thisEarthTube.r2) / thisEarthTube.r1) / 2.0 / DataGlobalConstants::Pi / thisEarthTube.PipeThermCond;
635 9652 : Rs = std::log((thisEarthTube.r1 + thisEarthTube.r2 + thisEarthTube.r3) / (thisEarthTube.r1 + thisEarthTube.r2)) / 2.0 /
636 4826 : DataGlobalConstants::Pi / thisEarthTube.SoilThermCond;
637 4826 : Rt = Rc + Rp + Rs;
638 4826 : OverallHeatTransCoef = 1.0 / Rt;
639 :
640 4826 : if (AirMassFlowRate * AirSpecHeat == 0.0) {
641 0 : thisEarthTube.InsideAirTemp = GroundTempz1z2t;
642 :
643 : } else {
644 :
645 : // Calculation of Pipe Outlet Air Temperature
646 4826 : if (state.dataEnvrn->OutDryBulbTemp > GroundTempz1z2t) {
647 14451 : Process1 = (std::log(std::abs(state.dataEnvrn->OutDryBulbTemp - GroundTempz1z2t)) * AirMassFlowRate * AirSpecHeat -
648 4817 : OverallHeatTransCoef * thisEarthTube.PipeLength) /
649 4817 : (AirMassFlowRate * AirSpecHeat);
650 4817 : thisEarthTube.InsideAirTemp = std::exp(Process1) + GroundTempz1z2t;
651 9 : } else if (state.dataEnvrn->OutDryBulbTemp == GroundTempz1z2t) {
652 0 : thisEarthTube.InsideAirTemp = GroundTempz1z2t;
653 : } else {
654 27 : Process1 = (std::log(std::abs(state.dataEnvrn->OutDryBulbTemp - GroundTempz1z2t)) * AirMassFlowRate * AirSpecHeat -
655 9 : OverallHeatTransCoef * thisEarthTube.PipeLength) /
656 9 : (AirMassFlowRate * AirSpecHeat);
657 9 : thisEarthTube.InsideAirTemp = GroundTempz1z2t - std::exp(Process1);
658 : }
659 : }
660 :
661 4826 : thisEarthTube.CalcEarthTubeHumRat(state, NZ);
662 : }
663 2106 : }
664 :
665 4826 : void EarthTubeData::CalcEarthTubeHumRat(EnergyPlusData &state, int const NZ)
666 : { // Zone number (index)
667 :
668 : // SUBROUTINE INFORMATION:
669 : // AUTHOR Kwang Ho Lee
670 : // DATE WRITTEN November 2005
671 : // MODIFIED Rick Strand, June 2017 (made this a separate subroutine)
672 :
673 : // PURPOSE OF THIS SUBROUTINE:
674 : // This subroutine determines the leaving humidity ratio for the EarthTube
675 : // and calculates parameters associated with humidity ratio.
676 :
677 4826 : Real64 InsideDewPointTemp = Psychrometrics::PsyTdpFnWPb(state, state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
678 4826 : Real64 InsideHumRat = 0.0;
679 4826 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
680 :
681 4826 : if (this->InsideAirTemp >= InsideDewPointTemp) {
682 617 : InsideHumRat = state.dataEnvrn->OutHumRat;
683 617 : Real64 const InsideEnthalpy = Psychrometrics::PsyHFnTdbW(this->InsideAirTemp, state.dataEnvrn->OutHumRat);
684 : // Intake fans will add some heat to the air, raising the temperature for an intake fan...
685 617 : if (this->FanType == Ventilation::Intake) {
686 : Real64 OutletAirEnthalpy;
687 205 : if (thisZoneHB.EAMFL == 0.0) {
688 0 : OutletAirEnthalpy = InsideEnthalpy;
689 : } else {
690 205 : OutletAirEnthalpy = InsideEnthalpy + this->FanPower / thisZoneHB.EAMFL;
691 : }
692 205 : this->AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, state.dataEnvrn->OutHumRat);
693 : } else {
694 412 : this->AirTemp = this->InsideAirTemp;
695 : }
696 617 : thisZoneHB.MCPTE = thisZoneHB.MCPE * this->AirTemp;
697 :
698 : } else {
699 4209 : InsideHumRat = Psychrometrics::PsyWFnTdpPb(state, this->InsideAirTemp, state.dataEnvrn->OutBaroPress);
700 4209 : Real64 const InsideEnthalpy = Psychrometrics::PsyHFnTdbW(this->InsideAirTemp, InsideHumRat);
701 : // Intake fans will add some heat to the air, raising the temperature for an intake fan...
702 4209 : if (this->FanType == Ventilation::Intake) {
703 : Real64 OutletAirEnthalpy;
704 1413 : if (thisZoneHB.EAMFL == 0.0) {
705 0 : OutletAirEnthalpy = InsideEnthalpy;
706 : } else {
707 1413 : OutletAirEnthalpy = InsideEnthalpy + this->FanPower / thisZoneHB.EAMFL;
708 : }
709 1413 : this->AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, InsideHumRat);
710 : } else {
711 2796 : this->AirTemp = this->InsideAirTemp;
712 : }
713 4209 : thisZoneHB.MCPTE = thisZoneHB.MCPE * this->AirTemp;
714 : }
715 :
716 4826 : this->HumRat = InsideHumRat;
717 4826 : this->WetBulbTemp = Psychrometrics::PsyTwbFnTdbWPb(state, this->InsideAirTemp, InsideHumRat, state.dataEnvrn->OutBaroPress);
718 4826 : thisZoneHB.EAMFLxHumRat = thisZoneHB.EAMFL * InsideHumRat;
719 4826 : }
720 :
721 2106 : void ReportEarthTube(EnergyPlusData &state)
722 : {
723 :
724 : // SUBROUTINE INFORMATION:
725 : // AUTHOR Kwang Ho Lee
726 : // DATE WRITTEN November 2005
727 : // MODIFIED B. Griffith April 2010 added output reports
728 :
729 : // PURPOSE OF THIS SUBROUTINE: This subroutine fills remaining report variables.
730 :
731 2106 : Real64 const ReportingConstant = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
732 :
733 8424 : for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ...
734 6318 : auto &thisZone = state.dataEarthTube->ZnRptET(ZoneLoop);
735 6318 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop);
736 :
737 : // Break the infiltration load into heat gain and loss components.
738 : Real64 const AirDensity =
739 6318 : Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
740 6318 : Real64 const CpAir = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat);
741 6318 : thisZone.EarthTubeVolume = (thisZoneHB.MCPE / CpAir / AirDensity) * ReportingConstant;
742 6318 : thisZone.EarthTubeMass = (thisZoneHB.MCPE / CpAir) * ReportingConstant;
743 6318 : thisZone.EarthTubeVolFlowRate = thisZoneHB.MCPE / CpAir / AirDensity;
744 6318 : thisZone.EarthTubeVolFlowRateStd = thisZoneHB.MCPE / CpAir / state.dataEnvrn->StdRhoAir;
745 6318 : thisZone.EarthTubeMassFlowRate = thisZoneHB.MCPE / CpAir;
746 6318 : thisZone.EarthTubeWaterMassFlowRate = thisZoneHB.EAMFLxHumRat;
747 :
748 6318 : thisZone.EarthTubeFanElec = 0.0;
749 6318 : thisZone.EarthTubeAirTemp = 0.0;
750 12636 : for (auto &thisEarthTube : state.dataEarthTube->EarthTubeSys) {
751 12636 : if (thisEarthTube.ZonePtr == ZoneLoop) {
752 6318 : thisZone.EarthTubeFanElec = thisEarthTube.FanPower * ReportingConstant;
753 6318 : thisZone.EarthTubeFanElecPower = thisEarthTube.FanPower;
754 :
755 : // Break the EarthTube load into heat gain and loss components.
756 6318 : if (thisZoneHB.ZT > thisEarthTube.AirTemp) {
757 6318 : thisZone.EarthTubeHeatLoss = thisZoneHB.MCPE * (thisZoneHB.ZT - thisEarthTube.AirTemp) * ReportingConstant;
758 6318 : thisZone.EarthTubeHeatLossRate = thisZoneHB.MCPE * (thisZoneHB.ZT - thisEarthTube.AirTemp);
759 6318 : thisZone.EarthTubeHeatGain = 0.0;
760 6318 : thisZone.EarthTubeHeatGainRate = 0.0;
761 0 : } else if (thisZoneHB.ZT <= thisEarthTube.AirTemp) {
762 0 : thisZone.EarthTubeHeatGain = thisZoneHB.MCPE * (thisEarthTube.AirTemp - thisZoneHB.ZT) * ReportingConstant;
763 0 : thisZone.EarthTubeHeatGainRate = thisZoneHB.MCPE * (thisEarthTube.AirTemp - thisZoneHB.ZT);
764 0 : thisZone.EarthTubeHeatLoss = 0.0;
765 0 : thisZone.EarthTubeHeatLossRate = 0.0;
766 : }
767 :
768 6318 : thisZone.EarthTubeAirTemp = thisEarthTube.AirTemp;
769 6318 : thisZone.EarthTubeWetBulbTemp = thisEarthTube.WetBulbTemp;
770 6318 : thisZone.EarthTubeHumRat = thisEarthTube.HumRat;
771 6318 : thisZone.EarthTubeOATreatmentPower = thisZoneHB.MCPE * (thisEarthTube.AirTemp - state.dataEnvrn->OutDryBulbTemp);
772 6318 : break; // DO loop
773 : }
774 : }
775 :
776 : } // ... end of zone loads report variable update loop.
777 2106 : }
778 :
779 2313 : } // namespace EnergyPlus::EarthTube
|