OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
BorisPusher.h
Go to the documentation of this file.
1 #ifndef CLASSIC_PartPusher_H
2 #define CLASSIC_PartPusher_H
3 
4 #include "Algorithms/Vektor.h"
5 #include "Algorithms/PartData.h"
6 #include "Physics/Physics.h"
7 
8 /*
9 
10 
11  */
12 
13 class BorisPusher {
14 
15 public:
16  BorisPusher(const PartData &ref);
17  BorisPusher();
18  void initialise(const PartData *ref);
19 
20  void kick(const Vector_t &R, Vector_t &P,
21  const Vector_t &Ef, const Vector_t &Bf,
22  const double &dt) const;
23 
24  void kick(const Vector_t &R, Vector_t &P,
25  const Vector_t &Ef, const Vector_t &Bf,
26  const double &dt, const double &mass,
27  const double &charge) const;
28 
29  void push(Vector_t &R, const Vector_t &P, const double &dt) const;
30 
31 private:
33 };
34 
36  itsReference(&ref)
37 { }
38 
40  itsReference(NULL)
41 { }
42 
44 {
45  itsReference = ref;
46 }
47 
48 inline void BorisPusher::kick(const Vector_t &R, Vector_t &P,
49  const Vector_t &Ef, const Vector_t &Bf,
50  const double &dt) const
51 {
52  kick(R, P, Ef, Bf, dt, itsReference->getM(), itsReference->getQ());
53 }
54 
55 
56 inline void BorisPusher::kick(const Vector_t &R, Vector_t &P,
57  const Vector_t &Ef, const Vector_t &Bf,
58  const double &dt, const double &mass,
59  const double &charge) const
60 {
61  // Implementation follows chapter 4-4, p. 61 - 63 from
62  // Birdsall, C. K. and Langdon, A. B. (1985). Plasma physics
63  // via computer simulation.
64  //
65  // Up to finite precision effects, the new implementation is equivalent to the
66  // old one, but uses less floating point operations.
67  //
68  // Relativistic variant implemented below is described in
69  // chapter 15-4, p. 356 - 357.
70  // However, since other units are used here, small
71  // modifications are required. The relativistic variant can be derived
72  // from the nonrelativistic one by replacing
73  // mass
74  // by
75  // gamma * rest mass
76  // and transforming the units.
77  //
78  // Parameters:
79  // R = x / (c * dt): Scaled position x, not used in here
80  // P = v / c * gamma: Scaled velocity v
81  // Ef: Electric field
82  // Bf: Magnetic field
83  // dt: Timestep
84  // mass = rest energy = rest mass * c * c
85  // charge
86 
87  using Physics::c;
88 
89  // Half step E
90  P += 0.5 * dt * charge * c / mass * Ef;
91 
92  // Full step B
93 
94  /*
95  LF
96  double const gamma = sqrt(1.0 + dot(P, P));
97  Vector_t const t = dt * charge * c * c / (gamma * mass) * Bf;
98  P += cross(P, t);
99  */
100 
101  double const gamma = sqrt(1.0 + dot(P, P));
102  Vector_t const t = 0.5 * dt * charge * c * c / (gamma * mass) * Bf;
103  Vector_t const w = P + cross(P, t);
104  Vector_t const s = 2.0 / (1.0 + dot(t, t)) * t;
105  P += cross(w, s);
106 
107  /* a poor Leap-Frog
108  P += 1.0 * dt * charge * c * c / (gamma * mass) * cross(P,Bf);
109  */
110 
111  // Half step E
112  P += 0.5 * dt * charge * c / mass * Ef;
113 }
114 
115 
116 inline void BorisPusher::push(Vector_t &R, const Vector_t &P, const double &/* dt */) const {
123  R += 0.5 * P / sqrt(1.0 + dot(P, P));
124 }
125 
126 #endif
Particle reference data.
Definition: PartData.h:38
const PartData * itsReference
Definition: BorisPusher.h:32
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
double getQ() const
The constant charge per particle.
Definition: PartData.h:107
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
Definition: Vector3D.cpp:111
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
Definition: BorisPusher.h:48
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
double getM() const
The constant mass per particle.
Definition: PartData.h:112
void push(Vector_t &R, const Vector_t &P, const double &dt) const
Definition: BorisPusher.h:116
void initialise(const PartData *ref)
Definition: BorisPusher.h:43