Function for computing the implicit contribution to the vertical diffusion of momentum, with a uniform grid and no terrain.
This function (explicitly instantiated below) handles staggering in x, y, or z through the template parameter, stagdir.
197 constexpr
Real gfac = (stagdir == 2) ? 2.0/3.0 : 1.0;
200 constexpr
int ioff = (stagdir == 0) ? 1 : 0;
201 constexpr
int joff = (stagdir == 1) ? 1 : 0;
204 int ilo = bx.smallEnd(0);
205 int ihi = bx.bigEnd(0);
206 int jlo = bx.smallEnd(1);
207 int jhi = bx.bigEnd(1);
208 int klo = bx.smallEnd(2);
209 int khi = bx.bigEnd(2);
210 amrex::ignore_unused(ilo, ihi, jlo, jhi);
214 amrex::FArrayBox RHS_fab, soln_fab, coeffA_fab, coeffB_fab, inv_coeffB_fab, coeffC_fab;
215 RHS_fab.resize(bx,1, amrex::The_Async_Arena());
216 soln_fab.resize(bx,1, amrex::The_Async_Arena());
217 coeffA_fab.resize(bx,1, amrex::The_Async_Arena());
218 coeffB_fab.resize(bx,1, amrex::The_Async_Arena());
219 inv_coeffB_fab.resize(bx,1, amrex::The_Async_Arena());
220 coeffC_fab.resize(bx,1, amrex::The_Async_Arena());
221 auto const& RHS_a = RHS_fab.array();
222 auto const& soln_a = soln_fab.array();
223 auto const& coeffA_a = coeffA_fab.array();
224 auto const& coeffB_a = coeffB_fab.array();
225 auto const& inv_coeffB_a = inv_coeffB_fab.array();
226 auto const& coeffC_a = coeffC_fab.array();
228 const auto&
dom_lo = lbound(domain);
229 const auto&
dom_hi = ubound(domain);
230 Real dz_inv = cellSizeInv[2];
238 amrex::ignore_unused(foextrap_on_zhi);
240 AMREX_ASSERT_WITH_MESSAGE(ext_dir_on_zlo || ext_dir_on_zhi || use_SurfLayer,
241 "Unexpected lower BC used with implicit vertical diffusion");
242 AMREX_ASSERT_WITH_MESSAGE(foextrap_on_zhi,
243 "Unexpected upper BC used with implicit vertical diffusion");
244 if (stagdir < 2 && (ext_dir_on_zlo || ext_dir_on_zhi)) {
245 amrex::Warning(
"No-slip walls have not been fully tested");
249 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int)
252 for (
int j(jlo); j<=jhi; ++j) {
253 for (
int i(ilo); i<=ihi; ++i) {
256 for (
int k(
klo); k <=
khi; k++)
261 Real rhoAlpha_lo, rhoAlpha_hi;
263 cell_data, mu_turb, mu_eff,
269 RHS_a(i,j,k) = face_data(i,j,k);
296 RHS_a(i,j,k) += implicit_fac * gfac * (tau_corr(i,j,k+1) - tau_corr(i,j,k))*dz_inv * dt;
300 coeffA_a(i,j,k) = -implicit_fac * gfac * rhoAlpha_lo * dt * dz_inv * dz_inv;
301 coeffC_a(i,j,k) = -implicit_fac * gfac * rhoAlpha_hi * dt * dz_inv * dz_inv;
305 if (ext_dir_on_zlo) {
308 coeffC_a(i,j,
klo) = 0.;
313 coeffC_a(i,j,
klo) = -0.5;
314 RHS_a(i,j,
klo) = face_data(i,j,
klo-1);
316 }
else if (use_SurfLayer) {
320 RHS_a(i,j,
klo) += coeffA_a(i,j,
klo) * (uhi - ulo);
324 coeffA_a(i,j,
klo) = 0.;
327 if (ext_dir_on_zhi) {
329 coeffA_a(i,j,
khi) = 0.;
334 coeffA_a(i,j,
khi) = -0.5;
335 RHS_a(i,j,
khi) = face_data(i,j,
khi+1);
340 coeffC_a(i,j,
khi) = 0.;
343 coeffB_a(i,j,k) = rhoface - coeffA_a(i,j,k) - coeffC_a(i,j,k);
347 for (
int k(
klo); k<=
khi; ++k) {
349 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:5
void ImplicitDiffForMom_N(const Box &bx, const Box &domain, const int level, const Real dt, const Array4< const Real > &cell_data, const Array4< Real > &face_data, const Array4< const Real > &tau_corr, const GpuArray< Real, AMREX_SPACEDIM > &cellSizeInv, const Array4< const Real > &mu_turb, const SolverChoice &solverChoice, const BCRec *bc_ptr, const bool use_SurfLayer, const Real implicit_fac)
Definition: ERF_ImplicitDiff_N.cpp:169
#define Rho_comp
Definition: ERF_IndexDefines.H:36
const int klo
Definition: ERF_InitCustomPertVels_ParticleTests.H:4
ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { const auto prob_lo=geomdata.ProbLo();const auto dx=geomdata.CellSize();const Real x=(prob_lo[0]+(i+0.5) *dx[0])/mf_m(i, j, 0);const Real z=z_cc(i, j, k);Real L=std::sqrt(std::pow((x - x_c)/x_r, 2)+std::pow((z - z_c)/z_r, 2));if(L<=1.0) { Real dT=T_pert *(std::cos(PI *L)+1.0)/2.0;Real Tbar_hse=p_hse(i, j, k)/(R_d *r_hse(i, j, k));Real theta_perturbed=(Tbar_hse+dT) *std::pow(p_0/p_hse(i, j, k), rdOcp);Real theta_0=(Tbar_hse) *std::pow(p_0/p_hse(i, j, k), rdOcp);if(const_rho) { state_pert(i, j, k, RhoTheta_comp)=r_hse(i, j, k) *(theta_perturbed - theta_0);} else { state_pert(i, j, k, Rho_comp)=getRhoThetagivenP(p_hse(i, j, k))/theta_perturbed - r_hse(i, j, k);} } })
const int khi
Definition: ERF_InitCustomPert_ParticleTests.H:11
const auto & dom_hi
Definition: ERF_SetupVertDiff.H:2
bool l_turb
Definition: ERF_SetupVertDiff.H:8
const auto & dom_lo
Definition: ERF_SetupVertDiff.H:1
bool l_consA
Definition: ERF_SetupVertDiff.H:7
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void SolveTridiag(int i, int j, int klo, int khi, const amrex::Array4< amrex::Real > &soln_a, const amrex::Array4< const amrex::Real > &coeffA_a, const amrex::Array4< amrex::Real > &coeffB_a, const amrex::Array4< amrex::Real > &inv_coeffB_a, const amrex::Array4< const amrex::Real > &coeffC_a, const amrex::Array4< const amrex::Real > &RHS_a)
Definition: ERF_SolveTridiag.H:6
@ xvel_bc
Definition: ERF_IndexDefines.H:87
@ foextrap
Definition: ERF_IndexDefines.H:208
@ ext_dir
Definition: ERF_IndexDefines.H:209
@ ext_dir_prim
Definition: ERF_IndexDefines.H:211
Definition: ERF_DiffStruct.H:19
amrex::Real rho0_trans
Definition: ERF_DiffStruct.H:91
MolecDiffType molec_diff_type
Definition: ERF_DiffStruct.H:84
amrex::Real dynamic_viscosity
Definition: ERF_DiffStruct.H:96
DiffChoice diffChoice
Definition: ERF_DataStruct.H:1077
amrex::Vector< TurbChoice > turbChoice
Definition: ERF_DataStruct.H:1080
Definition: ERF_TurbStruct.H:42
bool use_kturb
Definition: ERF_TurbStruct.H:424