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