WarpX
Toggle main menu visibility
Loading...
Searching...
No Matches
Source
Particles
Pusher
UpdateMomentumBoris.H
Go to the documentation of this file.
1
/* Copyright 2019 David Grote, Maxence Thevenet, Remi Lehe
2
* Weiqun Zhang
3
*
4
* This file is part of WarpX.
5
*
6
* License: BSD-3-Clause-LBNL
7
*/
8
#ifndef WARPX_PARTICLES_PUSHER_UPDATEMOMENTUM_BORIS_H_
9
#define WARPX_PARTICLES_PUSHER_UPDATEMOMENTUM_BORIS_H_
10
11
#include <
AMReX_REAL.H
>
12
19
AMREX_GPU_HOST_DEVICE
AMREX_INLINE
20
void
UpdateMomentumBoris
(
21
amrex::ParticleReal
& ux,
amrex::ParticleReal
& uy,
amrex::ParticleReal
& uz,
22
const
amrex::ParticleReal
Ex,
const
amrex::ParticleReal
Ey,
const
amrex::ParticleReal
Ez,
23
const
amrex::ParticleReal
Bx,
const
amrex::ParticleReal
By,
const
amrex::ParticleReal
Bz,
24
const
amrex::ParticleReal
q,
const
amrex::ParticleReal
m,
const
amrex::Real
dt,
MomentumPushType
momentum_push_type =
MomentumPushType::Full
)
25
{
26
using namespace
amrex::literals
;
27
28
const
amrex::ParticleReal
econst = 0.5_prt*q*dt/m;
29
30
if
(momentum_push_type ==
MomentumPushType::FirstHalf
|| momentum_push_type ==
MomentumPushType::Full
) {
31
// First half-push for E
32
ux += econst*Ex;
33
uy += econst*Ey;
34
uz += econst*Ez;
35
}
36
// Compute temporary gamma factor
37
constexpr
auto
inv_c2 =
PhysConst::inv_c2_v< amrex::ParticleReal>
;
38
const
amrex::ParticleReal
inv_gamma = 1._prt/std::sqrt(1._prt + (ux*ux + uy*uy + uz*uz)*inv_c2);
39
// Magnetic rotation
40
// - Compute temporary variables
41
amrex::ParticleReal
tx = econst*inv_gamma*Bx;
42
amrex::ParticleReal
ty = econst*inv_gamma*By;
43
amrex::ParticleReal
tz = econst*inv_gamma*Bz;
44
if
(momentum_push_type ==
MomentumPushType::FirstHalf
|| momentum_push_type ==
MomentumPushType::SecondHalf
) {
45
// For a full push, the Boris algorithm rotates the momentum about the vector t,
46
// by an angle alpha that satisfies tan(alpha/2) = |t| = dt q B /(2 gamma m).
47
// (See Birdsall and Langdon, "Plasma Physics via Computer Simulation", section 4-3, eq. 10)
48
// For half pushes, the combination of the first and second half push should result in a rotation by the same alpha.
49
// Therefore, each half push should use a modified t that results in a rotation by only alpha/2.
50
// Using the identity tan(alpha/2) = 2 tan(alpha/4) / (1 - tan(alpha/4)^2), one can see that t should be
51
// rescaled so that |t_half|/|t_full| = tan(alpha/4)/tan(alpha/2) = (sqrt(1 + |t_full|^2) - 1) / |t_full|^2.
52
const
amrex::ParticleReal
tsq = tx*tx + ty*ty + tz*tz;
53
const
amrex::ParticleReal
factor = (tsq > 0._prt) ? (std::sqrt(1._prt + tsq) - 1._prt) / tsq : 0.5_prt;
54
tx *= factor;
55
ty *= factor;
56
tz *= factor;
57
}
58
const
amrex::ParticleReal
tsqi = 2._prt/(1._prt + tx*tx + ty*ty + tz*tz);
59
const
amrex::ParticleReal
sx = tx*tsqi;
60
const
amrex::ParticleReal
sy = ty*tsqi;
61
const
amrex::ParticleReal
sz = tz*tsqi;
62
const
amrex::ParticleReal
ux_p = ux + uy*tz - uz*ty;
63
const
amrex::ParticleReal
uy_p = uy + uz*tx - ux*tz;
64
const
amrex::ParticleReal
uz_p = uz + ux*ty - uy*tx;
65
// - Update momentum
66
ux += uy_p*sz - uz_p*sy;
67
uy += uz_p*sx - ux_p*sz;
68
uz += ux_p*sy - uy_p*sx;
69
if
(momentum_push_type ==
MomentumPushType::SecondHalf
|| momentum_push_type ==
MomentumPushType::Full
) {
70
// Second half-push for E
71
ux += econst*Ex;
72
uy += econst*Ey;
73
uz += econst*Ez;
74
}
75
}
76
#endif
// WARPX_PARTICLES_PUSHER_UPDATEMOMENTUM_BORIS_H_
AMREX_INLINE
#define AMREX_INLINE
AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST_DEVICE
AMReX_REAL.H
UpdateMomentumBoris
AMREX_GPU_HOST_DEVICE AMREX_INLINE void UpdateMomentumBoris(amrex::ParticleReal &ux, amrex::ParticleReal &uy, amrex::ParticleReal &uz, const amrex::ParticleReal Ex, const amrex::ParticleReal Ey, const amrex::ParticleReal Ez, const amrex::ParticleReal Bx, const amrex::ParticleReal By, const amrex::ParticleReal Bz, const amrex::ParticleReal q, const amrex::ParticleReal m, const amrex::Real dt, MomentumPushType momentum_push_type=MomentumPushType::Full)
Push the particle's positions over one timestep, given the value of its momenta ux,...
Definition
UpdateMomentumBoris.H:20
MomentumPushType
MomentumPushType
For advanced collision algorithms that split the particle push in substeps.
Definition
WarpXAlgorithmSelection.H:188
MomentumPushType::SecondHalf
@ SecondHalf
Definition
WarpXAlgorithmSelection.H:188
MomentumPushType::Full
@ Full
Definition
WarpXAlgorithmSelection.H:188
MomentumPushType::FirstHalf
@ FirstHalf
Definition
WarpXAlgorithmSelection.H:188
amrex::Real
amrex_real Real
amrex::ParticleReal
amrex_particle_real ParticleReal
ablastr::constant::SI::inv_c2_v
constexpr auto inv_c2_v
inverse of the square of the vacuum speed of light [s^2/m^2] (variable template)
Definition
constant.H:153
amrex::literals
Generated by
1.17.0