WarpX
GetExternalFields.H
Go to the documentation of this file.
1 #ifndef WARPX_PARTICLES_GATHER_GETEXTERNALFIELDS_H_
2 #define WARPX_PARTICLES_GATHER_GETEXTERNALFIELDS_H_
3 
5 
7 #include "Utils/WarpXConst.H"
8 
9 #include <AMReX.H>
10 #include <AMReX_Array.H>
11 #include <AMReX_Extension.H>
12 #include <AMReX_GpuQualifiers.H>
13 #include <AMReX_Parser.H>
14 #include <AMReX_REAL.H>
15 
17 
22 {
23 
24  GetExternalEBField () = default;
25 
26  GetExternalEBField (const WarpXParIter& a_pti, int a_offset = 0) noexcept;
27 
30 
31  amrex::ParticleReal m_gamma_boost;
32  amrex::ParticleReal m_uz_boost;
33 
36 
43 
45  amrex::Real m_time;
46 
47  amrex::ParticleReal m_repeated_plasma_lens_period;
48  const amrex::ParticleReal* AMREX_RESTRICT m_repeated_plasma_lens_starts = nullptr;
49  const amrex::ParticleReal* AMREX_RESTRICT m_repeated_plasma_lens_lengths = nullptr;
50  const amrex::ParticleReal* AMREX_RESTRICT m_repeated_plasma_lens_strengths_E = nullptr;
51  const amrex::ParticleReal* AMREX_RESTRICT m_repeated_plasma_lens_strengths_B = nullptr;
53  amrex::Real m_dt;
54  const amrex::ParticleReal* AMREX_RESTRICT m_ux = nullptr;
55  const amrex::ParticleReal* AMREX_RESTRICT m_uy = nullptr;
56  const amrex::ParticleReal* AMREX_RESTRICT m_uz = nullptr;
57 
59  void operator () (long i,
60  amrex::ParticleReal& field_Ex,
61  amrex::ParticleReal& field_Ey,
62  amrex::ParticleReal& field_Ez,
63  amrex::ParticleReal& field_Bx,
64  amrex::ParticleReal& field_By,
65  amrex::ParticleReal& field_Bz) const noexcept
66  {
67  using namespace amrex::literals;
68 
69  if (m_Etype == None && m_Btype == None) return;
70 
71  amrex::ParticleReal Ex = 0._prt;
72  amrex::ParticleReal Ey = 0._prt;
73  amrex::ParticleReal Ez = 0._prt;
74  amrex::ParticleReal Bx = 0._prt;
75  amrex::ParticleReal By = 0._prt;
76  amrex::ParticleReal Bz = 0._prt;
77 
78  constexpr amrex::ParticleReal inv_c2 = 1._prt/(PhysConst::c*PhysConst::c);
79 
80  if (m_Etype == Constant)
81  {
82  Ex = m_Efield_value[0];
83  Ey = m_Efield_value[1];
84  Ez = m_Efield_value[2];
85  }
86  else if (m_Etype == ExternalFieldInitType::Parser)
87  {
88  amrex::ParticleReal x, y, z;
89  m_get_position(i, x, y, z);
90  amrex::Real lab_time = m_time;
91  if (m_gamma_boost > 1._prt) {
92  lab_time = m_gamma_boost*m_time + m_uz_boost*z*inv_c2;
93  z = m_gamma_boost*z + m_uz_boost*m_time;
94  }
95  Ex = m_Exfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
96  Ey = m_Eyfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
97  Ez = m_Ezfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
98  }
99 
100  if (m_Btype == Constant)
101  {
102  Bx = m_Bfield_value[0];
103  By = m_Bfield_value[1];
104  Bz = m_Bfield_value[2];
105  }
106  else if (m_Btype == ExternalFieldInitType::Parser)
107  {
108  amrex::ParticleReal x, y, z;
109  m_get_position(i, x, y, z);
110  amrex::Real lab_time = m_time;
111  if (m_gamma_boost > 1._prt) {
112  lab_time = m_gamma_boost*m_time + m_uz_boost*z*inv_c2;
113  z = m_gamma_boost*z + m_uz_boost*m_time;
114  }
115  Bx = m_Bxfield_partparser(x, y, z, lab_time);
116  By = m_Byfield_partparser(x, y, z, lab_time);
117  Bz = m_Bzfield_partparser(x, y, z, lab_time);
118  }
119 
120  if (m_Etype == RepeatedPlasmaLens ||
121  m_Btype == RepeatedPlasmaLens)
122  {
123  amrex::ParticleReal x, y, z;
124  m_get_position(i, x, y, z);
125 
126  const amrex::ParticleReal uxp = m_ux[i];
127  const amrex::ParticleReal uyp = m_uy[i];
128  const amrex::ParticleReal uzp = m_uz[i];
129 
130  const amrex::ParticleReal gamma = std::sqrt(1._prt + (uxp*uxp + uyp*uyp + uzp*uzp)*inv_c2);
131  const amrex::ParticleReal vzp = uzp/gamma;
132 
133  amrex::ParticleReal zl = z;
134  amrex::ParticleReal zr = z + vzp*m_dt;
135 
136  if (m_gamma_boost > 1._prt) {
137  zl = m_gamma_boost*zl + m_uz_boost*m_time;
138  zr = m_gamma_boost*zr + m_uz_boost*(m_time + m_dt);
139  }
140 
141  // This assumes that zl > 0.
142  int i_lens = static_cast<int>(std::floor(zl/m_repeated_plasma_lens_period));
143  i_lens = i_lens % m_n_lenses;
144  amrex::ParticleReal const lens_start = m_repeated_plasma_lens_starts[i_lens] + i_lens*m_repeated_plasma_lens_period;
145  amrex::ParticleReal const lens_end = lens_start + m_repeated_plasma_lens_lengths[i_lens];
146 
147  // Calculate the residence correction
148  // frac will be 1 if the step is completely inside the lens, between 0 and 1
149  // when entering or leaving the lens, and otherwise 0.
150  // This accounts for the case when particles step over the element without landing in it.
151  // This assumes that vzp > 0.
152  amrex::ParticleReal const zl_bounded = std::min(std::max(zl, lens_start), lens_end);
153  amrex::ParticleReal const zr_bounded = std::min(std::max(zr, lens_start), lens_end);
154  amrex::ParticleReal const frac = ((zr - zl) == 0._rt ? 1._rt : (zr_bounded - zl_bounded)/(zr - zl));
155 
156  // Note that "+=" is used since the fields may have been set above
157  // if a different E or Btype was specified.
158  Ex += x*frac*m_repeated_plasma_lens_strengths_E[i_lens];
159  Ey += y*frac*m_repeated_plasma_lens_strengths_E[i_lens];
160  Bx += +y*frac*m_repeated_plasma_lens_strengths_B[i_lens];
161  By += -x*frac*m_repeated_plasma_lens_strengths_B[i_lens];
162 
163  }
164 
165  if (m_gamma_boost > 1._prt) {
166  // Transform the fields to the boosted frame
167  const amrex::ParticleReal Ex_boost = m_gamma_boost*Ex - m_uz_boost*By;
168  const amrex::ParticleReal Ey_boost = m_gamma_boost*Ey + m_uz_boost*Bx;
169  const amrex::ParticleReal Bx_boost = m_gamma_boost*Bx + m_uz_boost*Ey*inv_c2;
170  const amrex::ParticleReal By_boost = m_gamma_boost*By - m_uz_boost*Ex*inv_c2;
171  Ex = Ex_boost;
172  Ey = Ey_boost;
173  Bx = Bx_boost;
174  By = By_boost;
175  }
176 
177  field_Ex += Ex;
178  field_Ey += Ey;
179  field_Ez += Ez;
180  field_Bx += Bx;
181  field_By += By;
182  field_Bz += Bz;
183 
184  }
185 };
186 
187 #endif
const amrex::ParticleReal *AMREX_RESTRICT m_uy
Definition: GetExternalFields.H:55
Definition: GetExternalFields.H:16
amrex::Real m_time
Definition: GetExternalFields.H:45
ExternalFieldInitType m_Btype
Definition: GetExternalFields.H:29
int gamma
Definition: Stencil.py:474
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(long i, amrex::ParticleReal &field_Ex, amrex::ParticleReal &field_Ey, amrex::ParticleReal &field_Ez, amrex::ParticleReal &field_Bx, amrex::ParticleReal &field_By, amrex::ParticleReal &field_Bz) const noexcept
Definition: GetExternalFields.H:59
Definition: GetExternalFields.H:16
amrex::ParticleReal m_repeated_plasma_lens_period
Definition: GetExternalFields.H:47
GetExternalEBField()=default
amrex::ParserExecutor< 4 > m_Byfield_partparser
Definition: GetExternalFields.H:41
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_lengths
Definition: GetExternalFields.H:49
amrex::ParserExecutor< 4 > m_Bzfield_partparser
Definition: GetExternalFields.H:42
def x
Definition: read_lab_particles.py:26
static constexpr auto c
vacuum speed of light [m/s]
Definition: constant.H:44
Definition: GetExternalFields.H:16
amrex::ParserExecutor< 4 > m_Bxfield_partparser
Definition: GetExternalFields.H:40
amrex::GpuArray< amrex::ParticleReal, 3 > m_Efield_value
Definition: GetExternalFields.H:34
amrex::ParserExecutor< 4 > m_Ezfield_partparser
Definition: GetExternalFields.H:39
amrex::ParserExecutor< 4 > m_Exfield_partparser
Definition: GetExternalFields.H:37
ExternalFieldInitType
Definition: GetExternalFields.H:16
amrex::GpuArray< amrex::ParticleReal, 3 > m_Bfield_value
Definition: GetExternalFields.H:35
def z
Definition: read_lab_particles.py:27
int m_n_lenses
Definition: GetExternalFields.H:52
#define AMREX_FORCE_INLINE
amrex::ParserExecutor< 4 > m_Eyfield_partparser
Definition: GetExternalFields.H:38
Functor class that assigns external field values (E and B) to particles.
Definition: GetExternalFields.H:21
#define AMREX_GPU_HOST_DEVICE
Definition: GetExternalFields.H:16
i
Definition: check_interp_points_and_weights.py:173
const amrex::ParticleReal *AMREX_RESTRICT m_ux
Definition: GetExternalFields.H:54
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_starts
Definition: GetExternalFields.H:48
GetParticlePosition m_get_position
Definition: GetExternalFields.H:44
ExternalFieldInitType m_Etype
Definition: GetExternalFields.H:28
amrex::ParticleReal m_gamma_boost
Definition: GetExternalFields.H:31
amrex::Real m_dt
Definition: GetExternalFields.H:53
const amrex::ParticleReal *AMREX_RESTRICT m_uz
Definition: GetExternalFields.H:56
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_strengths_E
Definition: GetExternalFields.H:50
amrex::ParticleReal m_uz_boost
Definition: GetExternalFields.H:32
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel...
Definition: GetAndSetPosition.H:52
Definition: WarpXParticleContainer.H:49
#define AMREX_RESTRICT
Definition: GetExternalFields.H:16
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_strengths_B
Definition: GetExternalFields.H:51