WarpX
Loading...
Searching...
No Matches
UpdatePosition.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_UPDATEPOSITION_H_
9#define WARPX_PARTICLES_PUSHER_UPDATEPOSITION_H_
10
11#include "Utils/WarpXConst.H"
12
13#include <AMReX.H>
14#include <AMReX_FArrayBox.H>
15#include <AMReX_REAL.H>
16
17
18
24void UpdatePosition ([[maybe_unused]] amrex::ParticleReal& x,
25 [[maybe_unused]] amrex::ParticleReal& y,
26 [[maybe_unused]] amrex::ParticleReal& z,
27 const amrex::ParticleReal ux, const amrex::ParticleReal uy, const amrex::ParticleReal uz,
28 const amrex::Real dt,
29 amrex::ParticleReal const mass)
30{
31 using namespace amrex::literals;
32
33 amrex::ParticleReal const u2 = ux*ux + uy*uy + uz*uz;
34
35 // massive particles
36 if (mass > 0.0_rt) {
37 constexpr amrex::ParticleReal inv_c2 = 1._prt/(PhysConst::c*PhysConst::c);
38 const amrex::ParticleReal inv_gamma = 1._prt/std::sqrt(1._prt + u2*inv_c2);
39
40 // Update positions over one time step
41#if !defined(WARPX_DIM_1D_Z)
42 x += ux * inv_gamma * dt;
43#endif
44#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
45 // Particles pushed in 3D even in 1D cylindrical, 1D spherical, and 2D cylindrical geometry
46 y += uy * inv_gamma * dt;
47#endif
48#if !defined(WARPX_DIM_RCYLINDER)
49 z += uz * inv_gamma * dt;
50#endif
51 }
52 // massless particles (photons)
53 else {
54 if (u2 > 0._prt) {
55 amrex::ParticleReal const c_over_unorm = PhysConst::c/std::sqrt(u2);
56
57 // Update positions over one time step
58#if !defined(WARPX_DIM_1D_Z)
59 x += ux * c_over_unorm * dt;
60#endif
61#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
62 // Particles pushed in 3D even in 1D cylindrical, 1D spherical, and 2D cylindrical geometry
63 y += uy * c_over_unorm * dt;
64#endif
65#if !defined(WARPX_DIM_RCYLINDER)
66 z += uz * c_over_unorm * dt;
67#endif
68 }
69 }
70}
71
77amrex::ParticleReal GetImplicitGammaInverse (const amrex::ParticleReal uxp_n,
78 const amrex::ParticleReal uyp_n,
79 const amrex::ParticleReal uzp_n,
80 const amrex::ParticleReal uxp_nph,
81 const amrex::ParticleReal uyp_nph,
82 const amrex::ParticleReal uzp_nph) noexcept
83{
84 using namespace amrex::literals;
85
86 constexpr amrex::ParticleReal inv_c2 = 1.0_prt/(PhysConst::c*PhysConst::c);
87
88 const amrex::ParticleReal uxp_np1 = 2._prt*uxp_nph - uxp_n;
89 const amrex::ParticleReal uyp_np1 = 2._prt*uyp_nph - uyp_n;
90 const amrex::ParticleReal uzp_np1 = 2._prt*uzp_nph - uzp_n;
91 const amrex::ParticleReal gamma_n = std::sqrt(1._prt + (uxp_n*uxp_n + uyp_n*uyp_n + uzp_n*uzp_n)*inv_c2);
92 const amrex::ParticleReal gamma_np1 = std::sqrt(1._prt + (uxp_np1*uxp_np1 + uyp_np1*uyp_np1 + uzp_np1*uzp_np1)*inv_c2);
93 const amrex::ParticleReal gaminv = 2._prt/(gamma_n + gamma_np1);
94
95 return gaminv;
96}
97
105void UpdatePositionImplicit ([[maybe_unused]] amrex::ParticleReal& x,
106 [[maybe_unused]] amrex::ParticleReal& y,
107 [[maybe_unused]] amrex::ParticleReal& z,
108 const amrex::ParticleReal ux_n, const amrex::ParticleReal uy_n, const amrex::ParticleReal uz_n,
109 const amrex::ParticleReal ux, const amrex::ParticleReal uy, const amrex::ParticleReal uz,
110 const amrex::Real dt )
111{
112
113 // Compute inverse Lorentz factor, the average of gamma at time levels n and n+1
114 const amrex::ParticleReal inv_gamma = GetImplicitGammaInverse(ux_n, uy_n, uz_n, ux, uy, uz);
115
116 // Update positions over one time step
117#if !defined(WARPX_DIM_1D_Z)
118 x += ux * inv_gamma * dt;
119#endif
120#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
121 // Radial pushes particles in 3D
122 y += uy * inv_gamma * dt;
123#endif
124#if !defined(WARPX_DIM_RCYLINDER)
125 z += uz * inv_gamma * dt;
126#endif
127}
128
134void PositionNorm ([[maybe_unused]] const amrex::ParticleReal dxp,
135 [[maybe_unused]] const amrex::ParticleReal dyp,
136 [[maybe_unused]] const amrex::ParticleReal dzp,
137 [[maybe_unused]] const amrex::ParticleReal dxp_save,
138 [[maybe_unused]] const amrex::ParticleReal dyp_save,
139 [[maybe_unused]] const amrex::ParticleReal dzp_save,
140 [[maybe_unused]] const amrex::ParticleReal idxg2,
141 [[maybe_unused]] const amrex::ParticleReal idyg2,
142 [[maybe_unused]] const amrex::ParticleReal idzg2,
143 amrex::ParticleReal& step_norm )
144{
145 using namespace amrex::literals;
146
147#if !defined(WARPX_DIM_RCYLINDER)
148 step_norm = (dzp - dzp_save)*(dzp - dzp_save)*idzg2;
149#else
150 step_norm = 0._prt;
151#endif
152#if !defined(WARPX_DIM_1D_Z)
153 step_norm += (dxp - dxp_save)*(dxp - dxp_save)*idxg2;
154#endif
155#if defined(WARPX_DIM_3D)
156 step_norm += (dyp - dyp_save)*(dyp - dyp_save)*idyg2;
157#elif defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
158 step_norm += (dyp - dyp_save)*(dyp - dyp_save)*idxg2;
159#endif
160 step_norm = std::sqrt(step_norm);
161
162}
163
164#endif // WARPX_PARTICLES_PUSHER_UPDATEPOSITION_H_
#define AMREX_FORCE_INLINE
#define AMREX_INLINE
#define AMREX_GPU_HOST_DEVICE
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal GetImplicitGammaInverse(const amrex::ParticleReal uxp_n, const amrex::ParticleReal uyp_n, const amrex::ParticleReal uzp_n, const amrex::ParticleReal uxp_nph, const amrex::ParticleReal uyp_nph, const amrex::ParticleReal uzp_nph) noexcept
Compute the inverse Lorentz factor for the position update in the implicit methods,...
Definition UpdatePosition.H:77
AMREX_GPU_HOST_DEVICE AMREX_INLINE void UpdatePositionImplicit(amrex::ParticleReal &x, amrex::ParticleReal &y, amrex::ParticleReal &z, const amrex::ParticleReal ux_n, const amrex::ParticleReal uy_n, const amrex::ParticleReal uz_n, const amrex::ParticleReal ux, const amrex::ParticleReal uy, const amrex::ParticleReal uz, const amrex::Real dt)
Push the particle's positions over one timestep, given the value of its momenta ux,...
Definition UpdatePosition.H:105
AMREX_GPU_HOST_DEVICE AMREX_INLINE void PositionNorm(const amrex::ParticleReal dxp, const amrex::ParticleReal dyp, const amrex::ParticleReal dzp, const amrex::ParticleReal dxp_save, const amrex::ParticleReal dyp_save, const amrex::ParticleReal dzp_save, const amrex::ParticleReal idxg2, const amrex::ParticleReal idyg2, const amrex::ParticleReal idzg2, amrex::ParticleReal &step_norm)
Check particle position for convergence. This is used by the Picard method used to achieve a self-con...
Definition UpdatePosition.H:134
AMREX_GPU_HOST_DEVICE AMREX_INLINE void UpdatePosition(amrex::ParticleReal &x, amrex::ParticleReal &y, amrex::ParticleReal &z, const amrex::ParticleReal ux, const amrex::ParticleReal uy, const amrex::ParticleReal uz, const amrex::Real dt, amrex::ParticleReal const mass)
Push the particle position over one time step, given the value of its momenta ux, uy,...
Definition UpdatePosition.H:24
constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:149