#include <stdio.h>
#include <stdlib.h>
#include "rebound.h"
#include "integrator_leapfrog.h"
const double reb_integrator_leapfrog_lf4_a = 0.675603595979828817023843904485;
const double reb_integrator_leapfrog_lf6_a[5] = {0.1867, 0.5554970237124784, 0.1294669489134754, -0.843265623387734, 0.9432033015235604};
const double reb_integrator_leapfrog_lf8_a[9] = {0.128865979381443, 0.581514087105251, -0.410175371469850, 0.1851469357165877, -0.4095523434208514, 0.1444059410800120, 0.2783355003936797, 0.3149566839162949, -0.6269948254051343979};
static void drift(struct reb_simulation* r, double dt){
const unsigned int N = r->N;
struct reb_particle* restrict const particles = r->particles;
#pragma omp parallel for schedule(guided)
for (unsigned int i=0;i<N;i++){
particles[i].x += dt * particles[i].vx;
particles[i].y += dt * particles[i].vy;
particles[i].z += dt * particles[i].vz;
}
r->t += dt; }
static void kick(struct reb_simulation* r, double dt){
const unsigned int N = r->N;
struct reb_particle* restrict const particles = r->particles;
#pragma omp parallel for schedule(guided)
for (unsigned int i=0;i<N;i++){
particles[i].vx += dt * particles[i].ax;
particles[i].vy += dt * particles[i].ay;
particles[i].vz += dt * particles[i].az;
}
}
void reb_integrator_leapfrog_step(struct reb_simulation* r){
r->gravity_ignore_terms = 0;
const double dt = r->dt;
switch (r->ri_leapfrog.order){
case 2:
drift(r, dt*0.5);
break;
case 4:
drift(r, dt*reb_integrator_leapfrog_lf4_a);
break;
case 6:
drift(r, dt*reb_integrator_leapfrog_lf6_a[0]*0.5);
break;
case 8:
drift(r, dt*reb_integrator_leapfrog_lf8_a[0]*0.5);
break;
default:
reb_simulation_error(r, "Leapfrog order not supported.");
return;
}
reb_simulation_update_acceleration(r);
switch (r->ri_leapfrog.order){
case 2:
kick(r, dt);
drift(r, dt*0.5);
break;
case 4:
kick(r, dt*2.*reb_integrator_leapfrog_lf4_a);
drift(r, dt*(0.5-reb_integrator_leapfrog_lf4_a));
reb_simulation_update_acceleration(r);
kick(r, dt*(1.-4.*reb_integrator_leapfrog_lf4_a));
drift(r, dt*(0.5-reb_integrator_leapfrog_lf4_a));
reb_simulation_update_acceleration(r);
kick(r, dt*2.*reb_integrator_leapfrog_lf4_a);
drift(r, dt*reb_integrator_leapfrog_lf4_a);
break;
case 6:
kick(r, dt*reb_integrator_leapfrog_lf6_a[0]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[0]+reb_integrator_leapfrog_lf6_a[1])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[1]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[1]+reb_integrator_leapfrog_lf6_a[2])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[2]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[2]+reb_integrator_leapfrog_lf6_a[3])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[3]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[3]+reb_integrator_leapfrog_lf6_a[4])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[4]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[3]+reb_integrator_leapfrog_lf6_a[4])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[3]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[2]+reb_integrator_leapfrog_lf6_a[3])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[2]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[1]+reb_integrator_leapfrog_lf6_a[2])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[1]);
drift(r, dt*(reb_integrator_leapfrog_lf6_a[0]+reb_integrator_leapfrog_lf6_a[1])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf6_a[0]);
drift(r, dt*reb_integrator_leapfrog_lf6_a[0]*0.5);
break;
case 8:
kick(r, dt*reb_integrator_leapfrog_lf8_a[0]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[0]+reb_integrator_leapfrog_lf8_a[1])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[1]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[1]+reb_integrator_leapfrog_lf8_a[2])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[2]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[2]+reb_integrator_leapfrog_lf8_a[3])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[3]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[3]+reb_integrator_leapfrog_lf8_a[4])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[4]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[4]+reb_integrator_leapfrog_lf8_a[5])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[5]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[5]+reb_integrator_leapfrog_lf8_a[6])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[6]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[6]+reb_integrator_leapfrog_lf8_a[7])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[7]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[7]+reb_integrator_leapfrog_lf8_a[8])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[8]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[7]+reb_integrator_leapfrog_lf8_a[8])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[7]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[6]+reb_integrator_leapfrog_lf8_a[7])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[6]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[5]+reb_integrator_leapfrog_lf8_a[6])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[5]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[4]+reb_integrator_leapfrog_lf8_a[5])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[4]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[3]+reb_integrator_leapfrog_lf8_a[4])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[3]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[2]+reb_integrator_leapfrog_lf8_a[3])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[2]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[1]+reb_integrator_leapfrog_lf8_a[2])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[1]);
drift(r, dt*(reb_integrator_leapfrog_lf8_a[0]+reb_integrator_leapfrog_lf8_a[1])*0.5);
reb_simulation_update_acceleration(r);
kick(r, dt*reb_integrator_leapfrog_lf8_a[0]);
drift(r, dt*reb_integrator_leapfrog_lf8_a[0]*0.5);
break;
default:
reb_simulation_error(r, "Leapfrog order not supported.");
return;
}
r->dt_last_done = dt;
}
void reb_integrator_leapfrog_synchronize(struct reb_simulation* r){
}
void reb_integrator_leapfrog_reset(struct reb_simulation* r){
r->ri_leapfrog.order = 2;
}