OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
RK4.hpp
Go to the documentation of this file.
1 //
2 // Class RK4
3 // Fourth order Runge-Kutta time integrator
4 //
5 // Copyright (c) 2008 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved
7 //
8 // This file is part of OPAL.
9 //
10 // OPAL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17 //
18 
19 template <typename FieldFunction, typename ... Arguments>
21  const size_t& i,
22  const double& t,
23  const double dt,
24  Arguments& ... args) const
25 {
26  // Fourth order Runge-Kutta integrator
27  // arguments:
28  // x Current value of dependent variable
29  // t Independent variable (usually time)
30  // dt Step size (usually time step)
31  // i index of particle
32 
33  double x[6];
34 
35  this->copyTo(bunch->R[i], bunch->P[i], &x[0]);
36 
37  double deriv1[6];
38  double deriv2[6];
39  double deriv3[6];
40  double deriv4[6];
41  double xtemp[6];
42 
43  // Evaluate f1 = f(x,t).
44 
45  bool outOfBound = derivate_m(bunch, x, t, deriv1 , i, args ...);
46  if (outOfBound)
47  return false;
48 
49  // Evaluate f2 = f( x+dt*f1/2, t+dt/2 ).
50  const double half_dt = 0.5 * dt;
51  const double t_half = t + half_dt;
52 
53  for(int j = 0; j < 6; ++j)
54  xtemp[j] = x[j] + half_dt * deriv1[j];
55 
56  outOfBound = derivate_m(bunch, xtemp, t_half, deriv2 , i, args ...);
57  if (outOfBound)
58  return false;
59 
60  // Evaluate f3 = f( x+dt*f2/2, t+dt/2 ).
61  for(int j = 0; j < 6; ++j)
62  xtemp[j] = x[j] + half_dt * deriv2[j];
63 
64  outOfBound = derivate_m(bunch, xtemp, t_half, deriv3 , i, args ...);
65  if (outOfBound)
66  return false;
67 
68  // Evaluate f4 = f( x+dt*f3, t+dt ).
69  double t_full = t + dt;
70  for(int j = 0; j < 6; ++j)
71  xtemp[j] = x[j] + dt * deriv3[j];
72 
73  outOfBound = derivate_m(bunch, xtemp, t_full, deriv4 , i, args ...);
74  if (outOfBound)
75  return false;
76 
77  // Return x(t+dt) computed from fourth-order R-K.
78  for(int j = 0; j < 6; ++j)
79  x[j] += dt / 6.*(deriv1[j] + deriv4[j] + 2.*(deriv2[j] + deriv3[j]));
80 
81  this->copyFrom(bunch->R[i], bunch->P[i], &x[0]);
82 
83  return true;
84 }
85 
86 
87 template <typename FieldFunction, typename ... Arguments>
89  double* y,
90  const double& t,
91  double* yp,
92  const size_t& i,
93  Arguments& ... args) const
94 {
95  // New for OPAL 2.0: Changing variables to m, T, s
96  // Currently: m, ns, kG
97 
98  Vector_t externalE, externalB, tempR;
99 
100  externalB = Vector_t(0.0, 0.0, 0.0);
101  externalE = Vector_t(0.0, 0.0, 0.0);
102 
103  for(int j = 0; j < 3; ++j)
104  tempR(j) = y[j];
105 
106  bunch->R[i] = tempR;
107 
108  bool outOfBound = this->fieldfunc_m(t, i, externalE, externalB, args ...);
109 
110  double qtom = bunch->Q[i] / (bunch->M[i] * mass_coeff); // m^2/s^2/GV
111 
112  double tempgamma = sqrt(1 + (y[3] * y[3] + y[4] * y[4] + y[5] * y[5]));
113 
114  yp[0] = c_mtns / tempgamma * y[3]; // [m/ns]
115  yp[1] = c_mtns / tempgamma * y[4]; // [m/ns]
116  yp[2] = c_mtns / tempgamma * y[5]; // [m/ns]
117 
118 /*
119  yp[0] = c_mmtns / tempgamma * y[3]; // [mm/ns]
120  yp[1] = c_mmtns / tempgamma * y[4]; // [mm/ns]
121  yp[2] = c_mmtns / tempgamma * y[5]; // [mm/ns]
122 */
123 
124  yp[3] = (externalE(0) / Physics::c + (externalB(2) * y[4] - externalB(1) * y[5]) / tempgamma) * qtom; // [1/ns]
125  yp[4] = (externalE(1) / Physics::c - (externalB(2) * y[3] - externalB(0) * y[5]) / tempgamma) * qtom; // [1/ns];
126  yp[5] = (externalE(2) / Physics::c + (externalB(1) * y[3] - externalB(0) * y[4]) / tempgamma) * qtom; // [1/ns];
127 
128  return outOfBound;
129 }
130 
131 
132 template <typename FieldFunction, typename ... Arguments>
134  const Vector_t& P,
135  double* x) const
136 {
137  for (int j = 0; j < 3; j++) {
138  x[j] = R(j); // [x,y,z] (mm)
139  x[j+3] = P(j); // [px,py,pz] (beta*gamma)
140  }
141 }
142 
143 
144 template <typename FieldFunction, typename ... Arguments>
146  Vector_t& P,
147  double* x) const
148 {
149  for(int j = 0; j < 3; j++) {
150  R(j) = x[j]; // [x,y,z] (mm)
151  P(j) = x[j+3]; // [px,py,pz] (beta*gamma)
152  }
153 }
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
ParticlePos_t & R
ParticleAttrib< double > M
ParticleAttrib< Vector_t > P
ParticleAttrib< double > Q
bool derivate_m(PartBunchBase< double, 3 > *bunch, double *y, const double &t, double *yp, const size_t &i, Arguments &... args) const
Definition: RK4.hpp:88
bool doAdvance_m(PartBunchBase< double, 3 > *bunch, const size_t &i, const double &t, const double dt, Arguments &... args) const
Definition: RK4.hpp:20
void copyFrom(Vector_t &R, Vector_t &P, double *x) const
Definition: RK4.hpp:145
void copyTo(const Vector_t &R, const Vector_t &P, double *x) const
Definition: RK4.hpp:133
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6