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