aboutsummaryrefslogtreecommitdiff
path: root/Source/Particles/WarpXParticleContainer.H
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Particles/WarpXParticleContainer.H')
-rw-r--r--Source/Particles/WarpXParticleContainer.H233
1 files changed, 233 insertions, 0 deletions
diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H
new file mode 100644
index 000000000..d11ce49c9
--- /dev/null
+++ b/Source/Particles/WarpXParticleContainer.H
@@ -0,0 +1,233 @@
+#ifndef WARPX_WarpXParticleContainer_H_
+#define WARPX_WarpXParticleContainer_H_
+
+#include <memory>
+
+#include <AMReX_Particles.H>
+#include <AMReX_AmrCore.H>
+
+struct PIdx
+{
+ enum { // Particle Attributes stored in amrex::ParticleContainer's struct of array
+ w = 0, // weight
+ ux, uy, uz, Ex, Ey, Ez, Bx, By, Bz,
+#if (BL_SPACEDIM == 2) && WARPX_RZ
+ theta, // RZ needs all three position components
+#endif
+#ifdef WARPX_STORE_OLD_PARTICLE_ATTRIBS
+ xold, yold, zold, uxold, uyold, uzold,
+#endif
+ nattribs
+ };
+};
+
+struct DiagIdx
+{
+ enum {
+ w = 0,
+ x, y, z, ux, uy, uz,
+ nattribs
+ };
+};
+
+class WarpXParIter
+ : public amrex::ParIter<0,0,PIdx::nattribs>
+{
+public:
+ using amrex::ParIter<0,0,PIdx::nattribs>::ParIter;
+
+ WarpXParIter (ContainerType& pc, int level);
+
+#if (AMREX_SPACEDIM == 2)
+ void GetPosition (amrex::Cuda::DeviceVector<amrex::Real>& x,
+ amrex::Cuda::DeviceVector<amrex::Real>& y,
+ amrex::Cuda::DeviceVector<amrex::Real>& z) const;
+ void SetPosition (const amrex::Cuda::DeviceVector<amrex::Real>& x,
+ const amrex::Cuda::DeviceVector<amrex::Real>& y,
+ const amrex::Cuda::DeviceVector<amrex::Real>& z);
+#endif
+
+ const std::array<RealVector, PIdx::nattribs>& GetAttribs () const {
+ return GetStructOfArrays().GetRealData();
+ }
+
+ std::array<RealVector, PIdx::nattribs>& GetAttribs () {
+ return GetStructOfArrays().GetRealData();
+ }
+
+ const RealVector& GetAttribs (int comp) const {
+ return GetStructOfArrays().GetRealData(comp);
+ }
+
+ RealVector& GetAttribs (int comp) {
+ return GetStructOfArrays().GetRealData(comp);
+ }
+};
+
+class MultiParticleContainer;
+
+class WarpXParticleContainer
+ : public amrex::ParticleContainer<0,0,PIdx::nattribs>
+{
+public:
+ friend MultiParticleContainer;
+
+ using DiagnosticParticleData = amrex::StructOfArrays<DiagIdx::nattribs, 0>;
+ using DiagnosticParticles = amrex::Vector<std::map<std::pair<int, int>, DiagnosticParticleData> >;
+
+ WarpXParticleContainer (amrex::AmrCore* amr_core, int ispecies);
+ virtual ~WarpXParticleContainer() {}
+
+ virtual void InitData () = 0;
+
+ virtual void FieldGatherES (const amrex::Vector<std::array<std::unique_ptr<amrex::MultiFab>, 3> >& E,
+ const amrex::Vector<std::unique_ptr<amrex::FabArray<amrex::BaseFab<int> > > >& masks) {}
+
+ virtual void FieldGather (int lev,
+ const amrex::MultiFab& Ex, const amrex::MultiFab& Ey, const amrex::MultiFab& Ez,
+ const amrex::MultiFab& Bx, const amrex::MultiFab& By, const amrex::MultiFab& Bz) {}
+
+#ifdef WARPX_DO_ELECTROSTATIC
+ virtual void EvolveES (const amrex::Vector<std::array<std::unique_ptr<amrex::MultiFab>, 3> >& E,
+ amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho,
+ amrex::Real t, amrex::Real dt) = 0;
+#endif // WARPX_DO_ELECTROSTATIC
+
+ virtual void Evolve (int lev,
+ const amrex::MultiFab& Ex, const amrex::MultiFab& Ey, const amrex::MultiFab& Ez,
+ const amrex::MultiFab& Bx, const amrex::MultiFab& By, const amrex::MultiFab& Bz,
+ amrex::MultiFab& jx, amrex::MultiFab& jy, amrex::MultiFab& jz,
+ amrex::MultiFab* cjx, amrex::MultiFab* cjy, amrex::MultiFab* cjz,
+ amrex::MultiFab* rho, amrex::MultiFab* crho,
+ const amrex::MultiFab* cEx, const amrex::MultiFab* cEy, const amrex::MultiFab* cEz,
+ const amrex::MultiFab* cBx, const amrex::MultiFab* cBy, const amrex::MultiFab* cBz,
+ amrex::Real t, amrex::Real dt) = 0;
+
+ virtual void PostRestart () = 0;
+
+ virtual void GetParticleSlice(const int direction, const amrex::Real z_old,
+ const amrex::Real z_new, const amrex::Real t_boost,
+ const amrex::Real t_lab, const amrex::Real dt,
+ DiagnosticParticles& diagnostic_particles) {}
+
+ void AllocData ();
+
+ ///
+ /// This pushes the particle positions by one half time step.
+ /// It is used to desynchronize the particles after initializaton
+ /// or when restarting from a checkpoint.
+ /// This is the electrostatic version of the particle push.
+ ///
+ void PushXES (amrex::Real dt);
+
+ ///
+ /// This pushes the particle positions by one half time step.
+ /// It is used to desynchronize the particles after initializaton
+ /// or when restarting from a checkpoint.
+ /// This is the electromagnetic version of the particle push.
+ ///
+ void PushX ( amrex::Real dt);
+ void PushX (int lev, amrex::Real dt);
+
+ ///
+ /// This pushes the particle momenta by dt.
+ ///
+ virtual void PushP (int lev, amrex::Real dt,
+ const amrex::MultiFab& Ex,
+ const amrex::MultiFab& Ey,
+ const amrex::MultiFab& Ez,
+ const amrex::MultiFab& Bx,
+ const amrex::MultiFab& By,
+ const amrex::MultiFab& Bz) = 0;
+
+ void DepositCharge(amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho,
+ bool local = false);
+ std::unique_ptr<amrex::MultiFab> GetChargeDensity(int lev, bool local = false);
+
+ virtual void DepositCharge(WarpXParIter& pti,
+ RealVector& wp,
+ amrex::MultiFab* rhomf,
+ amrex::MultiFab* crhomf,
+ int icomp,
+ const long np_current,
+ const long np,
+ int thread_num,
+ int lev );
+
+ virtual void DepositCurrent(WarpXParIter& pti,
+ RealVector& wp,
+ RealVector& uxp,
+ RealVector& uyp,
+ RealVector& uzp,
+ amrex::MultiFab& jx,
+ amrex::MultiFab& jy,
+ amrex::MultiFab& jz,
+ amrex::MultiFab* cjx,
+ amrex::MultiFab* cjy,
+ amrex::MultiFab* cjz,
+ const long np_current,
+ const long np,
+ int thread_num,
+ int lev,
+ amrex::Real dt );
+
+ ///
+ /// This returns the total charge for all the particles in this ParticleContainer.
+ /// This is needed when solving Poisson's equation with periodic boundary conditions.
+ ///
+ amrex::Real sumParticleCharge(bool local = false);
+
+ std::array<amrex::Real, 3> meanParticleVelocity(bool local = false);
+
+ amrex::Real maxParticleVelocity(bool local = false);
+
+ void AddNParticles (int lev,
+ int n, const amrex::Real* x, const amrex::Real* y, const amrex::Real* z,
+ const amrex::Real* vx, const amrex::Real* vy, const amrex::Real* vz,
+ int nattr, const amrex::Real* attr, int uniqueparticles, int id=-1);
+
+ void AddOneParticle (int lev, int grid, int tile,
+ amrex::Real x, amrex::Real y, amrex::Real z,
+ const std::array<amrex::Real,PIdx::nattribs>& attribs);
+
+ void AddOneParticle (ParticleTileType& particle_tile,
+ amrex::Real x, amrex::Real y, amrex::Real z,
+ const std::array<amrex::Real,PIdx::nattribs>& attribs);
+
+ void ReadHeader (std::istream& is);
+
+ void WriteHeader (std::ostream& os) const;
+
+ static void ReadParameters ();
+
+ static int NextID () { return ParticleType::NextID(); }
+
+ bool do_splitting = false;
+
+ // split along axes (0) or diagonals (1)
+ int split_type = 0;
+
+protected:
+
+ int species_id;
+
+ amrex::Real charge;
+ amrex::Real mass;
+
+ bool deposit_on_main_grid = false;
+
+ static int do_not_push;
+
+ amrex::Vector<std::unique_ptr<amrex::FArrayBox> > local_rho;
+ amrex::Vector<std::unique_ptr<amrex::FArrayBox> > local_jx;
+ amrex::Vector<std::unique_ptr<amrex::FArrayBox> > local_jy;
+ amrex::Vector<std::unique_ptr<amrex::FArrayBox> > local_jz;
+
+ amrex::Vector<amrex::Cuda::DeviceVector<amrex::Real> > m_xp, m_yp, m_zp, m_giv;
+
+private:
+ virtual void particlePostLocate(ParticleType& p, const amrex::ParticleLocData& pld,
+ const int lev) override;
+};
+
+#endif