ImpactX
Loading...
Searching...
No Matches
NonlinearLens.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_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
32
33namespace impactx::elements
34{
36 : public mixin::Named,
37 public mixin::BeamOptic<NonlinearLens>,
38 public mixin::LinearTransport<NonlinearLens>,
39 public mixin::Thin,
40 public mixin::Alignment,
42 // TODO: public amrex::simd::Vectorized<amrex::simd::native_simd_size_particlereal>
43 {
44 static constexpr auto type = "NonlinearLens";
46
66 amrex::ParticleReal rotation_degree = 0,
67 std::optional<std::string> name = std::nullopt
68 )
69 : Named(std::move(name)),
70 Alignment(dx, dy, rotation_degree),
71 m_knll(knll), m_cnll(cnll)
72 {
73 }
74
76 void reverse () { m_knll = -m_knll; }
77
79 using BeamOptic::operator();
80
88 void compute_constants (RefPart const & refpart)
89 {
90 using namespace amrex::literals; // for _rt and _prt
91
92 Alignment::compute_constants(refpart);
93
94 m_inv_cnll = 1.0_prt / m_cnll;
96 }
97
112 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
115 T_Real & AMREX_RESTRICT x,
116 T_Real & AMREX_RESTRICT y,
117 [[maybe_unused]] T_Real & AMREX_RESTRICT t,
118 T_Real & AMREX_RESTRICT px,
119 T_Real & AMREX_RESTRICT py,
120 T_Real & AMREX_RESTRICT pt,
121 [[maybe_unused]] T_IdCpu & AMREX_RESTRICT idcpu,
122 [[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
123 ) const
124 {
125 using namespace amrex::literals; // for _rt and _prt
126 using amrex::Math::powi;
127
128 // a complex type with two T_Real
130
131 // shift due to alignment errors of the element
132 shift_in(x, y, px, py);
133
134 // access reference particle values to find (beta*gamma)^2
135 //amrex::ParticleReal const pt_ref = refpart.pt;
136 //amrex::ParticleReal const betgam2 = powi<2>(pt_ref) - 1.0_prt;
137
138 // initialize output values
139 T_Real xout = x;
140 T_Real yout = y;
141 T_Real tout = t;
142 T_Real pxout = px;
143 T_Real pyout = py;
144 T_Real ptout = pt;
145
146 // assign complex position zeta = (x + iy)/cnll
147 Complex zeta(x, y);
148 zeta = zeta * m_inv_cnll;
149 Complex const re1(1.0_prt, 0.0_prt);
150 Complex const im1(0.0_prt, 1.0_prt);
151
152 // compute croot = sqrt(1-zeta**2)
153 Complex croot = powi<2>(zeta);
154 croot = re1 - croot;
155 croot = amrex::sqrt(croot);
156
157 // compute carcsin = arcsin(zeta)
158 Complex carcsin = im1 * zeta + croot;
159 carcsin = -im1 * amrex::log(carcsin);
160
161 // compute complex function F'(zeta)
162 Complex dF = zeta / powi<2>(croot);
163 dF = dF + carcsin / powi<3>(croot);
164
165 // compute momentum kick
166 T_Real const dpx = +m_kick * dF.m_real;
167 T_Real const dpy = -m_kick * dF.m_imag;
168
169 // advance position and momentum
170 // xout = x;
171 pxout = px + dpx;
172
173 // yout = y;
174 pyout = py + dpy;
175
176 // tout = t;
177 ptout = pt;
178
179 // assign updated values
180 x = xout;
181 y = yout;
182 t = tout;
183 px = pxout;
184 py = pyout;
185 pt = ptout;
186
187 // undo shift due to alignment errors of the element
188 shift_out(x, y, px, py);
189 }
190
192 using Thin::operator();
193
195 using LinearTransport::operator();
196
226 Map6x6
227 transport_map ([[maybe_unused]] RefPart const & AMREX_RESTRICT refpart) const
228 {
229 using namespace amrex::literals; // for _rt and _prt
230 using amrex::Math::powi;
231
233 // Leading 2*zeta term of F'(zeta); higher orders vanish at zero.
234 amrex::ParticleReal const k_lin = 2.0_prt * m_knll / powi<2>(m_cnll);
235 R(2,1) = -k_lin;
236 R(4,3) = +k_lin;
237
238 return R;
239 }
240
243
244 private:
245 // constants that are independent of the individually tracked particle,
246 // see: compute_constants() to refresh
249 };
250
251} // namespace impactx
252
254
255#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: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
Definition NonlinearLens.H:43
void reverse()
Definition NonlinearLens.H:76
amrex::ParticleReal m_kick
1 / m_cnll
Definition NonlinearLens.H:248
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition NonlinearLens.H:227
amrex::ParticleReal m_cnll
integrated strength of the nonlinear lens (m)
Definition NonlinearLens.H:242
amrex::ParticleReal m_inv_cnll
distance of singularities from the origin (m)
Definition NonlinearLens.H:247
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_Real &AMREX_RESTRICT t, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py, T_Real &AMREX_RESTRICT pt, T_IdCpu &AMREX_RESTRICT idcpu, RefPart const &AMREX_RESTRICT refpart) const
Definition NonlinearLens.H:114
amrex::ParticleReal m_knll
Definition NonlinearLens.H:241
NonlinearLens(amrex::ParticleReal knll, amrex::ParticleReal cnll, amrex::ParticleReal dx=0, amrex::ParticleReal dy=0, amrex::ParticleReal rotation_degree=0, std::optional< std::string > name=std::nullopt)
Definition NonlinearLens.H:61
void compute_constants(RefPart const &refpart)
Definition NonlinearLens.H:88
static constexpr auto type
Definition NonlinearLens.H:44
ImpactXParticleContainer::ParticleType PType
Definition NonlinearLens.H:45
Definition alignment.H:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shift_out(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py) const
Definition alignment.H:109
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dy() const
Definition alignment.H:146
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dx() const
Definition alignment.H:136
Alignment(amrex::ParticleReal dx, amrex::ParticleReal dy, amrex::ParticleReal rotation_degree)
Definition alignment.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shift_in(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py) const
Definition alignment.H:78
Definition beamoptic.H:436
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 thin.H:24