WarpX
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 
25 void UpdatePosition(amrex::ParticleReal& x, amrex::ParticleReal& y, amrex::ParticleReal& z,
26  const amrex::ParticleReal ux, const amrex::ParticleReal uy, const amrex::ParticleReal uz,
27  const amrex::Real dt )
28 {
29  using namespace amrex::literals;
30 
31  constexpr amrex::ParticleReal inv_c2 = 1._prt/(PhysConst::c*PhysConst::c);
32 
33  // Compute inverse Lorentz factor
34  const amrex::ParticleReal inv_gamma = 1._prt/std::sqrt(1._prt + (ux*ux + uy*uy + uz*uz)*inv_c2);
35  // Update positions over one time step
36 #if (AMREX_SPACEDIM >= 2)
37  x += ux * inv_gamma * dt;
38 #else
40 #endif
41 #if defined(WARPX_DIM_3D) || defined(WARPX_DIM_RZ) // RZ pushes particles in 3D
42  y += uy * inv_gamma * dt;
43 #else
45 #endif
46  z += uz * inv_gamma * dt;
47 }
48 
56 void UpdatePositionImplicit(amrex::ParticleReal& x, amrex::ParticleReal& y, amrex::ParticleReal& z,
57  const amrex::ParticleReal ux_n, const amrex::ParticleReal uy_n, const amrex::ParticleReal uz_n,
58  const amrex::ParticleReal ux, const amrex::ParticleReal uy, const amrex::ParticleReal uz,
59  const amrex::Real dt )
60 {
61  using namespace amrex::literals;
62 
63  constexpr amrex::ParticleReal inv_c2 = 1._prt/(PhysConst::c*PhysConst::c);
64 
65  // Compute inverse Lorentz factor, the average of gamma at time levels n and n+1
66  // The ux,uy,uz are the velocities at time level n+1/2
67  const amrex::ParticleReal ux_np1 = 2._prt*ux - ux_n;
68  const amrex::ParticleReal uy_np1 = 2._prt*uy - uy_n;
69  const amrex::ParticleReal uz_np1 = 2._prt*uz - uz_n;
70  const amrex::ParticleReal gamma_n = std::sqrt(1._prt + (ux_n*ux_n + uy_n*uy_n + uz_n*uz_n)*inv_c2);
71  const amrex::ParticleReal gamma_np1 = std::sqrt(1._prt + (ux_np1*ux_np1 + uy_np1*uy_np1 + uz_np1*uz_np1)*inv_c2);
72  const amrex::ParticleReal inv_gamma = 2.0_prt/(gamma_n + gamma_np1);
73 
74  // Update positions over one time step
75 #if (AMREX_SPACEDIM >= 2)
76  x += ux * inv_gamma * dt;
77 #else
79 #endif
80 #if defined(WARPX_DIM_3D) || defined(WARPX_DIM_RZ) // RZ pushes particles in 3D
81  y += uy * inv_gamma * dt;
82 #else
84 #endif
85  z += uz * inv_gamma * dt;
86 }
87 
93 void PositionNorm( amrex::ParticleReal dxp, amrex::ParticleReal dyp, amrex::ParticleReal dzp,
94  amrex::ParticleReal& dxp_save, amrex::ParticleReal& dyp_save, amrex::ParticleReal& dzp_save,
95  amrex::ParticleReal idxg2, amrex::ParticleReal idyg2, amrex::ParticleReal idzg2,
96  amrex::ParticleReal& step_norm, const int iter )
97 {
98  using namespace amrex::literals;
99 
100 #if defined(WARPX_DIM_1D_Z)
101  amrex::ignore_unused(dxp, dxp_save, idxg2);
102 #endif
103 #if !defined(WARPX_DIM_3D)
104  amrex::ignore_unused(dyp, dyp_save, idyg2);
105 #endif
106 
107  if (iter==0) { step_norm = 1.0_prt; }
108  else {
109  step_norm = (dzp - dzp_save)*(dzp - dzp_save)*idzg2;
110 #if !defined(WARPX_DIM_1D_Z)
111  step_norm += (dxp - dxp_save)*(dxp - dxp_save)*idxg2;
112 #endif
113 #if defined(WARPX_DIM_3D)
114  step_norm += (dyp - dyp_save)*(dyp - dyp_save)*idyg2;
115 #elif defined(WARPX_DIM_RZ)
116  step_norm += (dyp - dyp_save)*(dyp - dyp_save)*idxg2;
117 #endif
118  step_norm = std::sqrt(step_norm);
119  }
120  dzp_save = dzp;
121 #if !defined(WARPX_DIM_1D_Z)
122  dxp_save = dxp;
123 #endif
124 #if defined(WARPX_DIM_3D) || defined(WARPX_DIM_RZ)
125  dyp_save = dyp;
126 #endif
127 
128 }
129 
130 #endif // WARPX_PARTICLES_PUSHER_UPDATEPOSITION_H_
#define AMREX_INLINE
#define AMREX_GPU_HOST_DEVICE
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:56
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)
Push the particle's positions over one timestep, given the value of its momenta ux,...
Definition: UpdatePosition.H:25
AMREX_GPU_HOST_DEVICE AMREX_INLINE void PositionNorm(amrex::ParticleReal dxp, amrex::ParticleReal dyp, amrex::ParticleReal dzp, amrex::ParticleReal &dxp_save, amrex::ParticleReal &dyp_save, amrex::ParticleReal &dzp_save, amrex::ParticleReal idxg2, amrex::ParticleReal idyg2, amrex::ParticleReal idzg2, amrex::ParticleReal &step_norm, const int iter)
Check particle position for convergence. This is used by the theta-implicit and semi-implicit time so...
Definition: UpdatePosition.H:93
static constexpr auto c
vacuum speed of light [m/s]
Definition: constant.H:44
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
float dt
Definition: stencil.py:442