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
62 amrex::ParticleReal knll,
63 amrex::ParticleReal cnll,
64 amrex::ParticleReal dx = 0,
65 amrex::ParticleReal dy = 0,
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 using BeamOptic::operator();
77
85 void compute_constants (RefPart const & refpart)
86 {
87 using namespace amrex::literals; // for _rt and _prt
88
89 Alignment::compute_constants(refpart);
90
91 m_inv_cnll = 1.0_prt / m_cnll;
93 }
94
109 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
112 T_Real & AMREX_RESTRICT x,
113 T_Real & AMREX_RESTRICT y,
114 [[maybe_unused]] T_Real & AMREX_RESTRICT t,
115 T_Real & AMREX_RESTRICT px,
116 T_Real & AMREX_RESTRICT py,
117 T_Real & AMREX_RESTRICT pt,
118 [[maybe_unused]] T_IdCpu & AMREX_RESTRICT idcpu,
119 [[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
120 ) const
121 {
122 using namespace amrex::literals; // for _rt and _prt
123 using amrex::Math::powi;
124
125 // a complex type with two T_Real
127
128 // shift due to alignment errors of the element
129 shift_in(x, y, px, py);
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 // undo shift due to alignment errors of the element
185 shift_out(x, y, px, py);
186 }
187
189 using Thin::operator();
190
192 using LinearTransport::operator();
193
200 Map6x6
201 transport_map ([[maybe_unused]] RefPart const & AMREX_RESTRICT refpart) const
202 {
203 throw std::runtime_error(std::string(type) + ": Envelope tracking is not yet implemented!");
204 return Map6x6::Identity();
205 }
206
207 amrex::ParticleReal m_knll;
208 amrex::ParticleReal m_cnll;
209
210 private:
211 // constants that are independent of the individually tracked particle,
212 // see: compute_constants() to refresh
213 amrex::ParticleReal m_inv_cnll;
214 amrex::ParticleReal m_kick;
215 };
216
217} // namespace impactx
218
219#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)
amrex::GpuComplex< amrex::Real > Complex
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:54
@ 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:31
amrex::ParticleReal m_kick
1 / m_cnll
Definition NonlinearLens.H:214
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition NonlinearLens.H:201
amrex::ParticleReal m_cnll
integrated strength of the nonlinear lens (m)
Definition NonlinearLens.H:208
amrex::ParticleReal m_inv_cnll
distance of singularities from the origin (m)
Definition NonlinearLens.H:213
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:111
amrex::ParticleReal m_knll
Definition NonlinearLens.H:207
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:85
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:219
Definition lineartransport.H:29
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