Esempio n. 1
0
int main(int argc, char* argv[]){
    struct reb_simulation* r = reb_create_simulation();
    r->dt = 0.0012*2.*M_PI;                // initial timestep
    r->integrator = REB_INTEGRATOR_MERCURIUS;
    r->heartbeat  = heartbeat;

    struct reb_particle star = {0};
    star.m = 1;
    reb_add(r, star);
    
    // Add planets
    int N_planets = 3;
    for (int i=0;i<N_planets;i++){
        double a = 1.+.1*(double)i;        // semi major axis
        double v = sqrt(1./a);             // velocity (circular orbit)
        struct reb_particle planet = {0};
        planet.m = 2e-5; 
        planet.x = a; 
        planet.vy = v;
        reb_add(r, planet); 
    }
    reb_move_to_com(r);                // This makes sure the planetary systems stays within the computational domain and doesn't drift.
    e_init = reb_tools_energy(r);
    system("rm -rf energy.txt");

    reb_integrate(r, INFINITY);
}
Esempio n. 2
0
int main(int argc, char* argv[]){
    struct reb_simulation* r = reb_create_simulation();
    // Setup constants
    r->dt             = 4;                // in days
    tmax            = 7.3e10;            // 200 Myr
    r->G            = 1.4880826e-34;        // in AU^3 / kg / day^2.
    r->ri_whfast.safe_mode     = 0;        // Turn off safe mode. Need to call reb_integrator_synchronize() before outputs. 
    r->ri_whfast.corrector     = 11;        // 11th order symplectic corrector
    r->integrator        = REB_INTEGRATOR_WHFAST;
    r->heartbeat        = heartbeat;
    r->exact_finish_time = 1; // Finish exactly at tmax in reb_integrate(). Default is already 1.
    //r->integrator        = REB_INTEGRATOR_IAS15;        // Alternative non-symplectic integrator

    // Initial conditions
    for (int i=0;i<10;i++){
        struct reb_particle p = {0};
        p.x  = ss_pos[i][0];         p.y  = ss_pos[i][1];         p.z  = ss_pos[i][2];
        p.vx = ss_vel[i][0];         p.vy = ss_vel[i][1];         p.vz = ss_vel[i][2];
        p.m  = ss_mass[i];
        reb_add(r, p); 
    }
    reb_move_to_com(r);
    e_init = reb_tools_energy(r);
    system("rm -f energy.txt");
    reb_integrate(r, tmax);
}
Esempio n. 3
0
void heartbeat(struct reb_simulation* r){
    if (reb_output_check(r, 10000.)){
        reb_output_timing(r, tmax);
        reb_integrator_synchronize(r);
        FILE* f = fopen("energy.txt","a");
        double e = reb_tools_energy(r);
        fprintf(f,"%e %e\n",r->t, fabs((e-e_init)/e_init));
        fclose(f);
    }
}
Esempio n. 4
0
void heartbeat(struct reb_simulation* r){
    if (reb_output_check(r, 10.*2.*M_PI)){  
        reb_output_timing(r, 0);
    }
    if (reb_output_check(r, 2.*M_PI)){  
        // Once per year, output the relative energy error to a text file
        FILE* f = fopen("energy.txt","a");
        reb_integrator_synchronize(r);
        double e = reb_tools_energy(r);
        fprintf(f,"%e %e\n",r->t, fabs((e-e_init)/e_init));
        fclose(f);
    }
}
Esempio n. 5
0
void reb_integrator_hermes_part2(struct reb_simulation* r){
    reb_integrator_whfast_part2(r);
    
    calc_forces_on_planets(r, r->ri_hermes.a_f);
    
    struct reb_simulation* mini = r->ri_hermes.mini;
    r->ri_hermes.steps++;
    if (r->ri_hermes.mini_active){
        r->ri_hermes.steps_miniactive++;
        r->ri_hermes.steps_miniN += mini->N;
        reb_integrate(mini,r->t);

        for (int i=0; i<mini->N; i++){
            r->particles[r->ri_hermes.global_index_from_mini_index[i]] = mini->particles[i];
            r->particles[r->ri_hermes.global_index_from_mini_index[i]].sim = r;    
        }
        
        // Correct for energy jump in collision
        if(r->ri_hermes.collision_this_global_dt && r->track_energy_offset){
            double Ef = reb_tools_energy(r);
            r->energy_offset += r->ri_hermes.energy_before_timestep - Ef;
        }
    }
}
Esempio n. 6
0
int main(int argc, char* argv[]) {
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	const double k = 0.01720209895; // Gaussian constant
	r->dt = 40;			// in days
	r->G = k * k;			// These are the same units as used by the mercury6 code.
	r->ri_whfast.safe_mode = 0;     // Turn of safe mode. Need to call integrator_synchronize() before outputs.
	r->ri_whfast.corrector = 11;    // Turn on symplectic correctors (11th order).

	// Setup callbacks:
	r->heartbeat = heartbeat;
	r->force_is_velocitydependent = 0; // Force only depends on positions.
	r->integrator = REB_INTEGRATOR_WHFAST;
	//r->integrator	= REB_INTEGRATOR_IAS15;
	//r->integrator	= REB_INTEGRATOR_WH;

	// Initial conditions
	for (int i = 0; i < 6; i++) {
		struct reb_particle p;
		p.x = ss_pos[i][0];
		p.y = ss_pos[i][1];
		p.z = ss_pos[i][2];
		p.vx = ss_vel[i][0];
		p.vy = ss_vel[i][1];
		p.vz = ss_vel[i][2];
		p.ax = 0;
		p.ay = 0;
		p.az = 0;
		p.m = ss_mass[i];
		reb_add(r, p);
	}
	if (r->integrator == REB_INTEGRATOR_WH) {
		struct reb_particle* const particles = r->particles;
		// Move to heliocentric frame (required by WH integrator)
		for (int i = 1; i < r->N; i++) {
			particles[i].x -= particles[0].x;
			particles[i].y -= particles[0].y;
			particles[i].z -= particles[0].z;
			particles[i].vx -= particles[0].vx;
			particles[i].vy -= particles[0].vy;
			particles[i].vz -= particles[0].vz;
		}
		particles[0].x = 0;
		particles[0].y = 0;
		particles[0].z = 0;
		particles[0].vx = 0;
		particles[0].vy = 0;
		particles[0].vz = 0;
	} else {
		reb_move_to_com(r);
	}

	r->N_active = r->N - 1; // Pluto is treated as a test-particle.

	double e_initial = reb_tools_energy(r);

	// Start integration
	reb_integrate(r, tmax);

	double e_final = reb_tools_energy(r);
	printf("Done. Final time: %.4f. Relative energy error: %e\n", r->t, fabs((e_final - e_initial) / e_initial));
}
Esempio n. 7
0
void reb_integrator_hermes_part1(struct reb_simulation* r){
    r->gravity_ignore_10 = 0;
    const int _N_active = ((r->N_active==-1)?r->N:r->N_active) - r->N_var;
    struct reb_simulation* mini = r->ri_hermes.mini;
    if (mini == NULL){
        mini = reb_create_simulation();
        r->ri_hermes.mini = mini;
        mini->usleep = -1; // Disable visualiation
        mini->integrator = REB_INTEGRATOR_IAS15;
        mini->gravity = REB_GRAVITY_BASIC;
        mini->dt = r->dt;
        mini->additional_forces = reb_integrator_hermes_additional_forces_mini;
        mini->ri_hermes.global = r;    //set to != 0 so that collision.c knows to remove from both
    }
    mini->testparticle_type = r->testparticle_type;
    mini->collision = r->collision;
    mini->collision_resolve = r->collision_resolve;
    mini->collision_resolve_keep_sorted = r->collision_resolve_keep_sorted;
    mini->track_energy_offset = r->track_energy_offset;
    mini->force_is_velocity_dependent = r->force_is_velocity_dependent;
    mini->post_timestep_modifications = r->post_timestep_modifications;

    // Remove all particles from mini
    mini->t = r->t;
    int mini_previously_active = r->ri_hermes.mini_active;
    mini->N = 0;
    mini->energy_offset = 0.;
    r->ri_hermes.mini_active = 0;
    r->ri_hermes.global_index_from_mini_index_N = 0;
    r->ri_hermes.collision_this_global_dt = 0;
    
    if (_N_active>r->ri_hermes.a_Nmax){
        r->ri_hermes.a_i = realloc(r->ri_hermes.a_i,sizeof(double)*3*_N_active);
        r->ri_hermes.a_f = realloc(r->ri_hermes.a_f,sizeof(double)*3*_N_active);
        r->ri_hermes.a_Nmax = _N_active;
    }
    
    //reset is_in_mini
    if (r->N>r->ri_hermes.is_in_mini_Nmax){
        r->ri_hermes.is_in_mini_Nmax = r->N;
        r->ri_hermes.is_in_mini = realloc(r->ri_hermes.is_in_mini,r->N*sizeof(int));
    }
    for(int i=_N_active;i<r->N;i++)r->ri_hermes.is_in_mini[i] = 0;
    
    // Add all massive particles
    for (int i=0; i<_N_active; i++){
        reb_add(r->ri_hermes.mini, r->particles[i]);
        r->ri_hermes.is_in_mini[i] = 1;
        if (r->ri_hermes.global_index_from_mini_index_N>=r->ri_hermes.global_index_from_mini_index_Nmax){
            r->ri_hermes.global_index_from_mini_index_Nmax += 32;
            r->ri_hermes.global_index_from_mini_index = realloc(r->ri_hermes.global_index_from_mini_index,r->ri_hermes.global_index_from_mini_index_Nmax*sizeof(int));
        }
        r->ri_hermes.global_index_from_mini_index[r->ri_hermes.global_index_from_mini_index_N] = i;
        r->ri_hermes.global_index_from_mini_index_N++;
    }
    r->ri_hermes.mini->N_active = _N_active;

    reb_integrator_hermes_check_for_encounter(r);
        
    if (r->N != r->ri_hermes.mini->N || mini_previously_active==0) {
        reb_integrator_ias15_clear(r->ri_hermes.mini);
    }
    
    calc_forces_on_planets(r, r->ri_hermes.a_i);
    
    if(r->ri_hermes.mini_active && r->track_energy_offset){
        r->ri_hermes.energy_before_timestep = reb_tools_energy(r);
    }
    
    reb_integrator_whfast_part1(r);
}