aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Particles/WarpXParticleContainer.cpp22
-rw-r--r--Source/ablastr/particles/DepositCharge.H97
2 files changed, 79 insertions, 40 deletions
diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp
index f590d3cc0..e2a34727c 100644
--- a/Source/Particles/WarpXParticleContainer.cpp
+++ b/Source/Particles/WarpXParticleContainer.cpp
@@ -594,7 +594,11 @@ WarpXParticleContainer::DepositCharge (WarpXParIter& pti, RealVector const& wp,
{
if (!do_not_deposit) {
WarpX& warpx = WarpX::GetInstance();
+
+ // deposition guards
+ // note: this is smaller than rho->nGrowVect() for PSATD
const amrex::IntVect& ng_rho = warpx.get_ng_depos_rho();
+
const std::array<amrex::Real,3>& dx = WarpX::CellSize(std::max(depos_lev,0));
amrex::IntVect ref_ratio;
if (lev == depos_lev) {
@@ -641,12 +645,18 @@ WarpXParticleContainer::DepositCharge (WarpXParIter& pti, RealVector const& wp,
amrex::LayoutData<amrex::Real>* costs = WarpX::getCosts(lev);
amrex::Real* cost = costs ? &((*costs)[pti.index()]) : nullptr;
- ablastr::particles::deposit_charge<WarpXParticleContainer>
- (pti, wp, ion_lev, rho, icomp, nc, offset, np_to_depose,
- local_rho[thread_num], lev, depos_lev, this->charge,
- WarpX::nox, WarpX::noy, WarpX::noz, ng_rho, dx, xyzmin, ref_ratio,
- cost, WarpX::n_rz_azimuthal_modes, WarpX::load_balance_costs_update_algo,
- WarpX::do_device_synchronize);
+ AMREX_ALWAYS_ASSERT(WarpX::nox == WarpX::noy);
+ AMREX_ALWAYS_ASSERT(WarpX::nox == WarpX::noz);
+
+ ablastr::particles::deposit_charge<WarpXParticleContainer>(
+ pti, wp, this->charge, ion_lev,
+ rho, local_rho[thread_num],
+ WarpX::noz, dx, xyzmin, WarpX::n_rz_azimuthal_modes,
+ ng_rho, depos_lev, ref_ratio,
+ offset, np_to_depose,
+ icomp, nc,
+ cost, WarpX::load_balance_costs_update_algo, WarpX::do_device_synchronize
+ );
}
}
diff --git a/Source/ablastr/particles/DepositCharge.H b/Source/ablastr/particles/DepositCharge.H
index 548ebaddb..e66165361 100644
--- a/Source/ablastr/particles/DepositCharge.H
+++ b/Source/ablastr/particles/DepositCharge.H
@@ -18,6 +18,8 @@
#include <AMReX.H>
+#include <optional>
+
namespace ablastr {
namespace particles {
@@ -28,51 +30,78 @@ namespace particles {
*
* \param pti an amrex::ParIter pointing to the tile to operate on
* \param wp vector of the particle weights for those particles.
+ * \param charge charge of the particle species
* \param ion_lev pointer to array of particle ionization level. This is
required to have the charge of each macroparticle
since q is a scalar. For non-ionizable species,
ion_lev is a null pointer.
* \param rho MultiFab of the charge density
- * \param icomp component in MultiFab to start depositing to
- * \param nc number of components to deposit
- * \param offset index to start at when looping over particles to depose
- * \param np_to_depose number of particles to depose
* \param local_rho temporary FArrayBox for deposition with OpenMP
- * \param lev the level of the particles we are on
- * \param depos_lev the level to deposit the particles to
- * \param charge charge of the particle species
- * \param nox shape factor in the x direction
- * \param noy shape factor in the y direction
- * \param noz shape factor in the z direction
- * \param ng_rho number of ghost cells to use for rho
+ * \param particle_shape shape factor in each direction
* \param dx cell spacing at level lev
* \param xyzmin lo corner of the current tile in physical coordinates.
- * \param ref_ratio mesh refinement ratio between lev and depos_lev
+ * \param n_rz_azimuthal_modes number of azimuthal modes in use, irrelevant outside RZ geometry (default: 0)
+ * \param num_rho_deposition_guards number of ghost cells to use for rho (default: rho.nGrowVect())
+ * \param depos_lev the level to deposit the particles to (default: lev)
+ * \param rel_ref_ratio mesh refinement ratio between lev and depos_lev (default: 1)
+ * \param offset index to start at when looping over particles to depose (default: 0)
+ * \param np_to_depose number of particles to depose (default: pti.numParticles())
+ * \param icomp component in MultiFab to start depositing to
+ * \param nc number of components to deposit
* \param cost pointer to (load balancing) cost corresponding to box where present
- particles deposit current. If nullptr, costs are not updated.
- * \param n_rz_azimuthal_modes number of azimuthal modes in use, irrelevant outside RZ geometry.
- * \param load_balance_costs_update_algo selected method for updating load balance costs.
- * \param do_device_synchronize call amrex::Gpu::synchronize() for tiny profiler regions
+ particles deposit current. If nullptr, costs are not updated. (default: nullptr)
+ * \param load_balance_costs_update_algo selected method for updating load balance costs (default: 0)
+ * \param do_device_synchronize call amrex::Gpu::synchronize() for tiny profiler regions (default: true)
*/
template< typename T_PC >
static void
deposit_charge (typename T_PC::ParIterType& pti,
typename T_PC::RealVector const& wp,
- const int * const ion_lev,
- amrex::MultiFab* rho, const int icomp, const int nc,
- const long offset, const long np_to_depose,
- amrex::FArrayBox& local_rho, const int lev, const int depos_lev,
- const amrex::Real charge, const int nox, const int noy, const int noz,
- const amrex::IntVect& ng_rho, const std::array<amrex::Real,3>& dx,
- const std::array<amrex::Real, 3>& xyzmin,
- const amrex::IntVect& ref_ratio,
- amrex::Real* cost, const int n_rz_azimuthal_modes,
- const long load_balance_costs_update_algo,
- const bool do_device_synchronize)
+ amrex::Real const charge,
+ int const * const ion_lev,
+ amrex::MultiFab* rho,
+ amrex::FArrayBox& local_rho,
+ int const particle_shape,
+ std::array<amrex::Real, 3> const & dx,
+ std::array<amrex::Real, 3> const & xyzmin,
+ int const n_rz_azimuthal_modes = 0,
+ std::optional<amrex::IntVect> num_rho_deposition_guards = std::nullopt,
+ std::optional<int> depos_lev = std::nullopt,
+ std::optional<amrex::IntVect> rel_ref_ratio = std::nullopt,
+ long const offset = 0,
+ std::optional<long> np_to_depose = std::nullopt,
+ int const icomp = 0, int const nc = 1,
+ amrex::Real * const AMREX_RESTRICT cost = nullptr,
+ long const load_balance_costs_update_algo = 0,
+ bool const do_device_synchronize = true)
{
- AMREX_ALWAYS_ASSERT_WITH_MESSAGE((depos_lev==(lev-1)) ||
- (depos_lev==(lev )),
- "Deposition buffers only work for lev-1");
+ // deposition guards
+ amrex::IntVect ng_rho = rho->nGrowVect();
+ if (num_rho_deposition_guards.has_value())
+ ng_rho = num_rho_deposition_guards.value();
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(ng_rho <= rho->nGrowVect(),
+ "num_rho_deposition_guards are larger than allocated!");
+ // particle shape
+ auto const[nox, noy, noz] = std::array<int, 3>{particle_shape, particle_shape, particle_shape};
+
+ // used for MR when we want to deposit for a subset of the particles on the level in the
+ // current box; with offset, we start at a later particle index
+ if (!np_to_depose.has_value())
+ np_to_depose = pti.numParticles();
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(np_to_depose.value() + offset <= pti.numParticles(),
+ "np_to_depose + offset are out-of-bounds for particle iterator");
+
+ int const lev = pti.GetLevel();
+ if (!depos_lev.has_value())
+ depos_lev = lev;
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE((depos_lev.value() == (lev-1)) ||
+ (depos_lev.value() == (lev )),
+ "Deposition buffers only work for lev or lev-1");
+ if (!rel_ref_ratio.has_value()) {
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(lev == depos_lev,
+ "rel_ref_ratio must be set if lev != depos_lev");
+ rel_ref_ratio = amrex::IntVect(AMREX_D_DECL(1, 1, 1));
+ }
// If no particles, do not do anything
if (np_to_depose == 0) return;
@@ -118,7 +147,7 @@ deposit_charge (typename T_PC::ParIterType& pti,
if (lev == depos_lev) {
tilebox = pti.tilebox();
} else {
- tilebox = amrex::coarsen(pti.tilebox(),ref_ratio);
+ tilebox = amrex::coarsen(pti.tilebox(), rel_ref_ratio.value());
}
#ifndef AMREX_USE_GPU
@@ -154,17 +183,17 @@ deposit_charge (typename T_PC::ParIterType& pti,
if (nox == 1){
doChargeDepositionShapeN<1>(GetPosition, wp.dataPtr()+offset, ion_lev,
- rho_fab, np_to_depose, dx, xyzmin, lo, charge,
+ rho_fab, np_to_depose.value(), dx, xyzmin, lo, charge,
n_rz_azimuthal_modes, cost,
load_balance_costs_update_algo);
} else if (nox == 2){
doChargeDepositionShapeN<2>(GetPosition, wp.dataPtr()+offset, ion_lev,
- rho_fab, np_to_depose, dx, xyzmin, lo, charge,
+ rho_fab, np_to_depose.value(), dx, xyzmin, lo, charge,
n_rz_azimuthal_modes, cost,
load_balance_costs_update_algo);
} else if (nox == 3){
doChargeDepositionShapeN<3>(GetPosition, wp.dataPtr()+offset, ion_lev,
- rho_fab, np_to_depose, dx, xyzmin, lo, charge,
+ rho_fab, np_to_depose.value(), dx, xyzmin, lo, charge,
n_rz_azimuthal_modes, cost,
load_balance_costs_update_algo);
}