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 <cassert>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <AirflowNetwork/Solver.hpp>
57 : #include <EnergyPlus/ConvectionCoefficients.hh>
58 : #include <EnergyPlus/CrossVentMgr.hh>
59 : #include <EnergyPlus/Data/EnergyPlusData.hh>
60 : #include <EnergyPlus/DataEnvironment.hh>
61 : #include <EnergyPlus/DataGlobals.hh>
62 : #include <EnergyPlus/DataHeatBalFanSys.hh>
63 : #include <EnergyPlus/DataHeatBalSurface.hh>
64 : #include <EnergyPlus/DataHeatBalance.hh>
65 : #include <EnergyPlus/DataRoomAirModel.hh>
66 : #include <EnergyPlus/DataSurfaces.hh>
67 : #include <EnergyPlus/InternalHeatGains.hh>
68 : #include <EnergyPlus/Psychrometrics.hh>
69 : #include <EnergyPlus/ScheduleManager.hh>
70 : #include <EnergyPlus/UtilityRoutines.hh>
71 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
72 :
73 : namespace EnergyPlus {
74 :
75 : namespace RoomAir {
76 :
77 : // MODULE INFORMATION:
78 : // AUTHOR G. Carrilho da Graca
79 : // DATE WRITTEN October 2004
80 :
81 : // PURPOSE OF THIS MODULE:
82 : // Routines that implement the UCSD Cross Ventilation
83 :
84 : using namespace DataEnvironment;
85 : using namespace DataHeatBalance;
86 : using namespace DataHeatBalSurface;
87 : using namespace DataSurfaces;
88 : using Convect::CalcDetailedHcInForDVModel;
89 :
90 : Real64 constexpr Cjet1(1.873); // First correlation constant for the jet velocity
91 : Real64 constexpr Cjet2(0.243); // Second correlation constant for the jet velocity
92 : Real64 constexpr Crec1(0.591); // First correlation constant for the recirculation velocity
93 : Real64 constexpr Crec2(0.070); // Second correlation constant for the recirculation velocity
94 : Real64 constexpr CjetTemp(0.849); // Correlation constant for the jet temperature rise
95 : Real64 constexpr CrecTemp(1.385); // Correlation constant for the recirculation temperature rise
96 : Real64 constexpr CrecFlow1(0.415); // First correlation constant for the recirculation flow rate
97 : Real64 constexpr CrecFlow2(0.466); // Second correlation constant for the recirculation flow rate
98 :
99 4030 : void ManageCrossVent(EnergyPlusData &state,
100 : int const ZoneNum) // index number for the specified zone
101 : {
102 :
103 : // SUBROUTINE INFORMATION:
104 : // AUTHOR G. Carrilho da Graca
105 : // DATE WRITTEN October 2004
106 :
107 : // PURPOSE OF THIS SUBROUTINE:
108 : // manage the UCSD Cross Ventilation model
109 :
110 4030 : InitCrossVent(state, ZoneNum);
111 :
112 : // perform Cross Ventilation model calculations
113 4030 : CalcCrossVent(state, ZoneNum);
114 4030 : }
115 :
116 4030 : void InitCrossVent(EnergyPlusData &state, int const ZoneNum)
117 : {
118 :
119 : // SUBROUTINE INFORMATION:
120 : // AUTHOR G. Carrilho da Graca
121 : // DATE WRITTEN October 2004
122 :
123 : // PURPOSE OF THIS SUBROUTINE:
124 : // Low Energy Cooling by Ventilation initialization subroutine.
125 : // All the data preparation needed to run the LECV models.
126 : // The subroutines sets up arrays with the locations in the main EnergyPlus surface array of
127 : // ceiling, windows, doors and walls. The zone maximum and minimum height is calculated.
128 :
129 : // Do the one time initializations
130 4030 : if (state.dataCrossVentMgr->InitUCSDCV_MyOneTimeFlag) {
131 2 : state.dataCrossVentMgr->InitUCSDCV_MyEnvrnFlag.dimension(state.dataGlobal->NumOfZones, true);
132 2 : state.dataCrossVentMgr->InitUCSDCV_MyOneTimeFlag = false;
133 : }
134 :
135 : // Do the begin environment initializations
136 4030 : if (state.dataGlobal->BeginEnvrnFlag && state.dataCrossVentMgr->InitUCSDCV_MyEnvrnFlag(ZoneNum)) {
137 12 : state.dataCrossVentMgr->InitUCSDCV_MyEnvrnFlag(ZoneNum) = false;
138 : }
139 :
140 4030 : if (!state.dataGlobal->BeginEnvrnFlag) {
141 3999 : state.dataCrossVentMgr->InitUCSDCV_MyEnvrnFlag(ZoneNum) = true;
142 : }
143 4030 : }
144 :
145 16535 : void HcCrossVent(EnergyPlusData &state, int const ZoneNum)
146 : {
147 :
148 : // SUBROUTINE INFORMATION:
149 : // AUTHOR G. Carrilho da Graca
150 : // DATE WRITTEN October 2004
151 : // MODIFIED 8/2013 - Sam Brunswick
152 : // To improve convection coefficient calculation
153 :
154 : // PURPOSE OF THIS SUBROUTINE:
155 : // Main subroutine for convection calculation in the UCSD Cross Ventilation model.
156 : // It calls CalcDetailedHcInForDVModel for convection coefficient
157 : // initial calculations and averages the final result comparing the position of the surface with
158 : // the interface subzone height.
159 :
160 : // Initialize HAT and HA
161 16535 : state.dataCrossVentMgr->HAT_J = 0.0;
162 16535 : state.dataCrossVentMgr->HAT_R = 0.0;
163 16535 : state.dataCrossVentMgr->HA_J = 0.0;
164 16535 : state.dataCrossVentMgr->HA_R = 0.0;
165 :
166 : // Is the air flow model for this zone set to UCSDCV Cross Ventilation?
167 16535 : if (state.dataRoomAir->IsZoneCrossVent(ZoneNum)) {
168 :
169 16535 : Real64 zoneJetRecAreaRatio = state.dataRoomAir->JetRecAreaRatio(ZoneNum);
170 :
171 : // WALL Hc, HA and HAT calculation
172 82675 : for (int Ctd = state.dataRoomAir->PosZ_Wall(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Wall(ZoneNum).end; ++Ctd) {
173 66140 : int SurfNum = state.dataRoomAir->APos_Wall(Ctd);
174 66140 : if (SurfNum == 0) {
175 0 : continue;
176 : }
177 :
178 66140 : auto const &surf = state.dataSurface->Surface(SurfNum);
179 66140 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
180 66140 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
181 66140 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
182 66140 : CalcDetailedHcInForDVModel(
183 66140 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
184 66140 : state.dataRoomAir->HWall(Ctd) = state.dataRoomAir->CrossVentHcIn(SurfNum);
185 66140 : state.dataCrossVentMgr->HAT_R += surf.Area * state.dataHeatBalSurf->SurfTempIn(SurfNum) * state.dataRoomAir->HWall(Ctd);
186 66140 : state.dataCrossVentMgr->HA_R += surf.Area * state.dataRoomAir->HWall(Ctd);
187 : } // END WALL
188 : // WINDOW Hc, HA and HAT CALCULATION
189 64861 : for (int Ctd = state.dataRoomAir->PosZ_Window(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Window(ZoneNum).end; ++Ctd) {
190 48326 : int SurfNum = state.dataRoomAir->APos_Window(Ctd);
191 48326 : if (SurfNum == 0) {
192 0 : continue;
193 : }
194 :
195 48326 : auto const &surf = state.dataSurface->Surface(SurfNum);
196 48326 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
197 48326 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
198 48326 : if (surf.Tilt > 10.0 && surf.Tilt < 170.0) { // Window Wall
199 48326 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
200 48326 : CalcDetailedHcInForDVModel(
201 48326 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
202 48326 : state.dataRoomAir->HWindow(Ctd) = state.dataRoomAir->CrossVentHcIn(SurfNum);
203 48326 : state.dataCrossVentMgr->HAT_R += surf.Area * state.dataHeatBalSurf->SurfTempIn(SurfNum) * state.dataRoomAir->HWindow(Ctd);
204 48326 : state.dataCrossVentMgr->HA_R += surf.Area * state.dataRoomAir->HWindow(Ctd);
205 : }
206 48326 : if (surf.Tilt <= 10.0) { // Window Ceiling
207 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTJET(ZoneNum);
208 0 : CalcDetailedHcInForDVModel(
209 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Ujet);
210 0 : Real64 Hjet = state.dataRoomAir->CrossVentHcIn(SurfNum);
211 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
212 0 : CalcDetailedHcInForDVModel(
213 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
214 0 : Real64 Hrec = state.dataRoomAir->CrossVentHcIn(SurfNum);
215 0 : state.dataRoomAir->HWindow(Ctd) = zoneJetRecAreaRatio * Hjet + (1 - zoneJetRecAreaRatio) * Hrec;
216 0 : state.dataCrossVentMgr->HAT_R += surf.Area * (1.0 - zoneJetRecAreaRatio) * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hrec;
217 0 : state.dataCrossVentMgr->HA_R += surf.Area * (1.0 - zoneJetRecAreaRatio) * Hrec;
218 0 : state.dataCrossVentMgr->HAT_J += surf.Area * zoneJetRecAreaRatio * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hjet;
219 0 : state.dataCrossVentMgr->HA_J += surf.Area * zoneJetRecAreaRatio * Hjet;
220 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) =
221 0 : zoneJetRecAreaRatio * state.dataRoomAir->ZTJET(ZoneNum) + (1 - zoneJetRecAreaRatio) * state.dataRoomAir->ZTREC(ZoneNum);
222 : }
223 48326 : if (surf.Tilt >= 170.0) { // Window Floor
224 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTJET(ZoneNum);
225 0 : CalcDetailedHcInForDVModel(
226 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Ujet);
227 0 : Real64 Hjet = state.dataRoomAir->CrossVentHcIn(SurfNum);
228 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
229 0 : CalcDetailedHcInForDVModel(
230 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
231 0 : Real64 Hrec = state.dataRoomAir->CrossVentHcIn(SurfNum);
232 0 : state.dataRoomAir->HWindow(Ctd) = zoneJetRecAreaRatio * Hjet + (1 - zoneJetRecAreaRatio) * Hrec;
233 0 : state.dataCrossVentMgr->HAT_R += surf.Area * (1.0 - zoneJetRecAreaRatio) * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hrec;
234 0 : state.dataCrossVentMgr->HA_R += surf.Area * (1.0 - zoneJetRecAreaRatio) * Hrec;
235 0 : state.dataCrossVentMgr->HAT_J += surf.Area * zoneJetRecAreaRatio * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hjet;
236 0 : state.dataCrossVentMgr->HA_J += surf.Area * zoneJetRecAreaRatio * Hjet;
237 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) =
238 0 : zoneJetRecAreaRatio * state.dataRoomAir->ZTJET(ZoneNum) + (1 - zoneJetRecAreaRatio) * state.dataRoomAir->ZTREC(ZoneNum);
239 : }
240 48326 : state.dataRoomAir->CrossVentHcIn(SurfNum) = state.dataRoomAir->HWindow(Ctd);
241 : } // END WINDOW
242 : // DOOR Hc, HA and HAT CALCULATION
243 16535 : for (int Ctd = state.dataRoomAir->PosZ_Door(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Door(ZoneNum).end; ++Ctd) { // DOOR
244 0 : int SurfNum = state.dataRoomAir->APos_Door(Ctd);
245 0 : if (SurfNum == 0) {
246 0 : continue;
247 : }
248 :
249 0 : auto const &surf = state.dataSurface->Surface(SurfNum);
250 0 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
251 0 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
252 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
253 0 : CalcDetailedHcInForDVModel(
254 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
255 0 : state.dataRoomAir->HDoor(Ctd) = state.dataRoomAir->CrossVentHcIn(SurfNum);
256 0 : state.dataCrossVentMgr->HAT_R += surf.Area * state.dataHeatBalSurf->SurfTempIn(SurfNum) * state.dataRoomAir->HDoor(Ctd);
257 0 : state.dataCrossVentMgr->HA_R += surf.Area * state.dataRoomAir->HDoor(Ctd);
258 : } // END DOOR
259 :
260 : // INTERNAL Hc, HA and HAT CALCULATION
261 16535 : for (int Ctd = state.dataRoomAir->PosZ_Internal(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Internal(ZoneNum).end; ++Ctd) {
262 0 : int SurfNum = state.dataRoomAir->APos_Internal(Ctd);
263 0 : if (SurfNum == 0) {
264 0 : continue;
265 : }
266 :
267 0 : auto const &surf = state.dataSurface->Surface(SurfNum);
268 0 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
269 0 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
270 0 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
271 0 : CalcDetailedHcInForDVModel(
272 0 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
273 0 : state.dataRoomAir->HInternal(Ctd) = state.dataRoomAir->CrossVentHcIn(SurfNum);
274 0 : state.dataCrossVentMgr->HAT_R += surf.Area * state.dataHeatBalSurf->SurfTempIn(SurfNum) * state.dataRoomAir->HInternal(Ctd);
275 0 : state.dataCrossVentMgr->HA_R += surf.Area * state.dataRoomAir->HInternal(Ctd);
276 : } // END INTERNAL
277 :
278 : // CEILING Hc, HA and HAT CALCULATION
279 33070 : for (int Ctd = state.dataRoomAir->PosZ_Ceiling(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Ceiling(ZoneNum).end; ++Ctd) {
280 16535 : int SurfNum = state.dataRoomAir->APos_Ceiling(Ctd);
281 16535 : if (SurfNum == 0) {
282 0 : continue;
283 : }
284 :
285 16535 : auto const &surf = state.dataSurface->Surface(SurfNum);
286 16535 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
287 16535 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
288 16535 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTJET(ZoneNum);
289 16535 : CalcDetailedHcInForDVModel(
290 16535 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Ujet);
291 16535 : Real64 Hjet = state.dataRoomAir->CrossVentHcIn(SurfNum);
292 16535 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
293 16535 : CalcDetailedHcInForDVModel(
294 16535 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
295 16535 : Real64 Hrec = state.dataRoomAir->CrossVentHcIn(SurfNum);
296 :
297 16535 : state.dataRoomAir->HCeiling(Ctd) = zoneJetRecAreaRatio * Hjet + (1 - zoneJetRecAreaRatio) * Hrec;
298 16535 : state.dataCrossVentMgr->HAT_R += surf.Area * (1 - zoneJetRecAreaRatio) * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hrec;
299 16535 : state.dataCrossVentMgr->HA_R += surf.Area * (1 - zoneJetRecAreaRatio) * Hrec;
300 16535 : state.dataCrossVentMgr->HAT_J += surf.Area * zoneJetRecAreaRatio * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hjet;
301 16535 : state.dataCrossVentMgr->HA_J += surf.Area * zoneJetRecAreaRatio * Hjet;
302 16535 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) =
303 16535 : zoneJetRecAreaRatio * state.dataRoomAir->ZTJET(ZoneNum) + (1 - zoneJetRecAreaRatio) * state.dataRoomAir->ZTREC(ZoneNum);
304 16535 : state.dataRoomAir->CrossVentHcIn(SurfNum) = state.dataRoomAir->HCeiling(Ctd);
305 : } // END CEILING
306 : // FLOOR Hc, HA and HAT CALCULATION
307 33070 : for (int Ctd = state.dataRoomAir->PosZ_Floor(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Floor(ZoneNum).end; ++Ctd) {
308 16535 : int SurfNum = state.dataRoomAir->APos_Floor(Ctd);
309 16535 : if (SurfNum == 0) {
310 0 : continue;
311 : }
312 :
313 16535 : auto const &surf = state.dataSurface->Surface(SurfNum);
314 16535 : state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
315 16535 : state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)];
316 16535 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTJET(ZoneNum);
317 16535 : CalcDetailedHcInForDVModel(
318 16535 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Ujet);
319 16535 : Real64 Hjet = state.dataRoomAir->CrossVentHcIn(SurfNum);
320 16535 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataRoomAir->ZTREC(ZoneNum);
321 16535 : CalcDetailedHcInForDVModel(
322 16535 : state, SurfNum, state.dataHeatBalSurf->SurfTempIn, state.dataRoomAir->CrossVentHcIn, state.dataRoomAir->Urec);
323 16535 : Real64 Hrec = state.dataRoomAir->CrossVentHcIn(SurfNum);
324 16535 : state.dataRoomAir->HFloor(Ctd) = zoneJetRecAreaRatio * Hjet + (1 - zoneJetRecAreaRatio) * Hrec;
325 16535 : state.dataCrossVentMgr->HAT_R += surf.Area * (1 - zoneJetRecAreaRatio) * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hrec;
326 16535 : state.dataCrossVentMgr->HA_R += surf.Area * (1 - zoneJetRecAreaRatio) * Hrec;
327 16535 : state.dataCrossVentMgr->HAT_J += surf.Area * zoneJetRecAreaRatio * state.dataHeatBalSurf->SurfTempIn(SurfNum) * Hjet;
328 16535 : state.dataCrossVentMgr->HA_J += surf.Area * zoneJetRecAreaRatio * Hjet;
329 16535 : state.dataHeatBal->SurfTempEffBulkAir(SurfNum) =
330 16535 : zoneJetRecAreaRatio * state.dataRoomAir->ZTJET(ZoneNum) + (1 - zoneJetRecAreaRatio) * state.dataRoomAir->ZTREC(ZoneNum);
331 16535 : state.dataRoomAir->CrossVentHcIn(SurfNum) = state.dataRoomAir->HFloor(Ctd);
332 : } // END FLOOR
333 : }
334 16535 : }
335 :
336 4030 : void EvolveParaCrossVent(EnergyPlusData &state, int const ZoneNum)
337 : {
338 :
339 : // SUBROUTINE INFORMATION:
340 : // AUTHOR G. Carrilho da Graca
341 : // DATE WRITTEN October 2004
342 : // MODIFIED 8/2013 - Sam Brunswick
343 : // To incorporate an improved model
344 : // and add modeling of multiple jets
345 :
346 : // PURPOSE OF THIS SUBROUTINE:
347 : // Subroutine for parameter actualization in the UCSD Cross Ventilation model.
348 :
349 4030 : Real64 constexpr MinUin(0.2);
350 :
351 : Real64 Uin; // Inflow air velocity [m/s]
352 : Real64 CosPhi; // Angle (in degrees) between the wind and the outward normal of the dominant surface
353 : Real64 SurfNorm; // Outward normal of surface
354 4030 : Real64 SumToZone(0.0); // Sum of velocities through
355 4030 : Real64 MaxFlux(0.0);
356 4030 : int MaxSurf(0);
357 : Real64 ActiveSurfNum;
358 : int NSides; // Number of sides in surface
359 : Real64 Wroom; // Room width
360 : Real64 Aroom; // Room area cross section
361 :
362 4030 : assert(state.dataRoomAir->AirModel.allocated());
363 4030 : state.dataRoomAir->RecInflowRatio(ZoneNum) = 0.0;
364 4030 : auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
365 :
366 : // Identify the dominant aperture:
367 4030 : MaxSurf = state.dataRoomAir->AFNSurfaceCrossVent(1, ZoneNum);
368 4030 : int const surfNum = state.afn->MultizoneSurfaceData(MaxSurf).SurfNum;
369 4030 : auto const &thisSurface = state.dataSurface->Surface(surfNum);
370 :
371 4030 : int afnSurfNum1 = state.dataRoomAir->AFNSurfaceCrossVent(1, ZoneNum);
372 :
373 4030 : if (thisSurface.Zone == ZoneNum) {
374 : // this is a direct airflow network aperture
375 4030 : SumToZone = state.afn->AirflowNetworkLinkSimu(afnSurfNum1).VolFLOW2;
376 4030 : MaxFlux = state.afn->AirflowNetworkLinkSimu(afnSurfNum1).VolFLOW2;
377 : } else {
378 : // this is an indirect airflow network aperture
379 0 : SumToZone = state.afn->AirflowNetworkLinkSimu(afnSurfNum1).VolFLOW;
380 0 : MaxFlux = state.afn->AirflowNetworkLinkSimu(afnSurfNum1).VolFLOW;
381 : }
382 :
383 12774 : for (int Ctd2 = 2; Ctd2 <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Ctd2) {
384 8744 : int afnSurfNum = state.dataRoomAir->AFNSurfaceCrossVent(Ctd2, ZoneNum);
385 8744 : if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(afnSurfNum).SurfNum).Zone == ZoneNum) {
386 8744 : if (state.afn->AirflowNetworkLinkSimu(afnSurfNum).VolFLOW2 > MaxFlux) {
387 440 : MaxFlux = state.afn->AirflowNetworkLinkSimu(afnSurfNum).VolFLOW2;
388 440 : MaxSurf = afnSurfNum;
389 : }
390 8744 : SumToZone += state.afn->AirflowNetworkLinkSimu(afnSurfNum).VolFLOW2;
391 : } else {
392 0 : if (state.afn->AirflowNetworkLinkSimu(afnSurfNum).VolFLOW > MaxFlux) {
393 0 : MaxFlux = state.afn->AirflowNetworkLinkSimu(afnSurfNum).VolFLOW;
394 0 : MaxSurf = afnSurfNum;
395 : }
396 0 : SumToZone += state.afn->AirflowNetworkLinkSimu(afnSurfNum).VolFLOW;
397 : }
398 : }
399 :
400 : // Check if wind direction is within +/- 90 degrees of the outward normal of the dominant surface
401 4030 : SurfNorm = thisSurface.Azimuth;
402 4030 : CosPhi = std::cos((state.dataEnvrn->WindDir - SurfNorm) * Constant::DegToRad);
403 4030 : if (CosPhi <= 0) {
404 1938 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
405 1938 : auto flows(state.dataRoomAir->CrossVentJetRecFlows(_, ZoneNum)); // This is an array slice, need to get rid of this (THIS_AUTO_OK)
406 10226 : for (int i = 1, u = flows.u(); i <= u; ++i) {
407 8288 : auto &e(flows(i));
408 8288 : e.Ujet = e.Urec = 0.0;
409 : }
410 1938 : state.dataRoomAir->Urec(ZoneNum) = 0.0;
411 1938 : state.dataRoomAir->Ujet(ZoneNum) = 0.0;
412 1938 : state.dataRoomAir->Qrec(ZoneNum) = 0.0;
413 1938 : if (thisSurface.ExtBoundCond > 0) {
414 0 : state.dataRoomAir->Tin(ZoneNum) =
415 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT;
416 1938 : } else if (thisSurface.ExtBoundCond == ExternalEnvironment) {
417 1938 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
418 0 : } else if (thisSurface.ExtBoundCond == Ground) {
419 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
420 0 : } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) {
421 0 : auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr);
422 0 : thisOSC.OSCTempCalc =
423 0 : (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) +
424 0 : thisOSC.ConstTempCoef * thisOSC.ConstTemp +
425 0 : thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
426 0 : thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum));
427 0 : state.dataRoomAir->Tin(ZoneNum) = thisOSC.OSCTempCalc;
428 0 : } else {
429 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
430 : }
431 1938 : return;
432 1938 : }
433 :
434 : // Calculate the opening area for all apertures
435 8516 : for (int Ctd = 1; Ctd <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Ctd) {
436 6424 : auto &jetRecFlows = state.dataRoomAir->CrossVentJetRecFlows(Ctd, ZoneNum);
437 6424 : auto const &surfParams = state.dataRoomAir->SurfParametersCrossDispVent(Ctd);
438 6424 : int cCompNum = state.afn->AirflowNetworkLinkageData(Ctd).CompNum;
439 6424 : if (state.afn->AirflowNetworkCompData(cCompNum).CompTypeNum == AirflowNetwork::iComponentTypeNum::DOP) {
440 6424 : jetRecFlows.Area = surfParams.Width * surfParams.Height * state.afn->MultizoneSurfaceData(Ctd).OpenFactor;
441 0 : } else if (state.afn->AirflowNetworkCompData(cCompNum).CompTypeNum == AirflowNetwork::iComponentTypeNum::SCR) {
442 0 : jetRecFlows.Area = surfParams.Width * surfParams.Height;
443 : } else {
444 0 : ShowSevereError(
445 : state, "RoomAirModelCrossVent:EvolveParaUCSDCV: Illegal leakage component referenced in the cross ventilation room air model");
446 0 : ShowContinueError(state,
447 0 : format("Surface {} in zone {} uses leakage component {}",
448 0 : state.afn->AirflowNetworkLinkageData(Ctd).Name,
449 0 : state.dataHeatBal->Zone(ZoneNum).Name,
450 0 : state.afn->AirflowNetworkLinkageData(Ctd).CompName));
451 0 : ShowContinueError(state, "Only leakage component types AirflowNetwork:MultiZone:Component:DetailedOpening and ");
452 0 : ShowContinueError(state, "AirflowNetwork:MultiZone:Surface:Crack can be used with the cross ventilation room air model");
453 0 : ShowFatalError(state, "Previous severe error causes program termination");
454 : }
455 : }
456 :
457 : // Calculate Droom, Wroom, Dstar
458 : // Droom the distance between the average point of the base surface of the airflow network Surface (if the base surface
459 : // is a Window or Door it looks for the second base surface).
460 : // Dstar is Droom corrected for wind angle
461 :
462 2092 : Vector3<Real64> baseCentroid;
463 :
464 2092 : Wroom = state.dataHeatBal->Zone(ZoneNum).Volume / state.dataHeatBal->Zone(ZoneNum).FloorArea;
465 2092 : auto const &baseSurface = state.dataSurface->Surface(thisSurface.BaseSurf);
466 2092 : if ((baseSurface.Sides == 3) || (baseSurface.Sides == 4)) {
467 2092 : baseCentroid = baseSurface.Centroid;
468 : } else {
469 : // If the surface has more than 4 vertex then average the vertex coordinates in X, Y and Z.
470 0 : NSides = baseSurface.Sides;
471 0 : assert(NSides > 0);
472 0 : baseCentroid = {0.0, 0.0, 0.0};
473 0 : for (int i = 1; i <= NSides; ++i) {
474 0 : baseCentroid += baseSurface.Vertex(i);
475 : }
476 0 : baseCentroid /= double(NSides);
477 : }
478 :
479 2092 : Vector3<Real64> wallCentroid;
480 2092 : Real64 const Wroom_2(pow_2(Wroom));
481 10460 : for (int Ctd = state.dataRoomAir->PosZ_Wall(ZoneNum).beg; Ctd <= state.dataRoomAir->PosZ_Wall(ZoneNum).end; ++Ctd) {
482 16736 : if ((state.dataSurface->Surface(state.dataRoomAir->APos_Wall(Ctd)).Sides == 3) ||
483 8368 : (state.dataSurface->Surface(state.dataRoomAir->APos_Wall(Ctd)).Sides == 4)) {
484 8368 : wallCentroid = state.dataSurface->Surface(state.dataRoomAir->APos_Wall(Ctd)).Centroid;
485 : } else {
486 0 : NSides = state.dataSurface->Surface(state.dataRoomAir->APos_Wall(Ctd)).Sides;
487 0 : assert(NSides > 0);
488 0 : wallCentroid = {0.0, 0.0, 0.0};
489 0 : for (int i = 1; i <= NSides; ++i) {
490 0 : wallCentroid += state.dataSurface->Surface(state.dataRoomAir->APos_Wall(Ctd)).Vertex(i);
491 : }
492 0 : wallCentroid /= double(NSides);
493 : }
494 : double DroomTemp =
495 8368 : std::sqrt(pow_2(baseCentroid.x - wallCentroid.x) + pow_2(baseCentroid.y - wallCentroid.y) + pow_2(baseCentroid.z - wallCentroid.z));
496 8368 : if (DroomTemp > state.dataRoomAir->Droom(ZoneNum)) {
497 8 : state.dataRoomAir->Droom(ZoneNum) = DroomTemp;
498 : }
499 8368 : state.dataRoomAir->Dstar(ZoneNum) =
500 8368 : min(state.dataRoomAir->Droom(ZoneNum) / CosPhi, std::sqrt(Wroom_2 + pow_2(state.dataRoomAir->Droom(ZoneNum))));
501 : }
502 :
503 : // Room area
504 2092 : Aroom = state.dataHeatBal->Zone(ZoneNum).Volume / state.dataRoomAir->Droom(ZoneNum);
505 :
506 : // Populate an array of inflow volume fluxes (Fin) for all apertures in the zone
507 : // Calculate inflow velocity (%Uin) for each aperture in the zone
508 8516 : for (int Ctd = 1; Ctd <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Ctd) {
509 6424 : auto &jetRecFlows = state.dataRoomAir->CrossVentJetRecFlows(Ctd, ZoneNum);
510 6424 : if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(Ctd).SurfNum).Zone == ZoneNum) {
511 : // this is a direct airflow network aperture
512 6424 : jetRecFlows.Fin = state.afn->AirflowNetworkLinkSimu(state.dataRoomAir->AFNSurfaceCrossVent(Ctd, ZoneNum)).VolFLOW2;
513 : } else {
514 : // this is an indirect airflow network aperture
515 0 : jetRecFlows.Fin = state.afn->AirflowNetworkLinkSimu(state.dataRoomAir->AFNSurfaceCrossVent(Ctd, ZoneNum)).VolFLOW;
516 : }
517 6424 : if (jetRecFlows.Area != 0) {
518 4148 : jetRecFlows.Uin = jetRecFlows.Fin / jetRecFlows.Area;
519 : } else {
520 2276 : jetRecFlows.Uin = 0.0;
521 : }
522 : }
523 :
524 : // Verify if Uin is higher than minimum for each aperture
525 : // Create a flow flag for each aperture
526 : // Calculate the total area of all active apertures
527 2092 : ActiveSurfNum = 0.0;
528 2092 : state.dataRoomAir->Ain(ZoneNum) = 0.0;
529 8516 : for (int Ctd = 1; Ctd <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Ctd) {
530 6424 : auto &jetRecFlows = state.dataRoomAir->CrossVentJetRecFlows(Ctd, ZoneNum);
531 6424 : jetRecFlows.FlowFlag = (int)(jetRecFlows.Uin > MinUin);
532 :
533 6424 : ActiveSurfNum += jetRecFlows.FlowFlag;
534 6424 : state.dataRoomAir->Ain(ZoneNum) += jetRecFlows.Area * jetRecFlows.FlowFlag;
535 : }
536 :
537 : // Verify if any of the apertures have minimum flow
538 2092 : if (ActiveSurfNum == 0) {
539 569 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
540 569 : if (thisSurface.ExtBoundCond > 0) {
541 0 : state.dataRoomAir->Tin(ZoneNum) =
542 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT;
543 569 : } else if (thisSurface.ExtBoundCond == ExternalEnvironment) {
544 569 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
545 0 : } else if (thisSurface.ExtBoundCond == Ground) {
546 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
547 0 : } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) {
548 0 : auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr);
549 0 : thisOSC.OSCTempCalc =
550 0 : (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) +
551 0 : thisOSC.ConstTempCoef * thisOSC.ConstTemp +
552 0 : thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
553 0 : thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum));
554 0 : state.dataRoomAir->Tin(ZoneNum) = thisOSC.OSCTempCalc;
555 0 : } else {
556 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
557 : }
558 569 : state.dataRoomAir->Urec(ZoneNum) = 0.0;
559 569 : state.dataRoomAir->Ujet(ZoneNum) = 0.0;
560 569 : state.dataRoomAir->Qrec(ZoneNum) = 0.0;
561 569 : auto flows(state.dataRoomAir->CrossVentJetRecFlows(_, ZoneNum)); // This is an array slice, need to get rid of this (THIS_AUTO_OK)
562 3414 : for (int i = 1, u = flows.u(); i <= u; ++i) {
563 2845 : auto &e(flows(i));
564 2845 : e.Ujet = e.Urec = 0.0;
565 : }
566 569 : return;
567 569 : }
568 :
569 : // Calculate Uin, the area weighted average velocity of all the active apertures in the zone
570 : // Calculate Qtot, the total volumetric flow rate through all active openings in the zone
571 1523 : Uin = 0.0;
572 :
573 5671 : for (int Ctd = 1; Ctd <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Ctd) {
574 4148 : auto const &jetRecFlows = state.dataRoomAir->CrossVentJetRecFlows(Ctd, ZoneNum);
575 4148 : Uin += jetRecFlows.Area * jetRecFlows.Uin * jetRecFlows.FlowFlag / state.dataRoomAir->Ain(ZoneNum);
576 : }
577 :
578 : // Verify if Uin is higher than minimum:
579 1523 : if (Uin < MinUin) {
580 0 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
581 0 : state.dataRoomAir->Urec(ZoneNum) = 0.0;
582 0 : state.dataRoomAir->Ujet(ZoneNum) = 0.0;
583 0 : state.dataRoomAir->Qrec(ZoneNum) = 0.0;
584 0 : state.dataRoomAir->RecInflowRatio(ZoneNum) = 0.0;
585 0 : auto flows(state.dataRoomAir->CrossVentJetRecFlows(_, ZoneNum)); // This is an array slice, need to get rid of this (THIS_AUTO_OK)
586 0 : for (int i = 1, u = flows.u(); i <= u; ++i) {
587 0 : auto &e(flows(i));
588 0 : e.Ujet = e.Urec = 0.0;
589 : }
590 0 : if (thisSurface.ExtBoundCond > 0) {
591 0 : state.dataRoomAir->Tin(ZoneNum) =
592 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT;
593 0 : } else if (thisSurface.ExtBoundCond == ExternalEnvironment) {
594 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
595 0 : } else if (thisSurface.ExtBoundCond == Ground) {
596 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
597 0 : } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) {
598 0 : auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr);
599 0 : thisOSC.OSCTempCalc =
600 0 : (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) +
601 0 : thisOSC.ConstTempCoef * thisOSC.ConstTemp +
602 0 : thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
603 0 : thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum));
604 0 : state.dataRoomAir->Tin(ZoneNum) = thisOSC.OSCTempCalc;
605 :
606 0 : } else {
607 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
608 : }
609 0 : return;
610 0 : }
611 :
612 : // Evaluate parameter that determines whether recirculations are present
613 3046 : for (int Ctd = 1; Ctd <= state.dataRoomAir->TotCrossVent; ++Ctd) {
614 1523 : if (ZoneNum == state.dataRoomAir->ZoneCrossVent(Ctd).ZonePtr) {
615 1523 : if (state.dataRoomAir->Ain(ZoneNum) / Aroom > 1.0 / 2.0) {
616 0 : state.dataRoomAir->JetRecAreaRatio(ZoneNum) = 1.0;
617 : } else {
618 1523 : state.dataRoomAir->JetRecAreaRatio(ZoneNum) = std::sqrt(state.dataRoomAir->Ain(ZoneNum) / Aroom);
619 : }
620 : }
621 : }
622 :
623 1523 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
624 : // Calculate jet and recirculation velocities for all active apertures
625 1523 : state.dataRoomAir->Ujet(ZoneNum) = 0.0;
626 1523 : state.dataRoomAir->Urec(ZoneNum) = 0.0;
627 1523 : state.dataRoomAir->Qrec(ZoneNum) = 0.0;
628 1523 : state.dataRoomAir->Qtot(ZoneNum) = 0.0;
629 1523 : auto flows(state.dataRoomAir->CrossVentJetRecFlows(_, ZoneNum)); // This is an array slice, need to get rid of this (THIS_AUTO_OK)
630 7194 : for (int i = 1, u = flows.u(); i <= u; ++i) {
631 5671 : auto &e(flows(i));
632 5671 : e.Ujet = e.Urec = e.Qrec = 0.0;
633 : }
634 5671 : for (int Ctd = 1; Ctd <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++Ctd) {
635 4148 : auto &jetRecFlows = state.dataRoomAir->CrossVentJetRecFlows(Ctd, ZoneNum);
636 4148 : if (jetRecFlows.Uin == 0) {
637 2074 : continue;
638 : }
639 :
640 2074 : Real64 dstarexp = max(state.dataRoomAir->Dstar(ZoneNum) / (6.0 * std::sqrt(jetRecFlows.Area)), 1.0);
641 2074 : jetRecFlows.Vjet = jetRecFlows.Uin * std::sqrt(jetRecFlows.Area) * 6.3 * std::log(dstarexp) / state.dataRoomAir->Dstar(ZoneNum);
642 2074 : jetRecFlows.Yjet = Cjet1 * std::sqrt(jetRecFlows.Area / Aroom) * jetRecFlows.Vjet / jetRecFlows.Uin + Cjet2;
643 2074 : jetRecFlows.Yrec = Crec1 * std::sqrt(jetRecFlows.Area / Aroom) * jetRecFlows.Vjet / jetRecFlows.Uin + Crec2;
644 2074 : jetRecFlows.YQrec = CrecFlow1 * std::sqrt(jetRecFlows.Area * Aroom) * jetRecFlows.Vjet / jetRecFlows.Uin + CrecFlow2;
645 2074 : jetRecFlows.Ujet = jetRecFlows.FlowFlag * jetRecFlows.Yjet / jetRecFlows.Uin;
646 2074 : jetRecFlows.Urec = jetRecFlows.FlowFlag * jetRecFlows.Yrec / jetRecFlows.Uin;
647 2074 : jetRecFlows.Qrec = jetRecFlows.FlowFlag * jetRecFlows.YQrec / jetRecFlows.Uin;
648 2074 : state.dataRoomAir->Ujet(ZoneNum) += jetRecFlows.Area * jetRecFlows.Ujet / state.dataRoomAir->Ain(ZoneNum);
649 2074 : state.dataRoomAir->Urec(ZoneNum) += jetRecFlows.Area * jetRecFlows.Urec / state.dataRoomAir->Ain(ZoneNum);
650 2074 : state.dataRoomAir->Qrec(ZoneNum) += jetRecFlows.Qrec;
651 2074 : state.dataRoomAir->Qtot(ZoneNum) += jetRecFlows.Fin * jetRecFlows.FlowFlag;
652 2074 : state.dataRoomAir->Urec(ZoneNum) += jetRecFlows.Area * jetRecFlows.Urec / state.dataRoomAir->Ain(ZoneNum);
653 : }
654 :
655 : // Ratio between recirculation flow rate and total inflow rate
656 1523 : if (state.dataRoomAir->Qtot(ZoneNum) != 0) {
657 1523 : state.dataRoomAir->RecInflowRatio(ZoneNum) = state.dataRoomAir->Qrec(ZoneNum) / state.dataRoomAir->Qtot(ZoneNum);
658 : } else {
659 0 : state.dataRoomAir->RecInflowRatio(ZoneNum) = 0.0;
660 : }
661 :
662 : // Set Tin based on external conditions of the dominant aperture
663 1523 : if (thisSurface.ExtBoundCond <= 0) {
664 1523 : if (thisSurface.ExtBoundCond == ExternalEnvironment) {
665 1523 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
666 0 : } else if (thisSurface.ExtBoundCond == Ground) {
667 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
668 0 : } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) {
669 0 : auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr);
670 0 : thisOSC.OSCTempCalc =
671 0 : (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) +
672 0 : thisOSC.ConstTempCoef * thisOSC.ConstTemp +
673 0 : thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
674 0 : thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum));
675 0 : state.dataRoomAir->Tin(ZoneNum) = thisOSC.OSCTempCalc;
676 0 : } else {
677 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
678 : }
679 : } else {
680 : // adiabatic surface
681 0 : if (surfNum == thisSurface.ExtBoundCond) {
682 0 : int NodeNum1 = state.afn->AirflowNetworkLinkageData(MaxSurf).NodeNums[0];
683 0 : int NodeNum2 = state.afn->AirflowNetworkLinkageData(MaxSurf).NodeNums[1];
684 0 : if (thisSurface.Zone == ZoneNum) {
685 0 : if (state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum <= 0) {
686 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
687 0 : } else if (state.dataRoomAir->AirModel(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum).AirModel ==
688 : RoomAir::RoomAirModel::CrossVent) {
689 0 : state.dataRoomAir->Tin(ZoneNum) =
690 0 : state.dataRoomAir->RoomOutflowTemp(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum);
691 : } else {
692 0 : state.dataRoomAir->Tin(ZoneNum) =
693 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum).MAT;
694 : }
695 :
696 : } else {
697 :
698 0 : if (state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum <= 0) {
699 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum);
700 0 : } else if (state.dataRoomAir->AirModel(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum).AirModel ==
701 : RoomAir::RoomAirModel::CrossVent) {
702 0 : state.dataRoomAir->Tin(ZoneNum) =
703 0 : state.dataRoomAir->RoomOutflowTemp(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum);
704 : } else {
705 0 : state.dataRoomAir->Tin(ZoneNum) =
706 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum).MAT;
707 : }
708 : }
709 0 : } else if ((thisSurface.Zone == ZoneNum) &&
710 0 : (state.dataRoomAir->AirModel(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).AirModel ==
711 : RoomAir::RoomAirModel::CrossVent)) {
712 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataRoomAir->RoomOutflowTemp(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone);
713 0 : } else if ((thisSurface.Zone != ZoneNum) &&
714 0 : (state.dataRoomAir->AirModel(thisSurface.Zone).AirModel == RoomAir::RoomAirModel::CrossVent)) {
715 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataRoomAir->RoomOutflowTemp(surfNum);
716 : } else {
717 0 : if (thisSurface.Zone == ZoneNum) {
718 0 : state.dataRoomAir->Tin(ZoneNum) =
719 0 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT;
720 : } else {
721 0 : state.dataRoomAir->Tin(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisSurface.Zone).MAT;
722 : }
723 : }
724 : }
725 2661 : }
726 :
727 4030 : void CalcCrossVent(EnergyPlusData &state,
728 : int const ZoneNum) // Which Zonenum
729 : {
730 :
731 : // SUBROUTINE INFORMATION:
732 : // AUTHOR G. Carrilho da Graca
733 : // DATE WRITTEN October 2004
734 : // MODIFIED 8/2013 - Sam Brunswick
735 : // To incorporate improved temperature calculations
736 :
737 : // PURPOSE OF THIS SUBROUTINE:
738 : // Subroutine for cross ventilation modelling.
739 :
740 : // REFERENCES:
741 : // Model developed by Paul Linden (UCSD), G. Carrilho da Graca (UCSD) and P. Haves (LBL).
742 : // Work funded by the California Energy Comission. More information on the model can found in:
743 : // "Simplified Models for Heat Transfer in Rooms" G. Carrilho da Graca, Ph.D. thesis UCSD. December 2003.
744 :
745 4030 : auto const &zone = state.dataHeatBal->Zone(ZoneNum);
746 :
747 4030 : Real64 GainsFrac = 0.0; // Fraction of lower subzone internal gains that mix as opposed to forming plumes
748 4030 : Real64 ZoneMult = zone.Multiplier * zone.ListMultiplier; // total zone multiplier
749 4030 : auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
750 :
751 8060 : for (int Ctd = 1; Ctd <= state.dataRoomAir->TotCrossVent; ++Ctd) {
752 4030 : if (ZoneNum == state.dataRoomAir->ZoneCrossVent(Ctd).ZonePtr) {
753 4030 : GainsFrac = state.dataRoomAir->ZoneCrossVent(Ctd).gainsSched->getCurrentVal();
754 : }
755 : }
756 :
757 : // Total convective gains in the room
758 4030 : Real64 ConvGains = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum);
759 4030 : ConvGains += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) +
760 4030 : thisZoneHB.SysDepZoneLoadsLagged + thisZoneHB.NonAirSystemResponse / ZoneMult;
761 :
762 : // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very low or zero)
763 4030 : if (zone.NoHeatToReturnAir) {
764 0 : Real64 RetAirConvGain = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0);
765 0 : ConvGains += RetAirConvGain;
766 : }
767 :
768 4030 : Real64 ConvGainsJet = ConvGains * GainsFrac; // Total convective gains released in jet subzone
769 4030 : Real64 ConvGainsRec = ConvGains * (1.0 - GainsFrac); // Total convective gains released in recirculation subzone
770 4030 : Real64 MCp_Total = thisZoneHB.MCPI + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA;
771 4030 : Real64 MCpT_Total =
772 4030 : thisZoneHB.MCPTI + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + thisZoneHB.MDotCPOA * zone.OutDryBulbTemp;
773 :
774 4030 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithoutDistribution) {
775 4030 : MCp_Total = state.afn->exchangeData(ZoneNum).SumMCp + state.afn->exchangeData(ZoneNum).SumMVCp + state.afn->exchangeData(ZoneNum).SumMMCp;
776 4030 : MCpT_Total =
777 4030 : state.afn->exchangeData(ZoneNum).SumMCpT + state.afn->exchangeData(ZoneNum).SumMVCpT + state.afn->exchangeData(ZoneNum).SumMMCpT;
778 : }
779 :
780 4030 : EvolveParaCrossVent(state, ZoneNum);
781 : // Real64 L = state.dataRoomAir->Droom(ZoneNum);
782 :
783 4030 : if (state.dataRoomAir->AirModel(ZoneNum).SimAirModel) {
784 : //=============================== CROSS VENTILATION Calculation ==============================================
785 1523 : state.dataRoomAir->ZoneCrossVentIsMixing(ZoneNum) = 0.0;
786 1523 : state.dataRoomAir->ZoneCrossVentHasREC(ZoneNum) = 1.0;
787 7615 : for (int Ctd = 1; Ctd <= 4; ++Ctd) {
788 6092 : HcCrossVent(state, ZoneNum);
789 6092 : if (state.dataRoomAir->JetRecAreaRatio(ZoneNum) != 1.0) {
790 6092 : state.dataRoomAir->ZTREC(ZoneNum) =
791 6092 : (ConvGainsRec * CrecTemp + CrecTemp * state.dataCrossVentMgr->HAT_R + state.dataRoomAir->Tin(ZoneNum) * MCp_Total) /
792 6092 : (CrecTemp * state.dataCrossVentMgr->HA_R + MCp_Total);
793 : }
794 12184 : state.dataRoomAir->ZTJET(ZoneNum) = (ConvGainsJet * CjetTemp + ConvGainsRec * CjetTemp + CjetTemp * state.dataCrossVentMgr->HAT_J +
795 6092 : CjetTemp * state.dataCrossVentMgr->HAT_R + state.dataRoomAir->Tin(ZoneNum) * MCp_Total -
796 6092 : CjetTemp * state.dataCrossVentMgr->HA_R * state.dataRoomAir->ZTREC(ZoneNum)) /
797 6092 : (CjetTemp * state.dataCrossVentMgr->HA_J + MCp_Total);
798 6092 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) =
799 6092 : (ConvGainsJet + ConvGainsRec + state.dataCrossVentMgr->HAT_J + state.dataCrossVentMgr->HAT_R +
800 6092 : state.dataRoomAir->Tin(ZoneNum) * MCp_Total - state.dataCrossVentMgr->HA_J * state.dataRoomAir->ZTJET(ZoneNum) -
801 6092 : state.dataCrossVentMgr->HA_R * state.dataRoomAir->ZTREC(ZoneNum)) /
802 : MCp_Total;
803 : }
804 1523 : if (state.dataRoomAir->JetRecAreaRatio(ZoneNum) == 1.0) {
805 0 : state.dataRoomAir->ZoneCrossVentHasREC(ZoneNum) = 0.0;
806 0 : state.dataRoomAir->ZTREC(ZoneNum) = state.dataRoomAir->RoomOutflowTemp(ZoneNum);
807 0 : state.dataRoomAir->ZTREC(ZoneNum) = state.dataRoomAir->ZTJET(ZoneNum);
808 0 : state.dataRoomAir->ZTREC(ZoneNum) = state.dataRoomAir->ZTJET(ZoneNum);
809 : }
810 : // If temperature increase is above 1.5C then go to mixing
811 1523 : if (state.dataRoomAir->RoomOutflowTemp(ZoneNum) - state.dataRoomAir->Tin(ZoneNum) > 1.5) {
812 974 : state.dataRoomAir->ZoneCrossVentIsMixing(ZoneNum) = 1.0;
813 974 : state.dataRoomAir->ZoneCrossVentHasREC(ZoneNum) = 0.0;
814 974 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
815 974 : state.dataRoomAir->Ujet(ZoneNum) = 0.0;
816 974 : state.dataRoomAir->Urec(ZoneNum) = 0.0;
817 974 : state.dataRoomAir->Qrec(ZoneNum) = 0.0;
818 974 : state.dataRoomAir->RecInflowRatio(ZoneNum) = 0.0;
819 3900 : for (auto &e : state.dataRoomAir->CrossVentJetRecFlows) {
820 2926 : e.Ujet = 0.0;
821 2926 : e.Urec = 0.0;
822 : }
823 3896 : for (int Ctd = 1; Ctd <= 3; ++Ctd) {
824 2922 : Real64 ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
825 2922 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
826 2922 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
827 2922 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
828 2922 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
829 2922 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
830 2922 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
831 2922 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
832 2922 : HcCrossVent(state, ZoneNum);
833 2922 : ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
834 2922 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
835 2922 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
836 2922 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
837 2922 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
838 2922 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
839 2922 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
840 2922 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
841 : }
842 : }
843 : } else {
844 : //=============================== M I X E D Calculation ======================================================
845 2507 : state.dataRoomAir->ZoneCrossVentIsMixing(ZoneNum) = 1.0;
846 2507 : state.dataRoomAir->ZoneCrossVentHasREC(ZoneNum) = 0.0;
847 2507 : state.dataRoomAir->Ujet(ZoneNum) = 0.0;
848 2507 : state.dataRoomAir->Urec(ZoneNum) = 0.0;
849 2507 : state.dataRoomAir->Qrec(ZoneNum) = 0.0;
850 2507 : state.dataRoomAir->RecInflowRatio(ZoneNum) = 0.0;
851 13640 : for (auto &e : state.dataRoomAir->CrossVentJetRecFlows) {
852 11133 : e.Ujet = 0.0;
853 11133 : e.Urec = 0.0;
854 : }
855 10028 : for (int Ctd = 1; Ctd <= 3; ++Ctd) {
856 7521 : Real64 ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
857 7521 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
858 7521 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
859 7521 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
860 7521 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
861 7521 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
862 7521 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
863 7521 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
864 7521 : HcCrossVent(state, ZoneNum);
865 7521 : ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
866 7521 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
867 7521 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
868 7521 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
869 7521 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = ZTAveraged;
870 7521 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
871 7521 : state.dataRoomAir->ZTJET(ZoneNum) = ZTAveraged;
872 7521 : state.dataRoomAir->ZTREC(ZoneNum) = ZTAveraged;
873 : }
874 : }
875 4030 : }
876 :
877 : } // namespace RoomAir
878 :
879 : } // namespace EnergyPlus
|