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 : #include <string>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Fmath.hh>
54 : #include <ObjexxFCL/member.functions.hh>
55 :
56 : // EnergyPlus Headers
57 : #include <EnergyPlus/Construction.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataEnvironment.hh>
60 : #include <EnergyPlus/DataHeatBalSurface.hh>
61 : #include <EnergyPlus/DataHeatBalance.hh>
62 : #include <EnergyPlus/DataIPShortCuts.hh>
63 : #include <EnergyPlus/DataMoistureBalance.hh>
64 : #include <EnergyPlus/DataSurfaces.hh>
65 : #include <EnergyPlus/DisplayRoutines.hh>
66 : #include <EnergyPlus/General.hh>
67 : #include <EnergyPlus/HeatBalanceHAMTManager.hh>
68 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
69 : #include <EnergyPlus/Material.hh>
70 : #include <EnergyPlus/OutputProcessor.hh>
71 : #include <EnergyPlus/Psychrometrics.hh>
72 : #include <EnergyPlus/UtilityRoutines.hh>
73 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
74 :
75 : namespace EnergyPlus {
76 :
77 : namespace HeatBalanceHAMTManager {
78 :
79 : // MODULE INFORMATION:
80 : // AUTHOR Phillip Biddulph
81 : // DATE WRITTEN June 2008
82 : // MODIFIED
83 : // Bug fixes to make sure HAMT can cope with data limits ! PDB August 2009
84 : // RE-ENGINEERED
85 :
86 : // PURPOSE OF THIS MODULE:
87 : // Calculate, record and report the one dimentional heat and moisture transfer
88 : // through a surface given the material composition of the building surface and
89 : // the external and internal Temperatures and Relative Humidities.
90 :
91 : // METHODOLOGY EMPLOYED:
92 : // Each surface is split into "cells", where all characteristics are initiallised.
93 : // Cells are matched and links created in the initialisation routine.
94 : // The internal and external "surfaces" of the surface are virtual cells to allow for the
95 : // input of heat and vapor via heat transfer coefficients, radiation,
96 : // and vapor transfer coefficients
97 : // Uses Forward (implicit) finite difference alogorithm. Heat transfer is caclulated first,
98 : // with the option of including the latent heat, then liquid and vapor transfer. The process is ittereated.
99 : // Once the temperatures have converged the internal surface
100 : // temperature and vapor densities are passed back to EnergyPlus.
101 :
102 : // Temperatures and relative humidities are updated once EnergyPlus has checked that
103 : // the zone temperatures have converged.
104 :
105 : // REFERENCES:
106 : // K?zel, H.M. (1995) Simultaneous Heat and Moisture Transport in Building Components.
107 : // One- and two-dimensional calculation using simple parameters. IRB Verlag 1995
108 : // Holman, J.P. (2002) Heat Transfer, Ninth Edition. McGraw-Hill
109 : // Winterton, R.H.S. (1997) Heat Transfer. (Oxford Chemistry Primers; 50) Oxford University Press
110 : // Kumar Kumaran, M. (1996) IEA ANNEX 24, Final Report, Volume 3
111 :
112 : // USE STATEMENTS:
113 :
114 : // Using/Aliasing
115 : using namespace DataSurfaces;
116 : using DataHeatBalSurface::MinSurfaceTempLimit;
117 : using DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal;
118 : using namespace DataHeatBalance;
119 : using namespace Psychrometrics;
120 :
121 353337 : void ManageHeatBalHAMT(EnergyPlusData &state, int const SurfNum, Real64 &SurfTempInTmp, Real64 &TempSurfOutTmp)
122 : {
123 :
124 : // SUBROUTINE INFORMATION:
125 : // AUTHOR Phillip Biddulph
126 : // DATE WRITTEN June 2008
127 : // MODIFIED na
128 : // RE-ENGINEERED na
129 :
130 : // PURPOSE OF THIS SUBROUTINE:
131 : // Manages the Heat and Moisture Transfer calculations.
132 :
133 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
134 353337 : auto &OneTimeFlag = state.dataHeatBalHAMTMgr->OneTimeFlag;
135 :
136 353337 : if (OneTimeFlag) {
137 3 : OneTimeFlag = false;
138 3 : DisplayString(state, "Initialising Heat and Moisture Transfer Model");
139 3 : GetHeatBalHAMTInput(state);
140 3 : InitHeatBalHAMT(state);
141 : }
142 :
143 353337 : CalcHeatBalHAMT(state, SurfNum, SurfTempInTmp, TempSurfOutTmp);
144 353337 : }
145 :
146 3 : void GetHeatBalHAMTInput(EnergyPlusData &state)
147 : {
148 :
149 : // SUBROUTINE INFORMATION:
150 : // AUTHOR Phillip Biddulph
151 : // DATE WRITTEN June 2008
152 : // MODIFIED na
153 : // RE-ENGINEERED na
154 :
155 : // PURPOSE OF THIS SUBROUTINE:
156 : // gets input for the HAMT model
157 :
158 : // SUBROUTINE PARAMETER DEFINITIONS:
159 3 : static std::string const cHAMTObject1("MaterialProperty:HeatAndMoistureTransfer:Settings");
160 3 : static std::string const cHAMTObject2("MaterialProperty:HeatAndMoistureTransfer:SorptionIsotherm");
161 3 : static std::string const cHAMTObject3("MaterialProperty:HeatAndMoistureTransfer:Suction");
162 3 : static std::string const cHAMTObject4("MaterialProperty:HeatAndMoistureTransfer:Redistribution");
163 3 : static std::string const cHAMTObject5("MaterialProperty:HeatAndMoistureTransfer:Diffusion");
164 3 : static std::string const cHAMTObject6("MaterialProperty:HeatAndMoistureTransfer:ThermalConductivity");
165 3 : static std::string const cHAMTObject7("SurfaceProperties:VaporCoefficients");
166 :
167 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
168 :
169 6 : Array1D_string AlphaArray;
170 6 : Array1D_string cAlphaFieldNames;
171 6 : Array1D_string cNumericFieldNames;
172 :
173 6 : Array1D_bool lAlphaBlanks;
174 6 : Array1D_bool lNumericBlanks;
175 :
176 6 : Array1D<Real64> NumArray;
177 :
178 : Real64 dumrh;
179 : Real64 dumdata;
180 : Real64 avdata;
181 :
182 : int MaxNums;
183 : int MaxAlphas;
184 : int NumParams;
185 : int NumNums;
186 : int NumAlphas;
187 : int status;
188 : int matid;
189 : int iso;
190 : int Numid;
191 : int suc;
192 : int red;
193 : int mu;
194 : int tc;
195 :
196 : int HAMTitems;
197 : int item;
198 : int ii;
199 : int jj;
200 : int vtcsid;
201 :
202 : bool avflag;
203 : bool isoerrrise;
204 : bool ErrorsFound;
205 :
206 3 : state.dataHeatBalHAMTMgr->watertot.allocate(state.dataSurface->TotSurfaces);
207 3 : state.dataHeatBalHAMTMgr->surfrh.allocate(state.dataSurface->TotSurfaces);
208 3 : state.dataHeatBalHAMTMgr->surfextrh.allocate(state.dataSurface->TotSurfaces);
209 3 : state.dataHeatBalHAMTMgr->surftemp.allocate(state.dataSurface->TotSurfaces);
210 3 : state.dataHeatBalHAMTMgr->surfexttemp.allocate(state.dataSurface->TotSurfaces);
211 3 : state.dataHeatBalHAMTMgr->surfvp.allocate(state.dataSurface->TotSurfaces);
212 :
213 3 : state.dataHeatBalHAMTMgr->firstcell.allocate(state.dataSurface->TotSurfaces);
214 3 : state.dataHeatBalHAMTMgr->lastcell.allocate(state.dataSurface->TotSurfaces);
215 3 : state.dataHeatBalHAMTMgr->Extcell.allocate(state.dataSurface->TotSurfaces);
216 3 : state.dataHeatBalHAMTMgr->ExtRadcell.allocate(state.dataSurface->TotSurfaces);
217 3 : state.dataHeatBalHAMTMgr->ExtConcell.allocate(state.dataSurface->TotSurfaces);
218 3 : state.dataHeatBalHAMTMgr->ExtSkycell.allocate(state.dataSurface->TotSurfaces);
219 3 : state.dataHeatBalHAMTMgr->ExtGrncell.allocate(state.dataSurface->TotSurfaces);
220 3 : state.dataHeatBalHAMTMgr->Intcell.allocate(state.dataSurface->TotSurfaces);
221 3 : state.dataHeatBalHAMTMgr->IntConcell.allocate(state.dataSurface->TotSurfaces);
222 :
223 3 : state.dataHeatBalHAMTMgr->extvtc.allocate(state.dataSurface->TotSurfaces);
224 3 : state.dataHeatBalHAMTMgr->intvtc.allocate(state.dataSurface->TotSurfaces);
225 3 : state.dataHeatBalHAMTMgr->extvtcflag.allocate(state.dataSurface->TotSurfaces);
226 3 : state.dataHeatBalHAMTMgr->intvtcflag.allocate(state.dataSurface->TotSurfaces);
227 3 : state.dataHeatBalHAMTMgr->MyEnvrnFlag.allocate(state.dataSurface->TotSurfaces);
228 :
229 3 : state.dataHeatBalHAMTMgr->extvtc = -1.0;
230 3 : state.dataHeatBalHAMTMgr->intvtc = -1.0;
231 3 : state.dataHeatBalHAMTMgr->extvtcflag = false;
232 3 : state.dataHeatBalHAMTMgr->intvtcflag = false;
233 3 : state.dataHeatBalHAMTMgr->MyEnvrnFlag = true;
234 :
235 3 : state.dataHeatBalHAMTMgr->latswitch = true;
236 3 : state.dataHeatBalHAMTMgr->rainswitch = true;
237 :
238 3 : MaxAlphas = 0;
239 3 : MaxNums = 0;
240 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject1, NumParams, NumAlphas, NumNums);
241 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
242 3 : MaxNums = max(MaxNums, NumNums);
243 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject2, NumParams, NumAlphas, NumNums);
244 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
245 3 : MaxNums = max(MaxNums, NumNums);
246 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject3, NumParams, NumAlphas, NumNums);
247 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
248 3 : MaxNums = max(MaxNums, NumNums);
249 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject4, NumParams, NumAlphas, NumNums);
250 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
251 3 : MaxNums = max(MaxNums, NumNums);
252 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject5, NumParams, NumAlphas, NumNums);
253 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
254 3 : MaxNums = max(MaxNums, NumNums);
255 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject6, NumParams, NumAlphas, NumNums);
256 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
257 3 : MaxNums = max(MaxNums, NumNums);
258 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cHAMTObject7, NumParams, NumAlphas, NumNums);
259 3 : MaxAlphas = max(MaxAlphas, NumAlphas);
260 3 : MaxNums = max(MaxNums, NumNums);
261 :
262 3 : ErrorsFound = false;
263 :
264 3 : AlphaArray.allocate(MaxAlphas);
265 3 : cAlphaFieldNames.allocate(MaxAlphas);
266 3 : cNumericFieldNames.allocate(MaxNums);
267 3 : NumArray.dimension(MaxNums, 0.0);
268 3 : lAlphaBlanks.dimension(MaxAlphas, false);
269 3 : lNumericBlanks.dimension(MaxNums, false);
270 :
271 3 : HAMTitems =
272 3 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cHAMTObject1); // MaterialProperty:HeatAndMoistureTransfer:Settings
273 16 : for (item = 1; item <= HAMTitems; ++item) {
274 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
275 : cHAMTObject1,
276 : item,
277 : AlphaArray,
278 : NumAlphas,
279 : NumArray,
280 : NumNums,
281 : status,
282 : lNumericBlanks,
283 : lAlphaBlanks,
284 : cAlphaFieldNames,
285 : cNumericFieldNames);
286 :
287 13 : matid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataMaterial->Material);
288 :
289 13 : if (matid == 0) {
290 0 : ShowSevereError(state, cHAMTObject1 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
291 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
292 0 : ErrorsFound = true;
293 0 : continue;
294 : }
295 13 : if (state.dataMaterial->Material(matid).ROnly) {
296 0 : ShowWarningError(state,
297 0 : cHAMTObject1 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is defined as an R-only value material.");
298 0 : continue;
299 : }
300 :
301 13 : state.dataMaterial->Material(matid).Porosity = NumArray(1);
302 13 : state.dataMaterial->Material(matid).iwater = NumArray(2);
303 : }
304 :
305 3 : HAMTitems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(
306 : state, cHAMTObject2); // MaterialProperty:HeatAndMoistureTransfer:SorptionIsotherm
307 16 : for (item = 1; item <= HAMTitems; ++item) {
308 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
309 : cHAMTObject2,
310 : item,
311 : AlphaArray,
312 : NumAlphas,
313 : NumArray,
314 : NumNums,
315 : status,
316 : lNumericBlanks,
317 : lAlphaBlanks,
318 : cAlphaFieldNames,
319 : cNumericFieldNames);
320 :
321 13 : matid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataMaterial->Material);
322 :
323 13 : if (matid == 0) {
324 0 : ShowSevereError(state, cHAMTObject2 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
325 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
326 0 : ErrorsFound = true;
327 0 : continue;
328 : }
329 13 : if (state.dataMaterial->Material(matid).ROnly) {
330 0 : ShowWarningError(state,
331 0 : cHAMTObject2 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is defined as an R-only value material.");
332 0 : continue;
333 : }
334 :
335 13 : Numid = 1;
336 :
337 13 : state.dataMaterial->Material(matid).niso = int(NumArray(Numid));
338 :
339 115 : for (iso = 1; iso <= state.dataMaterial->Material(matid).niso; ++iso) {
340 102 : ++Numid;
341 102 : state.dataMaterial->Material(matid).isorh(iso) = NumArray(Numid);
342 102 : ++Numid;
343 102 : state.dataMaterial->Material(matid).isodata(iso) = NumArray(Numid);
344 : }
345 :
346 13 : ++state.dataMaterial->Material(matid).niso;
347 13 : state.dataMaterial->Material(matid).isorh(state.dataMaterial->Material(matid).niso) = rhmax;
348 13 : state.dataMaterial->Material(matid).isodata(state.dataMaterial->Material(matid).niso) =
349 13 : state.dataMaterial->Material(matid).Porosity * wdensity;
350 :
351 13 : ++state.dataMaterial->Material(matid).niso;
352 13 : state.dataMaterial->Material(matid).isorh(state.dataMaterial->Material(matid).niso) = 0.0;
353 13 : state.dataMaterial->Material(matid).isodata(state.dataMaterial->Material(matid).niso) = 0.0;
354 : }
355 :
356 : // check the isotherm
357 27 : for (matid = 1; matid <= state.dataHeatBal->TotMaterials; ++matid) {
358 24 : if (state.dataMaterial->Material(matid).niso > 0) {
359 : // - First sort
360 128 : for (jj = 1; jj <= state.dataMaterial->Material(matid).niso - 1; ++jj) {
361 722 : for (ii = jj + 1; ii <= state.dataMaterial->Material(matid).niso; ++ii) {
362 607 : if (state.dataMaterial->Material(matid).isorh(jj) > state.dataMaterial->Material(matid).isorh(ii)) {
363 :
364 115 : dumrh = state.dataMaterial->Material(matid).isorh(jj);
365 115 : dumdata = state.dataMaterial->Material(matid).isodata(jj);
366 :
367 115 : state.dataMaterial->Material(matid).isorh(jj) = state.dataMaterial->Material(matid).isorh(ii);
368 115 : state.dataMaterial->Material(matid).isodata(jj) = state.dataMaterial->Material(matid).isodata(ii);
369 :
370 115 : state.dataMaterial->Material(matid).isorh(ii) = dumrh;
371 115 : state.dataMaterial->Material(matid).isodata(ii) = dumdata;
372 : }
373 : }
374 : }
375 : //- Now make sure the data rises
376 13 : isoerrrise = false;
377 13 : for (ii = 1; ii <= 100; ++ii) {
378 13 : avflag = true;
379 128 : for (jj = 1; jj <= state.dataMaterial->Material(matid).niso - 1; ++jj) {
380 115 : if (state.dataMaterial->Material(matid).isodata(jj) > state.dataMaterial->Material(matid).isodata(jj + 1)) {
381 0 : isoerrrise = true;
382 0 : avdata = (state.dataMaterial->Material(matid).isodata(jj) + state.dataMaterial->Material(matid).isodata(jj + 1)) / 2.0;
383 0 : state.dataMaterial->Material(matid).isodata(jj) = avdata;
384 0 : state.dataMaterial->Material(matid).isodata(jj + 1) = avdata;
385 0 : avflag = false;
386 : }
387 : }
388 13 : if (avflag) break;
389 : }
390 13 : if (isoerrrise) {
391 0 : ShowWarningError(state, cHAMTObject2 + " data not rising - Check material " + state.dataMaterial->Material(matid).Name);
392 0 : ShowContinueError(state, "Isotherm data has been fixed, and the simulation continues.");
393 : }
394 : }
395 : }
396 :
397 3 : HAMTitems =
398 3 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cHAMTObject3); // MaterialProperty:HeatAndMoistureTransfer:Suction
399 16 : for (item = 1; item <= HAMTitems; ++item) {
400 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
401 : cHAMTObject3,
402 : item,
403 : AlphaArray,
404 : NumAlphas,
405 : NumArray,
406 : NumNums,
407 : status,
408 : lNumericBlanks,
409 : lAlphaBlanks,
410 : cAlphaFieldNames,
411 : cNumericFieldNames);
412 :
413 13 : matid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataMaterial->Material);
414 :
415 13 : if (matid == 0) {
416 0 : ShowSevereError(state, cHAMTObject3 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
417 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
418 0 : ErrorsFound = true;
419 0 : continue;
420 : }
421 13 : if (state.dataMaterial->Material(matid).ROnly) {
422 0 : ShowWarningError(state,
423 0 : cHAMTObject3 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is defined as an R-only value material.");
424 0 : continue;
425 : }
426 :
427 13 : Numid = 1;
428 :
429 13 : state.dataMaterial->Material(matid).nsuc = NumArray(Numid);
430 44 : for (suc = 1; suc <= state.dataMaterial->Material(matid).nsuc; ++suc) {
431 31 : ++Numid;
432 31 : state.dataMaterial->Material(matid).sucwater(suc) = NumArray(Numid);
433 31 : ++Numid;
434 31 : state.dataMaterial->Material(matid).sucdata(suc) = NumArray(Numid);
435 : }
436 :
437 13 : ++state.dataMaterial->Material(matid).nsuc;
438 13 : state.dataMaterial->Material(matid).sucwater(state.dataMaterial->Material(matid).nsuc) =
439 13 : state.dataMaterial->Material(matid).isodata(state.dataMaterial->Material(matid).niso);
440 13 : state.dataMaterial->Material(matid).sucdata(state.dataMaterial->Material(matid).nsuc) =
441 13 : state.dataMaterial->Material(matid).sucdata(state.dataMaterial->Material(matid).nsuc - 1);
442 : }
443 :
444 3 : HAMTitems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(
445 : state, cHAMTObject4); // MaterialProperty:HeatAndMoistureTransfer:Redistribution
446 16 : for (item = 1; item <= HAMTitems; ++item) {
447 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
448 : cHAMTObject4,
449 : item,
450 : AlphaArray,
451 : NumAlphas,
452 : NumArray,
453 : NumNums,
454 : status,
455 : lNumericBlanks,
456 : lAlphaBlanks,
457 : cAlphaFieldNames,
458 : cNumericFieldNames);
459 :
460 13 : matid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataMaterial->Material);
461 13 : if (matid == 0) {
462 0 : ShowSevereError(state, cHAMTObject4 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
463 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
464 0 : ErrorsFound = true;
465 0 : continue;
466 : }
467 13 : if (state.dataMaterial->Material(matid).ROnly) {
468 0 : ShowWarningError(state,
469 0 : cHAMTObject4 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is defined as an R-only value material.");
470 0 : continue;
471 : }
472 13 : Numid = 1;
473 :
474 13 : state.dataMaterial->Material(matid).nred = NumArray(Numid);
475 44 : for (red = 1; red <= state.dataMaterial->Material(matid).nred; ++red) {
476 31 : ++Numid;
477 31 : state.dataMaterial->Material(matid).redwater(red) = NumArray(Numid);
478 31 : ++Numid;
479 31 : state.dataMaterial->Material(matid).reddata(red) = NumArray(Numid);
480 : }
481 :
482 13 : ++state.dataMaterial->Material(matid).nred;
483 13 : state.dataMaterial->Material(matid).redwater(state.dataMaterial->Material(matid).nred) =
484 13 : state.dataMaterial->Material(matid).isodata(state.dataMaterial->Material(matid).niso);
485 13 : state.dataMaterial->Material(matid).reddata(state.dataMaterial->Material(matid).nred) =
486 13 : state.dataMaterial->Material(matid).reddata(state.dataMaterial->Material(matid).nred - 1);
487 : }
488 :
489 3 : HAMTitems =
490 3 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cHAMTObject5); // MaterialProperty:HeatAndMoistureTransfer:Diffusion
491 16 : for (item = 1; item <= HAMTitems; ++item) {
492 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
493 : cHAMTObject5,
494 : item,
495 : AlphaArray,
496 : NumAlphas,
497 : NumArray,
498 : NumNums,
499 : status,
500 : lNumericBlanks,
501 : lAlphaBlanks,
502 : cAlphaFieldNames,
503 : cNumericFieldNames);
504 :
505 13 : matid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataMaterial->Material);
506 13 : if (matid == 0) {
507 0 : ShowSevereError(state, cHAMTObject5 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
508 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
509 0 : ErrorsFound = true;
510 0 : continue;
511 : }
512 13 : if (state.dataMaterial->Material(matid).ROnly) {
513 0 : ShowWarningError(state,
514 0 : cHAMTObject5 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is defined as an R-only value material.");
515 0 : continue;
516 : }
517 :
518 13 : Numid = 1;
519 :
520 13 : state.dataMaterial->Material(matid).nmu = NumArray(Numid);
521 13 : if (state.dataMaterial->Material(matid).nmu > 0) {
522 30 : for (mu = 1; mu <= state.dataMaterial->Material(matid).nmu; ++mu) {
523 17 : ++Numid;
524 17 : state.dataMaterial->Material(matid).murh(mu) = NumArray(Numid);
525 17 : ++Numid;
526 17 : state.dataMaterial->Material(matid).mudata(mu) = NumArray(Numid);
527 : }
528 :
529 13 : ++state.dataMaterial->Material(matid).nmu;
530 13 : state.dataMaterial->Material(matid).murh(state.dataMaterial->Material(matid).nmu) =
531 13 : state.dataMaterial->Material(matid).isorh(state.dataMaterial->Material(matid).niso);
532 13 : state.dataMaterial->Material(matid).mudata(state.dataMaterial->Material(matid).nmu) =
533 13 : state.dataMaterial->Material(matid).mudata(state.dataMaterial->Material(matid).nmu - 1);
534 : }
535 : }
536 :
537 3 : HAMTitems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(
538 : state, cHAMTObject6); // MaterialProperty:HeatAndMoistureTransfer:ThermalConductivity
539 16 : for (item = 1; item <= HAMTitems; ++item) {
540 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
541 : cHAMTObject6,
542 : item,
543 : AlphaArray,
544 : NumAlphas,
545 : NumArray,
546 : NumNums,
547 : status,
548 : lNumericBlanks,
549 : lAlphaBlanks,
550 : cAlphaFieldNames,
551 : cNumericFieldNames);
552 :
553 13 : matid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataMaterial->Material);
554 13 : if (matid == 0) {
555 0 : ShowSevereError(state, cHAMTObject6 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
556 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
557 0 : ErrorsFound = true;
558 0 : continue;
559 : }
560 13 : if (state.dataMaterial->Material(matid).ROnly) {
561 0 : ShowWarningError(state,
562 0 : cHAMTObject6 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is defined as an R-only value material.");
563 0 : continue;
564 : }
565 13 : Numid = 1;
566 :
567 13 : state.dataMaterial->Material(matid).ntc = NumArray(Numid);
568 13 : if (state.dataMaterial->Material(matid).ntc > 0) {
569 37 : for (tc = 1; tc <= state.dataMaterial->Material(matid).ntc; ++tc) {
570 24 : ++Numid;
571 24 : state.dataMaterial->Material(matid).tcwater(tc) = NumArray(Numid);
572 24 : ++Numid;
573 24 : state.dataMaterial->Material(matid).tcdata(tc) = NumArray(Numid);
574 : }
575 :
576 13 : ++state.dataMaterial->Material(matid).ntc;
577 13 : state.dataMaterial->Material(matid).tcwater(state.dataMaterial->Material(matid).ntc) =
578 13 : state.dataMaterial->Material(matid).isodata(state.dataMaterial->Material(matid).niso);
579 13 : state.dataMaterial->Material(matid).tcdata(state.dataMaterial->Material(matid).ntc) =
580 13 : state.dataMaterial->Material(matid).tcdata(state.dataMaterial->Material(matid).ntc - 1);
581 : }
582 : }
583 :
584 : // Vapor Transfer coefficients
585 3 : HAMTitems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cHAMTObject7); // SurfaceProperties:VaporCoefficients
586 15 : for (item = 1; item <= HAMTitems; ++item) {
587 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
588 : cHAMTObject7,
589 : item,
590 : AlphaArray,
591 : NumAlphas,
592 : NumArray,
593 : NumNums,
594 : status,
595 : lNumericBlanks,
596 : lAlphaBlanks,
597 : cAlphaFieldNames,
598 : cNumericFieldNames);
599 :
600 12 : vtcsid = UtilityRoutines::FindItemInList(AlphaArray(1), state.dataSurface->Surface);
601 12 : if (vtcsid == 0) {
602 0 : ShowSevereError(state, cHAMTObject7 + ' ' + cAlphaFieldNames(1) + "=\"" + AlphaArray(1) + "\" is invalid (undefined).");
603 0 : ShowContinueError(state, "The basic material must be defined in addition to specifying HeatAndMoistureTransfer properties.");
604 0 : ErrorsFound = true;
605 0 : continue;
606 : }
607 :
608 12 : if (AlphaArray(2) == "YES") {
609 12 : state.dataHeatBalHAMTMgr->extvtcflag(vtcsid) = true;
610 12 : state.dataHeatBalHAMTMgr->extvtc(vtcsid) = NumArray(1);
611 : }
612 :
613 12 : if (AlphaArray(3) == "YES") {
614 12 : state.dataHeatBalHAMTMgr->intvtcflag(vtcsid) = true;
615 12 : state.dataHeatBalHAMTMgr->intvtc(vtcsid) = NumArray(2);
616 : }
617 : }
618 :
619 3 : AlphaArray.deallocate();
620 3 : cAlphaFieldNames.deallocate();
621 3 : cNumericFieldNames.deallocate();
622 3 : NumArray.deallocate();
623 3 : lAlphaBlanks.deallocate();
624 3 : lNumericBlanks.deallocate();
625 :
626 3 : if (ErrorsFound) {
627 0 : ShowFatalError(state, "GetHeatBalHAMTInput: Errors found getting input. Program terminates.");
628 : }
629 3 : }
630 :
631 3 : void InitHeatBalHAMT(EnergyPlusData &state)
632 : {
633 : // SUBROUTINE INFORMATION:
634 : // AUTHOR Phillip Biddulph
635 : // DATE WRITTEN June 2008
636 : // MODIFIED B. Griffith, Aug 2012 for surface-specific algorithms
637 : // RE-ENGINEERED na
638 :
639 : // Using/Aliasing
640 : using General::ScanForReports;
641 :
642 : // Locals
643 : // SUBROUTINE PARAMETER DEFINITIONS:
644 3 : Real64 constexpr adjdist(0.00005); // Allowable distance between two cells, also used as limit on cell length
645 : static constexpr std::string_view RoutineName("InitCombinedHeatAndMoistureFiniteElement: ");
646 :
647 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
648 : int ii;
649 : int cid;
650 : int cid1;
651 : int cid2;
652 : int sid;
653 : int conid;
654 : int lid;
655 : int matid;
656 : int did;
657 : int adj1;
658 : int adj2;
659 : int errorCount;
660 : int MaterNum;
661 :
662 : Real64 runor;
663 : Real64 high1;
664 : Real64 low2;
665 : Real64 testlen;
666 : Real64 waterd; // water density
667 : bool DoReport;
668 :
669 3 : auto &cells(state.dataHeatBalHAMTMgr->cells);
670 :
671 3 : state.dataHeatBalHAMTMgr->deltat = state.dataGlobal->TimeStepZone * 3600.0;
672 :
673 : // Check the materials information and work out how many cells are required.
674 3 : errorCount = 0;
675 3 : state.dataHeatBalHAMTMgr->TotCellsMax = 0;
676 27 : for (sid = 1; sid <= state.dataSurface->TotSurfaces; ++sid) {
677 24 : if (state.dataSurface->Surface(sid).Class == SurfaceClass::Window) continue;
678 20 : if (state.dataSurface->Surface(sid).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::HAMT) continue;
679 13 : conid = state.dataSurface->Surface(sid).Construction;
680 13 : if (conid == 0) continue;
681 59 : for (lid = 1; lid <= state.dataConstruction->Construct(conid).TotLayers; ++lid) {
682 46 : matid = state.dataConstruction->Construct(conid).LayerPoint(lid);
683 46 : if (state.dataMaterial->Material(matid).ROnly) {
684 0 : ShowSevereError(state,
685 0 : std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name +
686 : " cannot contain R-only value materials.");
687 0 : ShowContinueError(state, "Reference Material=\"" + state.dataMaterial->Material(matid).Name + "\".");
688 0 : ++errorCount;
689 0 : continue;
690 : }
691 :
692 46 : if (state.dataMaterial->Material(matid).nmu < 0) {
693 0 : ShowSevereError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
694 0 : ShowContinueError(state,
695 0 : "Reference Material=\"" + state.dataMaterial->Material(matid).Name +
696 : "\" does not have required Water Vapor Diffusion Resistance Factor (mu) data.");
697 0 : ++errorCount;
698 : }
699 :
700 46 : if (state.dataMaterial->Material(matid).niso < 0) {
701 0 : ShowSevereError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
702 0 : ShowContinueError(
703 0 : state, "Reference Material=\"" + state.dataMaterial->Material(matid).Name + "\" does not have required isotherm data.");
704 0 : ++errorCount;
705 : }
706 46 : if (state.dataMaterial->Material(matid).nsuc < 0) {
707 0 : ShowSevereError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
708 0 : ShowContinueError(state,
709 0 : "Reference Material=\"" + state.dataMaterial->Material(matid).Name +
710 : "\" does not have required liquid transport coefficient (suction) data.");
711 0 : ++errorCount;
712 : }
713 46 : if (state.dataMaterial->Material(matid).nred < 0) {
714 0 : ShowSevereError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
715 0 : ShowContinueError(state,
716 0 : "Reference Material=\"" + state.dataMaterial->Material(matid).Name +
717 : "\" does not have required liquid transport coefficient (redistribution) data.");
718 0 : ++errorCount;
719 : }
720 46 : if (state.dataMaterial->Material(matid).ntc < 0) {
721 0 : if (state.dataMaterial->Material(matid).Conductivity > 0) {
722 0 : ShowWarningError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
723 0 : ShowContinueError(state,
724 0 : "Reference Material=\"" + state.dataMaterial->Material(matid).Name +
725 : "\" does not have thermal conductivity data. Using fixed value.");
726 0 : state.dataMaterial->Material(matid).ntc = 2;
727 0 : state.dataMaterial->Material(matid).tcwater(1) = 0.0;
728 0 : state.dataMaterial->Material(matid).tcdata(1) = state.dataMaterial->Material(matid).Conductivity;
729 0 : state.dataMaterial->Material(matid).tcwater(2) =
730 0 : state.dataMaterial->Material(matid).isodata(state.dataMaterial->Material(matid).niso);
731 0 : state.dataMaterial->Material(matid).tcdata(2) = state.dataMaterial->Material(matid).Conductivity;
732 : } else {
733 0 : ShowSevereError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
734 0 : ShowContinueError(state,
735 0 : "Reference Material=\"" + state.dataMaterial->Material(matid).Name +
736 : "\" does not have required thermal conductivity data.");
737 0 : ++errorCount;
738 : }
739 : }
740 :
741 : // convert material water content to RH
742 :
743 46 : waterd = state.dataMaterial->Material(matid).iwater * state.dataMaterial->Material(matid).Density;
744 184 : interp(state.dataMaterial->Material(matid).niso,
745 46 : state.dataMaterial->Material(matid).isodata,
746 46 : state.dataMaterial->Material(matid).isorh,
747 : waterd,
748 46 : state.dataMaterial->Material(matid).irh);
749 :
750 46 : state.dataMaterial->Material(matid).divs =
751 92 : int(state.dataMaterial->Material(matid).Thickness / state.dataMaterial->Material(matid).divsize) +
752 46 : state.dataMaterial->Material(matid).divmin;
753 46 : if (state.dataMaterial->Material(matid).divs > state.dataMaterial->Material(matid).divmax) {
754 22 : state.dataMaterial->Material(matid).divs = state.dataMaterial->Material(matid).divmax;
755 : }
756 : // Check length of cell - reduce number of divisions if necessary
757 46 : Real64 const sin_negPIOvr2 = std::sin(-DataGlobalConstants::Pi / 2.0);
758 : while (true) {
759 92 : testlen = state.dataMaterial->Material(matid).Thickness *
760 46 : ((std::sin(DataGlobalConstants::Pi * (-1.0 / double(state.dataMaterial->Material(matid).divs)) -
761 46 : DataGlobalConstants::Pi / 2.0) /
762 46 : 2.0) -
763 : (sin_negPIOvr2 / 2.0));
764 46 : if (testlen > adjdist) break;
765 0 : --state.dataMaterial->Material(matid).divs;
766 0 : if (state.dataMaterial->Material(matid).divs < 1) {
767 0 : ShowSevereError(state, std::string{RoutineName} + "Construction=" + state.dataConstruction->Construct(conid).Name);
768 0 : ShowContinueError(state, "Reference Material=\"" + state.dataMaterial->Material(matid).Name + "\" is too thin.");
769 0 : ++errorCount;
770 0 : break;
771 : }
772 : }
773 46 : state.dataHeatBalHAMTMgr->TotCellsMax += state.dataMaterial->Material(matid).divs;
774 : }
775 13 : state.dataHeatBalHAMTMgr->TotCellsMax += 7;
776 : }
777 :
778 3 : if (errorCount > 0) {
779 0 : ShowFatalError(state, "CombinedHeatAndMoistureFiniteElement: Incomplete data to start solution, program terminates.");
780 : }
781 :
782 : // Make the cells and initialize
783 3 : cells.allocate(state.dataHeatBalHAMTMgr->TotCellsMax);
784 440 : for (auto &e : cells) {
785 437 : e.adjs = -1;
786 437 : e.adjsl = -1;
787 : }
788 :
789 3 : cid = 0;
790 :
791 : // Set up surface cell structure
792 27 : for (sid = 1; sid <= state.dataSurface->TotSurfaces; ++sid) {
793 24 : if (!state.dataSurface->Surface(sid).HeatTransSurf) continue;
794 22 : if (state.dataSurface->Surface(sid).Class == SurfaceClass::Window) continue;
795 18 : if (state.dataSurface->Surface(sid).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::HAMT) continue;
796 : // Boundary Cells
797 13 : runor = -0.02;
798 : // Air Convection Cell
799 13 : ++cid;
800 13 : state.dataHeatBalHAMTMgr->firstcell(sid) = cid;
801 13 : state.dataHeatBalHAMTMgr->ExtConcell(sid) = cid;
802 13 : cells(cid).rh = 0.0;
803 13 : cells(cid).sid = sid;
804 13 : cells(cid).length(1) = 0.01;
805 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
806 :
807 : // Air Radiation Cell
808 13 : ++cid;
809 13 : state.dataHeatBalHAMTMgr->ExtRadcell(sid) = cid;
810 13 : cells(cid).rh = 0.0;
811 13 : cells(cid).sid = sid;
812 13 : cells(cid).length(1) = 0.01;
813 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
814 :
815 : // Sky Cell
816 13 : ++cid;
817 13 : state.dataHeatBalHAMTMgr->ExtSkycell(sid) = cid;
818 13 : cells(cid).rh = 0.0;
819 13 : cells(cid).sid = sid;
820 13 : cells(cid).length(1) = 0.01;
821 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
822 :
823 : // Ground Cell
824 13 : ++cid;
825 13 : state.dataHeatBalHAMTMgr->ExtGrncell(sid) = cid;
826 13 : cells(cid).rh = 0.0;
827 13 : cells(cid).sid = sid;
828 13 : cells(cid).length(1) = 0.01;
829 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
830 13 : runor += cells(cid).length(1);
831 :
832 : // External Virtual Cell
833 13 : ++cid;
834 13 : state.dataHeatBalHAMTMgr->Extcell(sid) = cid;
835 13 : cells(cid).rh = 0.0;
836 13 : cells(cid).sid = sid;
837 13 : cells(cid).length(1) = 0.01;
838 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
839 13 : runor += cells(cid).length(1);
840 :
841 : // Material Cells
842 13 : conid = state.dataSurface->Surface(sid).Construction;
843 59 : for (lid = 1; lid <= state.dataConstruction->Construct(conid).TotLayers; ++lid) {
844 46 : matid = state.dataConstruction->Construct(conid).LayerPoint(lid);
845 :
846 392 : for (did = 1; did <= state.dataMaterial->Material(matid).divs; ++did) {
847 346 : ++cid;
848 :
849 346 : cells(cid).matid = matid;
850 346 : cells(cid).sid = sid;
851 :
852 346 : cells(cid).temp = state.dataMaterial->Material(matid).itemp;
853 346 : cells(cid).tempp1 = state.dataMaterial->Material(matid).itemp;
854 346 : cells(cid).tempp2 = state.dataMaterial->Material(matid).itemp;
855 :
856 346 : cells(cid).rh = state.dataMaterial->Material(matid).irh;
857 346 : cells(cid).rhp1 = state.dataMaterial->Material(matid).irh;
858 346 : cells(cid).rhp2 = state.dataMaterial->Material(matid).irh;
859 :
860 346 : cells(cid).density = state.dataMaterial->Material(matid).Density;
861 346 : cells(cid).spech = state.dataMaterial->Material(matid).SpecHeat;
862 :
863 : // Make cells smaller near the surface
864 346 : cells(cid).length(1) =
865 692 : state.dataMaterial->Material(matid).Thickness *
866 346 : ((std::sin(DataGlobalConstants::Pi * (-double(did) / double(state.dataMaterial->Material(matid).divs)) -
867 346 : DataGlobalConstants::Pi / 2.0) /
868 346 : 2.0) -
869 346 : (std::sin(DataGlobalConstants::Pi * (-double(did - 1) / double(state.dataMaterial->Material(matid).divs)) -
870 346 : DataGlobalConstants::Pi / 2.0) /
871 : 2.0));
872 :
873 346 : cells(cid).origin(1) = runor + cells(cid).length(1) / 2.0;
874 346 : runor += cells(cid).length(1);
875 :
876 346 : cells(cid).volume = cells(cid).length(1) * state.dataSurface->Surface(sid).Area;
877 : }
878 : }
879 :
880 : // Interior Virtual Cell
881 13 : ++cid;
882 13 : state.dataHeatBalHAMTMgr->Intcell(sid) = cid;
883 13 : cells(cid).sid = sid;
884 13 : cells(cid).rh = 0.0;
885 13 : cells(cid).length(1) = 0.01;
886 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
887 13 : runor += cells(cid).length(1);
888 :
889 : // Air Convection Cell
890 13 : ++cid;
891 13 : state.dataHeatBalHAMTMgr->lastcell(sid) = cid;
892 13 : state.dataHeatBalHAMTMgr->IntConcell(sid) = cid;
893 13 : cells(cid).rh = 0.0;
894 13 : cells(cid).sid = sid;
895 13 : cells(cid).length(1) = 0.01;
896 13 : cells(cid).origin(1) = cells(cid).length(1) / 2.0 + runor;
897 : }
898 :
899 : // Find adjacent cells.
900 440 : for (cid1 = 1; cid1 <= state.dataHeatBalHAMTMgr->TotCellsMax; ++cid1) {
901 81806 : for (cid2 = 1; cid2 <= state.dataHeatBalHAMTMgr->TotCellsMax; ++cid2) {
902 81369 : if ((cid1 != cid2) && (cells(cid1).sid == cells(cid2).sid)) {
903 14652 : high1 = cells(cid1).origin(1) + cells(cid1).length(1) / 2.0;
904 14652 : low2 = cells(cid2).origin(1) - cells(cid2).length(1) / 2.0;
905 14652 : if (std::abs(low2 - high1) < adjdist) {
906 424 : adj1 = 0;
907 835 : for (ii = 1; ii <= adjmax; ++ii) {
908 835 : ++adj1;
909 835 : if (cells(cid1).adjs(adj1) == -1) break;
910 : }
911 424 : adj2 = 0;
912 502 : for (ii = 1; ii <= adjmax; ++ii) {
913 502 : ++adj2;
914 502 : if (cells(cid2).adjs(adj2) == -1) break;
915 : }
916 424 : cells(cid1).adjs(adj1) = cid2;
917 424 : cells(cid2).adjs(adj2) = cid1;
918 :
919 424 : cells(cid1).adjsl(adj1) = adj2;
920 424 : cells(cid2).adjsl(adj2) = adj1;
921 :
922 424 : sid = cells(cid1).sid;
923 424 : cells(cid1).overlap(adj1) = state.dataSurface->Surface(sid).Area;
924 424 : cells(cid2).overlap(adj2) = state.dataSurface->Surface(sid).Area;
925 424 : cells(cid1).dist(adj1) = cells(cid1).length(1) / 2.0;
926 424 : cells(cid2).dist(adj2) = cells(cid2).length(1) / 2.0;
927 : }
928 : }
929 : }
930 : }
931 :
932 : // Reset surface virtual cell origins and volumes. Initialize report variables.
933 : static constexpr std::string_view Format_1966("! <HAMT cells>, Surface Name, Construction Name, Cell Numbers\n");
934 3 : print(state.files.eio, Format_1966);
935 : static constexpr std::string_view Format_1965("! <HAMT origins>, Surface Name, Construction Name, Cell origins (m) \n");
936 3 : print(state.files.eio, Format_1965);
937 : // cCurrentModuleObject='MaterialProperty:HeatAndMoistureTransfer:*'
938 27 : for (sid = 1; sid <= state.dataSurface->TotSurfaces; ++sid) {
939 24 : if (!state.dataSurface->Surface(sid).HeatTransSurf) continue;
940 22 : if (state.dataSurface->Surface(sid).Class == SurfaceClass::Window) continue;
941 18 : if (state.dataSurface->Surface(sid).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::HAMT) continue;
942 13 : cells(state.dataHeatBalHAMTMgr->Extcell(sid)).origin(1) += cells(state.dataHeatBalHAMTMgr->Extcell(sid)).length(1) / 2.0;
943 13 : cells(state.dataHeatBalHAMTMgr->Intcell(sid)).origin(1) -= cells(state.dataHeatBalHAMTMgr->Intcell(sid)).length(1) / 2.0;
944 13 : cells(state.dataHeatBalHAMTMgr->Extcell(sid)).volume = 0.0;
945 13 : cells(state.dataHeatBalHAMTMgr->Intcell(sid)).volume = 0.0;
946 13 : state.dataHeatBalHAMTMgr->watertot(sid) = 0.0;
947 13 : state.dataHeatBalHAMTMgr->surfrh(sid) = 0.0;
948 13 : state.dataHeatBalHAMTMgr->surfextrh(sid) = 0.0;
949 13 : state.dataHeatBalHAMTMgr->surftemp(sid) = 0.0;
950 13 : state.dataHeatBalHAMTMgr->surfexttemp(sid) = 0.0;
951 13 : state.dataHeatBalHAMTMgr->surfvp(sid) = 0.0;
952 39 : SetupOutputVariable(state,
953 : "HAMT Surface Average Water Content Ratio",
954 : OutputProcessor::Unit::kg_kg,
955 13 : state.dataHeatBalHAMTMgr->watertot(sid),
956 : OutputProcessor::SOVTimeStepType::Zone,
957 : OutputProcessor::SOVStoreType::State,
958 26 : state.dataSurface->Surface(sid).Name);
959 39 : SetupOutputVariable(state,
960 : "HAMT Surface Inside Face Temperature",
961 : OutputProcessor::Unit::C,
962 13 : state.dataHeatBalHAMTMgr->surftemp(sid),
963 : OutputProcessor::SOVTimeStepType::Zone,
964 : OutputProcessor::SOVStoreType::State,
965 26 : state.dataSurface->Surface(sid).Name);
966 39 : SetupOutputVariable(state,
967 : "HAMT Surface Inside Face Relative Humidity",
968 : OutputProcessor::Unit::Perc,
969 13 : state.dataHeatBalHAMTMgr->surfrh(sid),
970 : OutputProcessor::SOVTimeStepType::Zone,
971 : OutputProcessor::SOVStoreType::State,
972 26 : state.dataSurface->Surface(sid).Name);
973 39 : SetupOutputVariable(state,
974 : "HAMT Surface Inside Face Vapor Pressure",
975 : OutputProcessor::Unit::Pa,
976 13 : state.dataHeatBalHAMTMgr->surfvp(sid),
977 : OutputProcessor::SOVTimeStepType::Zone,
978 : OutputProcessor::SOVStoreType::State,
979 26 : state.dataSurface->Surface(sid).Name);
980 39 : SetupOutputVariable(state,
981 : "HAMT Surface Outside Face Temperature",
982 : OutputProcessor::Unit::C,
983 13 : state.dataHeatBalHAMTMgr->surfexttemp(sid),
984 : OutputProcessor::SOVTimeStepType::Zone,
985 : OutputProcessor::SOVStoreType::State,
986 26 : state.dataSurface->Surface(sid).Name);
987 39 : SetupOutputVariable(state,
988 : "HAMT Surface Outside Face Relative Humidity",
989 : OutputProcessor::Unit::Perc,
990 13 : state.dataHeatBalHAMTMgr->surfextrh(sid),
991 : OutputProcessor::SOVTimeStepType::Zone,
992 : OutputProcessor::SOVStoreType::State,
993 26 : state.dataSurface->Surface(sid).Name);
994 :
995 : // write cell origins to initialization output file
996 13 : conid = state.dataSurface->Surface(sid).Construction;
997 13 : print(state.files.eio, "HAMT cells, {},{}", state.dataSurface->Surface(sid).Name, state.dataConstruction->Construct(conid).Name);
998 385 : for (int concell = 1, concell_end = state.dataHeatBalHAMTMgr->Intcell(sid) - state.dataHeatBalHAMTMgr->Extcell(sid) + 1;
999 385 : concell <= concell_end;
1000 : ++concell) {
1001 372 : print(state.files.eio, ",{:4}", concell);
1002 : }
1003 13 : print(state.files.eio, "\n");
1004 13 : print(state.files.eio, "HAMT origins,{},{}", state.dataSurface->Surface(sid).Name, state.dataConstruction->Construct(conid).Name);
1005 385 : for (int cellid = state.dataHeatBalHAMTMgr->Extcell(sid); cellid <= state.dataHeatBalHAMTMgr->Intcell(sid); ++cellid) {
1006 372 : print(state.files.eio, ",{:10.7F}", cells(cellid).origin(1));
1007 : }
1008 13 : print(state.files.eio, "\n");
1009 :
1010 385 : for (int cellid = state.dataHeatBalHAMTMgr->Extcell(sid), concell = 1; cellid <= state.dataHeatBalHAMTMgr->Intcell(sid);
1011 : ++cellid, ++concell) {
1012 1860 : SetupOutputVariable(state,
1013 744 : format("HAMT Surface Temperature Cell {}", concell),
1014 : OutputProcessor::Unit::C,
1015 372 : cells(cellid).temp,
1016 : OutputProcessor::SOVTimeStepType::Zone,
1017 : OutputProcessor::SOVStoreType::State,
1018 372 : state.dataSurface->Surface(sid).Name);
1019 : }
1020 385 : for (int cellid = state.dataHeatBalHAMTMgr->Extcell(sid), concell = 1; cellid <= state.dataHeatBalHAMTMgr->Intcell(sid);
1021 : ++cellid, ++concell) {
1022 1860 : SetupOutputVariable(state,
1023 744 : format("HAMT Surface Water Content Cell {}", concell),
1024 : OutputProcessor::Unit::kg_kg,
1025 372 : cells(cellid).wreport,
1026 : OutputProcessor::SOVTimeStepType::Zone,
1027 : OutputProcessor::SOVStoreType::State,
1028 372 : state.dataSurface->Surface(sid).Name);
1029 : }
1030 385 : for (int cellid = state.dataHeatBalHAMTMgr->Extcell(sid), concell = 1; cellid <= state.dataHeatBalHAMTMgr->Intcell(sid);
1031 : ++cellid, ++concell) {
1032 1860 : SetupOutputVariable(state,
1033 744 : format("HAMT Surface Relative Humidity Cell {}", concell),
1034 : OutputProcessor::Unit::Perc,
1035 372 : cells(cellid).rhp,
1036 : OutputProcessor::SOVTimeStepType::Zone,
1037 : OutputProcessor::SOVStoreType::State,
1038 372 : state.dataSurface->Surface(sid).Name);
1039 : }
1040 : }
1041 :
1042 3 : ScanForReports(state, "Constructions", DoReport, "Constructions");
1043 3 : if (DoReport) {
1044 :
1045 : static constexpr std::string_view Format_108("! <Material Nominal Resistance>, Material Name, Nominal R\n");
1046 2 : print(state.files.eio, Format_108);
1047 :
1048 19 : for (MaterNum = 1; MaterNum <= state.dataHeatBal->TotMaterials; ++MaterNum) {
1049 :
1050 : static constexpr std::string_view Format_111("Material Nominal Resistance,{},{:.4R}\n");
1051 17 : print(state.files.eio, Format_111, state.dataMaterial->Material(MaterNum).Name, state.dataHeatBal->NominalR(MaterNum));
1052 : }
1053 : }
1054 3 : }
1055 :
1056 353337 : void CalcHeatBalHAMT(EnergyPlusData &state, int const sid, Real64 &SurfTempInTmp, Real64 &TempSurfOutTmp)
1057 : {
1058 : // SUBROUTINE INFORMATION:
1059 : // AUTHOR Phillip Biddulph
1060 : // DATE WRITTEN June 2008
1061 : // MODIFIED na
1062 : // RE-ENGINEERED na
1063 :
1064 : // PURPOSE OF THIS SUBROUTINE:
1065 : // To calculate the heat and moisture transfer through the surface
1066 :
1067 : // Using/Aliasing
1068 : using DataSurfaces::OtherSideCondModeledExt;
1069 :
1070 : // Locals
1071 : // SUBROUTINE ARGUMENT DEFINITIONS:
1072 :
1073 : // SUBROUTINE PARAMETER DEFINITIONS:
1074 353337 : static std::string const HAMTExt("HAMT-Ext");
1075 353337 : static std::string const HAMTInt("HAMT-Int");
1076 :
1077 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1078 : Real64 SurfTempInP;
1079 : Real64 RhoIn;
1080 : Real64 RhoOut;
1081 : Real64 torsum;
1082 : Real64 oorsum;
1083 : Real64 phioosum;
1084 : Real64 phiorsum;
1085 : Real64 vpoosum;
1086 : Real64 vporsum;
1087 : Real64 rhr1;
1088 : Real64 rhr2;
1089 : Real64 wcap;
1090 : Real64 thermr1;
1091 : Real64 thermr2;
1092 : Real64 tcap;
1093 : Real64 qvp;
1094 : Real64 vaporr1;
1095 : Real64 vaporr2;
1096 : Real64 vpdiff;
1097 : Real64 sumtp1;
1098 : Real64 tempmax;
1099 : Real64 tempmin;
1100 :
1101 : int ii;
1102 : int matid;
1103 : int itter;
1104 : int cid;
1105 : int adj;
1106 : int adjl;
1107 :
1108 353337 : auto &qvpErrCount = state.dataHeatBalHAMTMgr->qvpErrCount;
1109 353337 : auto &qvpErrReport = state.dataHeatBalHAMTMgr->qvpErrReport;
1110 : Real64 denominator;
1111 :
1112 353337 : auto &cells(state.dataHeatBalHAMTMgr->cells);
1113 353337 : auto &Extcell(state.dataHeatBalHAMTMgr->Extcell);
1114 353337 : auto &Intcell(state.dataHeatBalHAMTMgr->Intcell);
1115 :
1116 353337 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalHAMTMgr->MyEnvrnFlag(sid)) {
1117 118 : cells(Extcell(sid)).rh = 0.0;
1118 118 : cells(Extcell(sid)).rhp1 = 0.0;
1119 118 : cells(Extcell(sid)).rhp2 = 0.0;
1120 :
1121 118 : cells(Extcell(sid)).temp = 10.0;
1122 118 : cells(Extcell(sid)).tempp1 = 10.0;
1123 118 : cells(Extcell(sid)).tempp2 = 10.0;
1124 :
1125 118 : cells(Intcell(sid)).rh = 0.0;
1126 118 : cells(Intcell(sid)).rhp1 = 0.0;
1127 118 : cells(Intcell(sid)).rhp2 = 0.0;
1128 :
1129 118 : cells(Intcell(sid)).temp = 10.0;
1130 118 : cells(Intcell(sid)).tempp1 = 10.0;
1131 118 : cells(Intcell(sid)).tempp2 = 10.0;
1132 :
1133 3240 : for (cid = Extcell(sid) + 1; cid <= Intcell(sid) - 1; ++cid) {
1134 3122 : matid = cells(cid).matid;
1135 :
1136 3122 : cells(cid).temp = state.dataMaterial->Material(matid).itemp;
1137 3122 : cells(cid).tempp1 = state.dataMaterial->Material(matid).itemp;
1138 3122 : cells(cid).tempp2 = state.dataMaterial->Material(matid).itemp;
1139 :
1140 3122 : cells(cid).rh = state.dataMaterial->Material(matid).irh;
1141 3122 : cells(cid).rhp1 = state.dataMaterial->Material(matid).irh;
1142 3122 : cells(cid).rhp2 = state.dataMaterial->Material(matid).irh;
1143 : }
1144 118 : state.dataHeatBalHAMTMgr->MyEnvrnFlag(sid) = false;
1145 : }
1146 353337 : if (!state.dataGlobal->BeginEnvrnFlag) {
1147 352727 : state.dataHeatBalHAMTMgr->MyEnvrnFlag(sid) = true;
1148 : }
1149 :
1150 : // Set all the boundary values
1151 353337 : cells(state.dataHeatBalHAMTMgr->ExtRadcell(sid)).temp = state.dataMstBal->TempOutsideAirFD(sid);
1152 353337 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).temp = state.dataMstBal->TempOutsideAirFD(sid);
1153 353337 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(sid).Zone);
1154 353337 : if (state.dataSurface->Surface(sid).ExtBoundCond == OtherSideCondModeledExt) {
1155 : // CR8046 switch modeled rad temp for sky temp.
1156 0 : cells(state.dataHeatBalHAMTMgr->ExtSkycell(sid)).temp = state.dataSurface->OSCM(state.dataSurface->Surface(sid).OSCMPtr).TRad;
1157 0 : cells(Extcell(sid)).Qadds = 0.0; // eliminate incident shortwave on underlying surface
1158 : } else {
1159 353337 : cells(state.dataHeatBalHAMTMgr->ExtSkycell(sid)).temp = state.dataEnvrn->SkyTemp;
1160 :
1161 353337 : cells(Extcell(sid)).Qadds = state.dataSurface->Surface(sid).Area * state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(sid);
1162 : }
1163 :
1164 353337 : cells(state.dataHeatBalHAMTMgr->ExtGrncell(sid)).temp = state.dataMstBal->TempOutsideAirFD(sid);
1165 353337 : RhoOut = state.dataMstBal->RhoVaporAirOut(sid);
1166 :
1167 : // Special case when the surface is an internal mass
1168 353337 : if (state.dataSurface->Surface(sid).ExtBoundCond == sid) {
1169 0 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).temp = thisZoneHB.MAT;
1170 0 : RhoOut = state.dataMstBal->RhoVaporAirIn(sid);
1171 : }
1172 :
1173 353337 : RhoIn = state.dataMstBal->RhoVaporAirIn(sid);
1174 :
1175 353337 : cells(state.dataHeatBalHAMTMgr->ExtRadcell(sid)).htc = state.dataMstBal->HAirFD(sid);
1176 353337 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).htc = state.dataMstBal->HConvExtFD(sid);
1177 353337 : cells(state.dataHeatBalHAMTMgr->ExtSkycell(sid)).htc = state.dataMstBal->HSkyFD(sid);
1178 353337 : cells(state.dataHeatBalHAMTMgr->ExtGrncell(sid)).htc = state.dataMstBal->HGrndFD(sid);
1179 :
1180 353337 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).temp = thisZoneHB.MAT;
1181 :
1182 353337 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).htc = state.dataMstBal->HConvInFD(sid);
1183 :
1184 706674 : cells(Intcell(sid)).Qadds = state.dataSurface->Surface(sid).Area *
1185 706674 : (state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(sid) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(sid) +
1186 1060011 : state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(sid) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(sid) +
1187 353337 : state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(sid));
1188 :
1189 353337 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).rh =
1190 353337 : PsyRhFnTdbRhov(state, cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).temp, RhoOut, HAMTExt);
1191 353337 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh =
1192 353337 : PsyRhFnTdbRhov(state, cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).temp, RhoIn, HAMTInt);
1193 :
1194 353337 : if (cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).rh > rhmax) {
1195 0 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).rh = rhmax;
1196 : }
1197 353337 : if (cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh > rhmax) {
1198 0 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh = rhmax;
1199 : }
1200 :
1201 : // PDB August 2009 Start! Correction for when no vapour transfer coefficient have been defined.
1202 353337 : if (state.dataHeatBalHAMTMgr->extvtcflag(sid)) {
1203 312264 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).vtc = state.dataHeatBalHAMTMgr->extvtc(sid);
1204 : } else {
1205 41073 : if (cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).rh > 0) {
1206 41073 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).vtc =
1207 82146 : state.dataMstBal->HMassConvExtFD(sid) * RhoOut /
1208 82146 : (PsyPsatFnTemp(state, state.dataMstBal->TempOutsideAirFD(sid)) * cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).rh);
1209 : } else {
1210 0 : cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).vtc = 10000.0;
1211 : }
1212 : }
1213 :
1214 353337 : if (state.dataHeatBalHAMTMgr->intvtcflag(sid)) {
1215 312264 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc = state.dataHeatBalHAMTMgr->intvtc(sid);
1216 936792 : state.dataMstBal->HMassConvInFD(sid) = cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc * PsyPsatFnTemp(state, thisZoneHB.MAT) *
1217 624528 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh / RhoIn;
1218 : } else {
1219 41073 : if (cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh > 0) {
1220 41073 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc =
1221 82146 : state.dataMstBal->HMassConvInFD(sid) * RhoIn /
1222 82146 : (PsyPsatFnTemp(state, thisZoneHB.MAT) * cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh);
1223 : } else {
1224 0 : cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc = 10000.0;
1225 : }
1226 : }
1227 : // PDB August 2009 End
1228 :
1229 : // Initialise
1230 1766685 : for (cid = state.dataHeatBalHAMTMgr->firstcell(sid); cid <= Extcell(sid) - 1; ++cid) {
1231 1413348 : cells(cid).tempp1 = cells(cid).temp;
1232 1413348 : cells(cid).tempp2 = cells(cid).temp;
1233 1413348 : cells(cid).rhp1 = cells(cid).rh;
1234 1413348 : cells(cid).rhp2 = cells(cid).rh;
1235 : }
1236 706674 : for (cid = Intcell(sid) + 1; cid <= state.dataHeatBalHAMTMgr->lastcell(sid); ++cid) {
1237 353337 : cells(cid).tempp1 = cells(cid).temp;
1238 353337 : cells(cid).tempp2 = cells(cid).temp;
1239 353337 : cells(cid).rhp1 = cells(cid).rh;
1240 353337 : cells(cid).rhp2 = cells(cid).rh;
1241 : }
1242 :
1243 353337 : itter = 0;
1244 : while (true) {
1245 2442031 : ++itter;
1246 : // Update Moisture values
1247 :
1248 49373529 : for (cid = state.dataHeatBalHAMTMgr->firstcell(sid); cid <= state.dataHeatBalHAMTMgr->lastcell(sid); ++cid) {
1249 47975845 : matid = cells(cid).matid;
1250 47975845 : cells(cid).vp = RHtoVP(state, cells(cid).rh, cells(cid).temp);
1251 47975845 : cells(cid).vpp1 = RHtoVP(state, cells(cid).rhp1, cells(cid).tempp1);
1252 47975845 : cells(cid).vpsat = PsyPsatFnTemp(state, cells(cid).tempp1);
1253 47975845 : if (matid > 0) {
1254 190960285 : interp(state.dataMaterial->Material(matid).niso,
1255 38192057 : state.dataMaterial->Material(matid).isorh,
1256 38192057 : state.dataMaterial->Material(matid).isodata,
1257 38192057 : cells(cid).rhp1,
1258 38192057 : cells(cid).water,
1259 38192057 : cells(cid).dwdphi);
1260 38192057 : if (state.dataEnvrn->IsRain && state.dataHeatBalHAMTMgr->rainswitch) {
1261 0 : interp(state.dataMaterial->Material(matid).nsuc,
1262 0 : state.dataMaterial->Material(matid).sucwater,
1263 0 : state.dataMaterial->Material(matid).sucdata,
1264 0 : cells(cid).water,
1265 0 : cells(cid).dw);
1266 : } else {
1267 190960285 : interp(state.dataMaterial->Material(matid).nred,
1268 38192057 : state.dataMaterial->Material(matid).redwater,
1269 38192057 : state.dataMaterial->Material(matid).reddata,
1270 38192057 : cells(cid).water,
1271 38192057 : cells(cid).dw);
1272 : }
1273 190960285 : interp(state.dataMaterial->Material(matid).nmu,
1274 38192057 : state.dataMaterial->Material(matid).murh,
1275 38192057 : state.dataMaterial->Material(matid).mudata,
1276 38192057 : cells(cid).rhp1,
1277 38192057 : cells(cid).mu);
1278 190960285 : interp(state.dataMaterial->Material(matid).ntc,
1279 38192057 : state.dataMaterial->Material(matid).tcwater,
1280 38192057 : state.dataMaterial->Material(matid).tcdata,
1281 38192057 : cells(cid).water,
1282 38192057 : cells(cid).wthermalc);
1283 : }
1284 : }
1285 :
1286 : // Calculate Heat and Vapor resistances,
1287 42385109 : for (cid = Extcell(sid); cid <= Intcell(sid); ++cid) {
1288 40987425 : torsum = 0.0;
1289 40987425 : oorsum = 0.0;
1290 40987425 : vpdiff = 0.0;
1291 127155327 : for (ii = 1; ii <= adjmax; ++ii) {
1292 127155327 : adj = cells(cid).adjs(ii);
1293 127155327 : adjl = cells(cid).adjsl(ii);
1294 127155327 : if (adj == -1) break;
1295 :
1296 86167902 : if (cells(cid).htc > 0) {
1297 0 : thermr1 = 1.0 / (cells(cid).overlap(ii) * cells(cid).htc);
1298 86167902 : } else if (cells(cid).matid > 0) {
1299 76384114 : thermr1 = cells(cid).dist(ii) / (cells(cid).overlap(ii) * cells(cid).wthermalc);
1300 : } else {
1301 9783788 : thermr1 = 0.0;
1302 : }
1303 :
1304 86167902 : if (cells(cid).vtc > 0) {
1305 0 : vaporr1 = 1.0 / (cells(cid).overlap(ii) * cells(cid).vtc);
1306 86167902 : } else if (cells(cid).matid > 0) {
1307 76384114 : vaporr1 =
1308 76384114 : (cells(cid).dist(ii) * cells(cid).mu) / (cells(cid).overlap(ii) * WVDC(cells(cid).tempp1, state.dataEnvrn->OutBaroPress));
1309 : } else {
1310 9783788 : vaporr1 = 0.0;
1311 : }
1312 :
1313 86167902 : if (cells(adj).htc > 0) {
1314 6082930 : thermr2 = 1.0 / (cells(cid).overlap(ii) * cells(adj).htc);
1315 80084972 : } else if (cells(adj).matid > 0) {
1316 76384114 : thermr2 = cells(adj).dist(adjl) / (cells(cid).overlap(ii) * cells(adj).wthermalc);
1317 : } else {
1318 3700858 : thermr2 = 0.0;
1319 : }
1320 :
1321 86167902 : if (cells(adj).vtc > 0) {
1322 2795368 : vaporr2 = 1.0 / (cells(cid).overlap(ii) * cells(adj).vtc);
1323 83372534 : } else if (cells(adj).matid > 0) {
1324 76384114 : vaporr2 =
1325 76384114 : cells(adj).mu * cells(adj).dist(adjl) / (WVDC(cells(adj).tempp1, state.dataEnvrn->OutBaroPress) * cells(cid).overlap(ii));
1326 : } else {
1327 6988420 : vaporr2 = 0.0;
1328 : }
1329 :
1330 86167902 : if (thermr1 + thermr2 > 0) {
1331 85262412 : oorsum += 1.0 / (thermr1 + thermr2);
1332 85262412 : torsum += cells(adj).tempp1 / (thermr1 + thermr2);
1333 : }
1334 86167902 : if (vaporr1 + vaporr2 > 0) {
1335 81974850 : vpdiff += (cells(adj).vp - cells(cid).vp) / (vaporr1 + vaporr2);
1336 : }
1337 : }
1338 :
1339 : // Calculate Heat Capacitance
1340 40987425 : tcap = ((cells(cid).density * cells(cid).spech + cells(cid).water * wspech) * cells(cid).volume);
1341 :
1342 : // calculate the latent heat if wanted and check for divergence
1343 40987425 : qvp = 0.0;
1344 40987425 : if ((cells(cid).matid > 0) && (state.dataHeatBalHAMTMgr->latswitch)) {
1345 38192057 : qvp = vpdiff * whv;
1346 : }
1347 40987425 : if (std::abs(qvp) > qvplim) {
1348 0 : if (!state.dataGlobal->WarmupFlag) {
1349 0 : ++qvpErrCount;
1350 0 : if (qvpErrCount < 16) {
1351 0 : ShowWarningError(state, "HeatAndMoistureTransfer: Large Latent Heat for Surface " + state.dataSurface->Surface(sid).Name);
1352 : } else {
1353 0 : ShowRecurringWarningErrorAtEnd(state, "HeatAndMoistureTransfer: Large Latent Heat Errors ", qvpErrReport);
1354 : }
1355 : }
1356 0 : qvp = 0.0;
1357 : }
1358 :
1359 : // Calculate the temperature for the next time step
1360 81974850 : cells(cid).tempp1 = (torsum + qvp + cells(cid).Qadds + (tcap * cells(cid).temp / state.dataHeatBalHAMTMgr->deltat)) /
1361 40987425 : (oorsum + (tcap / state.dataHeatBalHAMTMgr->deltat));
1362 : }
1363 :
1364 : // Check for silly temperatures
1365 1397684 : tempmax = maxval(cells, &subcell::tempp1);
1366 1397684 : tempmin = minval(cells, &subcell::tempp1);
1367 1397684 : if (tempmax > state.dataHeatBalSurf->MaxSurfaceTempLimit) {
1368 0 : if (!state.dataGlobal->WarmupFlag) {
1369 0 : if (state.dataSurface->SurfHighTempErrCount(sid) == 0) {
1370 0 : ShowSevereMessage(
1371 : state,
1372 0 : format("HAMT: Temperature (high) out of bounds ({:.2R}) for surface={}", tempmax, state.dataSurface->Surface(sid).Name));
1373 0 : ShowContinueErrorTimeStamp(state, "");
1374 : }
1375 0 : ShowRecurringWarningErrorAtEnd(state,
1376 0 : "HAMT: Temperature Temperature (high) out of bounds; Surface=" +
1377 0 : state.dataSurface->Surface(sid).Name,
1378 0 : state.dataSurface->SurfHighTempErrCount(sid),
1379 : tempmax,
1380 : tempmax,
1381 : _,
1382 : "C",
1383 : "C");
1384 : }
1385 : }
1386 1397684 : if (tempmax > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) {
1387 0 : if (!state.dataGlobal->WarmupFlag) {
1388 0 : ShowSevereError(state,
1389 0 : format("HAMT: HAMT: Temperature (high) out of bounds ( {:.2R}) for surface={}",
1390 : tempmax,
1391 0 : state.dataSurface->Surface(sid).Name));
1392 0 : ShowContinueErrorTimeStamp(state, "");
1393 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
1394 : }
1395 : }
1396 1397684 : if (tempmin < MinSurfaceTempLimit) {
1397 0 : if (!state.dataGlobal->WarmupFlag) {
1398 0 : if (state.dataSurface->SurfHighTempErrCount(sid) == 0) {
1399 0 : ShowSevereMessage(
1400 : state,
1401 0 : format("HAMT: Temperature (low) out of bounds ({:.2R}) for surface={}", tempmin, state.dataSurface->Surface(sid).Name));
1402 0 : ShowContinueErrorTimeStamp(state, "");
1403 : }
1404 0 : ShowRecurringWarningErrorAtEnd(state,
1405 0 : "HAMT: Temperature Temperature (high) out of bounds; Surface=" +
1406 0 : state.dataSurface->Surface(sid).Name,
1407 0 : state.dataSurface->SurfHighTempErrCount(sid),
1408 : tempmin,
1409 : tempmin,
1410 : _,
1411 : "C",
1412 : "C");
1413 : }
1414 : }
1415 1397684 : if (tempmin < MinSurfaceTempLimitBeforeFatal) {
1416 0 : if (!state.dataGlobal->WarmupFlag) {
1417 0 : ShowSevereError(state,
1418 0 : format("HAMT: HAMT: Temperature (low) out of bounds ( {:.2R}) for surface={}",
1419 : tempmin,
1420 0 : state.dataSurface->Surface(sid).Name));
1421 0 : ShowContinueErrorTimeStamp(state, "");
1422 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
1423 : }
1424 : }
1425 :
1426 : // Calculate the liquid and vapor resisitances
1427 42385109 : for (cid = Extcell(sid); cid <= Intcell(sid); ++cid) {
1428 40987425 : phioosum = 0.0;
1429 40987425 : phiorsum = 0.0;
1430 40987425 : vpoosum = 0.0;
1431 40987425 : vporsum = 0.0;
1432 :
1433 127155327 : for (ii = 1; ii <= adjmax; ++ii) {
1434 127155327 : adj = cells(cid).adjs(ii);
1435 127155327 : adjl = cells(cid).adjsl(ii);
1436 127155327 : if (adj == -1) break;
1437 :
1438 86167902 : if (cells(cid).vtc > 0) {
1439 0 : vaporr1 = 1.0 / (cells(cid).overlap(ii) * cells(cid).vtc);
1440 86167902 : } else if (cells(cid).matid > 0) {
1441 76384114 : vaporr1 =
1442 76384114 : (cells(cid).dist(ii) * cells(cid).mu) / (cells(cid).overlap(ii) * WVDC(cells(cid).tempp1, state.dataEnvrn->OutBaroPress));
1443 : } else {
1444 9783788 : vaporr1 = 0.0;
1445 : }
1446 :
1447 86167902 : if (cells(adj).vtc > 0) {
1448 2795368 : vaporr2 = 1.0 / (cells(cid).overlap(ii) * cells(adj).vtc);
1449 83372534 : } else if (cells(adj).matid > 0) {
1450 152768228 : vaporr2 = (cells(adj).dist(adjl) * cells(adj).mu) /
1451 76384114 : (cells(cid).overlap(ii) * WVDC(cells(adj).tempp1, state.dataEnvrn->OutBaroPress));
1452 : } else {
1453 6988420 : vaporr2 = 0.0;
1454 : }
1455 86167902 : if (vaporr1 + vaporr2 > 0) {
1456 81974850 : vpoosum += 1.0 / (vaporr1 + vaporr2);
1457 81974850 : vporsum += (cells(adj).vpp1 / (vaporr1 + vaporr2));
1458 : }
1459 :
1460 86167902 : if ((cells(cid).dw > 0) && (cells(cid).dwdphi > 0)) {
1461 44430394 : rhr1 = cells(cid).dist(ii) / (cells(cid).overlap(ii) * cells(cid).dw * cells(cid).dwdphi);
1462 : } else {
1463 41737508 : rhr1 = 0.0;
1464 : }
1465 86167902 : if ((cells(adj).dw > 0) && (cells(adj).dwdphi > 0)) {
1466 44430394 : rhr2 = cells(adj).dist(adjl) / (cells(cid).overlap(ii) * cells(adj).dw * cells(adj).dwdphi);
1467 : } else {
1468 41737508 : rhr2 = 0.0;
1469 : }
1470 :
1471 : // IF(rhr1+rhr2>0)THEN
1472 86167902 : if (rhr1 * rhr2 > 0) {
1473 39602664 : phioosum += 1.0 / (rhr1 + rhr2);
1474 39602664 : phiorsum += (cells(adj).rhp1 / (rhr1 + rhr2));
1475 : }
1476 : }
1477 :
1478 : // Moisture Capacitance
1479 40987425 : if (cells(cid).dwdphi > 0.0) {
1480 38167079 : wcap = cells(cid).dwdphi * cells(cid).volume;
1481 : } else {
1482 2820346 : wcap = 0.0;
1483 : }
1484 :
1485 : // Calculate the RH for the next time step
1486 40987425 : denominator = (phioosum + vpoosum * cells(cid).vpsat + wcap / state.dataHeatBalHAMTMgr->deltat);
1487 40987425 : if (denominator != 0.0) {
1488 40987425 : cells(cid).rhp1 = (phiorsum + vporsum + (wcap * cells(cid).rh) / state.dataHeatBalHAMTMgr->deltat) / denominator;
1489 : } else {
1490 0 : ShowSevereError(state, "CalcHeatBalHAMT: demoninator in calculating RH is zero. Check material properties for accuracy.");
1491 0 : ShowContinueError(state, "...Problem occurs in Material=\"" + state.dataMaterial->Material(cells(cid).matid).Name + "\".");
1492 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
1493 : }
1494 :
1495 40987425 : if (cells(cid).rhp1 > rhmax) {
1496 52991 : cells(cid).rhp1 = rhmax;
1497 : }
1498 : }
1499 :
1500 : // Check for convergence or too many itterations
1501 1397684 : sumtp1 = 0.0;
1502 42385109 : for (cid = Extcell(sid); cid <= Intcell(sid); ++cid) {
1503 40987425 : if (sumtp1 < std::abs(cells(cid).tempp2 - cells(cid).tempp1)) {
1504 6023386 : sumtp1 = std::abs(cells(cid).tempp2 - cells(cid).tempp1);
1505 : }
1506 : }
1507 1397684 : if (sumtp1 < convt) {
1508 353039 : break;
1509 : }
1510 1044645 : if (itter > ittermax) {
1511 298 : break;
1512 : }
1513 37091691 : for (cid = state.dataHeatBalHAMTMgr->firstcell(sid); cid <= state.dataHeatBalHAMTMgr->lastcell(sid); ++cid) {
1514 36047344 : cells(cid).tempp2 = cells(cid).tempp1;
1515 36047344 : cells(cid).rhp2 = cells(cid).rhp1;
1516 : }
1517 : }
1518 :
1519 : // report back to CalcHeatBalanceInsideSurf
1520 353337 : TempSurfOutTmp = cells(Extcell(sid)).tempp1;
1521 353337 : SurfTempInTmp = cells(Intcell(sid)).tempp1;
1522 :
1523 353337 : SurfTempInP = cells(Intcell(sid)).rhp1 * PsyPsatFnTemp(state, cells(Intcell(sid)).tempp1);
1524 :
1525 353337 : state.dataMstBal->RhoVaporSurfIn(sid) = SurfTempInP / (461.52 * (thisZoneHB.MAT + DataGlobalConstants::KelvinConv));
1526 353337 : }
1527 :
1528 171564 : void UpdateHeatBalHAMT(EnergyPlusData &state, int const sid)
1529 : {
1530 : // SUBROUTINE INFORMATION:
1531 : // AUTHOR Phillip Biddulph
1532 : // DATE WRITTEN June 2008
1533 : // MODIFIED na
1534 : // RE-ENGINEERED na
1535 :
1536 : // PURPOSE OF THIS SUBROUTINE:
1537 : // The zone heat balance equation has converged, so now the HAMT values are to be fixed
1538 : // ready for the next itteration.
1539 : // Fill all the report variables
1540 :
1541 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1542 : int cid;
1543 : Real64 watermass;
1544 : Real64 matmass;
1545 : // unused1208 REAL(r64), SAVE :: InOld=0.0D0
1546 : // unused1208 REAL(r64), SAVE :: OutOld=0.0D0
1547 :
1548 : // Update Temperatures and RHs. Calculate report variables
1549 171564 : matmass = 0.0;
1550 171564 : watermass = 0.0;
1551 5927346 : for (cid = state.dataHeatBalHAMTMgr->firstcell(sid); cid <= state.dataHeatBalHAMTMgr->lastcell(sid); ++cid) {
1552 : // fix HAMT values for this surface
1553 5755782 : state.dataHeatBalHAMTMgr->cells(cid).temp = state.dataHeatBalHAMTMgr->cells(cid).tempp1;
1554 5755782 : state.dataHeatBalHAMTMgr->cells(cid).rh = state.dataHeatBalHAMTMgr->cells(cid).rhp1;
1555 5755782 : state.dataHeatBalHAMTMgr->cells(cid).rhp = state.dataHeatBalHAMTMgr->cells(cid).rh * 100.0;
1556 5755782 : if (state.dataHeatBalHAMTMgr->cells(cid).density > 0.0) {
1557 4554834 : state.dataHeatBalHAMTMgr->cells(cid).wreport =
1558 4554834 : state.dataHeatBalHAMTMgr->cells(cid).water / state.dataHeatBalHAMTMgr->cells(cid).density;
1559 4554834 : watermass += (state.dataHeatBalHAMTMgr->cells(cid).water * state.dataHeatBalHAMTMgr->cells(cid).volume);
1560 4554834 : matmass += (state.dataHeatBalHAMTMgr->cells(cid).density * state.dataHeatBalHAMTMgr->cells(cid).volume);
1561 : }
1562 : }
1563 :
1564 171564 : state.dataHeatBalHAMTMgr->watertot(sid) = 0.0;
1565 171564 : if (matmass > 0) state.dataHeatBalHAMTMgr->watertot(sid) = watermass / matmass;
1566 :
1567 171564 : state.dataHeatBalHAMTMgr->surfrh(sid) = 100.0 * state.dataHeatBalHAMTMgr->cells(state.dataHeatBalHAMTMgr->Intcell(sid)).rh;
1568 171564 : state.dataHeatBalHAMTMgr->surfextrh(sid) = 100.0 * state.dataHeatBalHAMTMgr->cells(state.dataHeatBalHAMTMgr->Extcell(sid)).rh;
1569 171564 : state.dataHeatBalHAMTMgr->surftemp(sid) = state.dataHeatBalHAMTMgr->cells(state.dataHeatBalHAMTMgr->Intcell(sid)).temp;
1570 171564 : state.dataHeatBalHAMTMgr->surfexttemp(sid) = state.dataHeatBalHAMTMgr->cells(state.dataHeatBalHAMTMgr->Extcell(sid)).temp;
1571 343128 : state.dataHeatBalHAMTMgr->surfvp(sid) = RHtoVP(state,
1572 171564 : state.dataHeatBalHAMTMgr->cells(state.dataHeatBalHAMTMgr->Intcell(sid)).rh,
1573 171564 : state.dataHeatBalHAMTMgr->cells(state.dataHeatBalHAMTMgr->Intcell(sid)).temp);
1574 171564 : }
1575 :
1576 : void
1577 152768274 : interp(int const ndata, const Array1D<Real64> &xx, const Array1D<Real64> &yy, Real64 const invalue, Real64 &outvalue, Optional<Real64> outgrad)
1578 : {
1579 : // SUBROUTINE INFORMATION:
1580 : // AUTHOR Phillip Biddulph
1581 : // DATE WRITTEN June 2008
1582 : // MODIFIED na
1583 : // RE-ENGINEERED na
1584 :
1585 : // PURPOSE OF THIS SUBROUTINE:
1586 : // To find a value by searching an array and interpolating between two coordinates
1587 : // Also returns the gradient if required.
1588 :
1589 : // METHODOLOGY EMPLOYED:
1590 : // Simple search
1591 :
1592 : // Argument array dimensioning
1593 152768274 : EP_SIZE_CHECK(xx, ndata);
1594 152768274 : EP_SIZE_CHECK(yy, ndata);
1595 :
1596 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1597 : Real64 xxlow;
1598 : Real64 xxhigh;
1599 : Real64 yylow;
1600 : Real64 yyhigh;
1601 : Real64 mygrad;
1602 : int step;
1603 :
1604 152768274 : mygrad = 0.0;
1605 152768274 : outvalue = 0.0;
1606 :
1607 152768274 : if (ndata > 1) {
1608 152768274 : xxlow = xx(1);
1609 152768274 : yylow = yy(1);
1610 214871054 : for (step = 2; step <= ndata; ++step) {
1611 214871054 : xxhigh = xx(step);
1612 214871054 : yyhigh = yy(step);
1613 214871054 : if (invalue <= xxhigh) break;
1614 62102780 : xxlow = xxhigh;
1615 62102780 : yylow = yyhigh;
1616 : }
1617 :
1618 152768274 : if (xxhigh > xxlow) {
1619 152768274 : mygrad = (yyhigh - yylow) / (xxhigh - xxlow);
1620 152768274 : outvalue = (invalue - xxlow) * mygrad + yylow;
1621 : // PDB August 2009 bug fix
1622 0 : } else if (std::abs(xxhigh - xxlow) < 0.0000000001) {
1623 0 : outvalue = yylow;
1624 : }
1625 : }
1626 :
1627 152768274 : if (present(outgrad)) {
1628 : // return gradient if required
1629 38192057 : outgrad = mygrad;
1630 : }
1631 152768274 : }
1632 :
1633 96123254 : Real64 RHtoVP(EnergyPlusData &state, Real64 const RH, Real64 const Temperature)
1634 : {
1635 : // FUNCTION INFORMATION:
1636 : // AUTHOR Phillip Biddulph
1637 : // DATE WRITTEN June 2008
1638 : // MODIFIED na
1639 : // RE-ENGINEERED na
1640 :
1641 : // PURPOSE OF THIS FUNCTION:
1642 : // Convert Relative Humidity and Temperature to Vapor Pressure
1643 :
1644 : // Return value
1645 : Real64 RHtoVP;
1646 :
1647 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1648 : Real64 VPSat;
1649 :
1650 96123254 : VPSat = PsyPsatFnTemp(state, Temperature);
1651 :
1652 96123254 : RHtoVP = RH * VPSat;
1653 :
1654 96123254 : return RHtoVP;
1655 : }
1656 :
1657 305536456 : Real64 WVDC(Real64 const Temperature, Real64 const ambp)
1658 : {
1659 : // FUNCTION INFORMATION:
1660 : // AUTHOR Phillip Biddulph
1661 : // DATE WRITTEN June 2008
1662 : // MODIFIED na
1663 : // RE-ENGINEERED na
1664 :
1665 : // PURPOSE OF THIS FUNCTION:
1666 : // To calculate the Water Vapor Diffusion Coefficient in air
1667 : // using the temperature and ambient atmospheric pressor
1668 :
1669 : // REFERENCES:
1670 : // K?zel, H.M. (1995) Simultaneous Heat and Moisture Transport in Building Components.
1671 : // One- and two-dimensional calculation using simple parameters. IRB Verlag 1995
1672 :
1673 : // Return value
1674 : Real64 WVDC;
1675 :
1676 305536456 : WVDC = (2.e-7 * std::pow(Temperature + DataGlobalConstants::KelvinConv, 0.81)) / ambp;
1677 :
1678 305536456 : return WVDC;
1679 : }
1680 :
1681 : // COPYRIGHT NOTICE
1682 :
1683 : // Portions Copyright (c) University College London 2007. All rights
1684 : // reserved.
1685 :
1686 : // UCL LEGAL NOTICE
1687 : // Neither UCL, members of UCL nor any person or organisation acting on
1688 : // behalf of either:
1689 :
1690 : // A. Makes any warranty of representation, express or implied with
1691 : // respect to the accuracy, completeness, or usefulness of the
1692 : // information contained in this program, including any warranty of
1693 : // merchantability or fitness of any purpose with respect to the
1694 : // program, or that the use of any information disclosed in this
1695 : // program may not infringe privately-owned rights, or
1696 :
1697 : // B. Assumes any liability with respect to the use of, or for any and
1698 : // all damages resulting from the use of the program or any portion
1699 : // thereof or any information disclosed therein.
1700 :
1701 : } // namespace HeatBalanceHAMTManager
1702 :
1703 2313 : } // namespace EnergyPlus
|