OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
19template <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
87template <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
132template <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
144template <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:45
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