ImpactX
Loading...
Searching...
No Matches
spintransport.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
8 * License: BSD-3-Clause-LBNL
9 */
10#ifndef IMPACTX_ELEMENTS_MIXIN_SPIN_TRANSPORT_H
11#define IMPACTX_ELEMENTS_MIXIN_SPIN_TRANSPORT_H
12
14
15#include <ablastr/constant.H>
16
17#include <AMReX_Math.H>
18#include <AMReX_Extension.H>
19#include <AMReX_REAL.H>
20#include <AMReX_SIMD.H>
21
22#include <cmath>
23
24
26{
36 {
46 template<typename T_Real=amrex::ParticleReal>
49 T_Real const & AMREX_RESTRICT lambdax,
50 T_Real const & AMREX_RESTRICT lambday,
51 T_Real const & AMREX_RESTRICT lambdaz,
52 T_Real & AMREX_RESTRICT sx,
53 T_Real & AMREX_RESTRICT sy,
54 T_Real & AMREX_RESTRICT sz
55 ) const
56 {
57 using namespace amrex::literals; // for _prt
58 using namespace std; // for cmath(float)
59
60 // Compute quaternion coefficients
61 T_Real const angle = sqrt(lambdax*lambdax + lambday*lambday + lambdaz*lambdaz);
62
63 auto const [sin_half_angle, cos_half_angle] = amrex::Math::sincos(angle*0.5_prt);
64 T_Real const w0 = cos_half_angle;
65 T_Real const c_sin_half = -sin_half_angle / angle;
66
67 auto const non_zero_angle = angle!=0_prt;
68#ifdef AMREX_USE_SIMD
69 T_Real w1 = 0_prt;
70 amrex::simd::stdx::where(non_zero_angle, w1) = lambdax * c_sin_half;
71 T_Real w2 = 0_prt;
72 amrex::simd::stdx::where(non_zero_angle, w2) = lambday * c_sin_half;
73 T_Real w3 = 0_prt;
74 amrex::simd::stdx::where(non_zero_angle, w3) = lambdaz * c_sin_half;
75#else
76 T_Real w1 = non_zero_angle ? lambdax * c_sin_half : 0_prt;
77 T_Real w2 = non_zero_angle ? lambday * c_sin_half : 0_prt;
78 T_Real w3 = non_zero_angle ? lambdaz * c_sin_half : 0_prt;
79#endif
80
81 // Apply rotation
82 T_Real const sxout = (1_prt-2_prt*(w2*w2+w3*w3))*sx + 2_prt*(w1*w2+w0*w3)*sy + 2_prt*(w1*w3-w0*w2)*sz;
83 T_Real const syout = 2_prt*(w1*w2-w0*w3)*sx + (1_prt-2_prt*(w1*w1+w3*w3))*sy + 2_prt*(w0*w1+w2*w3)*sz;
84 T_Real const szout = 2_prt*(w0*w2+w1*w3)*sx + 2_prt*(w2*w3-w0*w1)*sy + (1_prt-2_prt*(w1*w1+w2*w2))*sz;
85
86 // Update spin vector
87 sx = sxout;
88 sy = syout;
89 sz = szout;
90 }
91
119 template<typename T_Real=amrex::ParticleReal>
122 T_Real const & AMREX_RESTRICT x,
123 T_Real const & AMREX_RESTRICT ux,
124 T_Real const & AMREX_RESTRICT uy,
125 T_Real const & AMREX_RESTRICT uz,
126 T_Real const & AMREX_RESTRICT gamma,
128 amrex::ParticleReal const & AMREX_RESTRICT gyro_anomaly,
129 T_Real const & AMREX_RESTRICT Bx,
130 T_Real const & AMREX_RESTRICT By,
131 T_Real const & AMREX_RESTRICT Bz,
132 T_Real const & AMREX_RESTRICT Ex,
133 T_Real const & AMREX_RESTRICT Ey,
134 T_Real const & AMREX_RESTRICT Ez,
135 T_Real & AMREX_RESTRICT Omegax,
136 T_Real & AMREX_RESTRICT Omegay,
137 T_Real & AMREX_RESTRICT Omegaz
138 ) const
139 {
140 using namespace amrex::literals; // for _prt
141 using namespace std; // for cmath(float)
142
143 // Evaluation of the full Thomas-BMT precession vector in the Frenet-Serret frame.
144 T_Real const beta_gamma = sqrt(gamma*gamma - 1_prt);
145 T_Real const beta_gamma_z = uz * beta_gamma;
146 T_Real const leading_factor = -(1_prt + h * x) / beta_gamma_z;
147 T_Real const udotB = ux*Bx + uy*By + uz*Bz;
148 T_Real const ucrossE_x = uy*Ez - uz*Ey;
149 T_Real const ucrossE_y = uz*Ex - ux*Ez;
150 T_Real const ucrossE_z = ux*Ey - uy*Ex;
151 T_Real const c1 = (1_prt + gyro_anomaly*gamma);
152 T_Real const c2 = gyro_anomaly * (gamma - 1_prt) * udotB;
153 T_Real const c3 = (gyro_anomaly + 1_prt / (1_prt + gamma)) * beta_gamma;
154 Omegax = leading_factor * (c1 * Bx - c2 * ux - c3 * ucrossE_x);
155 Omegay = leading_factor * (c1 * By - c2 * uy - c3 * ucrossE_y) + h;
156 Omegaz = leading_factor * (c1 * Bz - c2 * uz - c3 * ucrossE_z);
157 }
158
159 };
160
161} // namespace impactx::elements::mixin
162
163#endif // IMPACTX_ELEMENTS_MIXIN_SPIN_TRANSPORT_H
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
amrex_particle_real ParticleReal
__host__ __device__ std::pair< double, double > sincos(double x)
__host__ __device__ GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
Definition alignment.H:23
Definition spintransport.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void tbmt_precession_vector(T_Real const &AMREX_RESTRICT x, T_Real const &AMREX_RESTRICT ux, T_Real const &AMREX_RESTRICT uy, T_Real const &AMREX_RESTRICT uz, T_Real const &AMREX_RESTRICT gamma, amrex::ParticleReal const &AMREX_RESTRICT h, amrex::ParticleReal const &AMREX_RESTRICT gyro_anomaly, T_Real const &AMREX_RESTRICT Bx, T_Real const &AMREX_RESTRICT By, T_Real const &AMREX_RESTRICT Bz, T_Real const &AMREX_RESTRICT Ex, T_Real const &AMREX_RESTRICT Ey, T_Real const &AMREX_RESTRICT Ez, T_Real &AMREX_RESTRICT Omegax, T_Real &AMREX_RESTRICT Omegay, T_Real &AMREX_RESTRICT Omegaz) const
Definition spintransport.H:121
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