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