Function for computing the coefficients for the tridiagonal solver used in the fast integrator (the acoustic substepping).
56 const GpuArray<Real, AMREX_SPACEDIM>
dxInv = geom.InvCellSizeArray();
59 const Box &domain = geom.Domain();
61 MultiFab coeff_A_mf(fast_coeffs, amrex::make_alias, 0, 1);
62 MultiFab coeff_B_mf(fast_coeffs, amrex::make_alias, 1, 1);
63 MultiFab coeff_C_mf(fast_coeffs, amrex::make_alias, 2, 1);
64 MultiFab coeff_P_mf(fast_coeffs, amrex::make_alias, 3, 1);
65 MultiFab coeff_Q_mf(fast_coeffs, amrex::make_alias, 4, 1);
66 MultiFab beta_s_mf(fast_coeffs, amrex::make_alias, 5, 1);
68 const bool has_z_nd = (z_phys_nd !=
nullptr);
73 const Array<Real,AMREX_SPACEDIM> grav{
zero,
zero, -gravity};
74 const GpuArray<Real,AMREX_SPACEDIM> grav_gpu{grav[0], grav[1], grav[2]};
80 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
86 Box bx = mfi.tilebox();
87 Box tbz = surroundingNodes(bx,2);
89 const Array4<const Real> & stage_cons = S_stage_data[
IntVars::cons].const_array(mfi);
90 const Array4<const Real> & prim = S_stage_prim.const_array(mfi);
92 const Array4<const Real>& detJ = (mesh_type != MeshType::ConstantDz) ?
93 detJ_cc->const_array(mfi) : Array4<const Real>{};
95 const Array4<const Real>& pi_stage_ca = pi_stage.const_array(mfi);
97 FArrayBox gam_fab; gam_fab.resize(surroundingNodes(bx,2),1,The_Async_Arena());
99 auto const& coeffA_a = coeff_A_mf.array(mfi);
100 auto const& coeffB_a = coeff_B_mf.array(mfi);
101 auto const& coeffC_a = coeff_C_mf.array(mfi);
102 auto const& coeffP_a = coeff_P_mf.array(mfi);
103 auto const& coeffQ_a = coeff_Q_mf.array(mfi);
104 auto const& gam_a = gam_fab.array();
105 auto const& beta_s_a = beta_s_mf.array(mfi);
107 const Array4<const Real>& z_nd = (has_z_nd) ? z_phys_nd->const_array(mfi) : Array4<const Real>{};
113 ParallelFor(tbz, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
115 if (use_variable_beta_s) {
118 beta_s_a(i,j,k) = amrex::max(beta_s_min, amrex::min(beta_s_max, h_xi*h_xi + h_eta*h_eta));
120 beta_s_a(i,j,k) = beta_s;
128 Box bx_shrunk_in_k = bx;
129 int klo = tbz.smallEnd(2);
130 int khi = tbz.bigEnd(2);
131 bx_shrunk_in_k.setSmall(2,
klo+1);
132 bx_shrunk_in_k.setBig(2,
khi-1);
140 if (mesh_type != MeshType::ConstantDz)
142 ParallelFor(bx_shrunk_in_k, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
144 Real pi_c =
myhalf * (pi_stage_ca(i,j,k-1) + pi_stage_ca(i,j,k));
146 Real detJ_on_kface =
myhalf * (detJ(i,j,k) + detJ(i,j,k-1));
147 Real inv_detJ_on_kface =
one / detJ_on_kface;
154 Real Thm_grad = dzi * inv_detJ_on_kface * ( Thm_hi - Thm_lo );
164 if (l_use_moisture) {
167 coeff_P /= (
one +
q);
168 coeff_Q /= (
one +
q);
174 coeffP_a(i,j,k) = coeff_P;
175 coeffQ_a(i,j,k) = coeff_Q;
188 Real D_A = beta_2_km1 * beta_2_k * dzi *
static_cast<Real>(dtau * dtau);
189 Real D_B = beta_2_k * beta_2_k * dzi *
static_cast<Real>(dtau * dtau);
190 Real D_C = beta_2_k * beta_2_kp1 * dzi *
static_cast<Real>(dtau * dtau);
191 coeffA_a(i,j,k) = D_A * (
one/detJ(i,j,k-1)) * ( halfg - coeff_Q * theta_t_lo );
192 coeffC_a(i,j,k) = D_C * (
one/detJ(i,j,k )) * (-halfg + coeff_P * theta_t_hi );
194 coeffB_a(i,j,k) =
one + D_B * ( (coeff_Q/detJ(i,j,k-1) - coeff_P/detJ(i,j,k)) * theta_t_mid
195 + halfg * (
one/detJ(i,j,k) -
one/detJ(i,j,k-1)) );
200 ParallelFor(bx_shrunk_in_k, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
202 Real pi_c =
myhalf * (pi_stage_ca(i,j,k-1) + pi_stage_ca(i,j,k));
209 Real Thm_grad = dzi * ( Thm_hi - Thm_lo );
219 if (l_use_moisture) {
222 coeff_P /= (
one +
q);
223 coeff_Q /= (
one +
q);
229 coeffP_a(i,j,k) = coeff_P;
230 coeffQ_a(i,j,k) = coeff_Q;
243 Real D_A = beta_2_km1 * beta_2_k * dzi *
static_cast<Real>(dtau * dtau);
244 Real D_B = beta_2_k * beta_2_k * dzi *
static_cast<Real>(dtau * dtau);
245 Real D_C = beta_2_k * beta_2_kp1 * dzi *
static_cast<Real>(dtau * dtau);
246 coeffA_a(i,j,k) = D_A * ( halfg - coeff_Q * theta_t_lo );
247 coeffC_a(i,j,k) = D_C * (-halfg + coeff_P * theta_t_hi );
249 coeffB_a(i,j,k) =
one + D_B * (coeff_Q - coeff_P) * theta_t_mid;
253 amrex::Box b2d = tbz;
256 auto const lo = amrex::lbound(bx);
257 auto const hi = amrex::ubound(bx);
259 auto const domhi = amrex::ubound(domain);
262 BL_PROFILE(
"make_coeffs_b2d_loop");
264 ParallelFor(b2d, [=] AMREX_GPU_DEVICE (
int i,
int j,
int) {
267 coeffA_a(i,j,
lo.z) =
zero;
268 coeffB_a(i,j,
lo.z) =
one;
269 coeffC_a(i,j,
lo.z) =
zero;
272 coeffA_a(i,j,
hi.z+1) =
zero;
273 coeffB_a(i,j,
hi.z+1) =
one;
274 coeffC_a(i,j,
hi.z+1) =
zero;
278 if ( (
hi.z == domhi.z) &&
281 coeffA_a(i,j,
hi.z+1) = -
one;
285 gam_a(i,j,
lo.z) = coeffC_a(i,j,
lo.z) / coeffB_a(i,j,
lo.z);
286 for (
int k =
lo.z+1; k <=
hi.z+1; k++) {
287 coeffB_a(i,j,k) =
one / ( coeffB_a(i,j,k) - coeffA_a(i,j,k)*gam_a(i,j,k-1) );
288 gam_a(i,j,k) = coeffC_a(i,j,k) * coeffB_a(i,j,k);
293 for (
int j =
lo.y; j <=
hi.y; ++j) {
295 for (
int i =
lo.x; i <=
hi.x; ++i) {
296 coeffA_a(i,j,
lo.z) =
zero;
297 coeffB_a(i,j,
lo.z) =
one;
298 coeffC_a(i,j,
lo.z) =
zero;
299 gam_a(i,j,
lo.z) = coeffC_a(i,j,
lo.z) / coeffB_a(i,j,
lo.z);
302 for (
int j =
lo.y; j <=
hi.y; ++j) {
304 for (
int i =
lo.x; i <=
hi.x; ++i) {
307 coeffA_a(i,j,
hi.z+1) =
zero;
308 coeffB_a(i,j,
hi.z+1) =
one;
309 coeffC_a(i,j,
hi.z+1) =
zero;
313 if ( (
hi.z == domhi.z) &&
316 coeffA_a(i,j,
hi.z+1) = -
one;
320 for (
int k =
lo.z+1; k <=
hi.z+1; ++k) {
321 for (
int j =
lo.y; j <=
hi.y; ++j) {
323 for (
int i =
lo.x; i <=
hi.x; ++i) {
324 coeffB_a(i,j,k) =
one / ( coeffB_a(i,j,k) - coeffA_a(i,j,k)*gam_a(i,j,k-1) );
325 gam_a(i,j,k) = coeffC_a(i,j,k) * coeffB_a(i,j,k);
constexpr amrex::Real RvoRd
Definition: ERF_Constants.H:59
constexpr amrex::Real R_d
Definition: ERF_Constants.H:49
constexpr amrex::Real Gamma
Definition: ERF_Constants.H:70
#define PrimQ1_comp
Definition: ERF_IndexDefines.H:82
#define PrimQ2_comp
Definition: ERF_IndexDefines.H:83
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:54
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:79
amrex::GpuArray< Real, AMREX_SPACEDIM > dxInv
Definition: ERF_InitCustomPertVels_ParticleTests.H:17
const int khi
Definition: ERF_InitCustomPert_Bubble.H:25
const int klo
Definition: ERF_InitCustomPert_KE.H:9
void make_fast_coeffs(int, MultiFab &fast_coeffs, Vector< MultiFab > &S_stage_data, const MultiFab &S_stage_prim, const MultiFab &pi_stage, const amrex::Geometry geom, bool l_use_moisture, MeshType mesh_type, Real gravity, Real c_p, std::unique_ptr< MultiFab > &detJ_cc, const double dtau, Real beta_s, const MultiFab *z_phys_nd, bool use_variable_beta_s, Real beta_s_min, Real beta_s_max, amrex::GpuArray< ERF_BC, AMREX_SPACEDIM *2 > &phys_bc_type)
Definition: ERF_MakeFastCoeffs.cpp:35
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::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtKface(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:444
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtKface(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:467
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
@ cons
Definition: ERF_IndexDefines.H:272
@ q
Definition: ERF_WSM6.H:294