diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/FieldSolver/WarpXPushFieldsEM.cpp | 88 | ||||
-rw-r--r-- | Source/FieldSolver/WarpXPushFieldsEM_K.H | 54 |
2 files changed, 79 insertions, 63 deletions
diff --git a/Source/FieldSolver/WarpXPushFieldsEM.cpp b/Source/FieldSolver/WarpXPushFieldsEM.cpp index 33279813e..7e19a3472 100644 --- a/Source/FieldSolver/WarpXPushFieldsEM.cpp +++ b/Source/FieldSolver/WarpXPushFieldsEM.cpp @@ -700,12 +700,12 @@ WarpX::DampFieldsInGuards(std::array<std::unique_ptr<amrex::MultiFab>,3>& Efield // Get the tileboxes from Efield and Bfield so that they include the guard cells // and take the staggering of each MultiFab into account - amrex::Box tex = amrex::convert((*Efield[0])[mfi].box(), Efield[0]->ixType().toIntVect()); - amrex::Box tey = amrex::convert((*Efield[1])[mfi].box(), Efield[1]->ixType().toIntVect()); - amrex::Box tez = amrex::convert((*Efield[2])[mfi].box(), Efield[2]->ixType().toIntVect()); - amrex::Box tbx = amrex::convert((*Bfield[0])[mfi].box(), Bfield[0]->ixType().toIntVect()); - amrex::Box tby = amrex::convert((*Bfield[1])[mfi].box(), Bfield[1]->ixType().toIntVect()); - amrex::Box tbz = amrex::convert((*Bfield[2])[mfi].box(), Bfield[2]->ixType().toIntVect()); + const amrex::Box tex = amrex::convert((*Efield[0])[mfi].box(), Efield[0]->ixType().toIntVect()); + const amrex::Box tey = amrex::convert((*Efield[1])[mfi].box(), Efield[1]->ixType().toIntVect()); + const amrex::Box tez = amrex::convert((*Efield[2])[mfi].box(), Efield[2]->ixType().toIntVect()); + const amrex::Box tbx = amrex::convert((*Bfield[0])[mfi].box(), Bfield[0]->ixType().toIntVect()); + const amrex::Box tby = amrex::convert((*Bfield[1])[mfi].box(), Bfield[1]->ixType().toIntVect()); + const amrex::Box tbz = amrex::convert((*Bfield[2])[mfi].box(), Bfield[2]->ixType().toIntVect()); // Get smallEnd of tileboxes const int tex_smallEnd_z = tex.smallEnd(zdir); @@ -727,43 +727,49 @@ WarpX::DampFieldsInGuards(std::array<std::unique_ptr<amrex::MultiFab>,3>& Efield amrex::Box const& domain = Geom(0).Domain(); int const nz_domain = domain.bigEnd(zdir); - // Set the tileboxes so that they only cover the lower/upper half of the guard cells - constrain_tilebox_to_guards(tex, zdir, nz_domain, tex_smallEnd_z, tex_bigEnd_z); - constrain_tilebox_to_guards(tey, zdir, nz_domain, tey_smallEnd_z, tey_bigEnd_z); - constrain_tilebox_to_guards(tez, zdir, nz_domain, tez_smallEnd_z, tez_bigEnd_z); - constrain_tilebox_to_guards(tbx, zdir, nz_domain, tbx_smallEnd_z, tbx_bigEnd_z); - constrain_tilebox_to_guards(tby, zdir, nz_domain, tby_smallEnd_z, tby_bigEnd_z); - constrain_tilebox_to_guards(tbz, zdir, nz_domain, tbz_smallEnd_z, tbz_bigEnd_z); + // Loop over the lower and upper guards + for (int iside = 0 ; iside < 2 ; iside++) + { - amrex::ParallelFor( - tex, Efield[0]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) - { - damp_field_in_guards(Ex_arr, i, j, k, icomp, zdir, nz_domain, tex_smallEnd_z, tex_bigEnd_z); - }, - tey, Efield[1]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) - { - damp_field_in_guards(Ey_arr, i, j, k, icomp, zdir, nz_domain, tey_smallEnd_z, tey_bigEnd_z); - }, - tez, Efield[2]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) - { - damp_field_in_guards(Ez_arr, i, j, k, icomp, zdir, nz_domain, tez_smallEnd_z, tez_bigEnd_z); - } - ); + // Set the tileboxes so that they only cover the lower/upper half of the guard cells + amrex::Box tex_guard = constrain_tilebox_to_guards(tex, zdir, iside, nz_domain, tex_smallEnd_z, tex_bigEnd_z); + amrex::Box tey_guard = constrain_tilebox_to_guards(tey, zdir, iside, nz_domain, tey_smallEnd_z, tey_bigEnd_z); + amrex::Box tez_guard = constrain_tilebox_to_guards(tez, zdir, iside, nz_domain, tez_smallEnd_z, tez_bigEnd_z); + amrex::Box tbx_guard = constrain_tilebox_to_guards(tbx, zdir, iside, nz_domain, tbx_smallEnd_z, tbx_bigEnd_z); + amrex::Box tby_guard = constrain_tilebox_to_guards(tby, zdir, iside, nz_domain, tby_smallEnd_z, tby_bigEnd_z); + amrex::Box tbz_guard = constrain_tilebox_to_guards(tbz, zdir, iside, nz_domain, tbz_smallEnd_z, tbz_bigEnd_z); + + amrex::ParallelFor( + tex_guard, Efield[0]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Ex_arr, i, j, k, icomp, zdir, nz_domain, tex_smallEnd_z, tex_bigEnd_z); + }, + tey_guard, Efield[1]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Ey_arr, i, j, k, icomp, zdir, nz_domain, tey_smallEnd_z, tey_bigEnd_z); + }, + tez_guard, Efield[2]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Ez_arr, i, j, k, icomp, zdir, nz_domain, tez_smallEnd_z, tez_bigEnd_z); + } + ); + + amrex::ParallelFor( + tbx_guard, Bfield[0]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Bx_arr, i, j, k, icomp, zdir, nz_domain, tbx_smallEnd_z, tbx_bigEnd_z); + }, + tby_guard, Bfield[1]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(By_arr, i, j, k, icomp, zdir, nz_domain, tby_smallEnd_z, tby_bigEnd_z); + }, + tbz_guard, Bfield[2]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Bz_arr, i, j, k, icomp, zdir, nz_domain, tbz_smallEnd_z, tbz_bigEnd_z); + } + ); - amrex::ParallelFor( - tbx, Bfield[0]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) - { - damp_field_in_guards(Bx_arr, i, j, k, icomp, zdir, nz_domain, tbx_smallEnd_z, tbx_bigEnd_z); - }, - tby, Bfield[1]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) - { - damp_field_in_guards(By_arr, i, j, k, icomp, zdir, nz_domain, tby_smallEnd_z, tby_bigEnd_z); - }, - tbz, Bfield[2]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) - { - damp_field_in_guards(Bz_arr, i, j, k, icomp, zdir, nz_domain, tbz_smallEnd_z, tbz_bigEnd_z); - } - ); + } } } diff --git a/Source/FieldSolver/WarpXPushFieldsEM_K.H b/Source/FieldSolver/WarpXPushFieldsEM_K.H index 8fe1b781b..e8e675cd2 100644 --- a/Source/FieldSolver/WarpXPushFieldsEM_K.H +++ b/Source/FieldSolver/WarpXPushFieldsEM_K.H @@ -13,36 +13,48 @@ #include <AMReX.H> /* - * \brief Set a tilebox so that it only covers the lower/upper half of the guard cells. + * \brief Return a tilebox that only covers the outer half of the guard cells. + * For tileboxes that don't include cells beyond the whole domain, + * an empty box is returned. * - * \param[in,out] tb tilebox to be modified + * \param[in,out] input_tb tilebox to be modified * \param[in] dir direction where the tilebox smallEnd/bigEnd is modified - * \param[in] n_domain number of cells in the whole simulation domain - * \param[in] tb_smallEnd smallEnd of the tilebox - * \param[in] tb_bigEnd bigEnd of the tilebox + * \param[in] n_domain number of valid cells in the whole simulation domain + * \param[in] tb_smallEnd the lowest index of the tilebox, including guard cells + * \param[in] tb_bigEnd the highest index of the tilebox, including guard cells */ AMREX_GPU_HOST_DEVICE AMREX_INLINE -void constrain_tilebox_to_guards( - amrex::Box& tb, +amrex::Box constrain_tilebox_to_guards( + const amrex::Box& input_tb, const int dir, + const int iside, const int n_domain, const int tb_smallEnd, const int tb_bigEnd) { using namespace amrex; - const int n_tile = tb_bigEnd; + amrex::Box constrained_tb = input_tb; - if (tb_smallEnd < 0) + // If the input_tb does not overlap either the lower or upper guard, + // an empty box is returned. + + if (iside == 0) { + // Lower guard const int n_guard = -tb_smallEnd; - tb.setBig(dir, 0 - n_guard/2 - 1); + const int upper_bound = (tb_smallEnd < 0 ? -n_guard/2 : tb_smallEnd); + constrained_tb.setBig(dir, upper_bound - 1); } - else if (n_tile > n_domain) + else if (iside == 1) { - const int n_guard = n_tile - n_domain; - tb.setSmall(dir, n_domain + n_guard/2 + 1); + // Upper guard + const int n_guard = tb_bigEnd - n_domain; + const int lower_bound = (tb_bigEnd > n_domain ? n_domain + n_guard/2 : tb_bigEnd); + constrained_tb.setSmall(dir, lower_bound + 1); } + + return constrained_tb; } /* @@ -54,9 +66,9 @@ void constrain_tilebox_to_guards( * \oaram[in] k index along z (in 3D, \c k = 0 in 2D/RZ) * \param[in] icomp index along the fourth component of the array * \param]in] dir direction where the field will be damped - * \param[in] n_domain number of cells in the whole simulation domain - * \param[in] tb_smallEnd smallEnd of the current tilebox - * \param[in] tb_bigEnd bigEnd of the current tilebox + * \param[in] n_domain number of valid cells in the whole simulation domain + * \param[in] tb_smallEnd the lowest index of the tilebox, including guard cells + * \param[in] tb_bigEnd the highest index of the tilebox, including guard cells */ AMREX_GPU_HOST_DEVICE AMREX_INLINE void damp_field_in_guards( @@ -77,9 +89,7 @@ void damp_field_in_guards( // dir = 2: idx = k (z in 3D) const int idx = ((dir == 0) ? i : ((dir == 1) ? j : k)); - const int n_tile = tb_bigEnd; - - if (tb_smallEnd < 0) + if (idx < 0) { // Apply damping factor in guards cells below the lower end of the domain const int n_guard = -tb_smallEnd; @@ -92,12 +102,12 @@ void damp_field_in_guards( mf_arr(i,j,k,icomp) *= damp_factor; } - else if (n_tile > n_domain) + else if (idx > n_domain) { // Apply damping factor in guards cells above the upper end of the domain - const int n_guard = n_tile - n_domain; + const int n_guard = tb_bigEnd - n_domain; - const amrex::Real cell = static_cast<amrex::Real>(n_tile - idx); + const amrex::Real cell = static_cast<amrex::Real>(tb_bigEnd - idx); const amrex::Real phase = MathConst::pi * cell / n_guard; const amrex::Real sin_phase = std::sin(phase); |