OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
19template <typename FieldFunction, typename... Arguments>
21 PartBunch_t* bunch, const size_t& i, const double& t, const double dt,
22 Arguments&... args) const {
23 // Fourth order Runge-Kutta integrator
24 // arguments:
25 // x Current value of dependent variable
26 // t Independent variable (usually time)
27 // dt Step size (usually time step)
28 // i index of particle
29
30 double x[6];
31
32 // \todo this->copyTo(bunch->R(i), bunch->P(i), &x[0]);
33
34 double deriv1[6];
35 double deriv2[6];
36 double deriv3[6];
37 double deriv4[6];
38 double xtemp[6];
39
40 // Evaluate f1 = f(x,t).
41
42 bool outOfBound = derivate_m(bunch, x, t, deriv1, i, args...);
43 if (outOfBound)
44 return false;
45
46 // Evaluate f2 = f( x+dt*f1/2, t+dt/2 ).
47 const double half_dt = 0.5 * dt;
48 const double t_half = t + half_dt;
49
50 for (int j = 0; j < 6; ++j)
51 xtemp[j] = x[j] + half_dt * deriv1[j];
52
53 outOfBound = derivate_m(bunch, xtemp, t_half, deriv2, i, args...);
54 if (outOfBound)
55 return false;
56
57 // Evaluate f3 = f( x+dt*f2/2, t+dt/2 ).
58 for (int j = 0; j < 6; ++j)
59 xtemp[j] = x[j] + half_dt * deriv2[j];
60
61 outOfBound = derivate_m(bunch, xtemp, t_half, deriv3, i, args...);
62 if (outOfBound)
63 return false;
64
65 // Evaluate f4 = f( x+dt*f3, t+dt ).
66 double t_full = t + dt;
67 for (int j = 0; j < 6; ++j)
68 xtemp[j] = x[j] + dt * deriv3[j];
69
70 outOfBound = derivate_m(bunch, xtemp, t_full, deriv4, i, args...);
71 if (outOfBound)
72 return false;
73
74 // Return x(t+dt) computed from fourth-order R-K.
75 for (int j = 0; j < 6; ++j)
76 x[j] += dt / 6. * (deriv1[j] + deriv4[j] + 2. * (deriv2[j] + deriv3[j]));
77
78 // \todo this->copyFrom(bunch->R(i), bunch->P(i), &x[0]);
79
80 return true;
81}
82
83template <typename FieldFunction, typename... Arguments>
85 PartBunch_t* bunch, double* y, const double& t, double* yp, const size_t& i,
86 Arguments&... args) const {
87 // New for OPAL 2.0: Changing variables to m, T, s
88 // Currently: m, ns, kG
89
90 Vector_t<double, 3> externalE, externalB, tempR;
91
92 externalB = Vector_t<double, 3>(0.0, 0.0, 0.0);
93 externalE = Vector_t<double, 3>(0.0, 0.0, 0.0);
94
95 for (int j = 0; j < 3; ++j)
96 tempR(j) = y[j];
97
98 // \todo bunch->R(i) = tempR;
99
100 bool outOfBound = this->fieldfunc_m(t, i, externalE, externalB, args...);
101
102 double qtom = 1.0; // \todo = bunch->Q(i) / (bunch->M(i) * mass_coeff); // m^2/s^2/GV
103
104 double tempgamma = sqrt(1 + (y[3] * y[3] + y[4] * y[4] + y[5] * y[5]));
105
106 yp[0] = c_mtns / tempgamma * y[3]; // [m/ns]
107 yp[1] = c_mtns / tempgamma * y[4]; // [m/ns]
108 yp[2] = c_mtns / tempgamma * y[5]; // [m/ns]
109
110 /*
111 yp[0] = c_mmtns / tempgamma * y[3]; // [mm/ns]
112 yp[1] = c_mmtns / tempgamma * y[4]; // [mm/ns]
113 yp[2] = c_mmtns / tempgamma * y[5]; // [mm/ns]
114 */
115
116 yp[3] = (externalE(0) / Physics::c + (externalB(2) * y[4] - externalB(1) * y[5]) / tempgamma)
117 * qtom; // [1/ns]
118 yp[4] = (externalE(1) / Physics::c - (externalB(2) * y[3] - externalB(0) * y[5]) / tempgamma)
119 * qtom; // [1/ns];
120 yp[5] = (externalE(2) / Physics::c + (externalB(1) * y[3] - externalB(0) * y[4]) / tempgamma)
121 * qtom; // [1/ns];
122
123 return outOfBound;
124}
125
126template <typename FieldFunction, typename... Arguments>
128 const Vector_t<double, 3>& R, const Vector_t<double, 3>& P, double* x) const {
129 for (int j = 0; j < 3; j++) {
130 x[j] = R(j); // [x,y,z] (mm)
131 x[j + 3] = P(j); // [px,py,pz] (beta*gamma)
132 }
133}
134
135template <typename FieldFunction, typename... Arguments>
137 Vector_t<double, 3>& R, Vector_t<double, 3>& P, double* x) const {
138 for (int j = 0; j < 3; j++) {
139 R(j) = x[j]; // [x,y,z] (mm)
140 P(j) = x[j + 3]; // [px,py,pz] (beta*gamma)
141 }
142}
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
ippl::Vector< T, Dim > Vector_t
constexpr double c
The velocity of light in m/s.
Definition Physics.h:45
void copyFrom(Vector_t< double, 3 > &R, Vector_t< double, 3 > &P, double *x) const
Definition RK4.hpp:136
void copyTo(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, double *x) const
Definition RK4.hpp:127
bool derivate_m(PartBunch_t *bunch, double *y, const double &t, double *yp, const size_t &i, Arguments &... args) const
Definition RK4.hpp:84
bool doAdvance_m(PartBunch_t *bunch, const size_t &i, const double &t, const double dt, Arguments &... args) const
Definition RK4.hpp:20
const double c_mtns
Definition RK4.h:64
const FieldFunction & fieldfunc_m
Definition Stepper.h:65