ImpactX
Loading...
Searching...
No Matches
Multipole.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_MULTIPOLE_H
11#define IMPACTX_MULTIPOLE_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_REAL.H>
24#include <AMReX_SIMD.H>
25
26#include <cmath>
27#include <stdexcept>
28
29
30namespace impactx::elements
31{
32 struct Multipole
33 : public mixin::Named,
34 public mixin::BeamOptic<Multipole>,
35 public mixin::LinearTransport<Multipole>,
36 public mixin::Thin,
37 public mixin::Alignment,
39#ifndef _WIN32
40 // https://github.com/AMReX-Codes/amrex/issues/4609
41 , public amrex::simd::Vectorized<amrex::simd::native_simd_size_particlereal>
42#endif
43 {
44 static constexpr auto type = "Multipole";
46
51 void
53 {
54 int const m = m_multipole - 1;
55 m_mfactorial = 1;
56 for( int n = 1; n < m + 1; n = n + 1 ) {
57 m_mfactorial *= n;
58 }
59 }
60
72 int multipole,
73 amrex::ParticleReal K_normal,
74 amrex::ParticleReal K_skew,
75 amrex::ParticleReal dx = 0,
76 amrex::ParticleReal dy = 0,
77 amrex::ParticleReal rotation_degree = 0,
78 std::optional<std::string> name = std::nullopt
79 )
80 : Named(std::move(name)),
81 Alignment(dx, dy, rotation_degree),
82 m_multipole(multipole), m_Kn(K_normal), m_Ks(K_skew)
83 {
85 }
86
88 using BeamOptic::operator();
89
97 void compute_constants (RefPart const & refpart)
98 {
99 using namespace amrex::literals; // for _rt and _prt
100
101 Alignment::compute_constants(refpart);
102
103 // assign complex position and complex multipole strength
104 m_alpha = {m_Kn, m_Ks};
105
106 m_inv_factorial = 1.0_prt / static_cast<amrex::ParticleReal>(m_mfactorial);
107 }
108
123 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
126 T_Real & AMREX_RESTRICT x,
127 T_Real & AMREX_RESTRICT y,
128 [[maybe_unused]] T_Real & AMREX_RESTRICT t,
129 T_Real & AMREX_RESTRICT px,
130 T_Real & AMREX_RESTRICT py,
131 T_Real & AMREX_RESTRICT pt,
132 [[maybe_unused]] T_IdCpu & AMREX_RESTRICT idcpu,
133 [[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
134 ) const
135 {
136 using namespace amrex::literals; // for _rt and _prt
137
138 // shift due to alignment errors of the element
139 shift_in(x, y, px, py);
140
141 // a complex type with two T_Real
143
144 // access reference particle values to find (beta*gamma)^2
145 //amrex::ParticleReal const pt_ref = refpart.pt;
146 //amrex::ParticleReal const betgam2 = powi<2>(pt_ref) - 1.0_prt;
147
148 // initialize output values
149 T_Real xout = x;
150 T_Real yout = y;
151 T_Real tout = t;
152 T_Real pxout = px;
153 T_Real pyout = py;
154 T_Real ptout = pt;
155
156 // assign complex position and complex multipole strength
157 Complex const zeta(x, y);
158
159 // compute complex momentum kick
160 int const m = m_multipole - 1;
161 Complex const kick = amrex::pow(zeta, m) * m_alpha;
162 T_Real const dpx = -1.0_prt * kick.m_real * m_inv_factorial;
163 T_Real const dpy = kick.m_imag * m_inv_factorial;
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 // undo shift due to alignment errors of the element
184 shift_out(x, y, px, py);
185 }
186
188 using Thin::operator();
189
191 using LinearTransport::operator();
192
199 Map6x6
200 transport_map ([[maybe_unused]] RefPart const & AMREX_RESTRICT refpart) const
201 {
202 throw std::runtime_error(std::string(type) + ": Envelope tracking is not yet implemented!");
203 return Map6x6::Identity();
204 }
205
207 amrex::ParticleReal m_Kn;
208 amrex::ParticleReal m_Ks;
209
210 private:
211 // constants that are independent of the individually tracked particle
212 // see: compute_factorial() to refresh
214 // see: compute_constants() to refresh
216 amrex::ParticleReal m_inv_factorial;
217 };
218
219} // namespace impactx
220
221#endif // IMPACTX_MULTIPOLE_H
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST
amrex::GpuComplex< amrex::Real > Complex
__host__ __device__ GpuComplex< T > pow(const GpuComplex< T > &a_z, const T &a_y) 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
Multipole(int multipole, amrex::ParticleReal K_normal, amrex::ParticleReal K_skew, amrex::ParticleReal dx=0, amrex::ParticleReal dy=0, amrex::ParticleReal rotation_degree=0, std::optional< std::string > name=std::nullopt)
Definition Multipole.H:71
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition Multipole.H:200
int m_mfactorial
integrated skew multipole coefficient
Definition Multipole.H:213
void compute_factorial()
Definition Multipole.H:52
void compute_constants(RefPart const &refpart)
Definition Multipole.H:97
int m_multipole
Definition Multipole.H:206
ImpactXParticleContainer::ParticleType PType
Definition Multipole.H:45
amrex::ParticleReal m_Kn
multipole index
Definition Multipole.H:207
static constexpr auto type
Definition Multipole.H:44
amrex::ParticleReal m_inv_factorial
Definition Multipole.H:216
amrex::ParticleReal m_Ks
integrated normal multipole coefficient
Definition Multipole.H:208
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 Multipole.H:125
amrex::GpuComplex< amrex::ParticleReal > m_alpha
factorial of multipole index
Definition Multipole.H:215
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