WarpX
ImpactIonization.H
Go to the documentation of this file.
1 /* Copyright 2021 Modern Electron
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 #ifndef WARPX_PARTICLES_COLLISION_IMPACT_IONIZATION_H_
8 #define WARPX_PARTICLES_COLLISION_IMPACT_IONIZATION_H_
9 
11 
12 #include "Utils/ParticleUtils.H"
13 #include "Utils/WarpXConst.H"
14 
15 #include <AMReX_Random.H>
16 #include <AMReX_REAL.H>
17 
27 {
28 public:
29 
51  ScatteringProcess const& mcc_process,
52  double const mass,
53  amrex::ParticleReal const total_collision_prob,
54  amrex::ParticleReal const nu_max,
55  amrex::ParserExecutor<4> const& n_a_func,
56  amrex::Real t
57  ) : m_mcc_process(mcc_process.executor()), m_mass(mass),
58  m_total_collision_prob(total_collision_prob),
59  m_nu_max(nu_max), m_n_a_func(n_a_func), m_t(t) { }
60 
70  template <typename PData>
73  const PData& ptd, int const i, amrex::RandomEngine const& engine
74  ) const noexcept
75  {
76  using namespace amrex;
77  using std::sqrt;
78 
79  // determine if this particle should collide
80  if (Random(engine) > m_total_collision_prob) { return false; }
81 
82  // get references to the particle to get its position
83  const auto& p = ptd.getSuperParticle(i);
84  ParticleReal x, y, z;
85  double E_coll;
86  get_particle_position(p, x, y, z);
87 
88  // calculate neutral density at particle location
89  const ParticleReal n_a = m_n_a_func(x, y, z, m_t);
90 
91  // get the particle velocity
92  const ParticleReal ux = ptd.m_rdata[PIdx::ux][i];
93  const ParticleReal uy = ptd.m_rdata[PIdx::uy][i];
94  const ParticleReal uz = ptd.m_rdata[PIdx::uz][i];
95 
96  // calculate kinetic energy
97  const ParticleReal u_coll2 = ux*ux + uy*uy + uz*uz;
98  ParticleUtils::getEnergy(u_coll2, m_mass, E_coll);
99 
100  // get collision cross-section
101  const ParticleReal sigma_E = m_mcc_process.getCrossSection(static_cast<amrex::ParticleReal>(E_coll));
102 
103  // calculate normalized collision frequency
104  const ParticleReal nu_i = n_a * sigma_E * sqrt(u_coll2) / m_nu_max;
105 
106  // check if this collision should be performed
107  return (Random(engine) <= nu_i);
108  }
109 
110 private:
112  double m_mass;
113  amrex::ParticleReal m_total_collision_prob = 0;
114  amrex::ParticleReal m_nu_max;
116  amrex::Real m_t;
117 };
118 
119 
124 {
125 public:
126 
149  amrex::ParticleReal energy_cost, double mass1, amrex::ParticleReal sqrt_kb_m,
150  amrex::ParserExecutor<4> const& T_a_func, amrex::Real t
151  ) : m_energy_cost(energy_cost), m_mass1(mass1),
152  m_sqrt_kb_m(sqrt_kb_m), m_T_a_func(T_a_func), m_t(t) { }
153 
168  template <typename DstData, typename SrcData>
170  void operator() (DstData& dst1, DstData& dst2, SrcData& src,
171  int const i_src, int const i_dst1, int const i_dst2,
172  amrex::RandomEngine const& engine) const noexcept
173  {
174  using namespace amrex;
175  using std::sqrt;
176 
177  // get references to the particle to get its position
178  const auto& p = src.getSuperParticle(i_src);
179  ParticleReal x, y, z;
180  double E_coll;
181  get_particle_position(p, x, y, z);
182 
183  // calculate standard deviation in neutral velocity distribution using
184  // the local temperature
185  const ParticleReal ion_vel_std = m_sqrt_kb_m * std::sqrt(m_T_a_func(x, y, z, m_t));
186 
187  // get references to the original particle's velocity
188  auto& ux = src.m_rdata[PIdx::ux][i_src];
189  auto& uy = src.m_rdata[PIdx::uy][i_src];
190  auto& uz = src.m_rdata[PIdx::uz][i_src];
191 
192  // get references to the new particles' velocities
193  auto& e_ux = dst1.m_rdata[PIdx::ux][i_dst1];
194  auto& e_uy = dst1.m_rdata[PIdx::uy][i_dst1];
195  auto& e_uz = dst1.m_rdata[PIdx::uz][i_dst1];
196  auto& i_ux = dst2.m_rdata[PIdx::ux][i_dst2];
197  auto& i_uy = dst2.m_rdata[PIdx::uy][i_dst2];
198  auto& i_uz = dst2.m_rdata[PIdx::uz][i_dst2];
199 
200  // calculate kinetic energy
201  const ParticleReal u_coll2 = ux*ux + uy*uy + uz*uz;
202  ParticleUtils::getEnergy(u_coll2, m_mass1, E_coll);
203 
204  // each electron gets half the energy (could change this later)
205  const auto E_out = static_cast<amrex::ParticleReal>((E_coll - m_energy_cost) / 2.0_prt * PhysConst::q_e);
206 
207  // precalculate often used value
208  constexpr auto c2 = PhysConst::c * PhysConst::c;
209  const auto mc2 = m_mass1*c2;
210 
211  const amrex::ParticleReal up = sqrt(E_out * (E_out + 2.0_prt*mc2) / c2) / m_mass1;
212 
213  // isotropically scatter electrons
214  ParticleUtils::RandomizeVelocity(ux, uy, uz, up, engine);
215  ParticleUtils::RandomizeVelocity(e_ux, e_uy, e_uz, up, engine);
216 
217  // get velocities for the ion from a Maxwellian distribution
218  i_ux = ion_vel_std * RandomNormal(0_prt, 1.0_prt, engine);
219  i_uy = ion_vel_std * RandomNormal(0_prt, 1.0_prt, engine);
220  i_uz = ion_vel_std * RandomNormal(0_prt, 1.0_prt, engine);
221  }
222 
223 private:
224  amrex::ParticleReal m_energy_cost;
225  double m_mass1;
226  amrex::ParticleReal m_sqrt_kb_m;
228  amrex::Real m_t;
229 };
230 #endif // WARPX_PARTICLES_COLLISION_IMPACT_IONIZATION_H_
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void get_particle_position(const WarpXParticleContainer::SuperParticleType &p, amrex::ParticleReal &x, amrex::ParticleReal &y, amrex::ParticleReal &z) noexcept
Extract the cartesian position coordinates of the particle p and store them in the variables x,...
Definition: GetAndSetPosition.H:28
Filter functor for impact ionization.
Definition: ImpactIonization.H:27
ImpactIonizationFilterFunc(ScatteringProcess const &mcc_process, double const mass, amrex::ParticleReal const total_collision_prob, amrex::ParticleReal const nu_max, amrex::ParserExecutor< 4 > const &n_a_func, amrex::Real t)
Constructor of the ImpactIonizationFilterFunc functor.
Definition: ImpactIonization.H:50
double m_mass
Definition: ImpactIonization.H:112
amrex::ParticleReal m_nu_max
Definition: ImpactIonization.H:114
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool operator()(const PData &ptd, int const i, amrex::RandomEngine const &engine) const noexcept
Functor call. This method determines if a given (electron) particle should undergo an ionization coll...
Definition: ImpactIonization.H:72
amrex::ParticleReal m_total_collision_prob
Definition: ImpactIonization.H:113
amrex::ParserExecutor< 4 > m_n_a_func
Definition: ImpactIonization.H:115
amrex::Real m_t
Definition: ImpactIonization.H:116
ScatteringProcess::Executor m_mcc_process
Definition: ImpactIonization.H:111
Transform functor for impact ionization.
Definition: ImpactIonization.H:124
ImpactIonizationTransformFunc(amrex::ParticleReal energy_cost, double mass1, amrex::ParticleReal sqrt_kb_m, amrex::ParserExecutor< 4 > const &T_a_func, amrex::Real t)
Constructor of the ImpactIonizationTransformFunc functor.
Definition: ImpactIonization.H:148
amrex::ParticleReal m_energy_cost
Definition: ImpactIonization.H:224
amrex::Real m_t
Definition: ImpactIonization.H:228
amrex::ParticleReal m_sqrt_kb_m
Definition: ImpactIonization.H:226
double m_mass1
Definition: ImpactIonization.H:225
amrex::ParserExecutor< 4 > m_T_a_func
Definition: ImpactIonization.H:227
Definition: ScatteringProcess.H:27
AMREX_GPU_HOST_DEVICE AMREX_INLINE void getEnergy(amrex::ParticleReal const u2, double const mass, double &energy)
Return (relativistic) particle energy given velocity and mass. Note the use of double since this calc...
Definition: ParticleUtils.H:46
AMREX_GPU_HOST_DEVICE AMREX_INLINE void RandomizeVelocity(amrex::ParticleReal &ux, amrex::ParticleReal &uy, amrex::ParticleReal &uz, const amrex::ParticleReal vp, amrex::RandomEngine const &engine)
Function to perform scattering of a particle that results in a random velocity vector with given magn...
Definition: ParticleUtils.H:162
static constexpr auto c
vacuum speed of light [m/s]
Definition: constant.H:44
static constexpr auto q_e
elementary charge [C]
Definition: constant.H:50
Real Random()
Real RandomNormal(Real mean, Real stddev)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
i
Definition: check_interp_points_and_weights.py:174
@ uz
Definition: NamedComponentParticleContainer.H:34
@ uy
Definition: NamedComponentParticleContainer.H:34
@ ux
Definition: NamedComponentParticleContainer.H:34
Definition: ScatteringProcess.H:71
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal getCrossSection(amrex::ParticleReal E_coll) const
Definition: ScatteringProcess.H:81