ImpactX
ExactSbend.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_EXACTSBEND_H
11 #define IMPACTX_EXACTSBEND_H
12 
14 #include "mixin/beamoptic.H"
15 #include "mixin/thick.H"
16 #include "mixin/nofinalize.H"
17 
18 #include <AMReX_Extension.H>
19 #include <AMReX_REAL.H>
20 #include <AMReX_Print.H> // for PrintToFile
21 
22 #include <cmath>
23 
24 
25 namespace impactx
26 {
27  struct ExactSbend
28  : public elements::BeamOptic<ExactSbend>,
29  public elements::Thick,
31  {
32  static constexpr auto name = "ExactSbend";
33  static constexpr amrex::ParticleReal degree2rad = ablastr::constant::math::pi / 180.0;
35 
53  ExactSbend( amrex::ParticleReal const ds, amrex::ParticleReal const phi,
54  amrex::ParticleReal const B, int const nslice )
55  : Thick(ds, nslice), m_phi(phi * degree2rad), m_B(B)
56  {
57  }
58 
60  using BeamOptic::operator();
61 
72  PType& AMREX_RESTRICT p,
73  amrex::ParticleReal & AMREX_RESTRICT px,
74  amrex::ParticleReal & AMREX_RESTRICT py,
75  amrex::ParticleReal & AMREX_RESTRICT pt,
76  RefPart const & refpart) const {
77 
78  using namespace amrex::literals; // for _rt and _prt
79 
80  // access AoS data such as positions and cpu/id
81  amrex::ParticleReal const x = p.pos(RealAoS::x);
82  amrex::ParticleReal const y = p.pos(RealAoS::y);
83  amrex::ParticleReal const t = p.pos(RealAoS::t);
84 
85  // angle of arc for the current slice
86  amrex::ParticleReal const slice_phi = m_phi / nslice();
87 
88  // access reference particle values to find beta
89  amrex::ParticleReal const bet = refpart.beta();
90 
91  // reference particle's orbital radius
92  amrex::ParticleReal const rc = (m_B != 0_prt) ? refpart.rigidity_Tm() / m_B : m_ds / m_phi;
93 
94  // intialize output values of momenta
95  amrex::ParticleReal pxout = px;
96  amrex::ParticleReal pyout = py;
97  amrex::ParticleReal ptout = pt;
98 
99  // assign intermediate quantities
100  amrex::ParticleReal const pperp = sqrt(pow(pt,2)-2.0_prt/bet*pt-pow(py,2)+1.0_prt);
101  amrex::ParticleReal const pzi = sqrt(pow(pperp,2)-pow(px,2));
102  amrex::ParticleReal const rho = rc + x;
103  amrex::ParticleReal const sin_phi = sin(slice_phi);
104  amrex::ParticleReal const cos_phi = cos(slice_phi);
105 
106  // update momenta
107  pxout = px*cos_phi + (pzi - rho/rc)*sin_phi;
108  pyout = py;
109  ptout = pt;
110 
111  // angle of momentum rotation
112  amrex::ParticleReal const pzf = sqrt(pow(pperp,2)-pow(pxout,2));
113  amrex::ParticleReal const theta = slice_phi + asin(px/pperp) - asin(pxout/pperp);
114 
115  // update position coordinates
116  p.pos(RealAoS::x) = -rc + rho*cos_phi + rc*(pzf + px*sin_phi - pzi*cos_phi);
117  p.pos(RealAoS::y) = y + theta*rc*py;
118  p.pos(RealAoS::t) = t - theta*rc*(pt - 1.0_prt/bet) - m_phi*rc/bet;
119 
120  // assign updated momenta
121  px = pxout;
122  py = pyout;
123  pt = ptout;
124 
125  }
126 
132  void operator() (RefPart & AMREX_RESTRICT refpart) const {
133 
134  using namespace amrex::literals; // for _rt and _prt
135 
136  // assign input reference particle values
137  amrex::ParticleReal const x = refpart.x;
138  amrex::ParticleReal const px = refpart.px;
139  amrex::ParticleReal const y = refpart.y;
140  amrex::ParticleReal const py = refpart.py;
141  amrex::ParticleReal const z = refpart.z;
142  amrex::ParticleReal const pz = refpart.pz;
143  amrex::ParticleReal const t = refpart.t;
144  amrex::ParticleReal const pt = refpart.pt;
145  amrex::ParticleReal const s = refpart.s;
146 
147  // length of the current slice
148  amrex::ParticleReal const slice_ds = m_ds / nslice();
149 
150  // assign intermediate parameters
151  amrex::ParticleReal const theta = m_phi / nslice();
152  amrex::ParticleReal const rc = (m_B != 0_prt) ? refpart.rigidity_Tm() / m_B : m_ds / m_phi;
153  amrex::ParticleReal const B = refpart.beta_gamma() /rc;
154 
155  // calculate expensive terms once
156  // TODO: use sincos function once wrapped in AMReX
157  amrex::ParticleReal const sin_theta = sin(theta);
158  amrex::ParticleReal const cos_theta = cos(theta);
159 
160  // advance position and momentum (bend)
161  refpart.px = px*cos_theta - pz*sin_theta;
162  refpart.py = py;
163  refpart.pz = pz*cos_theta + px*sin_theta;
164  refpart.pt = pt;
165 
166  refpart.x = x + (refpart.pz - pz)/B;
167  refpart.y = y + (theta/B)*py;
168  refpart.z = z - (refpart.px - px)/B;
169  refpart.t = t - (theta/B)*pt;
170 
171  // advance integrated path length
172  refpart.s = s + slice_ds;
173 
174  }
175 
176  private:
177  amrex::ParticleReal m_phi;
178  amrex::ParticleReal m_B;
179  };
180 
181 } // namespace impactx
182 
183 #endif // IMPACTX_EXACTSBEND_H
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
static constexpr amrex::Real pi
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > pow(const GpuComplex< T > &a_z, const T &a_y) noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
Definition: ImpactX.cpp:33
s
Definition: ExactSbend.H:31
amrex::ParticleReal m_B
bend angle in radians
Definition: ExactSbend.H:178
ExactSbend(amrex::ParticleReal const ds, amrex::ParticleReal const phi, amrex::ParticleReal const B, int const nslice)
Definition: ExactSbend.H:53
ImpactXParticleContainer::ParticleType PType
Definition: ExactSbend.H:34
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, RefPart const &refpart) const
Definition: ExactSbend.H:71
amrex::ParticleReal m_phi
Definition: ExactSbend.H:177
static constexpr auto name
Definition: ExactSbend.H:32
static constexpr amrex::ParticleReal degree2rad
Definition: ExactSbend.H:33
@ x
position in x [m] (at fixed s OR fixed t)
Definition: ImpactXParticleContainer.H:42
@ y
position in y [m] (at fixed s OR fixed t)
Definition: ImpactXParticleContainer.H:43
@ t
c * time-of-flight [m] (at fixed s)
Definition: ImpactXParticleContainer.H:44
Definition: ReferenceParticle.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal rigidity_Tm() const
Definition: ReferenceParticle.H:169
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal beta() const
Definition: ReferenceParticle.H:64
Definition: beamoptic.H:135
Definition: nofinalize.H:22
Definition: thick.H:24
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal ds() const
Definition: thick.H:50
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int nslice() const
Definition: thick.H:40
amrex::ParticleReal m_ds
Definition: thick.H:56
Thick(amrex::ParticleReal const ds, int const nslice)
Definition: thick.H:30