ImpactX
Toggle main menu visibility
Loading...
Searching...
No Matches
src
particles
distribution
SpinvMF.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_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
22
namespace
impactx::distribution
23
{
24
struct
SpinvMF
25
{
44
SpinvMF
(
45
amrex::ParticleReal
mux,
46
amrex::ParticleReal
muy,
47
amrex::ParticleReal
muz
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
58
m_kappa
=
inverse_Langevin
(pmag);
59
}
60
68
AMREX_GPU_HOST_DEVICE
AMREX_FORCE_INLINE
69
void
operator()
(
70
amrex::ParticleReal
&
AMREX_RESTRICT
sx,
71
amrex::ParticleReal
&
AMREX_RESTRICT
sy,
72
amrex::ParticleReal
&
AMREX_RESTRICT
sz,
73
amrex::RandomEngine
const
& engine
74
)
const
75
{
76
using namespace
amrex::literals
;
77
using
amrex::Math::powi
;
78
using
ablastr::constant::math::pi
;
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:
92
amrex::ParticleReal
x1 =
amrex::Random
(engine);
93
amrex::ParticleReal
x2 =
amrex::Random
(engine);
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);
98
amrex::ParticleReal
t
;
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
128
AMREX_GPU_HOST
AMREX_FORCE_INLINE
129
static
amrex::ParticleReal
130
inverse_Langevin
(
amrex::ParticleReal
pmag)
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
151
amrex::ParticleReal
m_muX
,
m_muY
,
m_muZ
;
152
amrex::ParticleReal
m_kappa
;
153
};
154
155
}
// namespace impactx::distribution
156
157
#endif
// IMPACTX_DISTRIBUTION_SPINVMF
AMREX_ASSERT_WITH_MESSAGE
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
AMREX_FORCE_INLINE
#define AMREX_FORCE_INLINE
AMREX_RESTRICT
#define AMREX_RESTRICT
AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST_DEVICE
AMREX_GPU_HOST
#define AMREX_GPU_HOST
AMReX_Math.H
AMReX_REAL.H
AMReX_Random.H
constant.H
amrex::ParticleReal
amrex_particle_real ParticleReal
amrex::Random
Real Random()
ablastr::constant::math::pi
constexpr auto pi
amrex::Math::powi
constexpr T powi(T x) noexcept
amrex::literals
impactx::distribution
Definition
All.H:28
impactx::CoordSystem::s
@ s
fixed s as the independent variable
Definition
ImpactXParticleContainer.H:37
impactx::CoordSystem::t
@ t
fixed t as the independent variable
Definition
ImpactXParticleContainer.H:38
amrex::RandomEngine
impactx::distribution::SpinvMF::m_muY
amrex::ParticleReal m_muY
Definition
SpinvMF.H:151
impactx::distribution::SpinvMF::m_muX
amrex::ParticleReal m_muX
Definition
SpinvMF.H:151
impactx::distribution::SpinvMF::m_muZ
amrex::ParticleReal m_muZ
Definition
SpinvMF.H:151
impactx::distribution::SpinvMF::SpinvMF
SpinvMF(amrex::ParticleReal mux, amrex::ParticleReal muy, amrex::ParticleReal muz)
Definition
SpinvMF.H:44
impactx::distribution::SpinvMF::operator()
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
impactx::distribution::SpinvMF::inverse_Langevin
AMREX_GPU_HOST static AMREX_FORCE_INLINE amrex::ParticleReal inverse_Langevin(amrex::ParticleReal pmag)
Definition
SpinvMF.H:130
impactx::distribution::SpinvMF::m_kappa
amrex::ParticleReal m_kappa
components of a unit vector specifying the mean direction
Definition
SpinvMF.H:152
Generated by
1.17.0