7 #ifndef ABLASTR_DEPOSIT_CHARGE_H_
8 #define ABLASTR_DEPOSIT_CHARGE_H_
53 template<
typename T_PC >
56 typename T_PC::RealVector
const& wp,
57 amrex::Real
const charge,
58 int const *
const ion_lev,
61 int const particle_shape,
62 std::array<amrex::Real, 3>
const &
dx,
63 std::array<amrex::Real, 3>
const & xyzmin,
64 int const n_rz_azimuthal_modes = 0,
65 std::optional<amrex::IntVect> num_rho_deposition_guards = std::nullopt,
66 std::optional<int> depos_lev = std::nullopt,
67 std::optional<amrex::IntVect> rel_ref_ratio = std::nullopt,
68 long const offset = 0,
69 std::optional<long> np_to_depose = std::nullopt,
70 int const icomp = 0,
int const nc = 1,
71 amrex::Real *
const AMREX_RESTRICT cost =
nullptr,
72 long const load_balance_costs_update_algo = 0,
73 bool const do_device_synchronize =
true)
77 if (num_rho_deposition_guards.has_value())
78 ng_rho = num_rho_deposition_guards.value();
80 "num_rho_deposition_guards are larger than allocated!");
82 auto const[
nox,
noy,
noz] = std::array<int, 3>{particle_shape, particle_shape, particle_shape};
86 if (!np_to_depose.has_value())
87 np_to_depose = pti.numParticles();
89 "np_to_depose + offset are out-of-bounds for particle iterator");
91 int const lev = pti.GetLevel();
92 if (!depos_lev.has_value())
95 (depos_lev.value() == (lev )),
96 "Deposition buffers only work for lev or lev-1");
97 if (!rel_ref_ratio.has_value()) {
99 "rel_ref_ratio must be set if lev != depos_lev");
104 if (np_to_depose == 0)
return;
111 #if defined(WARPX_DIM_1D_Z)
115 #elif defined(WARPX_DIM_XZ) || defined(WARPX_DIM_RZ)
118 static_cast<int>(
noz/2+1));
119 #elif defined(WARPX_DIM_3D)
121 static_cast<int>(
noy/2+1),
122 static_cast<int>(
noz/2+1));
127 #ifndef AMREX_USE_GPU
135 "Particles shape does not fit within tile (CPU) or guard cells (GPU) used for charge deposition");
137 ABLASTR_PROFILE_VAR_NS(
"ablastr::particles::deposit_charge::ChargeDeposition", blp_ppc_chd, do_device_synchronize);
138 ABLASTR_PROFILE_VAR_NS(
"ablastr::particles::deposit_charge::Accumulate", blp_accumulate, do_device_synchronize);
144 if (lev == depos_lev) {
145 tilebox = pti.tilebox();
150 #ifndef AMREX_USE_GPU
155 tilebox.
grow(ng_rho);
161 auto & rho_fab = rhoi.
get(pti);
171 auto & rho_fab = local_rho;
182 doChargeDepositionShapeN<1>(GetPosition, wp.dataPtr()+
offset, ion_lev,
183 rho_fab, np_to_depose.value(),
dx, xyzmin, lo, charge,
184 n_rz_azimuthal_modes, cost,
185 load_balance_costs_update_algo);
186 }
else if (
nox == 2){
187 doChargeDepositionShapeN<2>(GetPosition, wp.dataPtr()+
offset, ion_lev,
188 rho_fab, np_to_depose.value(),
dx, xyzmin, lo, charge,
189 n_rz_azimuthal_modes, cost,
190 load_balance_costs_update_algo);
191 }
else if (
nox == 3){
192 doChargeDepositionShapeN<3>(GetPosition, wp.dataPtr()+
offset, ion_lev,
193 rho_fab, np_to_depose.value(),
dx, xyzmin, lo, charge,
194 n_rz_azimuthal_modes, cost,
195 load_balance_costs_update_algo);
199 #ifndef AMREX_USE_GPU
202 (*rho)[pti].atomicAdd(local_rho, tb, tb, 0, icomp*
nc,
nc);
Array4< int const > offset
#define AMREX_D_DECL(a, b, c)
#define ABLASTR_PROFILE_VAR_START(vname, sync)
Definition: ProfilerWrapper.H:52
#define ABLASTR_PROFILE_VAR_NS(fname, vname, sync)
Definition: ProfilerWrapper.H:51
#define ABLASTR_PROFILE_VAR_STOP(vname, sync)
Definition: ProfilerWrapper.H:53
#define ABLASTR_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition: TextMsg.H:77
void setVal(T const &x, const Box &bx, int dcomp, int ncomp) noexcept
AMREX_GPU_HOST_DEVICE BoxND & grow(int i) noexcept
void resize(const Box &b, int N=1, Arena *ar=nullptr)
IntVect nGrowVect() const noexcept
IndexType ixType() const noexcept
const FAB & get(const MFIter &mfi) const noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IntVectND< dim > toIntVect() const noexcept
Definition: DepositCharge.H:22
static void deposit_charge(typename T_PC::ParIterType &pti, typename T_PC::RealVector const &wp, 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)
Definition: DepositCharge.H:55
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
IntVectND< AMREX_SPACEDIM > IntVect
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
int numParticlesOutOfRange(Iterator const &pti, int nGrow)
int nc
Definition: check_interp_points_and_weights.py:130
int nox
Definition: stencil.py:442
int dx
Definition: stencil.py:436
int noy
Definition: stencil.py:443
int noz
Definition: stencil.py:444
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel.
Definition: GetAndSetPosition.H:53