WarpX
ParticleBoundaries_K.H
Go to the documentation of this file.
1 /* Copyright 2021 David Grote, Remi Lehe, Revathi Jambunathan
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 #ifndef WARPX_PARTICLEBOUNDARIES_K_H_
8 #define WARPX_PARTICLEBOUNDARIES_K_H_
9 
10 #include "ParticleBoundaries.H"
12 
13 #include <AMReX_AmrCore.H>
14 
16  using namespace amrex::literals;
17  /* \brief Applies the boundary condition on a specific axis
18  * This is called by apply_boundaries.
19  */
21  void
22  apply_boundary (amrex::ParticleReal& x, amrex::Real xmin, amrex::Real xmax,
23  bool& change_sign_ux, bool& rethermalize_x, bool& particle_lost,
25  amrex::Real refl_probability_xmin, amrex::Real refl_probability_xmax,
26  amrex::RandomEngine const& engine )
27  {
28  if (x < xmin) {
29  if (xmin_bc == ParticleBoundaryType::Open) {
30  particle_lost = true;
31  }
32  else if (xmin_bc == ParticleBoundaryType::Absorbing) {
33  if (refl_probability_xmin == 0 || amrex::Random(engine) > refl_probability_xmin) {
34  particle_lost = true;
35  }
36  else
37  {
38  x = 2*xmin - x;
39  change_sign_ux = true;
40  }
41  }
42  else if (xmin_bc == ParticleBoundaryType::Reflecting) {
43  x = 2*xmin - x;
44  change_sign_ux = true;
45  }
46  else if (xmin_bc == ParticleBoundaryType::Thermal) {
47  x = 2*xmin - x;
48  rethermalize_x = true;
49  }
50  }
51  else if (x > xmax) {
52  if (xmax_bc == ParticleBoundaryType::Open) {
53  particle_lost = true;
54  }
55  else if (xmax_bc == ParticleBoundaryType::Absorbing) {
56  if (refl_probability_xmax == 0 || amrex::Random(engine) > refl_probability_xmax) {
57  particle_lost = true;
58  }
59  else
60  {
61  x = 2*xmax - x;
62  change_sign_ux = true;
63  }
64  }
65  else if (xmax_bc == ParticleBoundaryType::Reflecting) {
66  x = 2*xmax - x;
67  change_sign_ux = true;
68  }
69  else if (xmax_bc == ParticleBoundaryType::Thermal) {
70  x = 2*xmax - x;
71  rethermalize_x = true;
72  }
73  }
74  }
75 
76  /* \brief Thermalize particles that have been identified to cross the boundary.
77  * The normal component samples from a half-Maxwellian,
78  * and the two tangential components will sample from full Maxwellian disbutions
79  * with thermal velocity uth
80  */
82  void thermalize_boundary_particle (amrex::ParticleReal& u_norm, amrex::ParticleReal& u_tang1,
83  amrex::ParticleReal& u_tang2, amrex::Real uth,
84  amrex::RandomEngine const& engine)
85  {
86  u_tang1 = (uth > 0._rt) ? PhysConst::c * amrex::RandomNormal(0._rt, uth, engine) : 0._rt;
87  u_tang2 = (uth > 0._rt) ? PhysConst::c * amrex::RandomNormal(0._rt, uth, engine) : 0._rt;
88  u_norm = (uth > 0._rt) ? std::copysign(1._prt, -u_norm) * PhysConst::c * generateGaussianFluxDist(0._rt, uth, engine) : 0._rt;
89  }
90 
91 
92  /* \brief Applies absorbing, reflecting or thermal boundary condition to the input particles, along all axis.
93  * For reflecting boundaries, the position of the particle is changed appropriately and
94  * the sign of the velocity is changed (depending on the reflect_all_velocities flag).
95  * For absorbing, a flag is set whether the particle has been lost (it is up to the calling
96  * code to take appropriate action to remove any lost particles). Absorbing boundaries can
97  * be given a reflection coefficient for stochastic reflection of particles, this
98  * coefficient is zero by default.
99  * For thermal boundaries, the particle is first reflected and the position of the particle
100  * is changed appropriately.
101  * Note that periodic boundaries are handled in AMReX code.
102  *
103  * \param x, xmin, xmax: particle x position, location of x boundary
104  * \param y, ymin, ymax: particle y position, location of y boundary (3D only)
105  * \param z, zmin, zmax: particle z position, location of z boundary
106  * \param ux, uy, uz: particle momenta
107  * \param particle_lost: output, flags whether the particle was lost
108  * \param boundaries: object with boundary condition settings
109  */
111  void
113 #ifndef WARPX_DIM_1D_Z
114  amrex::ParticleReal& x, amrex::Real xmin, amrex::Real xmax,
115 #endif
116 #if (defined WARPX_DIM_3D) || (defined WARPX_DIM_RZ)
117  amrex::ParticleReal& y,
118 #endif
119 #if (defined WARPX_DIM_3D)
120  amrex::Real ymin, amrex::Real ymax,
121 #endif
122  amrex::ParticleReal& z, amrex::Real zmin, amrex::Real zmax,
123  amrex::ParticleReal& ux, amrex::ParticleReal& uy, amrex::ParticleReal& uz,
124  bool& particle_lost,
126  amrex::RandomEngine const& engine)
127  {
128  bool change_sign_ux = false;
129  bool change_sign_uy = false;
130  bool change_sign_uz = false;
131 
132 #ifndef WARPX_DIM_1D_Z
133  bool rethermalize_x = false; // stores if particle crosses x boundary and needs to be thermalized
134  apply_boundary(x, xmin, xmax, change_sign_ux, rethermalize_x, particle_lost,
135  boundaries.xmin_bc, boundaries.xmax_bc,
136  boundaries.reflection_model_xlo(-ux), boundaries.reflection_model_xhi(ux),
137  engine);
138  if (rethermalize_x) {
139  thermalize_boundary_particle(ux, uy, uz, boundaries.m_uth, engine);
140  }
141 #endif
142 #ifdef WARPX_DIM_3D
143  bool rethermalize_y = false; // stores if particle crosses y boundary and needs to be thermalized
144  apply_boundary(y, ymin, ymax, change_sign_uy, rethermalize_y, particle_lost,
145  boundaries.ymin_bc, boundaries.ymax_bc,
146  boundaries.reflection_model_ylo(-uy), boundaries.reflection_model_yhi(uy),
147  engine);
148  if (rethermalize_y) {
149  thermalize_boundary_particle(uy, uz, ux, boundaries.m_uth, engine);
150  }
151 #endif
152  bool rethermalize_z = false; // stores if particle crosses z boundary and needs to be thermalized
153  apply_boundary(z, zmin, zmax, change_sign_uz, rethermalize_z, particle_lost,
154  boundaries.zmin_bc, boundaries.zmax_bc,
155  boundaries.reflection_model_zlo(-uz), boundaries.reflection_model_zhi(uz),
156  engine);
157  if (rethermalize_z) {
158  thermalize_boundary_particle(uz, ux, uy, boundaries.m_uth, engine);
159  }
160 
161  if (boundaries.reflect_all_velocities && (change_sign_ux | change_sign_uy | change_sign_uz)) {
162  change_sign_ux = true;
163  change_sign_uy = true;
164  change_sign_uz = true;
165  }
166 #ifdef WARPX_DIM_RZ
167  // Note that the reflection of the position does "r = 2*rmax - r", but this is only approximate.
168  // The exact calculation requires the position at the start of the step.
169  if (change_sign_ux && change_sign_uy) {
170  ux = -ux;
171  uy = -uy;
172  } else if (change_sign_ux) {
173  // Reflect only ur
174  // Note that y is theta
175  amrex::Real ur = ux*std::cos(y) + uy*std::sin(y);
176  const amrex::Real ut = -ux*std::sin(y) + uy*std::cos(y);
177  ur = -ur;
178  ux = ur*std::cos(y) - ut*std::sin(y);
179  uy = ur*std::sin(y) + ut*std::cos(y);
180  }
181 #else
182  if (change_sign_ux) { ux = -ux; }
183  if (change_sign_uy) { uy = -uy; }
184 #endif
185  if (change_sign_uz) { uz = -uz; }
186  }
187 
188 }
189 #endif //WARPX_PARTICLEBOUNDARIES_K_H_
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
ParticleBoundaryType
Definition: WarpXAlgorithmSelection.H:173
@ Absorbing
particles crossing domain boundary are removed
@ Reflecting
particles are reflected
@ Open
particles cross domain boundary leave with damped j
Definition: ParticleBoundaries_K.H:15
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void thermalize_boundary_particle(amrex::ParticleReal &u_norm, amrex::ParticleReal &u_tang1, amrex::ParticleReal &u_tang2, amrex::Real uth, amrex::RandomEngine const &engine)
Definition: ParticleBoundaries_K.H:82
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void apply_boundary(amrex::ParticleReal &x, amrex::Real xmin, amrex::Real xmax, bool &change_sign_ux, bool &rethermalize_x, bool &particle_lost, ParticleBoundaryType xmin_bc, ParticleBoundaryType xmax_bc, amrex::Real refl_probability_xmin, amrex::Real refl_probability_xmax, amrex::RandomEngine const &engine)
Definition: ParticleBoundaries_K.H:22
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void apply_boundaries(amrex::ParticleReal &x, amrex::Real xmin, amrex::Real xmax, amrex::ParticleReal &y, amrex::ParticleReal &z, amrex::Real zmin, amrex::Real zmax, amrex::ParticleReal &ux, amrex::ParticleReal &uy, amrex::ParticleReal &uz, bool &particle_lost, ParticleBoundaries::ParticleBoundariesData const &boundaries, amrex::RandomEngine const &engine)
Definition: ParticleBoundaries_K.H:112
static constexpr auto c
vacuum speed of light [m/s]
Definition: constant.H:44
Real Random()
Real RandomNormal(Real mean, Real stddev)
xmin
Definition: stencil.py:424
xmax
Definition: stencil.py:425
Definition: ParticleBoundaries.H:51
bool reflect_all_velocities
Definition: ParticleBoundaries.H:68
amrex::ParserExecutor< 1 > reflection_model_ylo
Definition: ParticleBoundaries.H:63
ParticleBoundaryType ymax_bc
Definition: ParticleBoundaries.H:56
amrex::Real m_uth
Definition: ParticleBoundaries.H:59
ParticleBoundaryType xmin_bc
Definition: ParticleBoundaries.H:53
amrex::ParserExecutor< 1 > reflection_model_zhi
Definition: ParticleBoundaries.H:66
ParticleBoundaryType xmax_bc
Definition: ParticleBoundaries.H:54
amrex::ParserExecutor< 1 > reflection_model_xhi
Definition: ParticleBoundaries.H:62
ParticleBoundaryType zmax_bc
Definition: ParticleBoundaries.H:58
amrex::ParserExecutor< 1 > reflection_model_zlo
Definition: ParticleBoundaries.H:65
ParticleBoundaryType ymin_bc
Definition: ParticleBoundaries.H:55
amrex::ParserExecutor< 1 > reflection_model_xlo
Definition: ParticleBoundaries.H:61
ParticleBoundaryType zmin_bc
Definition: ParticleBoundaries.H:57
amrex::ParserExecutor< 1 > reflection_model_yhi
Definition: ParticleBoundaries.H:64