- #1
Zebx
- 12
- 3
- TL;DR Summary
- Comparing the error behaviour of a 3-body solution with Runge Kutta 4 by varying the stepsize I get 2^p = 2 instead of 16.
Hi, I'm trying to simulate a 3-body problem with a star at the center of reference system and 2 body orbiting around it using Runge Kutta 4. The 2 bodies perturb each other orbits gravitationally, so my ode system is actually a coupled armonic oscillator and I evaluate the solution of both bodies simultaneously. The code I use for Runge Kutta is the following
The RK function returns void cause I call it through one of the body solution, which is declared before I call Runge Kutta. I didn't post the entire code cause it's very long, but I will post other parts of it if needed.
The vectors u and p takes the positions and velocities of the first and the second body respectively. The variables are in the order (x, Vx, y, Vy, z, Vz), and I have x1 values from u[0] to u[N-1], V1x values from u[N] to u[2*N - 1] and so on, so the variables are all in one vector. The same goes for p. The function return 12 values (x1, V1x, y1, V1y, z1, V1z, x2, V2x, y2, V2y, z2, V2z), taking as arguments the positions and velocities of both bodies at the step n of the iteration. The first argument (time) is there just for completness. The last two argument functions are {0} but they would be filled with other bodies variables in case of 4 and 5 bodies simulation. The function work well with another method I'm using (velocity Verlet), and I get the correct results for the order of the solution in that case, and that's the problem: when I check for the behaviour of the error varying the stepsize using Runge Kutta 4 I always get 2 instead of 16. It's like I should use a different stepsize for one of the two bodies, but since they're coupled this would turn everything in "a dog chasing is own tail". How could I fix this? Thank you.
C++:
void RK(double h, fun f, vector<CB> obj, vector<Sol> s, int ab_order=0) {
int dim = 6;
vector<double> p = s[0].u;
vector<double> K1(2*dim);
vector<double> K2 = K1;
vector<double> K3 = K1;
vector<double> K4 = K1;
for (int n = 0; n < N-1; n++) {
t[n+1] = t[0] + (n+1)*h;
K1 = f(t[n] , {u[n] , u[N+n] , u[2*N+n] , u[3*N+n] , u[4*N+n] , u[5*N+n]} , obj, {p[n], p[N+n], p[2*N+n], p[3*N+n], p[4*N+n], p[5*N+n]}, {0}, {0});
K2 = f(t[n] + h/2, {u[n] + h*K1[0]/2, u[N+n] + h*K1[1]/2, u[2*N+n] + h*K1[2]/2, u[3*N+n] + h*K1[3]/2, u[4*N+n] + h*K1[4]/2, u[5*N+n] + h*K1[5]/2}, obj, {p[n], p[N+n], p[2*N+n], p[3*N+n], p[4*N+n], p[5*N+n]}, {0}, {0});
K3 = f(t[n] + h/2, {u[n] + h*K2[0]/2, u[N+n] + h*K2[1]/2, u[2*N+n] + h*K2[2]/2, u[3*N+n] + h*K2[3]/2, u[4*N+n] + h*K2[4]/2, u[5*N+n] + h*K2[5]/2}, obj, {p[n], p[N+n], p[2*N+n], p[3*N+n], p[4*N+n], p[5*N+n]}, {0}, {0});
K4 = f(t[n] + h , {u[n] + h*K3[0] , u[N+n] + h*K3[1] , u[2*N+n] + h*K3[2] , u[3*N+n] + h*K3[3] , u[4*N+n] + h*K3[4] , u[5*N+n] + h*K3[5]} , obj, {p[n], p[N+n], p[2*N+n], p[3*N+n], p[4*N+n], p[5*N+n]}, {0}, {0});
while (k < dim) {
u[k*N+n+1] = u[k*N+n] + h*(K1[k] + 2*K2[k] + 2*K3[k] + K4[k])/6;
p[k*N+n+1] = p[k*N+n] + h*(K1[dim+k] + 2*K2[dim+k] + 2*K3[dim+k] + K4[dim+k])/6;
k++;
}
k = 0;
}
vector<double>().swap(K1);
vector<double>().swap(K2);
vector<double>().swap(K3);
vector<double>().swap(K4);
vector<double>().swap(p);
}
The RK function returns void cause I call it through one of the body solution, which is declared before I call Runge Kutta. I didn't post the entire code cause it's very long, but I will post other parts of it if needed.
The vectors u and p takes the positions and velocities of the first and the second body respectively. The variables are in the order (x, Vx, y, Vy, z, Vz), and I have x1 values from u[0] to u[N-1], V1x values from u[N] to u[2*N - 1] and so on, so the variables are all in one vector. The same goes for p. The function return 12 values (x1, V1x, y1, V1y, z1, V1z, x2, V2x, y2, V2y, z2, V2z), taking as arguments the positions and velocities of both bodies at the step n of the iteration. The first argument (time) is there just for completness. The last two argument functions are {0} but they would be filled with other bodies variables in case of 4 and 5 bodies simulation. The function work well with another method I'm using (velocity Verlet), and I get the correct results for the order of the solution in that case, and that's the problem: when I check for the behaviour of the error varying the stepsize using Runge Kutta 4 I always get 2 instead of 16. It's like I should use a different stepsize for one of the two bodies, but since they're coupled this would turn everything in "a dog chasing is own tail". How could I fix this? Thank you.
Last edited: