Compute turbulent diffusivities using the Mellor-Yamada-Janjic (MYJ) closure model.
69 Real EPSQ1 = std::sqrt(EPSQ2);
80 Real A1 =
Real(0.659888514560862645);
81 Real A2x =
Real(0.6574209922667784586);
82 Real B1 =
Real(11.87799326209552761);
83 Real B2 =
Real(7.226971804046074028);
84 Real C1 =
Real(0.000830955950095854396);
91 Real ANMH = -
Real(9.)*A1*A2x*A2x*BTG*BTG;
105 Real AEQH =
Real(9.)*A1*A2x*A2x*B1*BTG*BTG
108 +
Real(18.)*A1*A1*A2x*(B2-
three*A2x)*BTG;
110 Real REQU = -AEQH/AEQM;
112 Real EPSGM = REQU*EPSGH;
114 Real UBRYL = (
Real(18.)*REQU*A1*A1*A2x*B2*C1*BTG +
Real(9.)*A1*A2x*A2x*B2*BTG*BTG)
119 Real AUBH =
Real(27.)*A1*A2x*A2x*B2*BTG*BTG-ADNH*UBRY3;
120 Real AUBM =
Real(54.)*A1*A1*A2x*B2*C1*BTG-ADNM*UBRY3;
122 Real BUBM =
Real(18.)*A1*A1*C1-BDNM*UBRY3;
127 #pragma omp parallel if (Gpu::notInLaunchRegion())
129 for (MFIter mfi(eddyViscosity,
false); mfi.isValid(); ++mfi) {
131 const Box& bx = mfi.validbox();
132 const Array4<Real >& cell_data = cons_in.array(mfi);
133 const Array4<Real >& K_turb = eddyViscosity.array(mfi);
134 const Array4<Real const>& uvel =
xvel.array(mfi);
135 const Array4<Real const>& vvel =
yvel.array(mfi);
138 const Box& dbx = geom.Domain();
142 int klo = bx.smallEnd(2);
143 int khi = bx.bigEnd(2);
144 Box planexy = makeSlab(bx,2,klo);
147 const GeometryData gdata = geom.data();
150 const Box xybx = PerpendicularBox<ZDir>(bx, IntVect{0,0,0});
151 FArrayBox qturb(bx,1,The_Async_Arena());
152 FArrayBox qintegral(xybx,2,The_Async_Arena());
153 IArrayBox pbl_k(xybx,1,The_Async_Arena());
154 qintegral.setVal<RunOn::Device>(0);
155 pbl_k.setVal<RunOn::Device>(
khi);
156 const Array4<Real> qint = qintegral.array();
157 const Array4<Real> qvel = qturb.array();
158 const Array4<int> k_arr = pbl_k.array();
161 const Array4<Real const> &z_nd_arr = z_phys_nd->array(mfi);
163 const auto&
dxInv = geom.InvCellSizeArray();
164 int izmin = geom.Domain().smallEnd(2);
165 int izmax = geom.Domain().bigEnd(2);
172 if (use_terrain_fitted_coords) {
173 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
176 for (
int k(klo); k<=
khi; ++k) {
179 qvel(i,j,k) = std::sqrt(q2);
181 k_arr(i,j,0) = std::min(k,k_arr(i,j,0));
186 for (
int k(klo); k<=k_arr(i,j,0); ++k) {
189 Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k)*
dz);
190 Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k)*
dz);
194 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
197 for (
int k(klo); k<=
khi; ++k) {
200 qvel(i,j,k) = std::sqrt(q2);
202 k_arr(i,j,0) = std::min(k,k_arr(i,j,0));
207 for (
int k(klo); k<=k_arr(i,j,0); ++k) {
209 const Real Zval = gdata.ProbLo(2) + (k +
myhalf)*gdata.CellSize(2);
210 Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k));
211 Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k));
217 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
220 int kpbl = k_arr(i,j,0);
223 Real l0 = std::max(std::min(ALPHA*qint(i,j,0,0)/qint(i,j,0,1),EL0MAX),EL0MIN);
226 for (
int k(klo); k<=
khi; ++k) {
229 Real dthetavdz, dudz, dvdz;
231 uvel, vvel, cell_data, izmin, izmax, pbl_derivative_dz_inv(i,j,k),
232 c_ext_dir_on_zlo, c_ext_dir_on_zhi,
233 u_ext_dir_on_zlo, u_ext_dir_on_zhi,
234 v_ext_dir_on_zlo, v_ext_dir_on_zhi,
235 dthetavdz, dudz, dvdz,
239 Real GML = std::max(dudz*dudz + dvdz*dvdz, EPSGM);
242 Real GHL = dthetavdz;
243 if (std::fabs(GHL)<=EPSGH) { GHL=EPSGH; }
248 if (GML/GHL <= REQU) {
251 Real AUBR = (AUBM*GML+AUBH*GHL)*GHL;
252 Real BUBR = BUBM*GML+BUBH*GHL;
255 ELM = std::max(std::sqrt(ELOQ2X*qvel(i,j,k)*qvel(i,j,k)),EPSL);
258 Real ADEN = (ADNM*GML+ADNH*GHL)*GHL;
259 Real BDEN = BDNM*GML+BDNH*GHL;
261 Real ELOQ2X =
one/(QOL2UN+EPSRU);
262 ELM = std::max(std::sqrt(ELOQ2X*qvel(i,j,k)*qvel(i,j,k)),EPSL);
268 L = std::min((met_h_zeta/
dxInv[2])*ELFC, ELM);
271 : gdata.ProbLo(2) + (k +
myhalf)*gdata.CellSize(2);
272 L = std::min(l0*d_kappa*zval / (d_kappa*zval + l0), ELM);
276 Real AEQU = (AEQM*GML+AEQH*GHL)*GHL;
277 Real BEQU = BEQM*GML+BEQH*GHL;
281 if ( ((GML+GHL*GHL)<=EPSTRB) ||
282 ((GHL>=EPSGH) && ((GML/GHL)<=REQU)) ||
287 Real ANUM=(ANMM*GML+ANMH*GHL)*GHL;
288 Real BNUM= BNMM*GML+BNMH*GHL;
290 Real ADEN=(ADNM*GML+ADNH*GHL)*GHL;
291 Real BDEN= BDNM*GML+BDNH*GHL;
294 Real ARHS=-(ANUM*BDEN-BNUM*ADEN)*
two;
298 Real DLOQ1=L/qvel(i,j,k);
301 Real ELOQ11=std::sqrt(ELOQ21);
302 Real ELOQ31=ELOQ21*ELOQ11;
303 Real ELOQ41=ELOQ21*ELOQ21;
304 Real ELOQ51=ELOQ21*ELOQ31;
306 Real RDEN1=
one/(ADEN*ELOQ41+BDEN*ELOQ21+CDEN);
308 Real RHSP1=(ARHS*ELOQ51+BRHS*ELOQ31+CRHS*ELOQ11)*RDEN1*RDEN1;
310 Real DTTURBL =
static_cast<Real>(dt);
311 Real ELOQ12=std::max(ELOQ11+(DLOQ1-ELOQ11)*exp(RHSP1*DTTURBL),EPS1);
313 Real ELOQ22=ELOQ12*ELOQ12;
314 Real ELOQ32=ELOQ22*ELOQ12;
315 Real ELOQ42=ELOQ22*ELOQ22;
316 Real ELOQ52=ELOQ22*ELOQ32;
318 Real RDEN2=
one/(ADEN*ELOQ42+BDEN*ELOQ22+CDEN);
319 Real RHS2 =-(ANUM*ELOQ42+BNUM*ELOQ22)*RDEN2+RB1;
320 Real RHSP2= (ARHS*ELOQ52+BRHS*ELOQ32+CRHS*ELOQ12)*RDEN2*RDEN2;
321 Real RHST2=RHS2/RHSP2;
323 Real ELOQ13=std::max(ELOQ12-RHST2+(RHST2+DLOQ1-ELOQ12)*exp(RHSP2*DTTURBL),EPS1);
327 qvel(i,j,k) = std::max(L/ELOQN,EPSQ1);
328 if (qvel(i,j,k)==EPSQ1) {L = EPSL; }
342 cell_data(i,j,k,
RhoKE_comp) =
myhalf*cell_data(i,j,k,
Rho_comp)*qvel(i,j,k)*qvel(i,j,k);
345 Real ELOQ2 = L*L/(qvel(i,j,k)*qvel(i,j,k));
346 Real ELOQ4 = ELOQ2*ELOQ2;
349 Real ADEN=(ADNM*GML+ADNH*GHL)*GHL;
350 Real BDEN= BDNM*GML+BDNH*GHL;
357 Real BESH=BSHM*GML+BSHH*GHL;
360 Real RDEN=
one/(ADEN*ELOQ4+BDEN*ELOQ2+CDEN);
363 Real SM=(BESM*ELOQ2+CESM)*RDEN;
364 Real SH=(BESH*ELOQ2+CESH)*RDEN;
constexpr amrex::Real three
Definition: ERF_Constants.H:11
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:63
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:64
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoKE_comp
Definition: ERF_IndexDefines.H:41
amrex::GpuArray< Real, AMREX_SPACEDIM > dxInv
Definition: ERF_InitCustomPertVels_ParticleTests.H:17
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
ParallelFor(fab_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void ComputeVerticalDerivativesPBL(int i, int j, int k, const amrex::Array4< const amrex::Real > &uvel, const amrex::Array4< const amrex::Real > &vvel, const amrex::Array4< const amrex::Real > &cell_data, const int izmin, const int izmax, const PBLDerivativeDzInv &dz_inv, const bool c_ext_dir_on_zlo, const bool c_ext_dir_on_zhi, const bool u_ext_dir_on_zlo, const bool u_ext_dir_on_zhi, const bool v_ext_dir_on_zlo, const bool v_ext_dir_on_zhi, amrex::Real &dthetadz, amrex::Real &dudz, amrex::Real &dvdz, const MoistureComponentIndices &moisture_indices)
Definition: ERF_PBLModels.H:277
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_Zrel_AtCellCenter(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:740
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:179
@ yvel_bc
Definition: ERF_IndexDefines.H:106
@ cons_bc
Definition: ERF_IndexDefines.H:89
@ xvel_bc
Definition: ERF_IndexDefines.H:105
@ ext_dir
Definition: ERF_IndexDefines.H:292
@ Theta_v
Definition: ERF_IndexDefines.H:250
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:254
@ Q_v
Definition: ERF_IndexDefines.H:253
@ Mom_v
Definition: ERF_IndexDefines.H:249
@ KE_v
Definition: ERF_IndexDefines.H:251
@ rho
Definition: ERF_Kessler.H:24
@ xvel
Definition: ERF_IndexDefines.H:215
@ yvel
Definition: ERF_IndexDefines.H:216
@ dz
Definition: ERF_AdvanceWDM6.cpp:270
Functor for inverse vertical spacings for terrain-following grids using cell-center heights.
Definition: ERF_PBLModels.H:457