Function for computing the turbulent viscosity with LES.
42 const GpuArray<Real, AMREX_SPACEDIM> cellSizeInv = geom.InvCellSizeArray();
43 const Box& domain = geom.Domain();
44 const int& klo = domain.smallEnd(2);
45 const bool use_most = (most !=
nullptr);
46 const bool use_terrain = (z_phys_nd !=
nullptr);
50 Real inv_sigma_k = 1.0 / turbChoice.
sigma_k;
54 if (turbChoice.
les_type == LESType::Smagorinsky)
56 Real Cs = turbChoice.
Cs;
59 #pragma omp parallel if (Gpu::notInLaunchRegion())
61 for (MFIter mfi(eddyViscosity,TilingIfNotGPU()); mfi.isValid(); ++mfi)
65 Box bxcc = mfi.growntilebox(1) & domain;
67 const Array4<Real>& mu_turb = eddyViscosity.array(mfi);
68 const Array4<Real>& hfx_x = Hfx1.array(mfi);
69 const Array4<Real>& hfx_y = Hfx2.array(mfi);
70 const Array4<Real>& hfx_z = Hfx3.array(mfi);
71 const Array4<Real const > &cell_data = cons_in.array(mfi);
73 Array4<Real const> tau11 = Tau11.array(mfi);
74 Array4<Real const> tau22 = Tau22.array(mfi);
75 Array4<Real const> tau33 = Tau33.array(mfi);
76 Array4<Real const> tau12 = Tau12.array(mfi);
77 Array4<Real const> tau13 = Tau13.array(mfi);
78 Array4<Real const> tau23 = Tau23.array(mfi);
80 Array4<Real const> mf_u = mapfac_u.array(mfi);
81 Array4<Real const> mf_v = mapfac_v.array(mfi);
83 Array4<Real const> z_nd_arr = (use_terrain) ? z_phys_nd->const_array(mfi) : Array4<Real const>{};
85 ParallelFor(bxcc, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
87 Real SmnSmn =
ComputeSmnSmn(i,j,k,tau11,tau22,tau33,tau12,tau13,tau23,klo,use_most,exp_most);
88 Real dxInv = cellSizeInv[0];
89 Real dyInv = cellSizeInv[1];
90 Real dzInv = cellSizeInv[2];
95 Real cellVolMsf = 1.0 / (dxInv * mf_u(i,j,0) * dyInv * mf_v(i,j,0) * dzInv);
96 Real DeltaMsf = std::pow(cellVolMsf,1.0/3.0);
97 Real CsDeltaSqrMsf = Cs*Cs*DeltaMsf*DeltaMsf;
104 if (use_most && k==klo) {
114 / cell_data(i,j,k+2,
Rho_comp) ) * dzInv;
131 else if (turbChoice.
les_type == LESType::Deardorff)
133 const Real l_C_k = turbChoice.
Ck;
134 const Real l_C_e = turbChoice.
Ce;
135 const Real l_C_e_wall = turbChoice.
Ce_wall;
136 const Real Ce_lcoeff = amrex::max(0.0, l_C_e - 1.9*l_C_k);
137 const Real l_abs_g = const_grav;
138 const Real l_inv_theta0 = 1.0 / turbChoice.
theta_ref;
141 #pragma omp parallel if (Gpu::notInLaunchRegion())
143 for ( MFIter mfi(eddyViscosity,TilingIfNotGPU()); mfi.isValid(); ++mfi)
145 Box bxcc = mfi.tilebox();
147 const Array4<Real>& mu_turb = eddyViscosity.array(mfi);
148 const Array4<Real>& hfx_x = Hfx1.array(mfi);
149 const Array4<Real>& hfx_y = Hfx2.array(mfi);
150 const Array4<Real>& hfx_z = Hfx3.array(mfi);
151 const Array4<Real>& diss = Diss.array(mfi);
153 const Array4<Real const > &cell_data = cons_in.array(mfi);
155 Array4<Real const> mf_u = mapfac_u.array(mfi);
156 Array4<Real const> mf_v = mapfac_v.array(mfi);
158 Array4<Real const> z_nd_arr = (use_terrain) ? z_phys_nd->const_array(mfi) : Array4<Real const>{};
160 ParallelFor(bxcc, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
162 Real dxInv = cellSizeInv[0];
163 Real dyInv = cellSizeInv[1];
164 Real dzInv = cellSizeInv[2];
169 Real cellVolMsf = 1.0 / (dxInv * mf_u(i,j,0) * dyInv * mf_v(i,j,0) * dzInv);
170 Real DeltaMsf = std::pow(cellVolMsf,1.0/3.0);
173 Real eps = std::numeric_limits<Real>::epsilon();
175 if (use_most && k==klo) {
185 / cell_data(i,j,k+2,
Rho_comp) ) * dzInv;
192 Real stratification = l_abs_g * dtheta_dz * l_inv_theta0;
194 if (stratification <= eps) {
197 length = 0.76 * std::sqrt(E / amrex::max(stratification,eps));
199 length = amrex::min(length, DeltaMsf);
201 length = amrex::max(length, 0.001 * DeltaMsf);
216 if ((l_C_e_wall > 0) && (k==0)) {
219 Ce = 1.9*l_C_k + Ce_lcoeff*length / DeltaMsf;
221 diss(i,j,k) = cell_data(i,j,k,
Rho_comp) * Ce * std::pow(E,1.5) / length;
237 Vector<Real> Factors = {inv_Pr_t, inv_sigma_k, inv_Sc_t, inv_Sc_t};
238 Gpu::AsyncVector<Real> d_Factors; d_Factors.resize(Factors.size());
239 Gpu::copy(Gpu::hostToDevice, Factors.begin(), Factors.end(), d_Factors.begin());
240 Real* fac_ptr = d_Factors.data();
242 const bool use_KE = ( (turbChoice.
les_type == LESType::Deardorff) ||
243 (turbChoice.
pbl_type == PBLType::MYNN25) );
246 #pragma omp parallel if (Gpu::notInLaunchRegion())
248 for ( MFIter mfi(eddyViscosity,TilingIfNotGPU()); mfi.isValid(); ++mfi)
250 Box bxcc = mfi.tilebox();
251 Box planex = bxcc; planex.setSmall(0, 1); planex.setBig(0, ngc); planex.grow(1,1);
252 Box planey = bxcc; planey.setSmall(1, 1); planey.setBig(1, ngc); planey.grow(0,1);
253 int i_lo = bxcc.smallEnd(0);
int i_hi = bxcc.bigEnd(0);
254 int j_lo = bxcc.smallEnd(1);
int j_hi = bxcc.bigEnd(1);
255 bxcc.growLo(0,ngc); bxcc.growHi(0,ngc);
256 bxcc.growLo(1,ngc); bxcc.growHi(1,ngc);
258 const Array4<Real>& mu_turb = eddyViscosity.array(mfi);
261 if (i_lo == domain.smallEnd(0)) {
262 ParallelFor(planex, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
264 int lj = amrex::min(amrex::max(j, domain.smallEnd(1)), domain.bigEnd(1));
269 if (i_hi == domain.bigEnd(0)) {
270 ParallelFor(planex, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
272 int lj = amrex::min(amrex::max(j, domain.smallEnd(1)), domain.bigEnd(1));
277 if (j_lo == domain.smallEnd(1)) {
278 ParallelFor(planey, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
280 int li = amrex::min(amrex::max(i, domain.smallEnd(0)), domain.bigEnd(0));
285 if (j_hi == domain.bigEnd(1)) {
286 ParallelFor(planey, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
288 int li = amrex::min(amrex::max(i, domain.smallEnd(0)), domain.bigEnd(0));
296 if (i_lo == domain.smallEnd(0)) {
297 ParallelFor(planex, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
299 int lj = amrex::min(amrex::max(j, domain.smallEnd(1)), domain.bigEnd(1));
303 if (i_hi == domain.bigEnd(0)) {
304 ParallelFor(planex, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
306 int lj = amrex::min(amrex::max(j, domain.smallEnd(1)), domain.bigEnd(1));
310 if (j_lo == domain.smallEnd(1)) {
311 ParallelFor(planey, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
313 int li = amrex::min(amrex::max(i, domain.smallEnd(0)), domain.bigEnd(0));
317 if (j_hi == domain.bigEnd(1)) {
318 ParallelFor(planey, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
320 int li = amrex::min(amrex::max(i, domain.smallEnd(0)), domain.bigEnd(0));
332 ParallelFor(bxcc, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
335 int indx_v = indx +
offset;
336 mu_turb(i,j,k,indx) = mu_turb(i,j,k,
EddyDiff::Mom_h) * fac_ptr[indx-1];
337 mu_turb(i,j,k,indx_v) = mu_turb(i,j,k,indx);
342 ParallelFor(bxcc, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
345 int indx_v = indx +
offset;
347 mu_turb(i,j,k,indx) = mu_turb(i,j,k,
EddyDiff::Mom_h) * fac_ptr[indx-1];
351 mu_turb(i,j,k,indx_v) = mu_turb(i,j,k,indx);
361 eddyViscosity.FillBoundary(geom.periodicity());
367 #pragma omp parallel if (Gpu::notInLaunchRegion())
369 for ( MFIter mfi(eddyViscosity,
TileNoZ()); mfi.isValid(); ++mfi)
371 Box bxcc = mfi.tilebox();
372 Box planez = bxcc; planez.setSmall(2, 1); planez.setBig(2, ngc);
373 int k_lo = bxcc.smallEnd(2);
int k_hi = bxcc.bigEnd(2);
374 planez.growLo(0,ngc); planez.growHi(0,ngc);
375 planez.growLo(1,ngc); planez.growHi(1,ngc);
377 const Array4<Real>& mu_turb = eddyViscosity.array(mfi);
385 ParallelFor(planez, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
388 int indx_v = indx +
offset;
389 mu_turb(i, j, k_lo-k, indx ) = mu_turb(i, j, k_lo, indx );
390 mu_turb(i, j, k_hi+k, indx ) = mu_turb(i, j, k_hi, indx );
391 mu_turb(i, j, k_lo-k, indx_v) = mu_turb(i, j, k_lo, indx_v);
392 mu_turb(i, j, k_hi+k, indx_v) = mu_turb(i, j, k_hi, indx_v);
397 ParallelFor(planez, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
400 int indx_v = indx +
offset;
401 mu_turb(i, j, k_lo-k, indx ) = mu_turb(i, j, k_lo, indx );
402 mu_turb(i, j, k_hi+k, indx ) = mu_turb(i, j, k_hi, indx );
403 mu_turb(i, j, k_lo-k, indx_v) = mu_turb(i, j, k_lo, indx_v);
404 mu_turb(i, j, k_hi+k, indx_v) = mu_turb(i, j, k_hi, indx_v);
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeSmnSmn(int &i, int &j, int &k, const amrex::Array4< amrex::Real const > &tau11, const amrex::Array4< amrex::Real const > &tau22, const amrex::Array4< amrex::Real const > &tau33, const amrex::Array4< amrex::Real const > &tau12, const amrex::Array4< amrex::Real const > &tau13, const amrex::Array4< amrex::Real const > &tau23, const int &klo, const bool &use_most, const bool &exp_most)
Definition: ERF_EddyViscosity.H:31
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:28
AMREX_FORCE_INLINE AMREX_GPU_DEVICE 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:39
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
@ Theta_v
Definition: ERF_IndexDefines.H:157
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:161
@ Mom_h
Definition: ERF_IndexDefines.H:151
@ Mom_v
Definition: ERF_IndexDefines.H:156
@ NumDiffs
Definition: ERF_IndexDefines.H:162
@ KE_h
Definition: ERF_IndexDefines.H:153
amrex::Real sigma_k
Definition: ERF_TurbStruct.H:193
amrex::Real Sc_t_inv
Definition: ERF_TurbStruct.H:185
amrex::Real Ck
Definition: ERF_TurbStruct.H:191
amrex::Real Cs
Definition: ERF_TurbStruct.H:177
amrex::Real Pr_t_inv
Definition: ERF_TurbStruct.H:182
amrex::Real Ce_wall
Definition: ERF_TurbStruct.H:189
amrex::Real Ce
Definition: ERF_TurbStruct.H:188
amrex::Real theta_ref
Definition: ERF_TurbStruct.H:195