Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array1D.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 : #include <ObjexxFCL/member.functions.hh>
55 :
56 : // EnergyPlus Headers
57 : #include <AirflowNetwork/Solver.hpp>
58 : #include <EnergyPlus/ConvectionCoefficients.hh>
59 : #include <EnergyPlus/Data/EnergyPlusData.hh>
60 : #include <EnergyPlus/DataEnvironment.hh>
61 : #include <EnergyPlus/DataHVACGlobals.hh>
62 : #include <EnergyPlus/DataHeatBalFanSys.hh>
63 : #include <EnergyPlus/DataHeatBalSurface.hh>
64 : #include <EnergyPlus/DataHeatBalance.hh>
65 : #include <EnergyPlus/DataLoopNode.hh>
66 : #include <EnergyPlus/DataRoomAirModel.hh>
67 : #include <EnergyPlus/DataSurfaces.hh>
68 : #include <EnergyPlus/DataZoneEquipment.hh>
69 : #include <EnergyPlus/DisplacementVentMgr.hh>
70 : #include <EnergyPlus/InternalHeatGains.hh>
71 : #include <EnergyPlus/Psychrometrics.hh>
72 : #include <EnergyPlus/ScheduleManager.hh>
73 : #include <EnergyPlus/UtilityRoutines.hh>
74 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
75 :
76 : namespace EnergyPlus {
77 :
78 : namespace RoomAir {
79 :
80 : // MODULE INFORMATION:
81 : // AUTHOR G. Carrilho da Graca
82 : // DATE WRITTEN February 2004
83 : // MODIFIED na
84 : // RE-ENGINEERED na
85 :
86 : // PURPOSE OF THIS MODULE:
87 : // Routines that implement the UCSD Displacement Ventilation
88 :
89 : // Using/Aliasing
90 : using namespace DataLoopNode;
91 : using namespace DataEnvironment;
92 : using namespace DataHeatBalance;
93 : using namespace DataHeatBalSurface;
94 : using namespace DataSurfaces;
95 : using Convect::CalcDetailedHcInForDVModel;
96 :
97 14995 : void ManageDispVent3Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
98 : {
99 :
100 : // SUBROUTINE INFORMATION:
101 : // AUTHOR G. Carrilho da Graca
102 : // DATE WRITTEN February 2004
103 :
104 : // PURPOSE OF THIS SUBROUTINE:
105 : // manage the UCSD Displacement Ventilation model
106 :
107 : // initialize Displacement Ventilation model
108 14995 : InitDispVent3Node(state, ZoneNum);
109 :
110 : // perform Displacement Ventilation model calculations
111 14995 : CalcDispVent3Node(state, ZoneNum);
112 14995 : }
113 :
114 : //**************************************************************************************************
115 :
116 14995 : void InitDispVent3Node(EnergyPlusData &state, int const ZoneNum)
117 : {
118 :
119 : // SUBROUTINE INFORMATION:
120 : // AUTHOR G. Carrilho da Graca
121 : // DATE WRITTEN February 2004
122 : // MODIFIED -
123 : // RE-ENGINEERED -
124 :
125 : // PURPOSE OF THIS SUBROUTINE:
126 : // Low Energy Cooling by Ventilation initialization subroutine.
127 : // All the data preparation needed to run the LECV models.
128 : // The subroutines sets up arrays with the locations in the main EnergyPlus surface array of
129 : // ceiling, windows, doors and walls. The zone maximum and minimum height is calculated.
130 :
131 : // Do the one time initializations
132 14995 : if (state.dataDispVentMgr->InitUCSDDVMyOneTimeFlag) {
133 4 : state.dataDispVentMgr->MyEnvrnFlag.dimension(state.dataGlobal->NumOfZones, true);
134 4 : state.dataDispVentMgr->HeightFloorSubzoneTop = 0.2;
135 4 : state.dataDispVentMgr->ThickOccupiedSubzoneMin = 0.2;
136 4 : state.dataDispVentMgr->HeightIntMassDefault = 2.0;
137 4 : state.dataDispVentMgr->InitUCSDDVMyOneTimeFlag = false;
138 : }
139 :
140 : // Do the begin environment initializations
141 14995 : if (state.dataGlobal->BeginEnvrnFlag && state.dataDispVentMgr->MyEnvrnFlag(ZoneNum)) {
142 28 : state.dataDispVentMgr->HAT_MX = 0.0;
143 28 : state.dataDispVentMgr->HAT_OC = 0.0;
144 28 : state.dataDispVentMgr->HA_MX = 0.0;
145 28 : state.dataDispVentMgr->HA_OC = 0.0;
146 28 : state.dataDispVentMgr->HAT_FLOOR = 0.0;
147 28 : state.dataDispVentMgr->HA_FLOOR = 0.0;
148 28 : state.dataDispVentMgr->MyEnvrnFlag(ZoneNum) = false;
149 : }
150 :
151 14995 : if (!state.dataGlobal->BeginEnvrnFlag) {
152 14907 : state.dataDispVentMgr->MyEnvrnFlag(ZoneNum) = true;
153 : }
154 :
155 : // initialize these module variables every timestep
156 14995 : state.dataDispVentMgr->HeightIntMass = state.dataDispVentMgr->HeightIntMassDefault;
157 14995 : }
158 :
159 : //**************************************************************************************************
160 :
161 64297 : void HcDispVent3Node(EnergyPlusData &state, int const ZoneNum, Real64 const FractionHeight)
162 : {
163 :
164 : // SUBROUTINE INFORMATION:
165 : // AUTHOR G. Carrilho da Graca
166 : // DATE WRITTEN February 2004
167 : // MODIFIED -
168 : // RE-ENGINEERED -
169 :
170 : // PURPOSE OF THIS SUBROUTINE:
171 : // Main subroutine for convection calculation in the UCSD Displacement Ventilation model.
172 : // It calls CalcDetailedHcInForDVModel for convection coefficient
173 : // initial calculations and averages the final result comparing the position of the surface with
174 : // the interface subzone height.
175 :
176 : // Using/Aliasing
177 : using namespace DataEnvironment;
178 : using namespace DataHeatBalance;
179 :
180 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
181 : Real64 HLD; // Convection coefficient for the lower area of surface
182 : Real64 TmedDV; // Average temperature for DV
183 : Real64 Z1; // auxiliary var for lowest height
184 : Real64 Z2; // auxiliary var for highest height
185 : Real64 ZSupSurf; // highest height for this surface
186 : Real64 ZInfSurf; // lowest height for this surface
187 : Real64 HLU; // Convection coefficient for the upper area of surface
188 : Real64 LayH; // Height of the Occupied/Mixed subzone interface
189 : Real64 LayFrac; // Fraction height of the Occupied/Mixed subzone interface
190 :
191 64297 : state.dataDispVentMgr->HAT_MX = 0.0;
192 64297 : state.dataDispVentMgr->HAT_OC = 0.0;
193 64297 : state.dataDispVentMgr->HA_MX = 0.0;
194 64297 : state.dataDispVentMgr->HA_OC = 0.0;
195 64297 : state.dataDispVentMgr->HAT_FLOOR = 0.0;
196 64297 : state.dataDispVentMgr->HA_FLOOR = 0.0;
197 64297 : auto &SurfTempIn(state.dataHeatBalSurf->SurfTempIn);
198 :
199 : // Is the air flow model for this zone set to UCSDDV Displacement Ventilation?
200 64297 : if (state.dataRoomAir->IsZoneDispVent3Node(ZoneNum)) {
201 64297 : LayFrac = FractionHeight;
202 64297 : LayH = FractionHeight * (state.dataRoomAir->ZoneCeilingHeight2(ZoneNum) - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum));
203 : // WALL Hc, HA and HAT calculation
204 321485 : for (int Ctd = state.dataRoomAir->PosZ_Wall(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Wall(ZoneNum).end; ++Ctd) {
205 257188 : int SurfNum = state.dataRoomAir->APos_Wall(Ctd);
206 257188 : if (SurfNum == 0) {
207 0 : continue;
208 : }
209 :
210 257188 : auto const &surf = state.dataSurface->Surface(SurfNum);
211 257188 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
212 257188 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
213 257188 : Z1 = minval(surf.Vertex, &Vector::z);
214 257188 : Z2 = maxval(surf.Vertex, &Vector::z);
215 257188 : ZSupSurf = Z2 - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
216 257188 : ZInfSurf = Z1 - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
217 :
218 : // The Wall surface is in the upper subzone
219 257188 : if (ZInfSurf > LayH) {
220 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
221 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
222 0 : state.dataRoomAir->HWall(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
223 0 : state.dataDispVentMgr->HAT_MX += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HWall(Ctd);
224 0 : state.dataDispVentMgr->HA_MX += surf.Area * state.dataRoomAir->HWall(Ctd);
225 : }
226 :
227 : // The Wall surface is in the lower subzone
228 257188 : if (ZSupSurf < LayH) {
229 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
230 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
231 0 : state.dataRoomAir->HWall(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
232 0 : state.dataDispVentMgr->HAT_OC += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HWall(Ctd);
233 0 : state.dataDispVentMgr->HA_OC += surf.Area * state.dataRoomAir->HWall(Ctd);
234 : }
235 :
236 : // The Wall surface is partially in upper and partially in lower subzone
237 257188 : if (ZInfSurf <= LayH && ZSupSurf >= LayH) {
238 257188 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
239 257188 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
240 257188 : HLU = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
241 257188 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
242 257188 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
243 257188 : HLD = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
244 257188 : TmedDV = ((ZSupSurf - LayH) * state.dataRoomAir->ZTMX(ZoneNum) + (LayH - ZInfSurf) * state.dataRoomAir->ZTOC(ZoneNum)) /
245 257188 : (ZSupSurf - ZInfSurf);
246 257188 : state.dataRoomAir->HWall(Ctd) = ((LayH - ZInfSurf) * HLD + (ZSupSurf - LayH) * HLU) / (ZSupSurf - ZInfSurf);
247 257188 : state.dataDispVentMgr->HAT_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLU;
248 257188 : state.dataDispVentMgr->HA_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * HLU;
249 257188 : state.dataDispVentMgr->HAT_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLD;
250 257188 : state.dataDispVentMgr->HA_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * HLD;
251 257188 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = TmedDV;
252 : }
253 :
254 257188 : state.dataRoomAir->DispVent3NodeHcIn(SurfNum) = state.dataRoomAir->HWall(Ctd);
255 :
256 : } // END WALL
257 :
258 : // WINDOW Hc, HA and HAT CALCULATION
259 301999 : for (int Ctd = state.dataRoomAir->PosZ_Window(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Window(ZoneNum).end; ++Ctd) {
260 237702 : int SurfNum = state.dataRoomAir->APos_Window(Ctd);
261 237702 : if (SurfNum == 0) {
262 0 : continue;
263 : }
264 :
265 237702 : auto const &surf = state.dataSurface->Surface(SurfNum);
266 237702 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
267 237702 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
268 237702 : if (surf.Tilt > 10.0 && surf.Tilt < 170.0) { // Window Wall
269 237702 : Z1 = minval(surf.Vertex, &Vector::z);
270 237702 : Z2 = maxval(surf.Vertex, &Vector::z);
271 237702 : ZSupSurf = Z2 - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
272 237702 : ZInfSurf = Z1 - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
273 :
274 237702 : if (ZInfSurf > LayH) {
275 182073 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
276 182073 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
277 182073 : state.dataRoomAir->HWindow(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
278 182073 : state.dataDispVentMgr->HAT_MX += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HWindow(Ctd);
279 182073 : state.dataDispVentMgr->HA_MX += surf.Area * state.dataRoomAir->HWindow(Ctd);
280 : }
281 :
282 237702 : if (ZSupSurf < LayH) {
283 15124 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
284 15124 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
285 15124 : state.dataRoomAir->HWindow(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
286 15124 : state.dataDispVentMgr->HAT_OC += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HWindow(Ctd);
287 15124 : state.dataDispVentMgr->HA_OC += surf.Area * state.dataRoomAir->HWindow(Ctd);
288 : }
289 :
290 237702 : if (ZInfSurf <= LayH && ZSupSurf >= LayH) {
291 40505 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
292 40505 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
293 40505 : HLU = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
294 40505 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
295 40505 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
296 40505 : HLD = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
297 40505 : TmedDV = ((ZSupSurf - LayH) * state.dataRoomAir->ZTMX(ZoneNum) + (LayH - ZInfSurf) * state.dataRoomAir->ZTOC(ZoneNum)) /
298 40505 : (ZSupSurf - ZInfSurf);
299 40505 : state.dataRoomAir->HWindow(Ctd) = ((LayH - ZInfSurf) * HLD + (ZSupSurf - LayH) * HLU) / (ZSupSurf - ZInfSurf);
300 40505 : state.dataDispVentMgr->HAT_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLU;
301 40505 : state.dataDispVentMgr->HA_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * HLU;
302 40505 : state.dataDispVentMgr->HAT_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLD;
303 40505 : state.dataDispVentMgr->HA_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * HLD;
304 40505 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = TmedDV;
305 : }
306 : }
307 :
308 237702 : if (surf.Tilt <= 10.0) { // Window Ceiling
309 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
310 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
311 0 : state.dataRoomAir->HWindow(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
312 0 : state.dataDispVentMgr->HAT_MX += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HWindow(Ctd);
313 0 : state.dataDispVentMgr->HA_MX += surf.Area * state.dataRoomAir->HWindow(Ctd);
314 : }
315 :
316 237702 : if (surf.Tilt >= 170.0) { // Window Floor
317 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
318 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
319 0 : state.dataRoomAir->HWindow(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
320 0 : state.dataDispVentMgr->HAT_OC += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HWindow(Ctd);
321 0 : state.dataDispVentMgr->HA_OC += surf.Area * state.dataRoomAir->HWindow(Ctd);
322 : }
323 :
324 237702 : state.dataRoomAir->DispVent3NodeHcIn(SurfNum) = state.dataRoomAir->HWindow(Ctd);
325 :
326 : } // END WINDOW
327 :
328 : // DOOR Hc, HA and HAT CALCULATION
329 64297 : for (int Ctd = state.dataRoomAir->PosZ_Door(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Door(ZoneNum).end; ++Ctd) { // DOOR
330 0 : int SurfNum = state.dataRoomAir->APos_Door(Ctd);
331 0 : if (SurfNum == 0) {
332 0 : continue;
333 : }
334 :
335 0 : auto const &surf = state.dataSurface->Surface(SurfNum);
336 0 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
337 0 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
338 0 : if (surf.Tilt > 10.0 && surf.Tilt < 170.0) { // Door Wall
339 0 : Z1 = minval(surf.Vertex, &Vector::z);
340 0 : Z2 = maxval(surf.Vertex, &Vector::z);
341 0 : ZSupSurf = Z2 - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
342 0 : ZInfSurf = Z1 - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
343 :
344 0 : if (ZInfSurf > LayH) {
345 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
346 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
347 0 : state.dataRoomAir->HDoor(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
348 0 : state.dataDispVentMgr->HAT_MX += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HDoor(Ctd);
349 0 : state.dataDispVentMgr->HA_MX += surf.Area * state.dataRoomAir->HDoor(Ctd);
350 : }
351 :
352 0 : if (ZSupSurf < LayH) {
353 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
354 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
355 0 : state.dataRoomAir->HDoor(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
356 0 : state.dataDispVentMgr->HAT_OC += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HDoor(Ctd);
357 0 : state.dataDispVentMgr->HA_OC += surf.Area * state.dataRoomAir->HDoor(Ctd);
358 : }
359 :
360 0 : if (ZInfSurf <= LayH && ZSupSurf >= LayH) {
361 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
362 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
363 0 : HLU = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
364 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
365 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
366 0 : HLD = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
367 0 : TmedDV = ((ZSupSurf - LayH) * state.dataRoomAir->ZTMX(ZoneNum) + (LayH - ZInfSurf) * state.dataRoomAir->ZTOC(ZoneNum)) /
368 0 : (ZSupSurf - ZInfSurf);
369 0 : state.dataRoomAir->HDoor(Ctd) = ((LayH - ZInfSurf) * HLD + (ZSupSurf - LayH) * HLU) / (ZSupSurf - ZInfSurf);
370 0 : state.dataDispVentMgr->HAT_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLU;
371 0 : state.dataDispVentMgr->HA_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * HLU;
372 0 : state.dataDispVentMgr->HAT_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLD;
373 0 : state.dataDispVentMgr->HA_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * HLD;
374 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = TmedDV;
375 : }
376 : }
377 :
378 0 : if (surf.Tilt <= 10.0) { // Door Ceiling
379 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
380 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
381 0 : state.dataRoomAir->HDoor(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
382 0 : state.dataDispVentMgr->HAT_MX += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HDoor(Ctd);
383 0 : state.dataDispVentMgr->HA_MX += surf.Area * state.dataRoomAir->HDoor(Ctd);
384 : }
385 :
386 0 : if (surf.Tilt >= 170.0) { // Door Floor
387 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
388 0 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
389 0 : state.dataRoomAir->HDoor(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
390 0 : state.dataDispVentMgr->HAT_OC += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HDoor(Ctd);
391 0 : state.dataDispVentMgr->HA_OC += surf.Area * state.dataRoomAir->HDoor(Ctd);
392 : }
393 :
394 0 : state.dataRoomAir->DispVent3NodeHcIn(SurfNum) = state.dataRoomAir->HDoor(Ctd);
395 :
396 : } // END DOOR
397 :
398 : // INTERNAL Hc, HA and HAT CALCULATION
399 64297 : state.dataDispVentMgr->HeightIntMass =
400 64297 : min(state.dataDispVentMgr->HeightIntMassDefault,
401 64297 : (state.dataRoomAir->ZoneCeilingHeight2(ZoneNum) - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum)));
402 138607 : for (int Ctd = state.dataRoomAir->PosZ_Internal(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Internal(ZoneNum).end; ++Ctd) {
403 74310 : int SurfNum = state.dataRoomAir->APos_Internal(Ctd);
404 74310 : if (SurfNum == 0) {
405 0 : continue;
406 : }
407 :
408 74310 : auto const &surf = state.dataSurface->Surface(SurfNum);
409 74310 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
410 74310 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
411 74310 : ZSupSurf = state.dataDispVentMgr->HeightIntMass;
412 74310 : ZInfSurf = 0.0;
413 :
414 74310 : if (ZSupSurf < LayH) {
415 4500 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
416 4500 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
417 4500 : state.dataRoomAir->HInternal(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
418 4500 : state.dataDispVentMgr->HAT_OC += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HInternal(Ctd);
419 4500 : state.dataDispVentMgr->HA_OC += surf.Area * state.dataRoomAir->HInternal(Ctd);
420 : }
421 :
422 74310 : if (ZInfSurf <= LayH && ZSupSurf >= LayH) {
423 69810 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
424 69810 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
425 69810 : HLU = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
426 69810 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTOC(ZoneNum);
427 69810 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
428 69810 : HLD = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
429 69810 : TmedDV = ((ZSupSurf - LayH) * state.dataRoomAir->ZTMX(ZoneNum) + (LayH - ZInfSurf) * state.dataRoomAir->ZTOC(ZoneNum)) /
430 69810 : (ZSupSurf - ZInfSurf);
431 69810 : state.dataRoomAir->HInternal(Ctd) = ((LayH - ZInfSurf) * HLD + (ZSupSurf - LayH) * HLU) / (ZSupSurf - ZInfSurf);
432 69810 : state.dataDispVentMgr->HAT_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLU;
433 69810 : state.dataDispVentMgr->HA_MX += surf.Area * (ZSupSurf - LayH) / (ZSupSurf - ZInfSurf) * HLU;
434 69810 : state.dataDispVentMgr->HAT_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * SurfTempIn(SurfNum) * HLD;
435 69810 : state.dataDispVentMgr->HA_OC += surf.Area * (LayH - ZInfSurf) / (ZSupSurf - ZInfSurf) * HLD;
436 69810 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = TmedDV;
437 : }
438 :
439 74310 : state.dataRoomAir->DispVent3NodeHcIn(SurfNum) = state.dataRoomAir->HInternal(Ctd);
440 : } // END INTERNAL
441 :
442 : // CEILING Hc, HA and HAT CALCULATION
443 128594 : for (int Ctd = state.dataRoomAir->PosZ_Ceiling(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Ceiling(ZoneNum).end; ++Ctd) {
444 64297 : int SurfNum = state.dataRoomAir->APos_Ceiling(Ctd);
445 64297 : if (SurfNum == 0) {
446 0 : continue;
447 : }
448 :
449 64297 : auto const &surf = state.dataSurface->Surface(SurfNum);
450 64297 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
451 64297 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
452 64297 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTMX(ZoneNum);
453 64297 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
454 64297 : state.dataRoomAir->HCeiling(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
455 64297 : state.dataDispVentMgr->HAT_MX += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HCeiling(Ctd);
456 64297 : state.dataDispVentMgr->HA_MX += surf.Area * state.dataRoomAir->HCeiling(Ctd);
457 64297 : state.dataRoomAir->DispVent3NodeHcIn(SurfNum) = state.dataRoomAir->HCeiling(Ctd);
458 : } // END CEILING
459 :
460 : // FLOOR Hc, HA and HAT CALCULATION
461 128594 : for (int Ctd = state.dataRoomAir->PosZ_Floor(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Floor(ZoneNum).end; ++Ctd) {
462 64297 : int SurfNum = state.dataRoomAir->APos_Floor(Ctd);
463 64297 : if (SurfNum == 0) {
464 0 : continue;
465 : }
466 :
467 64297 : auto const &surf = state.dataSurface->Surface(SurfNum);
468 64297 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
469 64297 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
470 64297 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTFloor(ZoneNum);
471 64297 : CalcDetailedHcInForDVModel(state, SurfNum, SurfTempIn, state.dataRoomAir->DispVent3NodeHcIn);
472 64297 : state.dataRoomAir->HFloor(Ctd) = state.dataRoomAir->DispVent3NodeHcIn(SurfNum);
473 64297 : state.dataDispVentMgr->HAT_FLOOR += surf.Area * SurfTempIn(SurfNum) * state.dataRoomAir->HFloor(Ctd);
474 64297 : state.dataDispVentMgr->HA_FLOOR += surf.Area * state.dataRoomAir->HFloor(Ctd);
475 64297 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTFloor(ZoneNum);
476 64297 : state.dataRoomAir->DispVent3NodeHcIn(SurfNum) = state.dataRoomAir->HFloor(Ctd);
477 : } // END FLOOR
478 : }
479 64297 : }
480 :
481 : //**************************************************************************************************
482 :
483 23860 : Real64 calculateThirdOrderFloorTemperature(Real64 temperatureHistoryTerm,
484 : Real64 HAT_floor,
485 : Real64 HA_floor,
486 : Real64 MCpT_Total,
487 : Real64 MCp_Total,
488 : Real64 occupiedTemp,
489 : Real64 nonAirSystemResponse,
490 : Real64 zoneMultiplier,
491 : Real64 airCap)
492 : {
493 23860 : const Real64 elevenOverSix = 11.0 / 6.0;
494 23860 : return (temperatureHistoryTerm + HAT_floor + MCpT_Total + 0.6 * occupiedTemp * MCp_Total + nonAirSystemResponse / zoneMultiplier) /
495 23860 : (elevenOverSix * airCap + HA_floor + 1.6 * MCp_Total);
496 : }
497 :
498 14995 : void CalcDispVent3Node(EnergyPlusData &state, int const ZoneNum) // Which Zonenum
499 : {
500 :
501 : // SUBROUTINE INFORMATION:
502 : // AUTHOR G. Carrilho da Graca
503 : // DATE WRITTEN February 2004
504 : // MODIFIED Brent Griffith June 2008 for new interpolation and time history
505 : // RE-ENGINEERED -
506 :
507 : // PURPOSE OF THIS SUBROUTINE:
508 : // Subroutine for displacement ventilation modelling.
509 : // This subroutine calculates the mixed subzone height, surface heat transfer coefficients and
510 : // room air equivalent temperatures and three space temperatures (floor subzone, occupied zone and upper,
511 : // mixed subzone temperature)
512 :
513 : // REFERENCES:
514 : // Model developed by Paul Linden (UCSD), G. Carrilho da Graca (UCSD) and P. Haves (LBL).
515 : // Work funded by the California Energy Comission. More information on the model can found in:
516 : // "Simplified Models for Heat Transfer in Rooms" G. Carrilho da Graca, Ph.D. thesis UCSD. December 2003.
517 :
518 : // Using/Aliasing
519 : using namespace DataEnvironment;
520 : using namespace DataHeatBalance;
521 :
522 14995 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
523 14995 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
524 :
525 : using Psychrometrics::PsyCpAirFnW;
526 : using Psychrometrics::PsyRhoAirFnPbTdbW;
527 :
528 : // SUBROUTINE PARAMETER DEFINITIONS:
529 14995 : Real64 const OneThird(1.0 / 3.0);
530 14995 : Real64 const MinFlow_pow_fac(std::pow(1.0 / 24.55 * 1.0, 1.0 / 0.6));
531 :
532 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
533 : Real64 HeightFrac; // Fractional height of transition between occupied and mixed subzones
534 : Real64 GainsFrac; // Fraction of lower subzone internal gains that mix as opposed to forming plumes
535 : Real64 ConvGains; // Total convective gains in the room
536 : Real64 ConvGainsOccupiedSubzone; // Total convective gains released in occupied subzone
537 : Real64 ConvGainsMixedSubzone; // Total convective gains released in mixed subzone
538 : Real64 MCp_Total; // Total capacity rate into the zone - assumed to enter at low level
539 : Real64 ZTAveraged;
540 : Real64 TempDiffCritRep; // Minimum temperature difference between mixed and occupied subzones for reporting
541 : bool MIXFLAG;
542 : Real64 MinFlow;
543 : Real64 NumPLPP; // Number of plumes per person
544 : Real64 MTGAUX;
545 : int ZoneEquipConfigNum;
546 : Real64 PowerInPlumes;
547 : Real64 SumSysMCp;
548 : Real64 SumSysMCpT;
549 : Real64 NodeTemp;
550 : Real64 MassFlowRate;
551 : Real64 CpAir;
552 : Real64 MCpT_Total;
553 : Real64 NumberOfPlumes;
554 : Real64 SumMCp;
555 : Real64 SumMCpT;
556 : Real64 TempHistTerm;
557 : Real64 PowerPerPlume;
558 : Real64 HeightMixedSubzoneAve; // Height of center of mixed air subzone
559 : Real64 HeightOccupiedSubzoneAve; // Height of center of occupied air subzone
560 : Real64 HeightFloorSubzoneAve; // Height of center of floor air subzone
561 : Real64 HeightThermostat; // Height of center of thermostat/temperature control sensor
562 : Real64 HeightComfort; // Height at which air temperature value is used to calculate comfort
563 : Real64 CeilingHeight;
564 : Real64 ZoneMult; // total zone multiplier
565 : int FlagApertures;
566 :
567 14995 : auto &TempDepCoef = state.dataDispVentMgr->TempDepCoef;
568 14995 : auto &TempIndCoef = state.dataDispVentMgr->TempIndCoef;
569 :
570 : Real64 RetAirGain;
571 14995 : assert(state.dataRoomAir->AirModel.allocated());
572 :
573 : // Exact solution or Euler method
574 14995 : if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) {
575 6608 : if (state.dataHVACGlobal->ShortenTimeStepSysRoomAir && TimeStepSys < state.dataGlobal->TimeStepZone) {
576 295 : if (state.dataHVACGlobal->PreviousTimeStep < state.dataGlobal->TimeStepZone) {
577 93 : state.dataRoomAir->Zone1Floor(ZoneNum) = state.dataRoomAir->ZoneM2Floor(ZoneNum);
578 93 : state.dataRoomAir->Zone1OC(ZoneNum) = state.dataRoomAir->ZoneM2OC(ZoneNum);
579 93 : state.dataRoomAir->Zone1MX(ZoneNum) = state.dataRoomAir->ZoneM2MX(ZoneNum);
580 : } else {
581 202 : state.dataRoomAir->Zone1Floor(ZoneNum) = state.dataRoomAir->ZoneMXFloor(ZoneNum);
582 202 : state.dataRoomAir->Zone1OC(ZoneNum) = state.dataRoomAir->ZoneMXOC(ZoneNum);
583 202 : state.dataRoomAir->Zone1MX(ZoneNum) = state.dataRoomAir->ZoneMXMX(ZoneNum);
584 : }
585 : } else {
586 6313 : state.dataRoomAir->Zone1Floor(ZoneNum) = state.dataRoomAir->ZTFloor(ZoneNum);
587 6313 : state.dataRoomAir->Zone1OC(ZoneNum) = state.dataRoomAir->ZTOC(ZoneNum);
588 6313 : state.dataRoomAir->Zone1MX(ZoneNum) = state.dataRoomAir->ZTMX(ZoneNum);
589 : }
590 : }
591 :
592 14995 : auto &zone = state.dataHeatBal->Zone(ZoneNum);
593 :
594 14995 : MIXFLAG = false;
595 14995 : FlagApertures = 1;
596 14995 : state.dataRoomAir->DispVent3NodeHcIn = state.dataHeatBalSurf->SurfHConvInt;
597 14995 : CeilingHeight = state.dataRoomAir->ZoneCeilingHeight2(ZoneNum) - state.dataRoomAir->ZoneCeilingHeight1(ZoneNum);
598 14995 : ZoneMult = zone.Multiplier * zone.ListMultiplier;
599 14995 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
600 :
601 29990 : for (int Ctd = 1; Ctd <= state.dataRoomAir->TotDispVent3Node; ++Ctd) {
602 14995 : auto &zoneDV3N = state.dataRoomAir->ZoneDispVent3Node(Ctd);
603 14995 : if (ZoneNum == zoneDV3N.ZonePtr) {
604 14995 : GainsFrac = zoneDV3N.gainsSched->getCurrentVal();
605 14995 : NumPLPP = zoneDV3N.NumPlumesPerOcc;
606 14995 : HeightThermostat = zoneDV3N.ThermostatHeight;
607 14995 : HeightComfort = zoneDV3N.ComfortHeight;
608 14995 : TempDiffCritRep = zoneDV3N.TempTrigger;
609 : }
610 : }
611 :
612 14995 : ConvGainsOccupiedSubzone = InternalHeatGains::SumInternalConvectionGainsByTypes(state, ZoneNum, IntGainTypesOccupied);
613 :
614 14995 : ConvGainsOccupiedSubzone += 0.5 * thisZoneHB.SysDepZoneLoadsLagged;
615 :
616 : // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very
617 : // low or zero)
618 14995 : if (zone.NoHeatToReturnAir) {
619 0 : RetAirGain = InternalHeatGains::SumReturnAirConvectionGainsByTypes(state, ZoneNum, IntGainTypesOccupied);
620 0 : ConvGainsOccupiedSubzone += RetAirGain;
621 : }
622 :
623 14995 : ConvGainsMixedSubzone = InternalHeatGains::SumInternalConvectionGainsByTypes(state, ZoneNum, IntGainTypesMixedSubzone);
624 14995 : ConvGainsMixedSubzone += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) +
625 14995 : 0.5 * thisZoneHB.SysDepZoneLoadsLagged;
626 14995 : if (zone.NoHeatToReturnAir) {
627 0 : RetAirGain = InternalHeatGains::SumReturnAirConvectionGainsByTypes(state, ZoneNum, IntGainTypesMixedSubzone);
628 0 : ConvGainsMixedSubzone += RetAirGain;
629 : }
630 :
631 14995 : ConvGains = ConvGainsOccupiedSubzone + ConvGainsMixedSubzone;
632 :
633 : // Make sure all types of internal gains have been gathered
634 44985 : assert((int)(size(IntGainTypesOccupied) + size(IntGainTypesMixedSubzone) + size(ExcludedIntGainTypes)) ==
635 : (int)DataHeatBalance::IntGainType::Num);
636 :
637 : //=================== Entering air system temperature and flow====================
638 14995 : SumSysMCp = 0.0;
639 14995 : SumSysMCpT = 0.0;
640 : // Check to make sure if this is a controlled zone and determine ZoneEquipConfigNum
641 14995 : ZoneEquipConfigNum = ZoneNum;
642 14995 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).IsControlled) {
643 16774 : for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++NodeNum) {
644 8387 : NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).Temp;
645 8387 : MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).MassFlowRate;
646 8387 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
647 8387 : SumSysMCp += MassFlowRate * CpAir;
648 8387 : SumSysMCpT += MassFlowRate * CpAir * NodeTemp;
649 : }
650 : }
651 :
652 14995 : SumMCp = thisZoneHB.MCPI + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA;
653 14995 : SumMCpT =
654 14995 : thisZoneHB.MCPTI + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + thisZoneHB.MDotCPOA * zone.OutDryBulbTemp;
655 14995 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithoutDistribution) {
656 6608 : SumMCp = state.afn->exchangeData(ZoneNum).SumMCp + state.afn->exchangeData(ZoneNum).SumMVCp + state.afn->exchangeData(ZoneNum).SumMMCp;
657 6608 : SumMCpT =
658 6608 : state.afn->exchangeData(ZoneNum).SumMCpT + state.afn->exchangeData(ZoneNum).SumMVCpT + state.afn->exchangeData(ZoneNum).SumMMCpT;
659 : }
660 :
661 14995 : MCp_Total = SumMCp + SumSysMCp;
662 14995 : MCpT_Total = SumMCpT + SumSysMCpT;
663 :
664 14995 : if (state.dataHeatBal->TotPeople > 0) {
665 14995 : int NumberOfOccupants = 0;
666 14995 : NumberOfPlumes = 0.0;
667 45126 : for (int Ctd = 1; Ctd <= state.dataHeatBal->TotPeople; ++Ctd) {
668 30131 : if (state.dataHeatBal->People(Ctd).ZonePtr == ZoneNum) {
669 30131 : NumberOfOccupants +=
670 30131 : state.dataHeatBal->People(Ctd).NumberOfPeople; // *GetCurrentScheduleValue(state, People(Ctd)%NumberOfPeoplePtr)
671 30131 : NumberOfPlumes = NumberOfOccupants * NumPLPP;
672 : }
673 : }
674 14995 : if (NumberOfPlumes == 0.0) {
675 0 : NumberOfPlumes = 1.0;
676 : }
677 14995 : PowerInPlumes = (1.0 - GainsFrac) * ConvGainsOccupiedSubzone;
678 14995 : PowerPerPlume = PowerInPlumes / NumberOfPlumes;
679 : } else {
680 0 : NumberOfPlumes = 1.0;
681 0 : PowerInPlumes = (1.0 - GainsFrac) * ConvGainsOccupiedSubzone;
682 0 : PowerPerPlume = PowerInPlumes / NumberOfPlumes;
683 : }
684 :
685 : // When AirflowNetwork is used verify if bottom apertures are inflowing and upper apertures are
686 : // outflowing. The lower apertures have to be located below 0.8m and the upper apertures
687 : // have to be located above 1.8m.
688 :
689 14995 : if (state.afn->NumOfLinksMultiZone > 0) {
690 26432 : for (int Loop = 1; Loop <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Loop) {
691 : // direct AirflowNetwork surface
692 19824 : int afnSurfNum = state.dataRoomAir->AFNSurfaceCrossVent(Loop, ZoneNum);
693 19824 : auto const &surfParams = state.dataRoomAir->SurfParametersCrossDispVent(afnSurfNum);
694 19824 : auto const &afnLinkSimu = state.afn->AirflowNetworkLinkSimu(afnSurfNum);
695 19824 : auto const &afnMzSurfData = state.afn->MultizoneSurfaceData(afnSurfNum);
696 19824 : auto const &afnMzSurf = state.dataSurface->Surface(afnMzSurfData.SurfNum);
697 19824 : if (afnMzSurf.Zone == ZoneNum) {
698 :
699 19824 : if ((surfParams.Zmax < 0.8 && afnLinkSimu.VolFLOW > 0)) {
700 0 : FlagApertures = 0;
701 0 : break;
702 : }
703 19824 : if (surfParams.Zmin > 1.8 && afnLinkSimu.VolFLOW2 > 0) {
704 0 : FlagApertures = 0;
705 0 : break;
706 : }
707 :
708 19824 : if ((surfParams.Zmin > 0.8 && surfParams.Zmin < 1.8) || (surfParams.Zmax > 0.8 && surfParams.Zmax < 1.8)) {
709 0 : FlagApertures = 0;
710 0 : break;
711 : }
712 : // indirect AirflowNetwork surface; this is an interzone surface
713 : } else {
714 0 : auto const &afnZone = state.dataHeatBal->Zone(afnMzSurf.Zone);
715 0 : if (surfParams.Zmax + afnZone.OriginZ - zone.OriginZ < 0.8 && afnLinkSimu.VolFLOW2 > 0) {
716 0 : FlagApertures = 0;
717 0 : break;
718 : }
719 0 : if (surfParams.Zmin + afnZone.OriginZ - zone.OriginZ > 1.8 && afnLinkSimu.VolFLOW > 0) {
720 0 : FlagApertures = 0;
721 0 : break;
722 : }
723 0 : if ((surfParams.Zmin + afnZone.OriginZ - zone.OriginZ > 0.8 && surfParams.Zmin + afnZone.OriginZ - zone.OriginZ < 1.8) ||
724 0 : (surfParams.Zmax + afnZone.OriginZ - zone.OriginZ > 0.8 && surfParams.Zmax + afnZone.OriginZ - zone.OriginZ < 1.8)) {
725 0 : FlagApertures = 0;
726 0 : break;
727 : }
728 : }
729 : }
730 : }
731 :
732 14995 : if ((PowerInPlumes == 0.0) || (MCpT_Total == 0.0) || FlagApertures == 0) {
733 : // The system will mix
734 5427 : HeightFrac = 0.0;
735 : } else {
736 9568 : Real64 const plume_fac(NumberOfPlumes * std::pow(PowerPerPlume, OneThird));
737 9568 : HeightFrac = min(24.55 * std::pow(MCp_Total * 0.000833 / plume_fac, 0.6) / CeilingHeight, 1.0);
738 47840 : for (int Ctd = 1; Ctd <= 4; ++Ctd) {
739 38272 : HcDispVent3Node(state, ZoneNum, HeightFrac);
740 : // HeightFrac = min( 24.55 * std::pow( MCp_Total * 0.000833 / ( NumberOfPlumes * std::pow( PowerPerPlume, OneThird ) ), 0.6 ) /
741 : // CeilingHeight, 1.0 ); //Tuned This does not vary in loop EPTeam-replaces above (cause diffs) HeightFrac =
742 : // MIN(24.55d0*(MCp_Total*0.000833d0/(NumberOfPlumes*PowerPerPlume**(1.0d0/3.d0)))**0.6 / CeilingHeight , 1.0d0)
743 38272 : state.dataRoomAir->HeightTransition(ZoneNum) = HeightFrac * CeilingHeight;
744 38272 : state.dataRoomAir->AIRRATFloor(ZoneNum) =
745 38272 : zone.Volume * min(state.dataRoomAir->HeightTransition(ZoneNum), state.dataDispVentMgr->HeightFloorSubzoneTop) / CeilingHeight *
746 76544 : zone.ZoneVolCapMultpSens *
747 38272 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAir->MATFloor(ZoneNum), thisZoneHB.airHumRat) *
748 38272 : PsyCpAirFnW(thisZoneHB.airHumRat) / TimeStepSysSec;
749 38272 : state.dataRoomAir->AIRRATOC(ZoneNum) =
750 38272 : zone.Volume * (state.dataRoomAir->HeightTransition(ZoneNum) - min(state.dataRoomAir->HeightTransition(ZoneNum), 0.2)) /
751 76544 : CeilingHeight * zone.ZoneVolCapMultpSens *
752 38272 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAir->MATOC(ZoneNum), thisZoneHB.airHumRat) *
753 38272 : PsyCpAirFnW(thisZoneHB.airHumRat) / TimeStepSysSec;
754 38272 : state.dataRoomAir->AIRRATMX(ZoneNum) =
755 38272 : zone.Volume * (CeilingHeight - state.dataRoomAir->HeightTransition(ZoneNum)) / CeilingHeight * zone.ZoneVolCapMultpSens *
756 38272 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAir->MATMX(ZoneNum), thisZoneHB.airHumRat) *
757 38272 : PsyCpAirFnW(thisZoneHB.airHumRat) / TimeStepSysSec;
758 :
759 38272 : if (state.dataHVACGlobal->UseZoneTimeStepHistory) {
760 32348 : state.dataRoomAir->ZTMFloor(ZoneNum)[2] = state.dataRoomAir->XMATFloor(ZoneNum)[2];
761 32348 : state.dataRoomAir->ZTMFloor(ZoneNum)[1] = state.dataRoomAir->XMATFloor(ZoneNum)[1];
762 32348 : state.dataRoomAir->ZTMFloor(ZoneNum)[0] = state.dataRoomAir->XMATFloor(ZoneNum)[0];
763 :
764 32348 : state.dataRoomAir->ZTMOC(ZoneNum)[2] = state.dataRoomAir->XMATOC(ZoneNum)[2];
765 32348 : state.dataRoomAir->ZTMOC(ZoneNum)[1] = state.dataRoomAir->XMATOC(ZoneNum)[1];
766 32348 : state.dataRoomAir->ZTMOC(ZoneNum)[0] = state.dataRoomAir->XMATOC(ZoneNum)[0];
767 :
768 32348 : state.dataRoomAir->ZTMMX(ZoneNum)[2] = state.dataRoomAir->XMATMX(ZoneNum)[2];
769 32348 : state.dataRoomAir->ZTMMX(ZoneNum)[1] = state.dataRoomAir->XMATMX(ZoneNum)[1];
770 32348 : state.dataRoomAir->ZTMMX(ZoneNum)[0] = state.dataRoomAir->XMATMX(ZoneNum)[0];
771 :
772 : } else {
773 5924 : state.dataRoomAir->ZTMFloor(ZoneNum)[2] = state.dataRoomAir->DSXMATFloor(ZoneNum)[2];
774 5924 : state.dataRoomAir->ZTMFloor(ZoneNum)[1] = state.dataRoomAir->DSXMATFloor(ZoneNum)[1];
775 5924 : state.dataRoomAir->ZTMFloor(ZoneNum)[0] = state.dataRoomAir->DSXMATFloor(ZoneNum)[0];
776 :
777 5924 : state.dataRoomAir->ZTMOC(ZoneNum)[2] = state.dataRoomAir->DSXMATOC(ZoneNum)[2];
778 5924 : state.dataRoomAir->ZTMOC(ZoneNum)[1] = state.dataRoomAir->DSXMATOC(ZoneNum)[1];
779 5924 : state.dataRoomAir->ZTMOC(ZoneNum)[0] = state.dataRoomAir->DSXMATOC(ZoneNum)[0];
780 :
781 5924 : state.dataRoomAir->ZTMMX(ZoneNum)[2] = state.dataRoomAir->DSXMATMX(ZoneNum)[2];
782 5924 : state.dataRoomAir->ZTMMX(ZoneNum)[1] = state.dataRoomAir->DSXMATMX(ZoneNum)[1];
783 5924 : state.dataRoomAir->ZTMMX(ZoneNum)[0] = state.dataRoomAir->DSXMATMX(ZoneNum)[0];
784 : }
785 :
786 38272 : Real64 AirCap = state.dataRoomAir->AIRRATFloor(ZoneNum);
787 38272 : TempHistTerm = AirCap * (3.0 * state.dataRoomAir->ZTMFloor(ZoneNum)[0] - (3.0 / 2.0) * state.dataRoomAir->ZTMFloor(ZoneNum)[1] +
788 38272 : OneThird * state.dataRoomAir->ZTMFloor(ZoneNum)[2]);
789 38272 : TempDepCoef = state.dataDispVentMgr->HA_FLOOR + MCp_Total;
790 38272 : TempIndCoef = state.dataDispVentMgr->HAT_FLOOR + MCpT_Total + thisZoneHB.NonAirSystemResponse / ZoneMult;
791 38272 : switch (state.dataHeatBal->ZoneAirSolutionAlgo) {
792 23860 : case DataHeatBalance::SolutionAlgo::ThirdOrder: {
793 23860 : state.dataRoomAir->ZTFloor(ZoneNum) = calculateThirdOrderFloorTemperature(TempHistTerm,
794 23860 : state.dataDispVentMgr->HAT_FLOOR,
795 23860 : state.dataDispVentMgr->HA_FLOOR,
796 : MCpT_Total,
797 : MCp_Total,
798 23860 : state.dataRoomAir->ZTOC(ZoneNum),
799 : thisZoneHB.NonAirSystemResponse,
800 : ZoneMult,
801 : AirCap);
802 23860 : } break;
803 0 : case DataHeatBalance::SolutionAlgo::AnalyticalSolution: {
804 0 : if (TempDepCoef == 0.0) { // B=0
805 0 : state.dataRoomAir->ZTFloor(ZoneNum) = state.dataRoomAir->Zone1Floor(ZoneNum) + TempIndCoef / AirCap;
806 : } else {
807 0 : state.dataRoomAir->ZTFloor(ZoneNum) =
808 0 : (state.dataRoomAir->Zone1Floor(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) +
809 0 : TempIndCoef / TempDepCoef;
810 : }
811 0 : } break;
812 14412 : case DataHeatBalance::SolutionAlgo::EulerMethod: {
813 14412 : state.dataRoomAir->ZTFloor(ZoneNum) = (AirCap * state.dataRoomAir->Zone1Floor(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef);
814 14412 : } break;
815 0 : default:
816 0 : break;
817 : }
818 38272 : AirCap = state.dataRoomAir->AIRRATOC(ZoneNum);
819 38272 : TempHistTerm = AirCap * (3.0 * state.dataRoomAir->ZTMOC(ZoneNum)[0] - (3.0 / 2.0) * state.dataRoomAir->ZTMOC(ZoneNum)[1] +
820 38272 : OneThird * state.dataRoomAir->ZTMOC(ZoneNum)[2]);
821 38272 : TempDepCoef = state.dataDispVentMgr->HA_OC + MCp_Total;
822 38272 : TempIndCoef = ConvGainsOccupiedSubzone * GainsFrac + state.dataDispVentMgr->HAT_OC + state.dataRoomAir->ZTFloor(ZoneNum) * MCp_Total;
823 38272 : switch (state.dataHeatBal->ZoneAirSolutionAlgo) {
824 23860 : case DataHeatBalance::SolutionAlgo::ThirdOrder: {
825 47720 : state.dataRoomAir->ZTOC(ZoneNum) = (TempHistTerm + ConvGainsOccupiedSubzone * GainsFrac + state.dataDispVentMgr->HAT_OC +
826 23860 : 1.6 * state.dataRoomAir->ZTFloor(ZoneNum) * MCp_Total) /
827 23860 : ((11.0 / 6.0) * AirCap + state.dataDispVentMgr->HA_OC + 1.6 * MCp_Total);
828 23860 : } break;
829 0 : case DataHeatBalance::SolutionAlgo::AnalyticalSolution: {
830 0 : if (TempDepCoef == 0.0) { // B=0
831 0 : state.dataRoomAir->ZTOC(ZoneNum) = state.dataRoomAir->Zone1OC(ZoneNum) + TempIndCoef / AirCap;
832 : } else {
833 0 : if (AirCap == 0.0) {
834 0 : state.dataRoomAir->ZTOC(ZoneNum) = TempIndCoef / TempDepCoef;
835 : } else {
836 0 : state.dataRoomAir->ZTOC(ZoneNum) =
837 0 : (state.dataRoomAir->Zone1OC(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) +
838 0 : TempIndCoef / TempDepCoef;
839 : }
840 : }
841 0 : } break;
842 14412 : case DataHeatBalance::SolutionAlgo::EulerMethod: {
843 14412 : state.dataRoomAir->ZTOC(ZoneNum) = (AirCap * state.dataRoomAir->Zone1OC(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef);
844 14412 : } break;
845 0 : default:
846 0 : break;
847 : }
848 38272 : AirCap = state.dataRoomAir->AIRRATMX(ZoneNum);
849 38272 : TempHistTerm = AirCap * (3.0 * state.dataRoomAir->ZTMMX(ZoneNum)[0] - (3.0 / 2.0) * state.dataRoomAir->ZTMMX(ZoneNum)[1] +
850 38272 : OneThird * state.dataRoomAir->ZTMMX(ZoneNum)[2]);
851 38272 : TempDepCoef = state.dataDispVentMgr->HA_MX + MCp_Total;
852 38272 : TempIndCoef = ConvGainsOccupiedSubzone * (1.0 - GainsFrac) + ConvGainsMixedSubzone + state.dataDispVentMgr->HAT_MX +
853 38272 : state.dataRoomAir->ZTOC(ZoneNum) * MCp_Total;
854 38272 : switch (state.dataHeatBal->ZoneAirSolutionAlgo) {
855 23860 : case DataHeatBalance::SolutionAlgo::ThirdOrder: {
856 23860 : state.dataRoomAir->ZTMX(ZoneNum) = (TempHistTerm + ConvGainsOccupiedSubzone * (1.0 - GainsFrac) + ConvGainsMixedSubzone +
857 23860 : state.dataDispVentMgr->HAT_MX + state.dataRoomAir->ZTOC(ZoneNum) * MCp_Total) /
858 23860 : ((11.0 / 6.0) * AirCap + state.dataDispVentMgr->HA_MX + MCp_Total);
859 23860 : } break;
860 0 : case DataHeatBalance::SolutionAlgo::AnalyticalSolution: {
861 0 : if (TempDepCoef == 0.0) { // B=0
862 0 : state.dataRoomAir->ZTMX(ZoneNum) = state.dataRoomAir->Zone1MX(ZoneNum) + TempIndCoef / AirCap;
863 : } else {
864 0 : if (AirCap == 0.0) {
865 0 : state.dataRoomAir->ZTMX(ZoneNum) = TempIndCoef / TempDepCoef;
866 : } else {
867 0 : state.dataRoomAir->ZTMX(ZoneNum) =
868 0 : (state.dataRoomAir->Zone1MX(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) +
869 0 : TempIndCoef / TempDepCoef;
870 : }
871 : }
872 0 : } break;
873 14412 : case DataHeatBalance::SolutionAlgo::EulerMethod: {
874 14412 : state.dataRoomAir->ZTMX(ZoneNum) = (AirCap * state.dataRoomAir->Zone1MX(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef);
875 14412 : } break;
876 0 : default:
877 0 : break;
878 : }
879 : }
880 :
881 : // MinFlow for interface layer at z = 1.0
882 9568 : MinFlow = MinFlow_pow_fac * plume_fac;
883 : // EPTeam above replaces (cause diffs?) MinFlow = (1.0d0/24.55d0*1.0d0)**(1.0d0/0.6d0)*NumberOfPlumes*PowerPerPlume**(1.0/3.0)
884 9568 : if (MinFlow != 0.0) {
885 9568 : state.dataRoomAir->FracMinFlow(ZoneNum) = MCp_Total * 0.000833 / MinFlow;
886 : } else {
887 0 : state.dataRoomAir->FracMinFlow(ZoneNum) = 9.999;
888 : }
889 9568 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
890 : }
891 :
892 : //=============================== M I X E D Calculation ==============================================
893 26442 : if (state.dataRoomAir->ZTMX(ZoneNum) < state.dataRoomAir->ZTOC(ZoneNum) || MCp_Total <= 0.0 ||
894 11447 : HeightFrac * CeilingHeight < (state.dataDispVentMgr->HeightFloorSubzoneTop + state.dataDispVentMgr->ThickOccupiedSubzoneMin)) {
895 8675 : MIXFLAG = true;
896 8675 : HeightFrac = 0.0;
897 8675 : state.dataRoomAir->AvgTempGrad(ZoneNum) = 0.0;
898 8675 : state.dataRoomAir->MaxTempGrad(ZoneNum) = 0.0;
899 8675 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
900 8675 : Real64 const thisZoneT1 = thisZoneHB.T1;
901 8675 : Real64 AirCap = thisZoneHB.AirPowerCap;
902 8675 : TempHistTerm = AirCap * (3.0 * thisZoneHB.ZTM[0] - (3.0 / 2.0) * thisZoneHB.ZTM[1] + OneThird * thisZoneHB.ZTM[2]);
903 :
904 34700 : for (int Ctd = 1; Ctd <= 3; ++Ctd) {
905 26025 : TempDepCoef = state.dataDispVentMgr->HA_MX + state.dataDispVentMgr->HA_OC + state.dataDispVentMgr->HA_FLOOR + MCp_Total;
906 26025 : TempIndCoef =
907 26025 : ConvGains + state.dataDispVentMgr->HAT_MX + state.dataDispVentMgr->HAT_OC + state.dataDispVentMgr->HAT_FLOOR + MCpT_Total;
908 26025 : switch (state.dataHeatBal->ZoneAirSolutionAlgo) {
909 10488 : case DataHeatBalance::SolutionAlgo::ThirdOrder: {
910 10488 : ZTAveraged = (TempHistTerm + ConvGains + state.dataDispVentMgr->HAT_MX + state.dataDispVentMgr->HAT_OC +
911 10488 : state.dataDispVentMgr->HAT_FLOOR + MCpT_Total) /
912 10488 : ((11.0 / 6.0) * AirCap + state.dataDispVentMgr->HA_MX + state.dataDispVentMgr->HA_OC +
913 10488 : state.dataDispVentMgr->HA_FLOOR + MCp_Total);
914 10488 : } break;
915 0 : case DataHeatBalance::SolutionAlgo::AnalyticalSolution: {
916 0 : if (TempDepCoef == 0.0) { // B=0
917 0 : ZTAveraged = thisZoneT1 + TempIndCoef / AirCap;
918 : } else {
919 0 : ZTAveraged =
920 0 : (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef;
921 : }
922 0 : } break;
923 15537 : case DataHeatBalance::SolutionAlgo::EulerMethod: {
924 15537 : ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef);
925 15537 : } break;
926 0 : default:
927 0 : break;
928 : }
929 26025 : state.dataRoomAir->ZTOC(ZoneNum) = ZTAveraged;
930 26025 : state.dataRoomAir->ZTMX(ZoneNum) = ZTAveraged;
931 26025 : state.dataRoomAir->ZTFloor(ZoneNum) = ZTAveraged;
932 26025 : HcDispVent3Node(state, ZoneNum, HeightFrac);
933 26025 : TempDepCoef = state.dataDispVentMgr->HA_MX + state.dataDispVentMgr->HA_OC + state.dataDispVentMgr->HA_FLOOR + MCp_Total;
934 26025 : TempIndCoef =
935 26025 : ConvGains + state.dataDispVentMgr->HAT_MX + state.dataDispVentMgr->HAT_OC + state.dataDispVentMgr->HAT_FLOOR + MCpT_Total;
936 26025 : switch (state.dataHeatBal->ZoneAirSolutionAlgo) {
937 10488 : case DataHeatBalance::SolutionAlgo::ThirdOrder: {
938 10488 : ZTAveraged = (TempHistTerm + ConvGains + state.dataDispVentMgr->HAT_MX + state.dataDispVentMgr->HAT_OC +
939 10488 : state.dataDispVentMgr->HAT_FLOOR + MCpT_Total) /
940 10488 : ((11.0 / 6.0) * AirCap + state.dataDispVentMgr->HA_MX + state.dataDispVentMgr->HA_OC +
941 10488 : state.dataDispVentMgr->HA_FLOOR + MCp_Total);
942 10488 : } break;
943 0 : case DataHeatBalance::SolutionAlgo::AnalyticalSolution: {
944 0 : if (TempDepCoef == 0.0) { // B=0
945 0 : ZTAveraged = thisZoneT1 + TempIndCoef / AirCap;
946 : } else {
947 0 : ZTAveraged =
948 0 : (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef;
949 : }
950 0 : } break;
951 15537 : case DataHeatBalance::SolutionAlgo::EulerMethod: {
952 15537 : ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef);
953 15537 : } break;
954 0 : default:
955 0 : break;
956 : }
957 26025 : state.dataRoomAir->ZTOC(ZoneNum) = ZTAveraged;
958 26025 : state.dataRoomAir->ZTMX(ZoneNum) = ZTAveraged;
959 26025 : state.dataRoomAir->ZTFloor(ZoneNum) = ZTAveraged;
960 : }
961 : }
962 : //=========================================================================================
963 :
964 : // Comfort temperature and temperature at the thermostat/temperature control sensor
965 :
966 14995 : state.dataRoomAir->HeightTransition(ZoneNum) = HeightFrac * CeilingHeight;
967 14995 : HeightMixedSubzoneAve = (CeilingHeight + state.dataRoomAir->HeightTransition(ZoneNum)) / 2.0;
968 14995 : HeightOccupiedSubzoneAve = (state.dataDispVentMgr->HeightFloorSubzoneTop + state.dataRoomAir->HeightTransition(ZoneNum)) / 2.0;
969 14995 : HeightFloorSubzoneAve = state.dataDispVentMgr->HeightFloorSubzoneTop / 2.0;
970 :
971 : // Comfort temperature
972 :
973 14995 : if (MIXFLAG) {
974 8675 : state.dataRoomAir->TCMF(ZoneNum) = ZTAveraged;
975 : } else {
976 6320 : if (HeightComfort >= 0.0 && HeightComfort < HeightFloorSubzoneAve) {
977 0 : ShowWarningError(state, format("Displacement ventilation comfort height is in floor subzone in Zone: {}", zone.Name));
978 0 : state.dataRoomAir->TCMF(ZoneNum) = state.dataRoomAir->ZTFloor(ZoneNum);
979 6320 : } else if (HeightComfort >= HeightFloorSubzoneAve && HeightComfort < HeightOccupiedSubzoneAve) {
980 1436 : state.dataRoomAir->TCMF(ZoneNum) = (state.dataRoomAir->ZTFloor(ZoneNum) * (HeightOccupiedSubzoneAve - HeightComfort) +
981 718 : state.dataRoomAir->ZTOC(ZoneNum) * (HeightComfort - HeightFloorSubzoneAve)) /
982 718 : (HeightOccupiedSubzoneAve - HeightFloorSubzoneAve);
983 : //! TCMF(ZoneNum) = (ZTFloor(ZoneNum) * (HeightOccupiedSubzoneAve - HeightComfort) &
984 : //! + ZTMX(ZoneNum) * (HeightComfort - HeightFloorSubzoneAve)) &
985 : //! / (HeightOccupiedSubzoneAve - HeightFloorSubzoneAve)
986 5602 : } else if (HeightComfort >= HeightOccupiedSubzoneAve && HeightComfort < HeightMixedSubzoneAve) {
987 11204 : state.dataRoomAir->TCMF(ZoneNum) = (state.dataRoomAir->ZTOC(ZoneNum) * (HeightMixedSubzoneAve - HeightComfort) +
988 5602 : state.dataRoomAir->ZTMX(ZoneNum) * (HeightComfort - HeightOccupiedSubzoneAve)) /
989 5602 : (HeightMixedSubzoneAve - HeightOccupiedSubzoneAve);
990 0 : } else if (HeightComfort >= HeightMixedSubzoneAve && HeightComfort <= CeilingHeight) {
991 0 : state.dataRoomAir->TCMF(ZoneNum) = state.dataRoomAir->ZTMX(ZoneNum);
992 : } else {
993 0 : ShowFatalError(state, format("Displacement ventilation comfort height is above ceiling or below floor in Zone: {}", zone.Name));
994 : }
995 : }
996 :
997 : // Temperature at the thermostat/temperature control sensor
998 :
999 14995 : if (MIXFLAG) {
1000 8675 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = ZTAveraged;
1001 : } else {
1002 6320 : if (HeightThermostat >= 0.0 && HeightThermostat < HeightFloorSubzoneAve) {
1003 0 : ShowWarningError(state, format("Displacement thermostat is in floor subzone in Zone: {}", zone.Name));
1004 0 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataRoomAir->ZTFloor(ZoneNum);
1005 6320 : } else if (HeightThermostat >= HeightFloorSubzoneAve && HeightThermostat < HeightOccupiedSubzoneAve) {
1006 718 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) =
1007 718 : (state.dataRoomAir->ZTFloor(ZoneNum) * (HeightOccupiedSubzoneAve - HeightThermostat) +
1008 718 : state.dataRoomAir->ZTOC(ZoneNum) * (HeightThermostat - HeightFloorSubzoneAve)) /
1009 718 : (HeightOccupiedSubzoneAve - HeightFloorSubzoneAve);
1010 : //! TempTstatAir(ZoneNum) = (ZTFloor(ZoneNum) * (HeightOccupiedSubzoneAve - HeightThermostat) &
1011 : //! + ZTMX(ZoneNum) * (HeightThermostat - HeightFloorSubzoneAve)) &
1012 : //! / (HeightOccupiedSubzoneAve - HeightFloorSubzoneAve)
1013 5602 : } else if (HeightThermostat >= HeightOccupiedSubzoneAve && HeightThermostat < HeightMixedSubzoneAve) {
1014 11204 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = (state.dataRoomAir->ZTOC(ZoneNum) * (HeightMixedSubzoneAve - HeightThermostat) +
1015 5602 : state.dataRoomAir->ZTMX(ZoneNum) * (HeightThermostat - HeightOccupiedSubzoneAve)) /
1016 5602 : (HeightMixedSubzoneAve - HeightOccupiedSubzoneAve);
1017 0 : } else if (HeightThermostat >= HeightMixedSubzoneAve && HeightThermostat <= CeilingHeight) {
1018 0 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataRoomAir->ZTMX(ZoneNum);
1019 : } else {
1020 0 : ShowFatalError(state, format("Displacement ventilation thermostat height is above ceiling or below floor in Zone: {}", zone.Name));
1021 : }
1022 : }
1023 :
1024 : // Temperature gradients
1025 :
1026 14995 : if ((HeightMixedSubzoneAve - HeightFloorSubzoneAve) > 0.1) {
1027 14995 : state.dataRoomAir->AvgTempGrad(ZoneNum) =
1028 14995 : (state.dataRoomAir->ZTMX(ZoneNum) - state.dataRoomAir->ZTFloor(ZoneNum)) / (HeightMixedSubzoneAve - HeightFloorSubzoneAve);
1029 : } else {
1030 0 : state.dataRoomAir->AvgTempGrad(ZoneNum) = -9.999;
1031 : }
1032 14995 : if ((HeightOccupiedSubzoneAve - HeightFloorSubzoneAve) > 0.1) {
1033 6320 : state.dataRoomAir->MaxTempGrad(ZoneNum) =
1034 6320 : (state.dataRoomAir->ZTOC(ZoneNum) - state.dataRoomAir->ZTFloor(ZoneNum)) / (HeightOccupiedSubzoneAve - HeightFloorSubzoneAve);
1035 : } else {
1036 8675 : state.dataRoomAir->MaxTempGrad(ZoneNum) = -9.999;
1037 : }
1038 14995 : if ((HeightMixedSubzoneAve - HeightOccupiedSubzoneAve) > 0.1) {
1039 14995 : MTGAUX = (state.dataRoomAir->ZTMX(ZoneNum) - state.dataRoomAir->ZTOC(ZoneNum)) / (HeightMixedSubzoneAve - HeightOccupiedSubzoneAve);
1040 : } else {
1041 0 : MTGAUX = -9.999;
1042 : }
1043 :
1044 14995 : if (MTGAUX > state.dataRoomAir->MaxTempGrad(ZoneNum)) {
1045 12122 : state.dataRoomAir->MaxTempGrad(ZoneNum) = MTGAUX;
1046 : }
1047 :
1048 14995 : if (MIXFLAG) {
1049 8675 : state.dataRoomAir->ZoneDispVent3NodeMixedFlag(ZoneNum) = 1;
1050 8675 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
1051 : } else {
1052 6320 : state.dataRoomAir->ZoneDispVent3NodeMixedFlag(ZoneNum) = 0;
1053 6320 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
1054 : }
1055 :
1056 14995 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) {
1057 8387 : int ZoneNodeNum = zone.SystemZoneNodeNumber;
1058 8387 : state.dataLoopNodes->Node(ZoneNodeNum).Temp = state.dataRoomAir->ZTMX(ZoneNum);
1059 : }
1060 :
1061 : // Mixed for reporting purposes
1062 14995 : if ((MIXFLAG) || ((state.dataRoomAir->ZTMX(ZoneNum) - state.dataRoomAir->ZTOC(ZoneNum)) < TempDiffCritRep)) {
1063 8934 : state.dataRoomAir->ZoneDispVent3NodeMixedFlagRep(ZoneNum) = 1.0;
1064 8934 : state.dataRoomAir->FracMinFlow(ZoneNum) = -1.0;
1065 8934 : state.dataRoomAir->HeightTransition(ZoneNum) = -9.999;
1066 8934 : state.dataRoomAir->AvgTempGrad(ZoneNum) = -9.999;
1067 8934 : state.dataRoomAir->MaxTempGrad(ZoneNum) = -9.999;
1068 : } else {
1069 6061 : state.dataRoomAir->ZoneDispVent3NodeMixedFlagRep(ZoneNum) = 0.0;
1070 : }
1071 14995 : }
1072 :
1073 : } // namespace RoomAir
1074 : } // namespace EnergyPlus
|