Function for computing the implicit contribution to the vertical diffusion of momentum, with a vertically stretched grid over flat terrain.
This function (explicitly instantiated below) handles staggering in x, y, or z through the template parameter, stagdir.
315 BL_PROFILE_VAR(
"ImplicitDiffForMom_S()",ImplicitDiffForMom_S);
326 constexpr
Real molec_fac = (stagdir == 2) ?
two :
one;
337 constexpr
int ioff = (stagdir == 0) ? 1 : 0;
338 constexpr
int joff = (stagdir == 1) ? 1 : 0;
341 int ilo = bx.smallEnd(0);
342 int ihi = bx.bigEnd(0);
343 int jlo = bx.smallEnd(1);
344 int jhi = bx.bigEnd(1);
345 int box_klo = bx.smallEnd(2);
346 int box_khi = bx.bigEnd(2);
347 amrex::ignore_unused(ilo, ihi, jlo, jhi);
352 constexpr
int knodal = (stagdir == 2) ? 1 : 0;
353 const int dom_klo = domain.smallEnd(2);
354 const int dom_khi = domain.bigEnd(2) + knodal;
358 amrex::FArrayBox RHS_fab, soln_fab, coeffG_fab;
359 RHS_fab.resize(bx,1, amrex::The_Async_Arena());
360 soln_fab.resize(bx,1, amrex::The_Async_Arena());
361 coeffG_fab.resize(bx,1, amrex::The_Async_Arena());
362 auto const& RHS_a = RHS_fab.array();
363 auto const& soln_a = soln_fab.array();
364 auto const& coeffG_a = coeffG_fab.array();
366 auto dz_ptr = stretched_dz_d.data();
375 amrex::ignore_unused(foextrap_on_zlo,foextrap_on_zhi);
378 "Unexpected lower BC for momentum used with implicit vertical diffusion");
380 "Unexpected upper BC for momentum used with implicit vertical diffusion");
382 Real Fact = implicit_fac * dt;
385 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int)
388 for (
int j(jlo); j<=jhi; ++j) {
389 for (
int i(ilo); i<=ihi; ++i) {
399 const int klo = amrex::max(box_klo, col_kext(i-ioff,j-joff,0,0),
400 col_kext(i ,j ,0,0));
401 const int khi = amrex::min(box_khi, col_kext(i-ioff,j-joff,0,1)+knodal,
402 col_kext(i ,j ,0,1)+knodal);
406 if (
khi <=
klo) {
return; }
408 if (
khi <=
klo) {
continue; }
445 Real rhoface, rhoAlpha_lo, rhoAlpha_hi;
446 Real dz_inv, dz_inv_lo, dz_inv_hi;
447 Real a_tmp, b_tmp, c_tmp, inv_b2_tmp;
451 cell_data, mu_turb, mu_eff,
454 dz_inv =
one / dz_ptr[
klo];
456 dz_inv_hi =
two / (dz_ptr[
klo] + dz_ptr[
klo+1]);
459 c_tmp = -Fact * gfac * rhoAlpha_hi * dz_inv_hi * dz_inv;
461 RHS_a(i,j,
klo) = face_data(i,j,
klo);
465 if (
klo != dom_klo) {
468 dz_inv_lo =
two / (dz_ptr[
klo] + dz_ptr[
klo-1]);
469 a_tmp = -Fact * rhoAlpha_lo * dz_inv_lo * dz_inv;
470 RHS_a(i,j,
klo) += Fact * gfac * (tau_corr(i,j,
klo+1) - tau_corr(i,j,
klo)) * dz_inv;
473 RHS_a(i,j,
klo) -= a_tmp * (face_data(i,j,
klo-1) / rho_below);
474 }
else if (ext_dir_on_zlo) {
475 RHS_a(i,j,
klo) += Fact * gfac * (tau_corr(i,j,
klo+1) - tau_corr(i,j,
klo)) * dz_inv;
481 a_tmp = -
two * Fact * rhoAlpha_lo * dz_inv_lo * dz_inv;
484 const Real wall_velocity = face_data(i,j,
klo-1) / rho_wall;
485 RHS_a(i,j,
klo) -= a_tmp * wall_velocity;
487 }
else if (use_SurfLayer) {
489 RHS_a(i,j,
klo) += Fact * gfac * (tau_corr(i,j,
klo+1) - tau(i,j,
klo)) * dz_inv;
490 RHS_a(i,j,
klo) += Fact * dz_inv * tau(i,j,
klo);
493 RHS_a(i,j,
klo) += Fact * gfac * (tau_corr(i,j,
klo+1) - tau_corr(i,j,
klo)) * dz_inv;
504 if (use_ysu_mom_countergradient && stagdir < 2) {
507 const Real gam_klo =
myhalf * (mu_turb(i,j,
klo ,hgam_comp) + mu_turb(i-ioff,j-joff,
klo ,hgam_comp));
508 const Real gam_kp1 =
myhalf * (mu_turb(i,j,
klo+1,hgam_comp) + mu_turb(i-ioff,j-joff,
klo+1,hgam_comp));
509 const Real gam_hi =
myhalf * (gam_klo + gam_kp1);
510 RHS_a(i,j,
klo) -= Fact * dz_inv * rhoAlpha_hi * gam_hi;
513 b_tmp = rhoface - a_tmp - c_tmp;
516 RHS_a(i,j,
klo) /= b_tmp;
517 coeffG_a(i,j,
klo) = c_tmp / b_tmp;
522 for (
int k(
klo+1); k <
khi; k++) {
525 cell_data, mu_turb, mu_eff,
528 dz_inv =
one / dz_ptr[k];
529 dz_inv_lo =
two / (dz_ptr[k] + dz_ptr[k-1]);
530 dz_inv_hi =
two / (dz_ptr[k] + dz_ptr[k+1]);
532 a_tmp = -Fact * rhoAlpha_lo * dz_inv_lo * dz_inv;
533 c_tmp = -Fact * rhoAlpha_hi * dz_inv_hi * dz_inv;
534 b_tmp = rhoface - a_tmp - c_tmp;
535 inv_b2_tmp =
one / (b_tmp - a_tmp * coeffG_a(i,j,k-1));
537 RHS_a(i,j,k) = face_data(i,j,k);
538 RHS_a(i,j,k) += Fact * gfac * (tau_corr(i,j,k+1) - tau_corr(i,j,k)) * dz_inv;
541 if (use_ysu_mom_countergradient && stagdir < 2) {
544 const Real gam_k =
myhalf * (mu_turb(i,j,k ,hgam_comp) + mu_turb(i-ioff,j-joff,k ,hgam_comp));
545 const Real gam_km1 =
myhalf * (mu_turb(i,j,k-1,hgam_comp) + mu_turb(i-ioff,j-joff,k-1,hgam_comp));
546 const Real gam_kp1 =
myhalf * (mu_turb(i,j,k+1,hgam_comp) + mu_turb(i-ioff,j-joff,k+1,hgam_comp));
547 const Real gam_hi =
myhalf * (gam_k + gam_kp1);
548 const Real gam_lo =
myhalf * (gam_k + gam_km1);
549 RHS_a(i,j,k) -= Fact * dz_inv * (rhoAlpha_hi * gam_hi - rhoAlpha_lo * gam_lo);
552 RHS_a(i,j,k) = (RHS_a(i,j,k) - a_tmp * RHS_a(i,j,k-1)) * inv_b2_tmp;
553 coeffG_a(i,j,k) = c_tmp * inv_b2_tmp;
561 cell_data, mu_turb, mu_eff,
564 dz_inv =
one / dz_ptr[
khi];
565 dz_inv_lo =
two / (dz_ptr[
khi] + dz_ptr[
khi-1]);
568 a_tmp = -Fact * gfac * rhoAlpha_lo * dz_inv_lo * dz_inv;
571 RHS_a(i,j,
khi) = face_data(i,j,
khi);
572 RHS_a(i,j,
khi) += Fact * gfac * (tau_corr(i,j,
khi+1) - tau_corr(i,j,
khi)) * dz_inv;
576 if (
khi != dom_khi) {
579 dz_inv_hi =
two / (dz_ptr[
khi] + dz_ptr[
khi+1]);
580 c_tmp = -Fact * rhoAlpha_hi * dz_inv_hi * dz_inv;
583 RHS_a(i,j,
khi) -= c_tmp * (face_data(i,j,
khi+1) / rho_above);
584 }
else if (ext_dir_on_zhi) {
590 c_tmp = -
two * Fact * rhoAlpha_hi * dz_inv_hi * dz_inv;
593 const Real wall_velocity = face_data(i,j,
khi+1) / rho_wall;
594 RHS_a(i,j,
khi) -= c_tmp * wall_velocity;
598 b_tmp = rhoface - a_tmp - c_tmp;
599 inv_b2_tmp =
one / (b_tmp - a_tmp * coeffG_a(i,j,
khi-1));
602 soln_a(i,j,
khi) = (RHS_a(i,j,
khi) - a_tmp * RHS_a(i,j,
khi-1)) * inv_b2_tmp;
607 for (
int k(
khi-1); k>=
klo; --k) {
608 soln_a(i,j,k) = RHS_a(i,j,k) - coeffG_a(i,j,k) * soln_a(i,j,k+1);
613 for (
int k(
klo); k<=
khi; ++k) {
615 face_data(i,j,k) = rhoface * soln_a(i,j,k);
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void getRhoAlphaForFaces(int i, int j, int k, int ioff, int joff, amrex::Real &rhoAlpha_lo, amrex::Real &rhoAlpha_hi, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &mu_turb, const amrex::Real mu_eff, bool l_consA, bool l_turb)
Definition: ERF_GetRhoAlphaForFaces.H:22
#define Rho_comp
Definition: ERF_IndexDefines.H:39
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
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);})
constexpr amrex::Real three
Definition: ERF_NumericalConstants.H:32
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:31
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
AMREX_ASSERT_WITH_MESSAGE(wbar_cutoff_min > wbar_cutoff_max, "ERROR: wbar_cutoff_min < wbar_cutoff_max")
@ xvel_bc
Definition: ERF_IndexDefines.H:105
@ foextrap
Definition: ERF_IndexDefines.H:296
@ ext_dir
Definition: ERF_IndexDefines.H:297
@ ext_dir_prim
Definition: ERF_IndexDefines.H:300
@ HGAMU_v
Definition: ERF_IndexDefines.H:262
@ HGAMV_v
Definition: ERF_IndexDefines.H:263
Definition: ERF_DiffStruct.H:22
MolecDiffType molec_diff_type
Selected molecular transport model.
Definition: ERF_DiffStruct.H:94
amrex::Real dynamic_viscosity
Dynamic viscosity for momentum diffusion [kg/(m-s)].
Definition: ERF_DiffStruct.H:106
amrex::Real rho0_trans
Reference density used to compute dynamic diffusion coefficients [kg/m3].
Definition: ERF_DiffStruct.H:101
amrex::Vector< TurbChoice > turbChoice
Turbulence options for each AMR level.
Definition: ERF_DataStruct.H:1974
DiffChoice diffChoice
Diffusion-related options.
Definition: ERF_DataStruct.H:1971
Definition: ERF_TurbStruct.H:115
bool use_kturb
Whether any turbulence model is active.
Definition: ERF_TurbStruct.H:835