WarpX
WarpXParticleContainer.H
Go to the documentation of this file.
1 /* Copyright 2019-2020 Andrew Myers, Axel Huebl, David Grote
2  * Jean-Luc Vay, Junmin Gu, Luca Fedeli
3  * Maxence Thevenet, Remi Lehe, Revathi Jambunathan
4  * Weiqun Zhang, Yinjian Zhao
5  *
6  * This file is part of WarpX.
7  *
8  * License: BSD-3-Clause-LBNL
9  */
10 #ifndef WARPX_WarpXParticleContainer_H_
11 #define WARPX_WarpXParticleContainer_H_
12 
14 #include "Utils/WarpXConst.H"
16 #include "Evolve/WarpXDtType.H"
18 
19 #ifdef WARPX_QED
22 #endif
23 
24 #include <AMReX_Particles.H>
25 #include <AMReX_AmrCore.H>
26 
27 #include <memory>
28 
29 enum struct ParticleBC { none=0, absorbing };
30 
32 
33 struct PIdx
34 {
35  enum { // Particle Attributes stored in amrex::ParticleContainer's struct of array
36  w = 0, // weight
37  ux, uy, uz,
38 #ifdef WARPX_DIM_RZ
39  theta, // RZ needs all three position components
40 #endif
41  nattribs
42  };
43 };
44 
45 struct DiagIdx
46 {
47  enum {
48  w = 0,
49  x, y, z, ux, uy, uz,
50  nattribs
51  };
52 };
53 
54 struct TmpIdx
55 {
56  enum {
57  xold = 0,
58  yold, zold, uxold, uyold, uzold,
59  nattribs
60  };
61 };
62 
64 {
65  const std::map<std::string, int> to_index = {
66  {"w", PIdx::w },
67  {"ux", PIdx::ux },
68  {"uy", PIdx::uy },
69  {"uz", PIdx::uz },
70 #ifdef WARPX_DIM_RZ
71  {"theta", PIdx::theta}
72 #endif
73  };
74 }
75 
77  : public amrex::ParIter<0,0,PIdx::nattribs>
78 {
79 public:
80  using amrex::ParIter<0,0,PIdx::nattribs>::ParIter;
81 
82  WarpXParIter (ContainerType& pc, int level);
83 
84  WarpXParIter (ContainerType& pc, int level, amrex::MFItInfo& info);
85 
86  const std::array<RealVector, PIdx::nattribs>& GetAttribs () const {
87  return GetStructOfArrays().GetRealData();
88  }
89 
90  std::array<RealVector, PIdx::nattribs>& GetAttribs () {
91  return GetStructOfArrays().GetRealData();
92  }
93 
94  const RealVector& GetAttribs (int comp) const {
95  return GetStructOfArrays().GetRealData(comp);
96  }
97 
98  RealVector& GetAttribs (int comp) {
99  return GetStructOfArrays().GetRealData(comp);
100  }
101 
102  IntVector& GetiAttribs (int comp) {
103  return GetStructOfArrays().GetIntData(comp);
104  }
105 };
106 
107 // Forward-declaration needed by WarpXParticleContainer below
109 
132  : public amrex::ParticleContainer<0,0,PIdx::nattribs>
133 {
134 public:
136 #ifdef WARPX_USE_OPENPMD
137  friend class WarpXOpenPMDPlot;
138 #endif
139 
140  // amrex::StructOfArrays with DiagIdx::nattribs amrex::ParticleReal components
141  // and 0 int components for the particle data.
142  using DiagnosticParticleData = amrex::StructOfArrays<DiagIdx::nattribs, 0>;
143  // DiagnosticParticles is a vector, with one element per MR level.
144  // DiagnosticParticles[lev] is typically a key-value pair where the key is
145  // a pair [grid_index, tile_index], and the value is the corresponding
146  // DiagnosticParticleData (see above) on this tile.
147  using DiagnosticParticles = amrex::Vector<std::map<std::pair<int, int>, DiagnosticParticleData> >;
148 
149  WarpXParticleContainer (amrex::AmrCore* amr_core, int ispecies);
151 
152  virtual void InitData () = 0;
153 
159  virtual void Evolve (int lev,
160  const amrex::MultiFab& Ex, const amrex::MultiFab& Ey, const amrex::MultiFab& Ez,
161  const amrex::MultiFab& Bx, const amrex::MultiFab& By, const amrex::MultiFab& Bz,
162  const amrex::MultiFab& Ex_avg, const amrex::MultiFab& Ey_avg, const amrex::MultiFab& Ez_avg,
163  const amrex::MultiFab& Bx_avg, const amrex::MultiFab& By_avg, const amrex::MultiFab& Bz_avg,
164  amrex::MultiFab& jx, amrex::MultiFab& jy, amrex::MultiFab& jz,
165  amrex::MultiFab* cjx, amrex::MultiFab* cjy, amrex::MultiFab* cjz,
166  amrex::MultiFab* rho, amrex::MultiFab* crho,
167  const amrex::MultiFab* cEx, const amrex::MultiFab* cEy, const amrex::MultiFab* cEz,
168  const amrex::MultiFab* cBx, const amrex::MultiFab* cBy, const amrex::MultiFab* cBz,
169  amrex::Real t, amrex::Real dt, DtType a_dt_type=DtType::Full) = 0;
170 
171  virtual void PostRestart () = 0;
172 
173  virtual void GetParticleSlice(const int /*direction*/, const amrex::Real /*z_old*/,
174  const amrex::Real /*z_new*/, const amrex::Real /*t_boost*/,
175  const amrex::Real /*t_lab*/, const amrex::Real /*dt*/,
176  DiagnosticParticles& /*diagnostic_particles*/) {}
177 
178  void AllocData ();
179 
185  void PushX ( amrex::Real dt);
186  void PushX (int lev, amrex::Real dt);
187 
191  virtual void PushP (int lev, amrex::Real dt,
192  const amrex::MultiFab& Ex,
193  const amrex::MultiFab& Ey,
194  const amrex::MultiFab& Ez,
195  const amrex::MultiFab& Bx,
196  const amrex::MultiFab& By,
197  const amrex::MultiFab& Bz) = 0;
198 
199  void DepositCharge(amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho,
200  bool local = false, bool reset = false,
201  bool do_rz_volume_scaling = false );
202  std::unique_ptr<amrex::MultiFab> GetChargeDensity(int lev, bool local = false);
203 
204  virtual void DepositCharge(WarpXParIter& pti,
205  RealVector& wp,
206  const int * const ion_lev,
207  amrex::MultiFab* rho,
208  int icomp,
209  const long offset,
210  const long np_to_depose,
211  int thread_num,
212  int lev,
213  int depos_lev);
214 
215  virtual void DepositCurrent(WarpXParIter& pti,
216  RealVector& wp,
217  RealVector& uxp,
218  RealVector& uyp,
219  RealVector& uzp,
220  const int * const ion_lev,
221  amrex::MultiFab* jx,
222  amrex::MultiFab* jy,
223  amrex::MultiFab* jz,
224  const long offset,
225  const long np_to_depose,
226  int thread_num,
227  int lev,
228  int depos_lev,
229  amrex::Real dt);
230 
231  // If particles start outside of the domain, ContinuousInjection
232  // makes sure that they are initialized when they enter the domain, and
233  // NOT before. Virtual function, overriden by derived classes.
234  // Current status:
235  // PhysicalParticleContainer: implemented.
236  // LaserParticleContainer: implemented.
237  // RigidInjectedParticleContainer: not implemented.
238  virtual void ContinuousInjection(const amrex::RealBox& /*injection_box*/) {}
239  // Update optional sub-class-specific injection location.
240  virtual void UpdateContinuousInjectionPosition(amrex::Real /*dt*/) {}
241 
246  amrex::Real sumParticleCharge(bool local = false);
247 
248  std::array<amrex::Real, 3> meanParticleVelocity(bool local = false);
249 
250  amrex::Real maxParticleVelocity(bool local = false);
251 
252  void AddNParticles (int lev,
253  int n, const amrex::ParticleReal* x, const amrex::ParticleReal* y, const amrex::ParticleReal* z,
254  const amrex::ParticleReal* vx, const amrex::ParticleReal* vy, const amrex::ParticleReal* vz,
255  int nattr, const amrex::ParticleReal* attr, int uniqueparticles, amrex::Long id=-1);
256 
257  virtual void ReadHeader (std::istream& is);
258 
259  virtual void WriteHeader (std::ostream& os) const;
260 
261  virtual void ConvertUnits (ConvertDirection /*convert_dir*/){}
262 
263  static void ReadParameters ();
264 
265  static void BackwardCompatibility ();
266 
272  void ApplyBoundaryConditions (ParticleBC boundary_conditions);
273 
274  bool do_splitting = false;
275  bool initialize_self_fields = false;
276  amrex::Real self_fields_required_precision = 1.e-11;
277 
278  // split along diagonals (0) or axes (1)
279  int split_type = 0;
280 
281  using amrex::ParticleContainer<0, 0, PIdx::nattribs>::AddRealComp;
282  using amrex::ParticleContainer<0, 0, PIdx::nattribs>::AddIntComp;
283 
284  void AddRealComp (const std::string& name, bool comm=true)
285  {
286  particle_comps[name] = NumRealComps();
287  particle_runtime_comps[name] = NumRealComps() - PIdx::nattribs;
288  AddRealComp(comm);
289  }
290 
291  void AddIntComp (const std::string& name, bool comm=true)
292  {
293  particle_icomps[name] = NumIntComps();
294  particle_runtime_icomps[name] = NumIntComps() - 0;
295  AddIntComp(comm);
296  }
297 
298  int doBackTransformedDiagnostics () const { return do_back_transformed_diagnostics; }
299 
300  std::map<std::string, int> getParticleComps () const noexcept { return particle_comps;}
301  std::map<std::string, int> getParticleiComps () const noexcept { return particle_icomps;}
302  std::map<std::string, int> getParticleRuntimeComps () const noexcept { return particle_runtime_comps;}
303  std::map<std::string, int> getParticleRuntimeiComps () const noexcept { return particle_runtime_icomps;}
304 
305  //amrex::Real getCharge () {return charge;}
306  amrex::ParticleReal getCharge () const {return charge;}
307  //amrex::Real getMass () {return mass;}
308  amrex::ParticleReal getMass () const {return mass;}
309 
310  int DoFieldIonization() const { return do_field_ionization; }
311  int DoQED() const {
312 #ifdef WARPX_QED
313  return m_do_qed;
314 #else
315  return false;
316 #endif
317  }
318  //Species for which QED effects are relevant should override these methods
319  virtual bool has_quantum_sync() const {return false;}
320  virtual bool has_breit_wheeler() const {return false;}
321 
322  // build filter functors
323  bool m_do_random_filter = false;
324  bool m_do_uniform_filter = false;
325  bool m_do_parser_filter = false;
326  amrex::Real m_random_fraction = 1.0;
327  int m_uniform_stride = 1;
328  std::unique_ptr<ParserWrapper<7>> m_particle_filter_parser;
329 
330  /* \brief This function tests if the current species
331  * is of a given PhysicalSpecies (specified as a template parameter).
332  * @tparam PhysSpec the PhysicalSpecies to test against
333  * @return the result of the test
334  */
335  template<PhysicalSpecies PhysSpec>
336  bool AmIA () const noexcept {return (physical_species == PhysSpec);}
337 
338  amrex::Array<amrex::Real,3> get_v_galilean () {return m_v_galilean;}
339 
346  virtual void resample (const int /*timestep*/) {}
347 
348 protected:
349  amrex::Array<amrex::Real,3> m_v_galilean = {{0}};
350  std::map<std::string, int> particle_comps;
351  std::map<std::string, int> particle_icomps;
352  std::map<std::string, int> particle_runtime_comps;
353  std::map<std::string, int> particle_runtime_icomps;
354 
356 
357  amrex::Real charge;
358  amrex::Real mass;
360 
362  bool m_deposit_on_main_grid = false;
363 
365  bool m_gather_from_main_grid = false;
366 
367  int do_not_push = 0;
368  int do_not_deposit = 0;
369  int do_not_gather = 0;
370 
371  // Whether to allow particles outside of the simulation domain to be
372  // initialized when they enter the domain.
373  // This is currently required because continuous injection does not
374  // support all features allowed by direct injection.
375  int do_continuous_injection = 0;
376 
377  int do_field_ionization = 0;
381  int ionization_initial_level = 0;
382  amrex::Gpu::DeviceVector<amrex::Real> ionization_energies;
383  amrex::Gpu::DeviceVector<amrex::Real> adk_power;
384  amrex::Gpu::DeviceVector<amrex::Real> adk_prefactor;
385  amrex::Gpu::DeviceVector<amrex::Real> adk_exp_prefactor;
386  std::string physical_element;
387 
388  int do_resampling = 0;
389 
390  int do_back_transformed_diagnostics = 1;
391 
392 #ifdef WARPX_QED
393  bool m_do_qed = false;
394 
395  //Species can receive a shared pointer to a QED engine (species for
396  //which this is relevant should override these functions)
397  virtual void
398  set_breit_wheeler_engine_ptr(std::shared_ptr<BreitWheelerEngine>){};
399  virtual void
400  set_quantum_sync_engine_ptr(std::shared_ptr<QuantumSynchrotronEngine>){};
401 
402  int m_qed_breit_wheeler_ele_product;
408 
409 #endif
410  amrex::Vector<amrex::FArrayBox> local_rho;
411  amrex::Vector<amrex::FArrayBox> local_jx;
412  amrex::Vector<amrex::FArrayBox> local_jy;
413  amrex::Vector<amrex::FArrayBox> local_jz;
414 
415 public:
416  using PairIndex = std::pair<int, int>;
417  using TmpParticleTile = std::array<amrex::Gpu::DeviceVector<amrex::ParticleReal>,
419  using TmpParticles = amrex::Vector<std::map<PairIndex, TmpParticleTile> >;
420 
421 protected:
423 
430  void defineAllParticleTiles () noexcept;
431 
432 private:
433  virtual void particlePostLocate(ParticleType& p, const amrex::ParticleLocData& pld,
434  const int lev) override;
435 
436 };
437 
438 #endif
const RealVector & GetAttribs(int comp) const
Definition: WarpXParticleContainer.H:94
virtual void UpdateContinuousInjectionPosition(amrex::Real)
Definition: WarpXParticleContainer.H:240
ParticleBC
Definition: WarpXParticleContainer.H:29
Definition: WarpXParticleContainer.H:33
DtType
Definition: WarpXDtType.H:10
std::array< amrex::Gpu::DeviceVector< amrex::ParticleReal >, TmpIdx::nattribs > TmpParticleTile
Definition: WarpXParticleContainer.H:418
Definition: WarpXParticleContainer.H:36
virtual void GetParticleSlice(const int, const amrex::Real, const amrex::Real, const amrex::Real, const amrex::Real, const amrex::Real, DiagnosticParticles &)
Definition: WarpXParticleContainer.H:173
virtual void set_breit_wheeler_engine_ptr(std::shared_ptr< BreitWheelerEngine >)
Definition: WarpXParticleContainer.H:398
std::unique_ptr< ParserWrapper< 7 > > m_particle_filter_parser
Definition: WarpXParticleContainer.H:328
amrex::Vector< amrex::FArrayBox > local_rho
Definition: WarpXParticleContainer.H:410
amrex::Gpu::DeviceVector< amrex::Real > adk_power
Definition: WarpXParticleContainer.H:383
int m_qed_breit_wheeler_pos_product
Definition: WarpXParticleContainer.H:404
void AddRealComp(const std::string &name, bool comm=true)
Definition: WarpXParticleContainer.H:284
Definition: WarpXParticleContainer.H:45
std::map< std::string, int > getParticleRuntimeiComps() const noexcept
Definition: WarpXParticleContainer.H:303
RealVector & GetAttribs(int comp)
Definition: WarpXParticleContainer.H:98
std::map< std::string, int > particle_icomps
Definition: WarpXParticleContainer.H:351
IntVector & GetiAttribs(int comp)
Definition: WarpXParticleContainer.H:102
std::map< std::string, int > particle_runtime_icomps
Definition: WarpXParticleContainer.H:353
def x
Definition: read_lab_particles.py:25
int DoFieldIonization() const
Definition: WarpXParticleContainer.H:310
PhysicalSpecies
Definition: SpeciesPhysicalProperties.H:19
const std::array< RealVector, PIdx::nattribs > & GetAttribs() const
Definition: WarpXParticleContainer.H:86
tuple w
Definition: yt3d_mpi.py:43
Definition: WarpXParticleContainer.H:49
Definition: MultiParticleContainer.H:53
virtual void set_quantum_sync_engine_ptr(std::shared_ptr< QuantumSynchrotronEngine >)
Definition: WarpXParticleContainer.H:400
bool AmIA() const noexcept
Definition: WarpXParticleContainer.H:336
def uz
Definition: read_lab_particles.py:29
int DoQED() const
Definition: WarpXParticleContainer.H:311
virtual void ContinuousInjection(const amrex::RealBox &)
Definition: WarpXParticleContainer.H:238
virtual void ConvertUnits(ConvertDirection)
Definition: WarpXParticleContainer.H:261
amrex::ParticleReal getCharge() const
Definition: WarpXParticleContainer.H:306
amrex::Gpu::DeviceVector< amrex::Real > adk_prefactor
Definition: WarpXParticleContainer.H:384
def z
Definition: read_lab_particles.py:26
amrex::ParticleReal getMass() const
Definition: WarpXParticleContainer.H:308
Definition: WarpXParticleContainer.H:41
PhysicalSpecies physical_species
Definition: WarpXParticleContainer.H:359
std::map< std::string, int > getParticleComps() const noexcept
Definition: WarpXParticleContainer.H:300
amrex::Vector< amrex::FArrayBox > local_jz
Definition: WarpXParticleContainer.H:413
amrex::Vector< std::map< std::pair< int, int >, DiagnosticParticleData > > DiagnosticParticles
Definition: WarpXParticleContainer.H:147
virtual ~WarpXParticleContainer()
Definition: WarpXParticleContainer.H:150
amrex::StructOfArrays< DiagIdx::nattribs, 0 > DiagnosticParticleData
Definition: WarpXParticleContainer.H:142
int doBackTransformedDiagnostics() const
Definition: WarpXParticleContainer.H:298
std::map< std::string, int > particle_comps
Definition: WarpXParticleContainer.H:350
amrex::Real charge
Definition: WarpXParticleContainer.H:357
std::string ionization_product_name
Definition: WarpXParticleContainer.H:379
amrex::Gpu::DeviceVector< amrex::Real > ionization_energies
Definition: WarpXParticleContainer.H:382
TmpParticles tmp_particle_data
Definition: WarpXParticleContainer.H:422
int n
Definition: run_libensemble_on_warpx.py:68
void AddIntComp(const std::string &name, bool comm=true)
Definition: WarpXParticleContainer.H:291
int species_id
Definition: WarpXParticleContainer.H:355
amrex::Gpu::DeviceVector< amrex::Real > adk_exp_prefactor
Definition: WarpXParticleContainer.H:385
Definition: WarpXParticleContainer.H:37
Definition: WarpXParticleContainer.H:58
virtual bool has_quantum_sync() const
Definition: WarpXParticleContainer.H:319
Definition: WarpXParticleContainer.H:37
amrex::Array< amrex::Real, 3 > get_v_galilean()
Definition: WarpXParticleContainer.H:338
amrex::Vector< std::map< PairIndex, TmpParticleTile > > TmpParticles
Definition: WarpXParticleContainer.H:419
Definition: WarpXParticleContainer.H:63
std::string physical_element
Definition: WarpXParticleContainer.H:386
std::map< std::string, int > getParticleRuntimeComps() const noexcept
Definition: WarpXParticleContainer.H:302
int ionization_product
Definition: WarpXParticleContainer.H:378
name
Definition: run_automated.py:204
ConvertDirection
Definition: WarpXParticleContainer.H:31
std::map< std::string, int > particle_runtime_comps
Definition: WarpXParticleContainer.H:352
Definition: WarpXParticleContainer.H:37
std::string m_qed_quantum_sync_phot_product_name
Definition: WarpXParticleContainer.H:407
virtual void resample(const int)
Virtual method to resample the species. Overriden by PhysicalParticleContainer only. Empty body is here because making the method purely virtual would mean that we need to override the method for every derived class. Note that in practice this function is never called because resample() is only called for PhysicalParticleContainers.
Definition: WarpXParticleContainer.H:346
virtual bool has_breit_wheeler() const
Definition: WarpXParticleContainer.H:320
Definition: WarpXParticleContainer.H:39
std::string m_qed_breit_wheeler_ele_product_name
Definition: WarpXParticleContainer.H:403
const std::map< std::string, int > to_index
Definition: WarpXParticleContainer.H:65
std::pair< int, int > PairIndex
Definition: WarpXParticleContainer.H:416
amrex::Real mass
Definition: WarpXParticleContainer.H:358
amrex::Vector< amrex::FArrayBox > local_jx
Definition: WarpXParticleContainer.H:411
Definition: WarpXParticleContainer.H:59
std::string m_qed_breit_wheeler_pos_product_name
Definition: WarpXParticleContainer.H:405
int ion_atomic_number
Definition: WarpXParticleContainer.H:380
def ux
Definition: read_lab_particles.py:28
std::map< std::string, int > getParticleiComps() const noexcept
Definition: WarpXParticleContainer.H:301
Definition: WarpXParticleContainer.H:76
std::array< RealVector, PIdx::nattribs > & GetAttribs()
Definition: WarpXParticleContainer.H:90
Definition: PML.H:52
Definition: WarpXParticleContainer.H:54
WarpXParticleContainer::ParticleType ParticleType
Definition: CollisionType.cpp:46
int m_qed_quantum_sync_phot_product
Definition: WarpXParticleContainer.H:406
friend MultiParticleContainer
Definition: WarpXParticleContainer.H:135
Definition: WarpXParticleContainer.H:131
amrex::Vector< amrex::FArrayBox > local_jy
Definition: WarpXParticleContainer.H:412
Definition: WarpXOpenPMD.H:83