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 
8 #include <AMReX.H>
9 #include <AMReX_Array.H>
10 #include <AMReX_Extension.H>
11 #include <AMReX_GpuQualifiers.H>
12 #include <AMReX_Parser.H>
13 #include <AMReX_REAL.H>
14 
16 
21 {
23 
24  amrex::GpuArray<amrex::ParticleReal, 3> m_field_value;
25 
26  amrex::ParserExecutor<4> m_xfield_partparser;
27  amrex::ParserExecutor<4> m_yfield_partparser;
28  amrex::ParserExecutor<4> m_zfield_partparser;
30  amrex::Real m_time;
31 
33  amrex::Real m_gamma_boost;
34  amrex::Real m_uz_boost;
35  const amrex::Real* AMREX_RESTRICT m_repeated_plasma_lens_starts = nullptr;
36  const amrex::Real* AMREX_RESTRICT m_repeated_plasma_lens_lengths = nullptr;
37  const amrex::Real* AMREX_RESTRICT m_repeated_plasma_lens_strengths_E = nullptr;
38  const amrex::Real* AMREX_RESTRICT m_repeated_plasma_lens_strengths_B = nullptr;
41  amrex::Real m_dt;
42  const amrex::ParticleReal* AMREX_RESTRICT m_ux = nullptr;
43  const amrex::ParticleReal* AMREX_RESTRICT m_uy = nullptr;
44  const amrex::ParticleReal* AMREX_RESTRICT m_uz = nullptr;
45 
46  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
47  void operator () (long i,
48  amrex::ParticleReal& field_x,
49  amrex::ParticleReal& field_y,
50  amrex::ParticleReal& field_z) const noexcept
51  {
52  using namespace amrex::literals;
53  if (m_type == Constant)
54  {
55  field_x += m_field_value[0];
56  field_y += m_field_value[1];
57  field_z += m_field_value[2];
58  }
59  else if (m_type == Parser)
60  {
61  amrex::ParticleReal x, y, z;
62  m_get_position(i, x, y, z);
63  field_x += m_xfield_partparser(x, y, z, m_time);
64  field_y += m_yfield_partparser(x, y, z, m_time);
65  field_z += m_zfield_partparser(x, y, z, m_time);
66  }
67  else if (m_type == RepeatedPlasmaLens)
68  {
69  amrex::ParticleReal x, y, z;
70  m_get_position(i, x, y, z);
71 
72  const amrex::ParticleReal uxp = m_ux[i];
73  const amrex::ParticleReal uyp = m_uy[i];
74  const amrex::ParticleReal uzp = m_uz[i];
75 
76  constexpr amrex::Real inv_c2 = 1._rt/(PhysConst::c*PhysConst::c);
77  const amrex::ParticleReal gamma = std::sqrt(1._rt + (uxp*uxp + uyp*uyp + uzp*uzp)*inv_c2);
78  const amrex::ParticleReal vzp = uzp/gamma;
79 
80  amrex::ParticleReal zl = z;
81  amrex::ParticleReal zr = z + vzp*m_dt;
82 
83  if (m_gamma_boost > 1._rt) {
84  zl = m_gamma_boost*zl + m_uz_boost*m_time;
85  zr = m_gamma_boost*zr + m_uz_boost*m_time;
86  }
87 
88  // This assumes that zl > 0.
89  int i_lens = static_cast<int>(std::floor(zl/m_repeated_plasma_lens_period));
90  i_lens = i_lens % m_n_lenses;
91  amrex::Real const lens_start = m_repeated_plasma_lens_starts[i_lens] + i_lens*m_repeated_plasma_lens_period;
92  amrex::Real const lens_end = lens_start + m_repeated_plasma_lens_lengths[i_lens];
93 
94  // Calculate the residence correction
95  // frac will be 1 if the step is completely inside the lens, between 0 and 1
96  // when entering or leaving the lens, and otherwise 0.
97  // This assumes that vzp > 0.
98  amrex::Real fl = 0.;
99  if (zl >= lens_start && zl < lens_end) fl = 1.;
100  amrex::Real fr = 0.;
101  if (zr >= lens_start && zr < lens_end) fr = 1.;
102  amrex::Real frac = fl;
103  if (fl > fr) frac = (lens_end - zl)/(zr - zl);
104  if (fr > fl) frac = (zr - lens_start)/(zr - zl);
105 
106  if (m_lens_is_electric) {
107  amrex::Real Ex = x*frac*m_repeated_plasma_lens_strengths_E[i_lens];
108  amrex::Real Ey = y*frac*m_repeated_plasma_lens_strengths_E[i_lens];
109  if (m_gamma_boost > 1._rt) {
110  // Transform the fields to the boosted frame
111  const amrex::Real Bx = +y*frac*m_repeated_plasma_lens_strengths_B[i_lens];
112  const amrex::Real By = -x*frac*m_repeated_plasma_lens_strengths_B[i_lens];
113  const amrex::Real vz_boost = m_uz_boost/m_gamma_boost;
114  const amrex::Real Ex_boost = m_gamma_boost*(Ex - vz_boost*By);
115  const amrex::Real Ey_boost = m_gamma_boost*(Ey + vz_boost*Bx);
116  Ex = Ex_boost;
117  Ey = Ey_boost;
118  }
119  field_x += Ex;
120  field_y += Ey;
121  } else {
122  amrex::Real Bx = +y*frac*m_repeated_plasma_lens_strengths_B[i_lens];
123  amrex::Real By = -x*frac*m_repeated_plasma_lens_strengths_B[i_lens];
124  if (m_gamma_boost > 1._rt) {
125  // Transform the fields to the boosted frame
126  const amrex::Real Ex = x*frac*m_repeated_plasma_lens_strengths_E[i_lens];
127  const amrex::Real Ey = y*frac*m_repeated_plasma_lens_strengths_E[i_lens];
128  const amrex::Real vz_boost = m_uz_boost/m_gamma_boost;
129  const amrex::Real Bx_boost = m_gamma_boost*(Bx + vz_boost*Ey*inv_c2);
130  const amrex::Real By_boost = m_gamma_boost*(By - vz_boost*Ex*inv_c2);
131  Bx = Bx_boost;
132  By = By_boost;
133  }
134  field_x += Bx;
135  field_y += By;
136  }
137 
138  }
139  else
140  {
141  amrex::Abort("ExternalFieldInitType not known!!! \n");
142  }
143  }
144 };
145 
150 {
151  GetExternalEField () = default;
152 
153  GetExternalEField (const WarpXParIter& a_pti, int a_offset = 0) noexcept;
154 };
155 
160 {
161  GetExternalBField () = default;
162 
163  GetExternalBField (const WarpXParIter& a_pti, int a_offset = 0) noexcept;
164 };
165 
166 #endif
Definition: GetExternalFields.H:15
const amrex::ParticleReal *AMREX_RESTRICT m_ux
Definition: GetExternalFields.H:42
Definition: GetExternalFields.H:15
amrex::ParserExecutor< 4 > m_yfield_partparser
Definition: GetExternalFields.H:27
def x
Definition: read_lab_particles.py:25
Base class for functors that assign external field values (E or B) to particles.
Definition: GetExternalFields.H:20
amrex::ParserExecutor< 4 > m_zfield_partparser
Definition: GetExternalFields.H:28
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(long i, amrex::ParticleReal &field_x, amrex::ParticleReal &field_y, amrex::ParticleReal &field_z) const noexcept
Definition: GetExternalFields.H:47
const amrex::ParticleReal *AMREX_RESTRICT m_uz
Definition: GetExternalFields.H:44
ExternalFieldInitType
Definition: GetExternalFields.H:15
def z
Definition: read_lab_particles.py:26
Functor that can be used to assign the external B field to a particle inside a ParallelFor kernel...
Definition: GetExternalFields.H:159
int m_n_lenses
Definition: GetExternalFields.H:39
const amrex::Real *AMREX_RESTRICT m_repeated_plasma_lens_starts
Definition: GetExternalFields.H:35
int m_lens_is_electric
Definition: GetExternalFields.H:40
amrex::Real m_dt
Definition: GetExternalFields.H:41
amrex::Real m_gamma_boost
Definition: GetExternalFields.H:33
ExternalFieldInitType m_type
Definition: GetExternalFields.H:22
amrex::Real m_time
Definition: GetExternalFields.H:30
amrex::GpuArray< amrex::ParticleReal, 3 > m_field_value
Definition: GetExternalFields.H:24
i
Definition: check_interp_points_and_weights.py:171
const amrex::Real *AMREX_RESTRICT m_repeated_plasma_lens_strengths_B
Definition: GetExternalFields.H:38
const amrex::Real *AMREX_RESTRICT m_repeated_plasma_lens_lengths
Definition: GetExternalFields.H:36
amrex::Real m_repeated_plasma_lens_period
Definition: GetExternalFields.H:32
amrex::Real m_uz_boost
Definition: GetExternalFields.H:34
const amrex::ParticleReal *AMREX_RESTRICT m_uy
Definition: GetExternalFields.H:43
const amrex::Real *AMREX_RESTRICT m_repeated_plasma_lens_strengths_E
Definition: GetExternalFields.H:37
GetParticlePosition m_get_position
Definition: GetExternalFields.H:29
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel...
Definition: GetAndSetPosition.H:48
Definition: WarpXParticleContainer.H:58
Functor that can be used to assign the external E field to a particle inside a ParallelFor kernel...
Definition: GetExternalFields.H:149
amrex::ParserExecutor< 4 > m_xfield_partparser
Definition: GetExternalFields.H:26
Definition: GetExternalFields.H:15