Esempio n. 1
0
void reb_integrator_hermes_reset(struct reb_simulation* r){
    //r->ri_hermes.timestep_too_large_warning = 0.; //Don't think we want to reset the warning.
    r->ri_hermes.steps = 0;
    r->ri_hermes.steps_miniactive = 0;
    r->ri_hermes.steps_miniN = 0;
    
    reb_integrator_whfast_reset(r);

    if (r->ri_hermes.mini){
        reb_free_simulation(r->ri_hermes.mini);
        r->ri_hermes.mini = NULL;
    }
    if(r->ri_hermes.global_index_from_mini_index){
        free(r->ri_hermes.global_index_from_mini_index);
        r->ri_hermes.global_index_from_mini_index = NULL;
        r->ri_hermes.global_index_from_mini_index_Nmax = 0;
    }
    if(r->ri_hermes.is_in_mini){
        free(r->ri_hermes.is_in_mini);
        r->ri_hermes.is_in_mini = NULL;
        r->ri_hermes.is_in_mini_Nmax = 0;
    }
    if(r->ri_hermes.a_i){
        free(r->ri_hermes.a_i);
    }
    if(r->ri_hermes.a_f){
        free(r->ri_hermes.a_f);
    }
    r->ri_hermes.a_Nmax = 0;
}
Esempio n. 2
0
int main(int argc, char* argv[]){
	{
		printf("Running simulation until t=10.\n");
		struct reb_simulation* r = reb_create_simulation();
		r->integrator	= REB_INTEGRATOR_SEI;
		r->collision	= REB_COLLISION_DIRECT;
		r->ri_sei.OMEGA	= 1.;	
		r->dt 		= 1e-4*2.*M_PI; 
		r->nghostx = 1; r->nghosty = 1; r->nghostz = 0;
		reb_configure_box(r,1.,1,1,1);

		while (r->N<50){
			struct reb_particle p = {0};
			p.x  = ((double)rand()/(double)RAND_MAX-0.5)*r->boxsize.x;
			p.y  = ((double)rand()/(double)RAND_MAX-0.5)*r->boxsize.y;
			p.z  = 0.1*((double)rand()/(double)RAND_MAX-0.5)*r->boxsize.z;
			p.vy = -1.5*p.x*r->ri_sei.OMEGA;
			p.m  = 0.01;
			p.r  = 0.05;
			reb_add(r, p);
		}
		reb_integrate(r,10.);
		printf("Saving simulation to binary file and freeing up memory.\n");
		reb_output_binary(r, "restart.bin");
		reb_free_simulation(r);
		r = NULL;
	}
	{
		printf("Creating simulation from binary file and integrating until t=20.\n");
		struct reb_simulation* r = reb_create_simulation_from_binary("restart.bin");
		reb_integrate(r,20.);
		printf("Done.\n");
	}
}
Esempio n. 3
0
void run_sim(){
	struct reb_simulation* const r = reb_create_simulation();
	// Setup constants
	r->integrator	= REB_INTEGRATOR_LEAPFROG;
	r->gravity	= REB_GRAVITY_BASIC;
	r->boundary	= REB_BOUNDARY_OPEN;
	r->opening_angle2	= 1.5;	// This constant determines the accuracy of the tree code gravity estimate.
	r->G 		= 1;		
	r->softening 	= 0.02;		// Gravitational softening length
	r->dt 		= 3e-2;		// Timestep
	const double boxsize = 10.2;
	reb_configure_box(r,boxsize,1,1,1);

	// Setup particles
	double disc_mass = 2e-1;	// Total disc mass
	int N = 2000;			// Number of particles
	// Initial conditions
	struct reb_particle star = {0};
	star.m 		= 1;
	reb_add(r, star);
	for (int i=0;i<N;i++){
		struct reb_particle pt = {0};
		double a	= reb_random_powerlaw(boxsize/10.,boxsize/2./1.2,-1.5);
		double phi 	= reb_random_uniform(0,2.*M_PI);
		pt.x 		= a*cos(phi);
		pt.y 		= a*sin(phi);
		pt.z 		= a*reb_random_normal(0.001);
		double mu 	= star.m + disc_mass * (pow(a,-3./2.)-pow(boxsize/10.,-3./2.))/(pow(boxsize/2./1.2,-3./2.)-pow(boxsize/10.,-3./2.));
		double vkep 	= sqrt(r->G*mu/a);
		pt.vx 		=  vkep * sin(phi);
		pt.vy 		= -vkep * cos(phi);
		pt.vz 		= 0;
		pt.m 		= disc_mass/(double)N;
		reb_add(r, pt);
	}

	reb_integrate(r, 1.0);
	reb_free_simulation(r);
}
Esempio n. 4
0
int main(int argc, char* argv[]) {
	struct reb_simulation* r;
    int var_i, var_ii;

    // We first integrate the vanilla simulation forward in time and look at the position of the testparticle at the end of the simulation.
    r = create_sim();
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100:                             %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);
    
    // Next, we shift the planet's initial x coordinate by a small amount and integrate the system again up til t=100. 
    double DeltaX = 0.001;
    printf("\nShifting planet's x coordinate by %f.\n", DeltaX);
    r = create_sim();
    r->particles[1].x += DeltaX;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 in shifted simulation:       %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);
    
    // Instead of shifting the initial x coordinate, we can also use variational equations. 
    r = create_sim();
    var_i = reb_add_var_1st_order(r, -1);   // The -1 means we vary a particle which is not a testparticle  and therefore can influence other particles
    
    // By default all components of variational particles are initialized to zero.
    // We are interested in shifting the planet's x coordinates and thus initialize the x coordinate of the variational particle to 1.
    r->particles[var_i+1].x = 1.;           
	reb_integrate(r,100.);
    // After the integration ran, we can estimate where the test particle would have been had we shifted the inner planet's initial x coordinate.
    printf("Position of testparticle at t=100 using 1st order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i+2].x,r->particles[2].y+DeltaX*r->particles[var_i+2].y);
    reb_free_simulation(r);

    // Better yet, we can use second order variational particles.
    r = create_sim();
    var_i = reb_add_var_1st_order(r, -1);
    var_ii = reb_add_var_2nd_order(r, -1, var_i, var_i);
    r->particles[var_i+1].x = 1.;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 2nd order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i+2].x+DeltaX*DeltaX/2.*r->particles[var_ii+2].x,r->particles[2].y+DeltaX*r->particles[var_i+2].y+DeltaX*DeltaX/2.*r->particles[var_ii+2].y);
    reb_free_simulation(r);

    
    // We now do the same as above, but vary the testparticle's position 
    printf("\nShifting testparticle's x coordinate by %f.\n", DeltaX);
    r = create_sim();
    r->particles[2].x += DeltaX;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 in shifted simulation:       %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);
    
    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2); // The 2 corresponds to the index of the testparticle that we vary.
    r->particles[var_i].x = 1.;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 1st order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x,r->particles[2].y+DeltaX*r->particles[var_i].y);
    reb_free_simulation(r);

    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2);
    var_ii = reb_add_var_2nd_order(r, 2, var_i, var_i);
    r->particles[var_i].x = 1.;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 2nd order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x+DeltaX*DeltaX/2.*r->particles[var_ii].x,r->particles[2].y+DeltaX*r->particles[var_i].y+DeltaX*DeltaX/2.*r->particles[var_ii].y);
    reb_free_simulation(r);

    
    // Instead of varying cartesian coordinates, we can also vary orbital elements. 
    printf("\nShifting planet's semi-major axis by %f.\n", DeltaX);
    r = create_sim();
    r->particles[2] = reb_tools_orbit_to_particle(1.,r->particles[0],0.,1.7+DeltaX,0.1,0.2,0.3,0.4,0.5);
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 in shifted simulation:       %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);

    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2);
    // The function that sets up the variational particle gets the same orbital parameters as the original particle.
    r->particles[var_i] = reb_derivatives_a(1.,r->particles[0],r->particles[2]);
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 1st order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x,r->particles[2].y+DeltaX*r->particles[var_i].y);
    reb_free_simulation(r);
    
    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2);
    var_ii = reb_add_var_2nd_order(r, 2, var_i, var_i);
    // first derivative with respect to a
    r->particles[var_i] = reb_derivatives_a(1.,r->particles[0],r->particles[2]);
    // second derivative with respect to a
    r->particles[var_ii] = reb_derivatives_a_a(1.,r->particles[0],r->particles[2]);
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 2nd order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x+DeltaX*DeltaX/2.*r->particles[var_ii].x,r->particles[2].y+DeltaX*r->particles[var_i].y+DeltaX*DeltaX/2.*r->particles[var_ii].y);
    reb_free_simulation(r);


}
Esempio n. 5
0
int main(int argc, char* argv[]){
	struct reb_simulation* const r = reb_create_simulation();
	// Setup constants
	r->integrator	= REB_INTEGRATOR_LEAPFROG;
	r->gravity	= REB_GRAVITY_TREE;
	r->boundary	= REB_BOUNDARY_OPEN;
	r->opening_angle2	= 1.5;		// This constant determines the accuracy of the tree code gravity estimate.
	r->G 		= 1;		
	r->softening 	= 0.02;		// Gravitational softening length
	r->dt 		= 3e-2;		// Timestep
	const double boxsize = 10.2;
    // Setup root boxes for gravity tree.
    // Here, we use 2x2=4 root boxes (each with length 'boxsize')
    // This allows you to use up to 4 MPI nodes.
	reb_configure_box(r,boxsize,2,2,1);

    // Initialize MPI
    // This can only be done after reb_configure_box.
    reb_mpi_init(r);

	// Setup particles only on master node
    // In the first timestep, the master node will 
    // distribute particles to other nodes. 
    // Note that this is not the most efficient method
    // for very large particle numbers.
    double disc_mass = 2e-1/r->mpi_num;	// Total disc mass
    int N = 10000/r->mpi_num;			// Number of particles
    // Initial conditions
    struct reb_particle star = {0};
    star.m 		= 1;
    if (r->mpi_id==0){
        reb_add(r, star);
    }
    for (int i=0;i<N;i++){
        struct reb_particle pt = {0};
        double a	= reb_random_powerlaw(boxsize/10.,boxsize/2./1.2,-1.5);
        double phi 	= reb_random_uniform(0,2.*M_PI);
        pt.x 		= a*cos(phi);
        pt.y 		= a*sin(phi);
        pt.z 		= a*reb_random_normal(0.001);
        double mu 	= star.m + disc_mass * (pow(a,-3./2.)-pow(boxsize/10.,-3./2.))/(pow(boxsize/2./1.2,-3./2.)-pow(boxsize/10.,-3./2.));
        double vkep 	= sqrt(r->G*mu/a);
        pt.vx 		=  vkep * sin(phi);
        pt.vy 		= -vkep * cos(phi);
        pt.vz 		= 0;
        pt.m 		= disc_mass/(double)N;
        reb_add(r, pt);
    }
	r->heartbeat = heartbeat;

#ifdef OPENGL
    // Hack to artificially increase particle array.
    // This cannot be done once OpenGL is activated. 
    r->allocatedN *=8;
    r->particles = realloc(r->particles,sizeof(struct reb_particle)*r->allocatedN);
#endif // OPENGL
    
	// Start the integration
    reb_integrate(r, INFINITY);

    // Cleanup
    reb_mpi_finalize(r);
    reb_free_simulation(r); 
}