aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/FieldSolver/WarpXPushFieldsEM.cpp88
-rw-r--r--Source/FieldSolver/WarpXPushFieldsEM_K.H54
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);