ImpactX
Loading...
Searching...
No Matches
NonlinearLens.H
Go to the documentation of this file.
1/* Copyright 2022-2026 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_NONLINEARLENS_H
11#define IMPACTX_NONLINEARLENS_H
12
14#include "mixin/alignment.H"
15#include "mixin/beamoptic.H"
16#include "mixin/thin.H"
18#include "mixin/named.H"
19#include "mixin/nofinalize.H"
20
21#include <AMReX_Extension.H>
22#include <AMReX_GpuComplex.H>
23#include <AMReX_Math.H>
24#include <AMReX_REAL.H>
25// TODO: #include <AMReX_SIMD.H>
26// SIMD will require better complex math support in vir-simd / C++26
27// https://github.com/mattkretz/vir-simd/issues/42
28
29#include <cmath>
30#include <stdexcept>
31
32namespace impactx::elements
33{
35 : public mixin::Named,
36 public mixin::BeamOptic<NonlinearLens>,
37 public mixin::LinearTransport<NonlinearLens>,
38 public mixin::Thin,
39 public mixin::Alignment,
41 // TODO: public amrex::simd::Vectorized<amrex::simd::native_simd_size_particlereal>
42 {
43 static constexpr auto type = "NonlinearLens";
45
66 std::optional<std::string> name = DEFAULT_name
67 )
68 : Named(std::move(name)),
69 Alignment(dx, dy, rotation_degree),
70 m_knll(knll), m_cnll(cnll)
71 {
72 }
73
75 void reverse () { m_knll = -m_knll; }
76
78 using BeamOptic::operator();
79
87 void compute_constants (RefPart const & refpart)
88 {
89 using namespace amrex::literals; // for _rt and _prt
90
91 Alignment::compute_constants(refpart);
92
93 m_inv_cnll = 1.0_prt / m_cnll;
95 }
96
111 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
114 T_Real const & AMREX_RESTRICT x,
115 T_Real const & AMREX_RESTRICT y,
116 [[maybe_unused]] T_Real const & AMREX_RESTRICT t,
117 T_Real & AMREX_RESTRICT px,
118 T_Real & AMREX_RESTRICT py,
119 [[maybe_unused]] T_Real const & AMREX_RESTRICT pt,
120 [[maybe_unused]] T_IdCpu const & AMREX_RESTRICT idcpu,
121 [[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
122 ) const
123 {
124 using namespace amrex::literals; // for _rt and _prt
125 using amrex::Math::powi;
126
127 // a complex type with two T_Real
129
130 // access reference particle values to find (beta*gamma)^2
131 //amrex::ParticleReal const pt_ref = refpart.pt;
132 //amrex::ParticleReal const betgam2 = powi<2>(pt_ref) - 1.0_prt;
133
134 // initialize output values
135 // T_Real xout = x;
136 // T_Real yout = y;
137 // T_Real tout = t;
138 T_Real pxout = px;
139 T_Real pyout = py;
140 // T_Real ptout = pt;
141
142 // assign complex position zeta = (x + iy)/cnll
143 Complex zeta(x, y);
144 zeta = zeta * m_inv_cnll;
145 Complex const re1(1.0_prt, 0.0_prt);
146 Complex const im1(0.0_prt, 1.0_prt);
147
148 // compute croot = sqrt(1-zeta**2)
149 Complex croot = powi<2>(zeta);
150 croot = re1 - croot;
151 croot = amrex::sqrt(croot);
152
153 // compute carcsin = arcsin(zeta)
154 Complex carcsin = im1 * zeta + croot;
155 carcsin = -im1 * amrex::log(carcsin);
156
157 // compute complex function F'(zeta)
158 Complex dF = zeta / powi<2>(croot);
159 dF = dF + carcsin / powi<3>(croot);
160
161 // compute momentum kick
162 T_Real const dpx = +m_kick * dF.m_real;
163 T_Real const dpy = -m_kick * dF.m_imag;
164
165 // advance position and momentum
166 // xout = x;
167 pxout = px + dpx;
168
169 // yout = y;
170 pyout = py + dpy;
171
172 // tout = t;
173 // ptout = pt;
174
175 // assign updated values
176 // x = xout;
177 // y = yout;
178 // t = tout;
179 px = pxout;
180 py = pyout;
181 // pt = ptout;
182 }
183
185 using Thin::operator();
186
188 using LinearTransport::operator();
189
219 Map6x6
220 transport_map ([[maybe_unused]] RefPart const & AMREX_RESTRICT refpart) const
221 {
222 using namespace amrex::literals; // for _rt and _prt
223 using amrex::Math::powi;
224
226 // Leading 2*zeta term of F'(zeta); higher orders vanish at zero.
227 amrex::ParticleReal const k_lin = 2.0_prt * m_knll / powi<2>(m_cnll);
228 R(2,1) = -k_lin;
229 R(4,3) = +k_lin;
230
231 // apply the transverse rotation (roll) alignment error
232 return rotate_aligned_map(R);
233 }
234
237
238 private:
239 // constants that are independent of the individually tracked particle,
240 // see: compute_constants() to refresh
243 };
244
245} // namespace impactx
246
248
249#endif // IMPACTX_NONLINEARLENS_H
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real dF(const amrex::Array4< amrex::Real > &U_minus, const amrex::Array4< amrex::Real > &U_plus, int i, int j, int k, amrex::Real clight, int comp, int dir)
#define IMPACTX_PUSH_EXTERN_TEMPLATE(ElementType)
Definition PushAll.H:78
amrex::GpuComplex< amrex::Real > Complex
amrex_particle_real ParticleReal
constexpr T powi(T x) noexcept
__host__ __device__ GpuComplex< T > log(const GpuComplex< T > &a_z) noexcept
__host__ __device__ GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
Definition All.H:55
@ 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
Definition NonlinearLens.H:42
void reverse()
Definition NonlinearLens.H:75
amrex::ParticleReal m_kick
1 / m_cnll
Definition NonlinearLens.H:242
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 NonlinearLens.H:113
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition NonlinearLens.H:220
amrex::ParticleReal m_cnll
integrated strength of the nonlinear lens (m)
Definition NonlinearLens.H:236
amrex::ParticleReal m_inv_cnll
distance of singularities from the origin (m)
Definition NonlinearLens.H:241
amrex::ParticleReal m_knll
Definition NonlinearLens.H:235
NonlinearLens(amrex::ParticleReal knll, amrex::ParticleReal cnll, amrex::ParticleReal dx=DEFAULT_dx, amrex::ParticleReal dy=DEFAULT_dy, amrex::ParticleReal rotation_degree=DEFAULT_rotation_degree, std::optional< std::string > name=DEFAULT_name)
Definition NonlinearLens.H:60
void compute_constants(RefPart const &refpart)
Definition NonlinearLens.H:87
static constexpr auto type
Definition NonlinearLens.H:43
ImpactXParticleContainer::ParticleType PType
Definition NonlinearLens.H:44
Definition alignment.H:29
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dy() const
Definition alignment.H:193
static constexpr amrex::ParticleReal DEFAULT_dy
Definition alignment.H:34
static constexpr amrex::ParticleReal DEFAULT_dx
Definition alignment.H:33
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dx() const
Definition alignment.H:183
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 rotate_aligned_map(Map6x6 const &R) const
Definition alignment.H:267
Alignment(amrex::ParticleReal dx, amrex::ParticleReal dy, amrex::ParticleReal rotation_degree)
Definition alignment.H:43
static constexpr amrex::ParticleReal DEFAULT_rotation_degree
Definition alignment.H:35
Definition beamoptic.H:567
Definition lineartransport.H:50
Definition named.H:29
static constexpr std::nullopt_t DEFAULT_name
Definition named.H:30
AMREX_GPU_HOST Named(std::optional< std::string > name)
Definition named.H:59
AMREX_FORCE_INLINE std::string name() const
Definition named.H:124
Definition nofinalize.H:22
Definition thin.H:24