WarpX
Loading...
Searching...
No Matches
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
10
11#include <AMReX.H>
12#include <AMReX_Array.H>
13#include <AMReX_Extension.H>
14#include <AMReX_GpuQualifiers.H>
15#include <AMReX_Parser.H>
16#include <AMReX_REAL.H>
17
18
23{
25
26 GetExternalEBField () = default;
27
28 GetExternalEBField (const WarpXParIter& a_pti, long a_offset = 0) noexcept;
29
32
33 amrex::ParticleReal m_gamma_boost;
34 amrex::ParticleReal m_uz_boost;
35
36 amrex::ParserExecutor<4> m_Exfield_partparser;
37 amrex::ParserExecutor<4> m_Eyfield_partparser;
38 amrex::ParserExecutor<4> m_Ezfield_partparser;
39 amrex::ParserExecutor<4> m_Bxfield_partparser;
40 amrex::ParserExecutor<4> m_Byfield_partparser;
41 amrex::ParserExecutor<4> m_Bzfield_partparser;
42
45
47 const amrex::ParticleReal* AMREX_RESTRICT m_repeated_plasma_lens_starts = nullptr;
48 const amrex::ParticleReal* AMREX_RESTRICT m_repeated_plasma_lens_lengths = nullptr;
52 amrex::Real m_dt;
53 const amrex::ParticleReal* AMREX_RESTRICT m_ux = nullptr;
54 const amrex::ParticleReal* AMREX_RESTRICT m_uy = nullptr;
55 const amrex::ParticleReal* AMREX_RESTRICT m_uz = nullptr;
56
58
60 bool isNoOp () const { return (m_Etype == None && m_Btype == None && !d_lattice_element_finder.m_initialized); }
61
63 void operator () (long i,
64 amrex::ParticleReal& field_Ex,
65 amrex::ParticleReal& field_Ey,
66 amrex::ParticleReal& field_Ez,
67 amrex::ParticleReal& field_Bx,
68 amrex::ParticleReal& field_By,
69 amrex::ParticleReal& field_Bz) const noexcept
70 {
71 using namespace amrex::literals;
72
73 if (d_lattice_element_finder.m_initialized) {
74 d_lattice_element_finder(i, field_Ex, field_Ey, field_Ez,
75 field_Bx, field_By, field_Bz);
76 }
77
78 if (m_Etype == None && m_Btype == None) { return; }
79
80 amrex::ParticleReal Ex = 0._prt;
81 amrex::ParticleReal Ey = 0._prt;
82 amrex::ParticleReal Ez = 0._prt;
83 amrex::ParticleReal Bx = 0._prt;
84 amrex::ParticleReal By = 0._prt;
85 amrex::ParticleReal Bz = 0._prt;
86
87 constexpr amrex::ParticleReal inv_c2 = 1._prt/(PhysConst::c*PhysConst::c);
88
90 {
91 amrex::ParticleReal x, y, z;
92 m_get_position(i, x, y, z);
93 amrex::Real lab_time = m_time;
94 if (m_gamma_boost > 1._prt) {
95 lab_time = m_gamma_boost*m_time + m_uz_boost*z*inv_c2;
97 }
98 Ex = m_Exfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
99 Ey = m_Eyfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
100 Ez = m_Ezfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
101 }
102
104 {
105 amrex::ParticleReal x, y, z;
106 m_get_position(i, x, y, z);
107 amrex::Real lab_time = m_time;
108 if (m_gamma_boost > 1._prt) {
109 lab_time = m_gamma_boost*m_time + m_uz_boost*z*inv_c2;
111 }
112 Bx = m_Bxfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
113 By = m_Byfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
114 Bz = m_Bzfield_partparser((amrex::ParticleReal) x, (amrex::ParticleReal) y, (amrex::ParticleReal) z, lab_time);
115 }
116
119 {
120 amrex::ParticleReal x, y, z;
121 m_get_position(i, x, y, z);
122
123 const amrex::ParticleReal uxp = m_ux[i];
124 const amrex::ParticleReal uyp = m_uy[i];
125 const amrex::ParticleReal uzp = m_uz[i];
126
127 const amrex::ParticleReal gamma = std::sqrt(1._prt + (uxp*uxp + uyp*uyp + uzp*uzp)*inv_c2);
128 const amrex::ParticleReal vzp = uzp/gamma;
129
130 // the current slice in z between now and the next time step
131 amrex::ParticleReal zl = z;
132 amrex::ParticleReal zr = z + vzp*m_dt;
133
134 if (m_gamma_boost > 1._prt) {
136 zr = m_gamma_boost*zr + m_uz_boost*(m_time + m_dt);
137 }
138
139 // the plasma lens periods do not start before z=0
140 if (zl > 0) {
141 // find which is the next lens
142 const auto i_lens = static_cast<int>(std::floor(zl/m_repeated_plasma_lens_period));
143 if (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 }
166
167 if (m_gamma_boost > 1._prt) {
168 // Transform the fields to the boosted frame
169 const amrex::ParticleReal Ex_boost = m_gamma_boost*Ex - m_uz_boost*By;
170 const amrex::ParticleReal Ey_boost = m_gamma_boost*Ey + m_uz_boost*Bx;
171 const amrex::ParticleReal Bx_boost = m_gamma_boost*Bx + m_uz_boost*Ey*inv_c2;
172 const amrex::ParticleReal By_boost = m_gamma_boost*By - m_uz_boost*Ex*inv_c2;
173 Ex = Ex_boost;
174 Ey = Ey_boost;
175 Bx = Bx_boost;
176 By = By_boost;
177 }
178
179 field_Ex += Ex;
180 field_Ey += Ey;
181 field_Ez += Ez;
182 field_Bx += Bx;
183 field_By += By;
184 field_Bz += Bz;
185
186 }
187};
188
189#endif
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
Definition WarpXParticleContainer.H:117
static constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:44
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_lengths
Definition GetExternalFields.H:48
const amrex::ParticleReal *AMREX_RESTRICT m_ux
Definition GetExternalFields.H:53
amrex::ParserExecutor< 4 > m_Bzfield_partparser
Definition GetExternalFields.H:41
const amrex::ParticleReal *AMREX_RESTRICT m_uy
Definition GetExternalFields.H:54
amrex::Real m_time
Definition GetExternalFields.H:44
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_strengths_B
Definition GetExternalFields.H:50
amrex::Real m_dt
Definition GetExternalFields.H:52
GetExternalEBField()=default
amrex::ParticleReal m_uz_boost
Definition GetExternalFields.H:34
LatticeElementFinderDevice d_lattice_element_finder
Definition GetExternalFields.H:57
amrex::ParticleReal m_gamma_boost
Definition GetExternalFields.H:33
int m_n_lenses
Definition GetExternalFields.H:51
ExternalFieldInitType m_Etype
Definition GetExternalFields.H:30
GetParticlePosition< PIdx > m_get_position
Definition GetExternalFields.H:43
ExternalFieldInitType
Definition GetExternalFields.H:24
@ Parser
Definition GetExternalFields.H:24
@ Unknown
Definition GetExternalFields.H:24
@ None
Definition GetExternalFields.H:24
@ RepeatedPlasmaLens
Definition GetExternalFields.H:24
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:63
ExternalFieldInitType m_Btype
Definition GetExternalFields.H:31
amrex::ParserExecutor< 4 > m_Exfield_partparser
Definition GetExternalFields.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool isNoOp() const
Definition GetExternalFields.H:60
amrex::ParticleReal m_repeated_plasma_lens_period
Definition GetExternalFields.H:46
amrex::ParserExecutor< 4 > m_Bxfield_partparser
Definition GetExternalFields.H:39
const amrex::ParticleReal *AMREX_RESTRICT m_uz
Definition GetExternalFields.H:55
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_strengths_E
Definition GetExternalFields.H:49
const amrex::ParticleReal *AMREX_RESTRICT m_repeated_plasma_lens_starts
Definition GetExternalFields.H:47
amrex::ParserExecutor< 4 > m_Byfield_partparser
Definition GetExternalFields.H:40
amrex::ParserExecutor< 4 > m_Ezfield_partparser
Definition GetExternalFields.H:38
amrex::ParserExecutor< 4 > m_Eyfield_partparser
Definition GetExternalFields.H:37
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel.
Definition GetAndSetPosition.H:75
The lattice element finder class that can be trivially copied to the device. This only has simple dat...
Definition LatticeElementFinder.H:108
Definition WarpXParticleContainer.H:58