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 const & AMREX_RESTRICT x,
116 T_Real const & AMREX_RESTRICT y,
117 [[maybe_unused]] T_Real const & AMREX_RESTRICT t,
118 T_Real & AMREX_RESTRICT px,
119 T_Real & AMREX_RESTRICT py,
120 [[maybe_unused]] T_Real const & AMREX_RESTRICT pt,
121 [[maybe_unused]] T_IdCpu const & 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 // access reference particle values to find (beta*gamma)^2
132 //amrex::ParticleReal const pt_ref = refpart.pt;
133 //amrex::ParticleReal const betgam2 = powi<2>(pt_ref) - 1.0_prt;
134
135 // initialize output values
136 // T_Real xout = x;
137 // T_Real yout = y;
138 // T_Real tout = t;
139 T_Real pxout = px;
140 T_Real pyout = py;
141 // T_Real ptout = pt;
142
143 // assign complex position zeta = (x + iy)/cnll
144 Complex zeta(x, y);
145 zeta = zeta * m_inv_cnll;
146 Complex const re1(1.0_prt, 0.0_prt);
147 Complex const im1(0.0_prt, 1.0_prt);
148
149 // compute croot = sqrt(1-zeta**2)
150 Complex croot = powi<2>(zeta);
151 croot = re1 - croot;
152 croot = amrex::sqrt(croot);
153
154 // compute carcsin = arcsin(zeta)
155 Complex carcsin = im1 * zeta + croot;
156 carcsin = -im1 * amrex::log(carcsin);
157
158 // compute complex function F'(zeta)
159 Complex dF = zeta / powi<2>(croot);
160 dF = dF + carcsin / powi<3>(croot);
161
162 // compute momentum kick
163 T_Real const dpx = +m_kick * dF.m_real;
164 T_Real const dpy = -m_kick * dF.m_imag;
165
166 // advance position and momentum
167 // xout = x;
168 pxout = px + dpx;
169
170 // yout = y;
171 pyout = py + dpy;
172
173 // tout = t;
174 // ptout = pt;
175
176 // assign updated values
177 // x = xout;
178 // y = yout;
179 // t = tout;
180 px = pxout;
181 py = pyout;
182 // pt = ptout;
183 }
184
186 using Thin::operator();
187
189 using LinearTransport::operator();
190
220 Map6x6
221 transport_map ([[maybe_unused]] RefPart const & AMREX_RESTRICT refpart) const
222 {
223 using namespace amrex::literals; // for _rt and _prt
224 using amrex::Math::powi;
225
227 // Leading 2*zeta term of F'(zeta); higher orders vanish at zero.
228 amrex::ParticleReal const k_lin = 2.0_prt * m_knll / powi<2>(m_cnll);
229 R(2,1) = -k_lin;
230 R(4,3) = +k_lin;
231
232 // apply the transverse rotation (roll) alignment error
233 return rotate_aligned_map(R);
234 }
235
238
239 private:
240 // constants that are independent of the individually tracked particle,
241 // see: compute_constants() to refresh
244 };
245
246} // namespace impactx
247
249
250#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:243
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:114
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition NonlinearLens.H:221
amrex::ParticleReal m_cnll
integrated strength of the nonlinear lens (m)
Definition NonlinearLens.H:237
amrex::ParticleReal m_inv_cnll
distance of singularities from the origin (m)
Definition NonlinearLens.H:242
amrex::ParticleReal m_knll
Definition NonlinearLens.H:236
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: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 thin.H:24