ImpactX
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/beamoptic.H"
15 #include "mixin/thin.H"
16 
17 #include <AMReX_Extension.H>
18 #include <AMReX_REAL.H>
19 #include <AMReX_GpuComplex.H>
20 
21 #include <cmath>
22 
23 namespace impactx
24 {
25  struct Multipole
26  : public elements::BeamOptic<Multipole>,
27  public elements::Thin
28  {
29  static constexpr auto name = "Multipole";
31 
38  Multipole( int const multipole,
39  amrex::ParticleReal const K_normal,
40  amrex::ParticleReal const K_skew )
41  : m_multipole(multipole), m_Kn(K_normal), m_Ks(K_skew)
42  {
43  // compute factorial of multipole index
44  int const m = m_multipole - 1;
45  m_mfactorial = 1;
46  for( int n = 1; n < m + 1; n = n + 1 ) {
47  m_mfactorial *= n;
48  }
49  }
50 
52  using BeamOptic::operator();
53 
65  PType& AMREX_RESTRICT p,
66  amrex::ParticleReal & AMREX_RESTRICT px,
67  amrex::ParticleReal & AMREX_RESTRICT py,
68  amrex::ParticleReal & AMREX_RESTRICT pt,
69  [[maybe_unused]] RefPart const & refpart) const {
70 
71  using namespace amrex::literals; // for _rt and _prt
72 
73  // a complex type with two amrex::ParticleReal
75 
76  // access AoS data such as positions and cpu/id
77  amrex::ParticleReal const x = p.pos(0);
78  amrex::ParticleReal const y = p.pos(1);
79  amrex::ParticleReal const t = p.pos(2);
80 
81  // access reference particle values to find (beta*gamma)^2
82  //amrex::ParticleReal const pt_ref = refpart.pt;
83  //amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt;
84 
85  // intialize output values of momenta
86  amrex::ParticleReal pxout = px;
87  amrex::ParticleReal pyout = py;
88  amrex::ParticleReal ptout = pt;
89 
90  // assign complex position and complex multipole strength
91  Complex const zeta(x, y);
92  Complex const alpha(m_Kn, m_Ks);
93 
94  // compute complex momentum kick
95  int const m = m_multipole - 1;
96  Complex kick = amrex::pow(zeta, m);
97  kick *= alpha;
98  amrex::ParticleReal const dpx = -1.0_prt*kick.m_real/m_mfactorial;
99  amrex::ParticleReal const dpy = kick.m_imag/m_mfactorial;
100 
101  // advance position and momentum
102  p.pos(0) = x;
103  pxout = px + dpx;
104 
105  p.pos(1) = y;
106  pyout = py + dpy;
107 
108  p.pos(2) = t;
109  ptout = pt;
110 
111  // assign updated momenta
112  px = pxout;
113  py = pyout;
114  pt = ptout;
115 
116  }
117 
119  using Thin::operator();
120 
121  private:
124  amrex::ParticleReal m_Kn;
125  amrex::ParticleReal m_Ks;
126 
127  };
128 
129 } // namespace impactx
130 
131 #endif // IMPACTX_MULTIPOLE_H
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(PType &AMREX_RESTRICT p, amrex::ParticleReal &AMREX_RESTRICT px, amrex::ParticleReal &AMREX_RESTRICT py, amrex::ParticleReal &AMREX_RESTRICT pt, [[maybe_unused]] RefPart const &refpart) const
Definition: Multipole.H:64
int m_multipole
Definition: Multipole.H:122
Definition: ImpactX.cpp:31
int m_mfactorial
multipole index
Definition: Multipole.H:123
Definition: beamoptic.H:131
Multipole(int const multipole, amrex::ParticleReal const K_normal, amrex::ParticleReal const K_skew)
Definition: Multipole.H:38
Definition: thin.H:23
Definition: Multipole.H:25
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
int n
amrex::ParticleReal m_Ks
integrated normal multipole coefficient
Definition: Multipole.H:125
Definition: ReferenceParticle.H:29
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > pow(const GpuComplex< T > &a_z, const T &a_y) noexcept
amrex::ParticleReal m_Kn
factorial of multipole index
Definition: Multipole.H:124
fftw_complex Complex
static constexpr auto name
Definition: Multipole.H:29