OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
SpinTBMTPusher.h
Go to the documentation of this file.
1//
2// Class SpinTBMTPusher
3// Thomas-BMT spin precession integrator using analytic Rodrigues rotation.
4// Preserves |Pol| exactly per step; sub-steps when the per-step rotation
5// angle exceeds a small-angle threshold.
6//
7// Copyright (c) 2008 - 2026, Paul Scherrer Institut, Villigen PSI, Switzerland
8// All rights reserved
9//
10// This file is part of OPAL.
11//
12// OPAL is free software: you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// You should have received a copy of the GNU General Public License
18// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
19//
20#ifndef OPALX_SpinTBMTPusher_H
21#define OPALX_SpinTBMTPusher_H
22
23#include "Physics/Physics.h"
24
25#include "Expression/IpplExpressions.h"
26#include "VectorMath.h"
27
29public:
30 KOKKOS_INLINE_FUNCTION SpinTBMTPusher() = default;
31
34 static constexpr double maxAngle_m = 0.1;
35
48 template <typename SpinVec>
49 KOKKOS_INLINE_FUNCTION void evolve(
50 SpinVec& Pol, const Vector_t<double, 3>& P, const Vector_t<double, 3>& Ef,
51 const Vector_t<double, 3>& Bf, const double& dt, const double& mass,
52 const double& charge, const double& anom) const {
53 // Thomas-BMT angular velocity vector Omega in the lab frame, lab time:
54 // Omega = -(q/m) [ (G + 1/gamma) B
55 // - (G gamma / (gamma+1)) (beta . B) beta
56 // - (G + 1/(gamma+1)) (beta x E) / c ]
57 //
58 // OPALX convention: mass is rest energy in eV (i.e. m*c^2 numerically),
59 // so q/m becomes charge*c^2/mass — same idiom used in BorisPusher.
60 const double bg2 = dot(P, P);
61 const double gamma = Kokkos::sqrt(1.0 + bg2);
62 const Vector_t<double, 3> beta = P / gamma;
63
64 const double betaDotB = dot(beta, Bf);
65 const Vector_t<double, 3> bcrossE = cross(beta, Ef);
66
67 const double k1 = anom + 1.0 / gamma;
68 const double k2 = (anom * gamma) / (gamma + 1.0);
69 const double k3 = anom + 1.0 / (gamma + 1.0);
70
71 const double prefactor = -charge * Physics::c * Physics::c / mass;
72 const Vector_t<double, 3> Omega =
73 prefactor * (k1 * Bf - k2 * betaDotB * beta - (k3 / Physics::c) * bcrossE);
74
75 const double omegaMag = Kokkos::sqrt(dot(Omega, Omega));
76 const double phi = omegaMag * dt;
77
78 if (phi < 1.0e-14) {
79 return;
80 }
81
82 // Sub-stepping for large rotations: split phi into N steps of size <= maxAngle_m.
83 // Rodrigues' formula is exact at any angle, but float precision and the
84 // assumption of constant Omega across the step degrade for large phi.
85 const int nSub = static_cast<int>(Kokkos::ceil(phi / maxAngle_m));
86 const double dphi = phi / static_cast<double>(nSub);
87 const double cosDphi = Kokkos::cos(dphi);
88 const double sinDphi = Kokkos::sin(dphi);
89
90 const Vector_t<double, 3> axis = Omega / omegaMag;
91
93 static_cast<double>(Pol[0]), static_cast<double>(Pol[1]),
94 static_cast<double>(Pol[2])};
95 for (int i = 0; i < nSub; ++i) {
96 // Rodrigues: S' = cos(dphi) S + sin(dphi) (axis x S) + (1-cos(dphi))(axis.S) axis
97 const Vector_t<double, 3> axisCrossS = cross(axis, S);
98 const double axisDotS = dot(axis, S);
99 S = cosDphi * S + sinDphi * axisCrossS + (1.0 - cosDphi) * axisDotS * axis;
100 }
101
102 Pol[0] = static_cast<float>(S[0]);
103 Pol[1] = static_cast<float>(S[1]);
104 Pol[2] = static_cast<float>(S[2]);
105 }
106};
107
108#endif
ippl::Vector< T, Dim > Vector_t
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
Definition Vector3D.cpp:89
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:95
KOKKOS_INLINE_FUNCTION SpinTBMTPusher()=default
KOKKOS_INLINE_FUNCTION void evolve(SpinVec &Pol, const Vector_t< double, 3 > &P, const Vector_t< double, 3 > &Ef, const Vector_t< double, 3 > &Bf, const double &dt, const double &mass, const double &charge, const double &anom) const
static constexpr double maxAngle_m
constexpr double c
The velocity of light in m/s.
Definition Physics.h:60