Function for computing the implicit contribution to the vertical diffusion of momentum, over terrain.
This function (explicitly instantiated below) handles staggering in x or y through the template parameter, stagdir.
500 BL_PROFILE_VAR(
"ImplicitDiffForMom_T()",ImplicitDiffForMom_T);
515 constexpr
int ioff = (stagdir == 0) ? 1 : 0;
516 constexpr
int joff = (stagdir == 1) ? 1 : 0;
519 int ilo = bx.smallEnd(0);
520 int ihi = bx.bigEnd(0);
521 int jlo = bx.smallEnd(1);
522 int jhi = bx.bigEnd(1);
523 int box_klo = bx.smallEnd(2);
524 int box_khi = bx.bigEnd(2);
525 amrex::ignore_unused(ilo, ihi, jlo, jhi);
529 const int dom_klo = domain.smallEnd(2);
530 const int dom_khi = domain.bigEnd(2);
534 amrex::FArrayBox RHS_fab, soln_fab, coeffG_fab;
535 RHS_fab.resize(bx,1, amrex::The_Async_Arena());
536 soln_fab.resize(bx,1, amrex::The_Async_Arena());
537 coeffG_fab.resize(bx,1, amrex::The_Async_Arena());
538 auto const& RHS_a = RHS_fab.array();
539 auto const& soln_a = soln_fab.array();
540 auto const& coeffG_a = coeffG_fab.array();
542 Real dz_inv = cellSizeInv[2];
551 amrex::ignore_unused(foextrap_on_zlo,foextrap_on_zhi);
554 "Unexpected lower BC for momentum used with implicit vertical diffusion");
556 "Unexpected upper BC for momentum used with implicit vertical diffusion");
558 Real Fact = implicit_fac * dt * dz_inv;
561 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int)
564 for (
int j(jlo); j<=jhi; ++j) {
565 for (
int i(ilo); i<=ihi; ++i) {
575 const int klo = amrex::max(box_klo, col_kext(i-ioff,j-joff,0,0),
576 col_kext(i ,j ,0,0));
577 const int khi = amrex::min(box_khi, col_kext(i-ioff,j-joff,0,1),
578 col_kext(i ,j ,0,1));
582 if (
khi <=
klo) {
return; }
584 if (
khi <=
klo) {
continue; }
625 Real rhoface, rhoAlpha_lo, rhoAlpha_hi;
626 Real detJface, met_h_zeta_lo, met_h_zeta_hi;
627 Real a_tmp, b_tmp, c_tmp, inv_b2_tmp;
629 detJface =
myhalf * (detJ(i,j,
klo) + detJ(i-ioff,j-joff,
klo));
632 cell_data, mu_turb, mu_eff,
635 if (implicit_metric) {
636 TerrainMetricMomCoeffs<stagdir>(i, j,
klo, dom_klo, dom_khi, metric_lo, metric_hi,
637 cell_data, mu_turb, mu_eff, l_consA, l_turb,
638 z_nd, cellSizeInv, mf_x, mf_y);
641 met_h_zeta_lo = MomFaceHZeta<stagdir>(i,j,
klo,cellSizeInv,z_nd);
642 met_h_zeta_hi = MomFaceHZeta<stagdir>(i,j,
klo+1,cellSizeInv,z_nd);
645 c_tmp = -Fact * (rhoAlpha_hi + metric_hi) * dz_inv / met_h_zeta_hi;
647 RHS_a(i,j,
klo) = detJface * face_data(i,j,
klo);
651 if (
klo != dom_klo) {
654 a_tmp = -Fact * (rhoAlpha_lo + metric_lo) * dz_inv / met_h_zeta_lo;
655 RHS_a(i,j,
klo) += Fact * (tau_corr(i,j,
klo+1) - tau_corr(i,j,
klo));
658 RHS_a(i,j,
klo) -= a_tmp * (face_data(i,j,
klo-1) / rho_below);
659 }
else if (ext_dir_on_zlo) {
660 RHS_a(i,j,
klo) += Fact * (tau_corr(i,j,
klo+1) - tau_corr(i,j,
klo));
665 const Real dz0 = MomFaceCellHeight<stagdir>(i, j,
klo , z_nd);
666 const Real dz1 = MomFaceCellHeight<stagdir>(i, j,
klo+1, z_nd);
669 a_tmp = Fact * rhoAlpha_lo * idz0 * wc.
c_wall;
670 c_tmp += Fact * rhoAlpha_lo * idz0 * wc.
c_1;
673 const Real wall_velocity = face_data(i,j,
klo-1) / rho_wall;
674 RHS_a(i,j,
klo) -= a_tmp * wall_velocity;
675 }
else if (use_SurfLayer) {
677 RHS_a(i,j,
klo) += Fact * (tau_corr(i,j,
klo+1) - tau(i,j,
klo));
678 RHS_a(i,j,
klo) += Fact * tau(i,j,
klo);
681 RHS_a(i,j,
klo) += Fact * (tau_corr(i,j,
klo+1) - tau_corr(i,j,
klo));
693 if (use_ysu_mom_countergradient) {
696 const Real gam_klo =
myhalf * (mu_turb(i,j,
klo ,hgam_comp) + mu_turb(i-ioff,j-joff,
klo ,hgam_comp));
697 const Real gam_kp1 =
myhalf * (mu_turb(i,j,
klo+1,hgam_comp) + mu_turb(i-ioff,j-joff,
klo+1,hgam_comp));
698 const Real gam_hi =
myhalf * (gam_klo + gam_kp1);
699 RHS_a(i,j,
klo) -= Fact * rhoAlpha_hi * gam_hi;
700 if (
klo != dom_klo) {
701 const Real gam_km1 =
myhalf * (mu_turb(i,j,
klo-1,hgam_comp) + mu_turb(i-ioff,j-joff,
klo-1,hgam_comp));
702 const Real gam_lo =
myhalf * (gam_klo + gam_km1);
703 RHS_a(i,j,
klo) += Fact * rhoAlpha_lo * gam_lo;
707 b_tmp = detJface * rhoface - a_tmp - c_tmp;
710 RHS_a(i,j,
klo) /= b_tmp;
711 coeffG_a(i,j,
klo) = c_tmp / b_tmp;
716 for (
int k(
klo+1); k <
khi; k++) {
717 detJface =
myhalf * (detJ(i,j,k) + detJ(i-ioff,j-joff,k));
720 cell_data, mu_turb, mu_eff,
723 if (implicit_metric) {
724 TerrainMetricMomCoeffs<stagdir>(i, j, k, dom_klo, dom_khi, metric_lo, metric_hi,
725 cell_data, mu_turb, mu_eff, l_consA, l_turb,
726 z_nd, cellSizeInv, mf_x, mf_y);
729 met_h_zeta_lo = MomFaceHZeta<stagdir>(i,j,k,cellSizeInv,z_nd);
730 met_h_zeta_hi = MomFaceHZeta<stagdir>(i,j,k+1,cellSizeInv,z_nd);
732 a_tmp = -Fact * (rhoAlpha_lo + metric_lo) * dz_inv / met_h_zeta_lo;
733 c_tmp = -Fact * (rhoAlpha_hi + metric_hi) * dz_inv / met_h_zeta_hi;
734 b_tmp = detJface * rhoface - a_tmp - c_tmp;
735 inv_b2_tmp =
one / (b_tmp - a_tmp * coeffG_a(i,j,k-1));
737 RHS_a(i,j,k) = detJface * face_data(i,j,k);
738 RHS_a(i,j,k) += Fact * (tau_corr(i,j,k+1) - tau_corr(i,j,k));
741 if (use_ysu_mom_countergradient) {
744 const Real gam_k =
myhalf * (mu_turb(i,j,k ,hgam_comp) + mu_turb(i-ioff,j-joff,k ,hgam_comp));
745 const Real gam_km1 =
myhalf * (mu_turb(i,j,k-1,hgam_comp) + mu_turb(i-ioff,j-joff,k-1,hgam_comp));
746 const Real gam_kp1 =
myhalf * (mu_turb(i,j,k+1,hgam_comp) + mu_turb(i-ioff,j-joff,k+1,hgam_comp));
747 const Real gam_hi =
myhalf * (gam_k + gam_kp1);
748 const Real gam_lo =
myhalf * (gam_k + gam_km1);
749 RHS_a(i,j,k) -= Fact * (rhoAlpha_hi * gam_hi - rhoAlpha_lo * gam_lo);
752 RHS_a(i,j,k) = (RHS_a(i,j,k) - a_tmp * RHS_a(i,j,k-1)) * inv_b2_tmp;
753 coeffG_a(i,j,k) = c_tmp * inv_b2_tmp;
759 detJface =
myhalf * (detJ(i,j,
khi) + detJ(i-ioff,j-joff,
khi));
762 cell_data, mu_turb, mu_eff,
765 if (implicit_metric) {
766 TerrainMetricMomCoeffs<stagdir>(i, j,
khi, dom_klo, dom_khi, metric_lo, metric_hi,
767 cell_data, mu_turb, mu_eff, l_consA, l_turb,
768 z_nd, cellSizeInv, mf_x, mf_y);
771 met_h_zeta_lo = MomFaceHZeta<stagdir>(i,j,
khi,cellSizeInv,z_nd);
772 met_h_zeta_hi = MomFaceHZeta<stagdir>(i,j,
khi+1,cellSizeInv,z_nd);
774 a_tmp = -Fact * (rhoAlpha_lo + metric_lo) * dz_inv / met_h_zeta_lo;
777 RHS_a(i,j,
khi) = detJface * face_data(i,j,
khi);
778 RHS_a(i,j,
khi) += Fact * (tau_corr(i,j,
khi+1) - tau_corr(i,j,
khi));
782 if (
khi != dom_khi) {
785 c_tmp = -Fact * (rhoAlpha_hi + metric_hi) * dz_inv / met_h_zeta_hi;
788 RHS_a(i,j,
khi) -= c_tmp * (face_data(i,j,
khi+1) / rho_above);
789 }
else if (ext_dir_on_zhi) {
793 const Real dz0 = MomFaceCellHeight<stagdir>(i, j,
khi , z_nd);
794 const Real dz1 = MomFaceCellHeight<stagdir>(i, j,
khi-1, z_nd);
797 c_tmp = Fact * rhoAlpha_hi * idz0 * wc.
c_wall;
798 a_tmp += Fact * rhoAlpha_hi * idz0 * wc.
c_1;
801 const Real wall_velocity = face_data(i,j,
khi+1) / rho_wall;
802 RHS_a(i,j,
khi) -= c_tmp * wall_velocity;
811 if (use_ysu_mom_countergradient) {
814 const Real gam_khi =
myhalf * (mu_turb(i,j,
khi ,hgam_comp) + mu_turb(i-ioff,j-joff,
khi ,hgam_comp));
815 const Real gam_km1 =
myhalf * (mu_turb(i,j,
khi-1,hgam_comp) + mu_turb(i-ioff,j-joff,
khi-1,hgam_comp));
816 const Real gam_lo =
myhalf * (gam_khi + gam_km1);
817 RHS_a(i,j,
khi) += Fact * rhoAlpha_lo * gam_lo;
818 if (
khi != dom_khi) {
819 const Real gam_kp1 =
myhalf * (mu_turb(i,j,
khi+1,hgam_comp) + mu_turb(i-ioff,j-joff,
khi+1,hgam_comp));
820 const Real gam_hi =
myhalf * (gam_khi + gam_kp1);
821 RHS_a(i,j,
khi) -= Fact * rhoAlpha_hi * gam_hi;
825 b_tmp = detJface * rhoface - a_tmp - c_tmp;
826 inv_b2_tmp =
one / (b_tmp - a_tmp * coeffG_a(i,j,
khi-1));
829 soln_a(i,j,
khi) = (RHS_a(i,j,
khi) - a_tmp * RHS_a(i,j,
khi-1)) * inv_b2_tmp;
834 for (
int k(
khi-1); k>=
klo; --k) {
835 soln_a(i,j,k) = RHS_a(i,j,k) - coeffG_a(i,j,k) * soln_a(i,j,k+1);
840 for (
int k(
klo); k<=
khi; ++k) {
842 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, const int eddy_comp=EddyDiff::Mom_v)
Definition: ERF_GetRhoAlphaForFaces.H:23
#define Rho_comp
Definition: ERF_IndexDefines.H:53
const int khi
Definition: ERF_InitCustomPert_Bubble.H:25
const int klo
Definition: ERF_InitCustomPert_KE.H:9
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 one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:41
AMREX_ASSERT_WITH_MESSAGE(wbar_cutoff_min > wbar_cutoff_max, "ERROR: wbar_cutoff_min < wbar_cutoff_max")
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE WallGradCoeffs WallGradientCoeffs(const amrex::Real dz0, const amrex::Real dz1) noexcept
Definition: ERF_WallGradientCoeffs.H:33
@ xvel_bc
Definition: ERF_IndexDefines.H:126
@ foextrap
Definition: ERF_IndexDefines.H:339
@ ext_dir
Definition: ERF_IndexDefines.H:340
@ ext_dir_prim
Definition: ERF_IndexDefines.H:343
@ HGAMU_v
Definition: ERF_IndexDefines.H:302
@ HGAMV_v
Definition: ERF_IndexDefines.H:303
Definition: ERF_DiffStruct.H:24
MolecDiffType molec_diff_type
Selected molecular transport model.
Definition: ERF_DiffStruct.H:96
amrex::Real dynamic_viscosity
Dynamic viscosity for momentum diffusion [kg/(m-s)].
Definition: ERF_DiffStruct.H:108
amrex::Real rho0_trans
Reference density used to compute dynamic diffusion coefficients [kg/m3].
Definition: ERF_DiffStruct.H:103
amrex::Vector< TurbChoice > turbChoice
Turbulence options for each AMR level.
Definition: ERF_DataStruct.H:2620
DiffChoice diffChoice
Diffusion-related options.
Definition: ERF_DataStruct.H:2617
Definition: ERF_TurbStruct.H:119
bool use_kturb
Whether any turbulence model is active.
Definition: ERF_TurbStruct.H:977
Definition: ERF_WallGradientCoeffs.H:25
amrex::Real c_wall
Definition: ERF_WallGradientCoeffs.H:26
amrex::Real c_1
Definition: ERF_WallGradientCoeffs.H:28