ImpactX
Loading...
Searching...
No Matches
SpinMap.H
Go to the documentation of this file.
1/* Copyright 2022-2026 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_ELEMENT_SPIN_MAP_H
11#define IMPACTX_ELEMENT_SPIN_MAP_H
12
14#include "mixin/alignment.H"
15#include "mixin/beamoptic.H"
17#include "mixin/spintransport.H"
18#include "mixin/named.H"
19#include "mixin/nofinalize.H"
20
21#include <AMReX_Extension.H>
22#include <AMReX_Math.H>
23#include <AMReX_REAL.H>
24#include <AMReX_SIMD.H>
25#include <AMReX_SmallMatrix.H>
26
27#include <cmath>
28#include <stdexcept>
29
31
34
35namespace impactx::elements
36{
37 struct SpinMap
38 : public mixin::Named,
39 public mixin::BeamOptic<SpinMap>,
40 public mixin::LinearTransport<SpinMap>,
41 public mixin::Alignment,
43 public mixin::NoFinalize,
44 public amrex::simd::Vectorized<amrex::simd::native_simd_size_particlereal>
45 {
46 static constexpr auto type = "SpinMap";
48
49 static constexpr amrex::ParticleReal DEFAULT_ds = 0;
50
66 Vector3 const & v,
67 Map3x6 const & A,
72 std::optional<std::string> name = DEFAULT_name
73 )
74 : Named(std::move(name)),
75 Alignment(dx, dy, rotation_degree)
76 {
79 m_ds = ds;
80 }
81
83 void reverse ()
84 {
85 throw std::runtime_error("SpinMap: reverse() is not yet supported.");
86
87 /* Reversibility: This works but is hacky
88 for (int i = 1; i <= 3; ++i) {
89 m_spin_rotation_vector(i) = -m_spin_rotation_vector(i);
90 for (int j = 1; j <= 6; ++j) {
91 m_spin_orbit_coupling(i,j) = -m_spin_orbit_coupling(i,j);
92 }
93 }
94 m_reversed = !m_reversed;
95 */
96 }
97
99 using BeamOptic::operator();
100
113 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
116 [[maybe_unused]] T_Real const & AMREX_RESTRICT x,
117 [[maybe_unused]] T_Real const & AMREX_RESTRICT y,
118 [[maybe_unused]] T_Real const & AMREX_RESTRICT t,
119 [[maybe_unused]] T_Real const & AMREX_RESTRICT px,
120 [[maybe_unused]] T_Real const & AMREX_RESTRICT py,
121 [[maybe_unused]] T_Real const & AMREX_RESTRICT pt,
122 [[maybe_unused]] T_IdCpu const & AMREX_RESTRICT idcpu,
123 [[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
124 ) const
125 {
126 // This element does nothing to the phase space variables.
127 }
128
134 void operator() ([[maybe_unused]] RefPart & AMREX_RESTRICT refpart) const
135 {
136 // This element does nothing to the reference particle.
137 }
138
144 int nslice () const
145 {
146 return 1;
147 }
148
155 {
156 return m_ds;
157 }
158
173 template<typename T_Real=amrex::ParticleReal, typename T_IdCpu=uint64_t>
176 T_Real const & AMREX_RESTRICT x,
177 T_Real const & AMREX_RESTRICT y,
178 T_Real const & AMREX_RESTRICT t,
179 T_Real const & AMREX_RESTRICT px,
180 T_Real const & AMREX_RESTRICT py,
181 T_Real const & AMREX_RESTRICT pt,
182 T_Real & AMREX_RESTRICT sx,
183 T_Real & AMREX_RESTRICT sy,
184 T_Real & AMREX_RESTRICT sz,
185 T_IdCpu const & AMREX_RESTRICT idcpu,
186 RefPart const & AMREX_RESTRICT refpart
187 ) const
188 {
189 using namespace amrex::literals; // for _rt and _prt
190
191 // initialize the three components of the axis-angle vector
192 T_Real lambdax = 0_prt;
193 T_Real lambday = 0_prt;
194 T_Real lambdaz = 0_prt;
195
196 // input phase space 6-vector
198 x, px, y, py, t, pt
199 };
200
201 // determine the rotation vector for off-design particles
202 amrex::SmallVector<T_Real, 3, 1> const vectorout = m_spin_orbit_coupling * vectorin;
203
204 // assign updated values
205 lambdax = vectorout(1);
206 lambday = vectorout(2);
207 lambdaz = vectorout(3);
208
209 /* Reversibility: This works but is hacky
210 T_Real const design_lambdax = m_spin_rotation_vector(1);
211 T_Real const design_lambday = m_spin_rotation_vector(2);
212 T_Real const design_lambdaz = m_spin_rotation_vector(3);
213
214 if (m_reversed) {
215 // The inverse map applies the inverse design rotation first,
216 // then the inverse orbit-dependent rotation.
217 rotate_spin(
218 design_lambdax,
219 design_lambday,
220 design_lambdaz,
221 sx, sy, sz
222 );
223 rotate_spin(lambdax,lambday,lambdaz,sx,sy,sz);
224 } else {
225 rotate_spin(lambdax,lambday,lambdaz,sx,sy,sz);
226 rotate_spin(
227 design_lambdax,
228 design_lambday,
229 design_lambdaz,
230 sx, sy, sz
231 );
232 }
233 */
234
235 { /* non-reversible block, replace with the above block to test */
236 // push the spin vector using the generator just determined
237 rotate_spin(lambdax,lambday,lambdaz,sx,sy,sz);
238
239 // specify the design rotation vector
240 lambdax = m_spin_rotation_vector(1);
241 lambday = m_spin_rotation_vector(2);
242 lambdaz = m_spin_rotation_vector(3);
243
244 // push the spin vector using the generator just determined
245 rotate_spin(lambdax,lambday,lambdaz,sx,sy,sz);
246 } /* end of non-reversible block, replace with the above block to test */
247
248 // phase space push (the identity for this element)
249 (*this)(x, y, t, px, py, pt, idcpu, refpart);
250 }
251
253 using LinearTransport::operator();
254
261 Map6x6
262 transport_map ([[maybe_unused]] RefPart const & AMREX_RESTRICT refpart) const
263 {
265 // apply the transverse rotation (roll) alignment error
266 return rotate_aligned_map(R);
267 }
268
269 Vector3 m_spin_rotation_vector; // 3x1 axis-angle vector for design spin rotation
270 Map3x6 m_spin_orbit_coupling; // 3x6 spin-orbit coupling matrix
271 amrex::ParticleReal m_ds; // finite ds allowed for bookkeeping, but we do not allow slicing
272 /* Reversibility: This works but is hacky */
273 // bool m_reversed = false; // apply inverse spin rotations in reverse order after reverse()
274 };
275
276} // namespace impactx
277
279
280#endif // IMPACTX_ELEMENT_SPIN_MAP_H
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST
#define IMPACTX_PUSH_EXTERN_TEMPLATE(ElementType)
Definition PushAll.H:78
amrex::SmallMatrix< amrex::ParticleReal, 3, 6, amrex::Order::F, 1 > Map3x6
Definition SpinMap.H:32
amrex::SmallMatrix< amrex::ParticleReal, 3, 1, amrex::Order::F, 1 > Vector3
Definition SpinMap.H:33
amrex_particle_real ParticleReal
SmallMatrix< T, N, 1, Order::F, StartIndex > SmallVector
Definition All.H:55
@ 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 SpinMap.H:45
static constexpr auto type
Definition SpinMap.H:46
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void spin_and_phasespace_push(T_Real const &AMREX_RESTRICT x, T_Real const &AMREX_RESTRICT y, T_Real const &AMREX_RESTRICT t, T_Real const &AMREX_RESTRICT px, T_Real const &AMREX_RESTRICT py, T_Real const &AMREX_RESTRICT pt, T_Real &AMREX_RESTRICT sx, T_Real &AMREX_RESTRICT sy, T_Real &AMREX_RESTRICT sz, T_IdCpu const &AMREX_RESTRICT idcpu, RefPart const &AMREX_RESTRICT refpart) const
Definition SpinMap.H:175
static constexpr amrex::ParticleReal DEFAULT_ds
Definition SpinMap.H:49
void reverse()
Definition SpinMap.H:83
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 const &AMREX_RESTRICT px, T_Real const &AMREX_RESTRICT py, T_Real const &AMREX_RESTRICT pt, T_IdCpu const &AMREX_RESTRICT idcpu, RefPart const &AMREX_RESTRICT refpart) const
Definition SpinMap.H:115
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal ds() const
Definition SpinMap.H:154
amrex::ParticleReal m_ds
Definition SpinMap.H:271
Vector3 m_spin_rotation_vector
Definition SpinMap.H:269
SpinMap(Vector3 const &v, Map3x6 const &A, amrex::ParticleReal ds=DEFAULT_ds, amrex::ParticleReal dx=DEFAULT_dx, amrex::ParticleReal dy=DEFAULT_dy, amrex::ParticleReal rotation_degree=DEFAULT_rotation_degree, std::optional< std::string > name=DEFAULT_name)
Definition SpinMap.H:65
ImpactXParticleContainer::ParticleType PType
Definition SpinMap.H:47
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition SpinMap.H:262
Map3x6 m_spin_orbit_coupling
Definition SpinMap.H:270
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int nslice() const
Definition SpinMap.H:144
Definition alignment.H:29
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dy() const
Definition alignment.H:193
static constexpr amrex::ParticleReal DEFAULT_dy
Definition alignment.H:34
static constexpr amrex::ParticleReal DEFAULT_dx
Definition alignment.H:33
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dx() const
Definition alignment.H:183
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 rotate_aligned_map(Map6x6 const &R) const
Definition alignment.H:267
Alignment(amrex::ParticleReal dx, amrex::ParticleReal dy, amrex::ParticleReal rotation_degree)
Definition alignment.H:43
static constexpr amrex::ParticleReal DEFAULT_rotation_degree
Definition alignment.H:35
Definition beamoptic.H:567
Definition lineartransport.H:50
Definition named.H:29
static constexpr std::nullopt_t DEFAULT_name
Definition named.H:30
AMREX_GPU_HOST Named(std::optional< std::string > name)
Definition named.H:59
AMREX_FORCE_INLINE std::string name() const
Definition named.H:124
Definition nofinalize.H:22
Definition spintransport.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void rotate_spin(T_Real const &AMREX_RESTRICT lambdax, T_Real const &AMREX_RESTRICT lambday, T_Real const &AMREX_RESTRICT lambdaz, T_Real &AMREX_RESTRICT sx, T_Real &AMREX_RESTRICT sy, T_Real &AMREX_RESTRICT sz) const
Definition spintransport.H:48