ImpactX
Loading...
Searching...
No Matches
SpinvMF.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_DISTRIBUTION_SPINVMF
11#define IMPACTX_DISTRIBUTION_SPINVMF
12
13#include <ablastr/constant.H>
14
15#include <AMReX_Math.H>
16#include <AMReX_Random.H>
17#include <AMReX_REAL.H>
18
19#include <cmath>
20
21
23{
24 struct SpinvMF
25 {
48 )
49 : m_muX(mux), m_muY(muy), m_muZ(muz)
50 {
51 // magnitude of the polarization vector (= polarization magnitude)
52 amrex::ParticleReal const pmag = std::sqrt(
53 mux * mux +
54 muy * muy +
55 muz * muz
56 );
57
59 }
60
73 amrex::RandomEngine const & engine
74 ) const
75 {
76 using namespace amrex::literals;
79
80 // Normalize the mean direction vector just in case:
81 amrex::ParticleReal mu_norm = std::sqrt(powi<2>(m_muX)+powi<2>(m_muY)+powi<2>(m_muZ));
82 amrex::ParticleReal mux = m_muX/mu_norm;
83 amrex::ParticleReal muy = m_muY/mu_norm;
84 amrex::ParticleReal muz = m_muZ/mu_norm;
85
86 // Evaluate constants independent of particle:
87 amrex::ParticleReal const muperp = std::sqrt(powi<2>(mux)+powi<2>(muy));
88 amrex::ParticleReal const a = (muperp==0) ? 0_prt : mux/muperp;
89 amrex::ParticleReal const b = (muperp==0) ? 1_prt : muy/muperp;
90
91 // Sample two iid random variables:
94
95 // Basic transformation of the random variables:
96 amrex::ParticleReal c = std::cos(2_prt*pi*x1);
97 amrex::ParticleReal s = std::sin(2_prt*pi*x1);
99 // The form of the function below is obtained from eq (30) of:
100 // D. Frisch and U. D. Hanebeck, "Deterministic Von Mises-Fisher Sampling on the Sphere Using
101 // Fibonacci Lattices", IEEE, 2023, DOI: 10.1109/SDF-MFI59545.2023.10361396
102 if(m_kappa > 0) {
103 t = 1_prt + std::log1p(x2 * std::expm1(-2_prt * m_kappa)) / m_kappa;
104 } else {
105 t = 1_prt - 2_prt * x2;
106 }
107
108 // Evaluation of the spin components
109 amrex::ParticleReal u = std::sqrt(1_prt-powi<2>(t));
110 sx = u * (b*c + a*muz*s) + t*mux;
111 sy = u * (-a*c + b*muz*s) + t*muy;
112 sz = u * (-muperp*s) + t*muz;
113
114 }
115
116
131 {
132 using namespace amrex::literals; // for _rt and _prt
133 using amrex::Math::powi;
134
135 AMREX_ASSERT_WITH_MESSAGE(pmag >= 0_prt, "Polarization magnitude must be greater or equal 0.");
136 AMREX_ASSERT_WITH_MESSAGE(pmag < 1_prt, "Polarization magnitude must be less than 1.");
137
138 // Evaluation of the inverse Langevin function. Here, we use the approximate expression
139 // due to R. Petrosyan. See:
140 // R. Petrosyan, Rheologica Acta 56, 21-26, 2016; doi:10.1007/s00397-016-0977-9
141 // R. Jedynak, Mathematics and Mechanics of Solids 24, 1-25, 2018; doi:10.1177/1081286518811395
142
143 amrex::ParticleReal concentration =
144 3_prt * pmag +
145 powi<2>(pmag) / 5_prt * std::sin(7_prt * pmag * 0.5_prt) +
146 powi<3>(pmag) / (1_prt - pmag);
147
148 return concentration;
149 }
150
153 };
154
155} // namespace impactx::distribution
156
157#endif // IMPACTX_DISTRIBUTION_SPINVMF
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST
amrex_particle_real ParticleReal
Real Random()
constexpr T powi(T x) noexcept
Definition All.H:28
@ s
fixed s as the independent variable
Definition ImpactXParticleContainer.H:37
@ t
fixed t as the independent variable
Definition ImpactXParticleContainer.H:38
amrex::ParticleReal m_muY
Definition SpinvMF.H:151
amrex::ParticleReal m_muX
Definition SpinvMF.H:151
amrex::ParticleReal m_muZ
Definition SpinvMF.H:151
SpinvMF(amrex::ParticleReal mux, amrex::ParticleReal muy, amrex::ParticleReal muz)
Definition SpinvMF.H:44
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(amrex::ParticleReal &AMREX_RESTRICT sx, amrex::ParticleReal &AMREX_RESTRICT sy, amrex::ParticleReal &AMREX_RESTRICT sz, amrex::RandomEngine const &engine) const
Definition SpinvMF.H:69
AMREX_GPU_HOST static AMREX_FORCE_INLINE amrex::ParticleReal inverse_Langevin(amrex::ParticleReal pmag)
Definition SpinvMF.H:130
amrex::ParticleReal m_kappa
components of a unit vector specifying the mean direction
Definition SpinvMF.H:152