ImpactX
Loading...
Searching...
No Matches
TaperedPL.H
Go to the documentation of this file.
1/* Copyright 2022-2023 The Regents of the University of California, through Lawrence
2 * Berkeley National Laboratory (subject to receipt of any required
3 * approvals from the U.S. Dept. of Energy). All rights reserved.
4 *
5 * This file is part of ImpactX.
6 *
7 * Authors: Chad Mitchell, Axel Huebl
8 * License: BSD-3-Clause-LBNL
9 */
10#ifndef IMPACTX_TAPEREDPL_H
11#define IMPACTX_TAPEREDPL_H
12
14#include "mixin/alignment.H"
15#include "mixin/beamoptic.H"
16#include "mixin/thin.H"
18#include "mixin/spintransport.H"
19#include "mixin/named.H"
20#include "mixin/nofinalize.H"
21
22#include <AMReX_Extension.H>
23#include <AMReX_Math.H>
24#include <AMReX_REAL.H>
25#include <AMReX_SIMD.H>
26
27#include <cmath>
28#include <stdexcept>
29
30
31namespace impactx::elements
32{
33 struct TaperedPL
34 : public mixin::Named,
35 public mixin::BeamOptic<TaperedPL>,
36 public mixin::LinearTransport<TaperedPL>,
37 public mixin::Thin,
38 public mixin::Alignment,
40 public mixin::NoFinalize,
41 // At least on Intel AVX512, there is a small overhead to vectorize this element
42 // for pure phase-space pushes. But a win for spin-tracking. See:
43 // https://github.com/BLAST-ImpactX/impactx/pull/1002
44 // https://github.com/BLAST-ImpactX/impactx/pull/1499
45 public amrex::simd::Vectorized<amrex::simd::native_simd_size_particlereal>
46 {
47 static constexpr auto type = "TaperedPL";
49
68 int unit,
71 amrex::ParticleReal rotation_degree = 0,
72 std::optional<std::string> name = std::nullopt
73 )
74 : Named(std::move(name)),
75 Alignment(dx, dy, rotation_degree),
76 m_k(k), m_taper(taper), m_unit(unit)
77 {
78 }
79
81 void reverse () { m_k = -m_k; }
82
90 void compute_constants (RefPart const & refpart)
91 {
92 using namespace amrex::literals; // for _rt and _prt
93
94 Alignment::compute_constants(refpart);
95
96 // normalize focusing strength units to MAD-X convention if needed
97 m_g = m_unit == 1 ? m_k / refpart.rigidity_Tm() : m_k;
98
99 // additional constants needed for spin push
100 m_beta = refpart.beta();
101 m_ibeta = 1_prt / m_beta;
102
103 }
104
106 using BeamOptic::operator();
107
120 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
123 T_Real const & AMREX_RESTRICT x,
124 T_Real const & AMREX_RESTRICT y,
125 [[maybe_unused]] T_Real const & AMREX_RESTRICT t,
126 T_Real & AMREX_RESTRICT px,
127 T_Real & AMREX_RESTRICT py,
128 [[maybe_unused]] T_Real const & AMREX_RESTRICT pt,
129 [[maybe_unused]] T_IdCpu const & AMREX_RESTRICT idcpu,
130 [[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
131 ) const
132 {
133 using namespace amrex::literals; // for _rt and _prt
134 using amrex::Math::powi;
135 using namespace std; // for cmath(float)
136
137 // initialize output values
138 // T_Real xout = x;
139 // T_Real yout = y;
140 // T_Real tout = t;
141 T_Real pxout = px;
142 T_Real pyout = py;
143 // T_Real ptout = pt;
144
145 // advance position and momentum
146 // xout = x;
147 pxout = px - m_g * ( x + m_taper*0.5_prt * (powi<2>(x) + powi<2>(y)) );
148
149 // yout = y;
150 pyout = py - m_g * ( y + m_taper * x * y );
151
152 // tout = t;
153 // ptout = pt;
154
155 // assign updated values
156 // x = xout;
157 // y = yout;
158 // t = tout;
159 px = pxout;
160 py = pyout;
161 // pt = ptout;
162 }
163
165 using Thin::operator();
166
167
182 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
185 T_Real const & AMREX_RESTRICT x,
186 T_Real const & AMREX_RESTRICT y,
187 T_Real const & AMREX_RESTRICT t,
188 T_Real & AMREX_RESTRICT px,
189 T_Real & AMREX_RESTRICT py,
190 T_Real const & AMREX_RESTRICT pt,
191 T_Real & AMREX_RESTRICT sx,
192 T_Real & AMREX_RESTRICT sy,
193 T_Real & AMREX_RESTRICT sz,
194 T_IdCpu const & AMREX_RESTRICT idcpu,
195 RefPart const & AMREX_RESTRICT refpart
196 ) const
197 {
198 using namespace amrex::literals; // for _rt and _prt
199 using namespace std; // for cmath(float)
200 using amrex::Math::powi;
201
202 // The Thomas-BMT generator is evaluated at the transverse momentum
203 // halfway through the kick, so that reversing the element (negating
204 // the strength) produces the exact inverse rotation.
205 T_Real const px_in = px;
206 T_Real const py_in = py;
207
208 // pure phase-space push (shared with the non-spin operator())
209 (*this)(x, y, t, px, py, pt, idcpu, refpart);
210
211 // transverse momenta at the kick midpoint
212 T_Real const px_mid = 0.5_prt * (px_in + px);
213 T_Real const py_mid = 0.5_prt * (py_in + py);
214
215 // initialize the three components of the axis-angle vector
216 T_Real lambdax = 0_prt;
217 T_Real lambday = 0_prt;
218 T_Real lambdaz = 0_prt;
219
220 // compute multipole magnetic field normalized by q/mc:
221 amrex::ParticleReal const gamma_ref = refpart.gamma();
222 T_Real const Bx = -m_g * ( y + m_taper * x * y ) * gamma_ref * m_beta;
223 T_Real const By = m_g * ( x + m_taper*0.5_prt * (powi<2>(x) + powi<2>(y)) ) * gamma_ref * m_beta;
224 T_Real const Bz = 0_prt;
225
226 // Electric field normalized by q/mc^2:
227 T_Real const Ex = 0.0_prt;
228 T_Real const Ey = 0.0_prt;
229 T_Real const Ez = 0.0_prt;
230
231 // Quantities required to evaluate the full Thomas-BMT precession
232 // vector, at the midpoint transverse momentum.
233 T_Real const Pnorm = sqrt(1_prt - 2_prt * pt * m_ibeta + pt*pt);
234 T_Real const iPnorm = 1_prt/Pnorm;
235 T_Real const Ps = sqrt(Pnorm*Pnorm - px_mid*px_mid - py_mid*py_mid);
236 T_Real const gamma = gamma_ref * (1_prt - pt*m_beta);
237 T_Real const ux = px_mid * iPnorm;
238 T_Real const uy = py_mid * iPnorm;
239 T_Real const uz = Ps * iPnorm;
240
241 // Zero curvature in a quadrupole
242 amrex::ParticleReal const h = 0.0_prt;
243
244 // Evaluation of the full Thomas-BMT precession vector.
245 amrex::ParticleReal const gyro_anomaly = refpart.gyromagnetic_anomaly;
246 tbmt_precession_vector(x, ux, uy, uz, gamma, h, gyro_anomaly, Bx, By, Bz, Ex, Ey, Ez, lambdax, lambday, lambdaz);
247
248 // push the spin vector using the generator just determined
249 rotate_spin(lambdax, lambday, lambdaz, sx, sy, sz);
250
251 }
252
253
255 using LinearTransport::operator();
256
291 Map6x6
292 transport_map (RefPart const & AMREX_RESTRICT refpart) const
293 {
294 using namespace amrex::literals; // for _rt and _prt
295
296 // Normalize focusing strength to MAD-X convention if needed.
297 amrex::ParticleReal const g = (m_unit == 1)
298 ? m_k / refpart.rigidity_Tm()
299 : m_k;
300
301 // Linearized axisymmetric focusing kick; taper is quadratic
302 // and therefore absent from the linear map.
304 R(2,1) = -g;
305 R(4,3) = -g;
306
307 // apply the transverse rotation (roll) alignment error
308 return rotate_aligned_map(R);
309 }
310
313 int m_unit;
314
315 private:
316 // constants that are independent of the individually tracked particle
320 };
321
322} // namespace impactx
323
325
326#endif // IMPACTX_TAPEREDPL_H
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST
#define IMPACTX_PUSH_EXTERN_TEMPLATE(ElementType)
Definition PushAll.H:78
amrex_particle_real ParticleReal
constexpr T powi(T x) noexcept
__host__ __device__ GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
Definition All.H:56
@ t
fixed t as the independent variable
Definition ImpactXParticleContainer.H:38
amrex::SmallMatrix< amrex::ParticleReal, 6, 6, amrex::Order::F, 1 > Map6x6
Definition CovarianceMatrix.H:20
static constexpr __host__ __device__ SmallMatrix< T, NRows, NCols, ORDER, StartIndex > Identity() noexcept
Definition ReferenceParticle.H:33
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal rigidity_Tm() const
Definition ReferenceParticle.H:260
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal beta() const
Definition ReferenceParticle.H:151
Definition TaperedPL.H:46
amrex::ParticleReal m_k
Definition TaperedPL.H:311
amrex::ParticleReal m_ibeta
relativistic beta
Definition TaperedPL.H:318
static constexpr auto type
Definition TaperedPL.H:47
ImpactXParticleContainer::ParticleType PType
Definition TaperedPL.H:48
void compute_constants(RefPart const &refpart)
Definition TaperedPL.H:90
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void spin_and_phasespace_push(T_Real const &AMREX_RESTRICT x, T_Real const &AMREX_RESTRICT y, T_Real const &AMREX_RESTRICT t, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py, T_Real const &AMREX_RESTRICT pt, T_Real &AMREX_RESTRICT sx, T_Real &AMREX_RESTRICT sy, T_Real &AMREX_RESTRICT sz, T_IdCpu const &AMREX_RESTRICT idcpu, RefPart const &AMREX_RESTRICT refpart) const
Definition TaperedPL.H:184
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition TaperedPL.H:292
TaperedPL(amrex::ParticleReal k, amrex::ParticleReal taper, int unit, amrex::ParticleReal dx=0, amrex::ParticleReal dy=0, amrex::ParticleReal rotation_degree=0, std::optional< std::string > name=std::nullopt)
Definition TaperedPL.H:65
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(T_Real const &AMREX_RESTRICT x, T_Real const &AMREX_RESTRICT y, T_Real const &AMREX_RESTRICT t, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py, T_Real const &AMREX_RESTRICT pt, T_IdCpu const &AMREX_RESTRICT idcpu, RefPart const &AMREX_RESTRICT refpart) const
Definition TaperedPL.H:122
amrex::ParticleReal m_g
inverse of beta
Definition TaperedPL.H:319
void reverse()
Definition TaperedPL.H:81
amrex::ParticleReal m_beta
units for linear focusing strength (field gradient)
Definition TaperedPL.H:317
amrex::ParticleReal m_taper
linear focusing strength (field gradient)
Definition TaperedPL.H:312
int m_unit
horizontal taper parameter
Definition TaperedPL.H:313
Definition alignment.H:29
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dy() const
Definition alignment.H:189
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dx() const
Definition alignment.H:179
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 rotate_aligned_map(Map6x6 const &R) const
Definition alignment.H:263
Alignment(amrex::ParticleReal dx, amrex::ParticleReal dy, amrex::ParticleReal rotation_degree)
Definition alignment.H:39
Definition beamoptic.H:529
Definition lineartransport.H:50
Definition named.H:29
AMREX_GPU_HOST Named(std::optional< std::string > name)
Definition named.H:57
AMREX_FORCE_INLINE std::string name() const
Definition named.H:122
Definition nofinalize.H:22
Definition spintransport.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void tbmt_precession_vector(T_Real const &AMREX_RESTRICT x, T_Real const &AMREX_RESTRICT ux, T_Real const &AMREX_RESTRICT uy, T_Real const &AMREX_RESTRICT uz, T_Real const &AMREX_RESTRICT gamma, amrex::ParticleReal const &AMREX_RESTRICT h, amrex::ParticleReal const &AMREX_RESTRICT gyro_anomaly, T_Real const &AMREX_RESTRICT Bx, T_Real const &AMREX_RESTRICT By, T_Real const &AMREX_RESTRICT Bz, T_Real const &AMREX_RESTRICT Ex, T_Real const &AMREX_RESTRICT Ey, T_Real const &AMREX_RESTRICT Ez, T_Real &AMREX_RESTRICT Omegax, T_Real &AMREX_RESTRICT Omegay, T_Real &AMREX_RESTRICT Omegaz) const
Definition spintransport.H:121
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void rotate_spin(T_Real const &AMREX_RESTRICT lambdax, T_Real const &AMREX_RESTRICT lambday, T_Real const &AMREX_RESTRICT lambdaz, T_Real &AMREX_RESTRICT sx, T_Real &AMREX_RESTRICT sy, T_Real &AMREX_RESTRICT sz) const
Definition spintransport.H:48
Definition thin.H:24