Example #1
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");
	}
}
Example #2
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);
}
Example #3
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->integrator			= REB_INTEGRATOR_IAS15;
	r->dt 				= 1e-6;			// initial timestep
	r->N_active			= 2; 			// only the star and the planet are massive.
	
	// Planet
	struct reb_particle planet = {0};
	planet.m  = Mplanet;
	reb_add(r, planet);

	struct reb_particle p = {0};			// test particle 
	double a = Rplanet*3.;				// small distance from planet (makes J2 important)
	double e = 0.1;
	double v = sqrt((1.+e)/(1.-e)*r->G*planet.m/a);	// setup eccentric orbit (ignores J2)
	p.x  = (1.-e)*a;
	p.vy = v;
	p.x += planet.x; 	p.y += planet.y; 	p.z += planet.z;
	p.vx += planet.vx; 	p.vy += planet.vy; 	p.vz += planet.vz;
	reb_add(r, p); 
	
	reb_move_to_com(r);

	system("rm -v a.txt");					// delete previous output

	// Setup callback functions
	r->heartbeat 		= heartbeat;
	r->additional_forces 	= force_J2;

	reb_integrate(r, tmax);
}
Example #4
0
int main(int argc, char* argv[]) {
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->opening_angle2	= .5;					// This determines the precission of the tree code gravity calculation.
	r->integrator			= REB_INTEGRATOR_SEI;
	r->boundary			= REB_BOUNDARY_SHEAR;
	r->gravity			= REB_GRAVITY_TREE;
	r->collision			= REB_COLLISION_TREE;
	double OMEGA 			= 0.00013143527;	// 1/s
	r->ri_sei.OMEGA 		= OMEGA;
	r->G 				= 6.67428e-11;		// N / (1e-5 kg)^2 m^2
	r->softening 			= 0.1;			// m
	r->dt 				= 1e-3*2.*M_PI/OMEGA;	// s
	// This example uses two root boxes in the x and y direction. 
	// Although not necessary in this case, it allows for the parallelization using MPI. 
	// See Rein & Liu for a description of what a root box is in this context.
	double surfacedensity 		= 600; 			// kg/m^2
	double particle_density		= 400;			// kg/m^3
	double particle_radius_min 	= 1;			// m
	double particle_radius_max 	= 4;			// m
	double particle_radius_slope 	= -3;	
	double boxsize 			= 100;			// m
	if (argc>1){						// Try to read boxsize from command line
		boxsize = atof(argv[1]);
	}
	reb_configure_box(r, boxsize, 2, 2, 1);
	r->nghostx = 2;
	r->nghosty = 2;
	r->nghostz = 0;
	
	// Use Bridges et al coefficient of restitution.
	r->coefficient_of_restitution = coefficient_of_restitution_bridges;
	// When two particles collide and the relative velocity is zero, the might sink into each other in the next time step.
	// By adding a small repulsive velocity to each collision, we prevent this from happening.
	r->minimum_collision_velocity = particle_radius_min*OMEGA*0.001;  // small fraction of the shear accross a particle


	// Add all ring paricles
	double total_mass = surfacedensity*r->boxsize.x*r->boxsize.y;
	double mass = 0;
	while(mass<total_mass){
		struct reb_particle pt = {0.};
		pt.x 		= reb_random_uniform(-r->boxsize.x/2.,r->boxsize.x/2.);
		pt.y 		= reb_random_uniform(-r->boxsize.y/2.,r->boxsize.y/2.);
		pt.z 		= reb_random_normal(1.);					// m
		pt.vx 		= 0;
		pt.vy 		= -1.5*pt.x*OMEGA;
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		double radius 	= reb_random_powerlaw(particle_radius_min,particle_radius_max,particle_radius_slope);
		pt.r 		= radius;						// m
		double		particle_mass = particle_density*4./3.*M_PI*radius*radius*radius;
		pt.m 		= particle_mass; 	// kg
		reb_add(r, pt);
		mass += particle_mass;
	}
	reb_integrate(r, 2./OMEGA);
}
Example #5
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);
}
Example #6
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	r->dt 			= 0.1*2.*M_PI;				// initial timestep
	r->integrator 		= REB_INTEGRATOR_IAS15;
	r->collision		= REB_COLLISION_DIRECT;
	r->collision_resolve 	= collision_record_only;		// Set function pointer for collision recording.
	r->heartbeat		= heartbeat;
	r->usleep		= 10000;				// Slow down integration (for visualization only)

	struct reb_particle star = {0};
	star.m = 1;
	star.r = 0;							// Star is pointmass
	reb_add(r, star);
	
	// Add planets
	int N_planets = 7;
	for (int i=0; i<N_planets; i++){
		double a = 1.+(double)i/(double)(N_planets-1);		// semi major axis
		double v = sqrt(1./a); 					// velocity (circular orbit)
		struct reb_particle planet = {0};
		planet.m = 1e-4; 
		double rhill = a * pow(planet.m/(3.*star.m),1./3.);	// Hill radius
		planet.r = rhill;					// Set planet radius to hill radius 
									// A collision is recorded when planets get within their hill radius
									// The hill radius of the particles might change, so it should be recalculated after a while
		planet.lastcollision = 0; 
		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.

	reb_integrate(r, INFINITY);
}
Example #7
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->force_is_velocity_dependent = 0; // Force only depends on positions.
	r->integrator = REB_INTEGRATOR_WHFAST;
	//r->integrator	= REB_INTEGRATOR_IAS15;

	// Initial conditions
	for (int i = 0; i < 6; 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);

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

	// Start integration
	reb_integrate(r, tmax);

}
Example #8
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->dt 			= 1e-4;		// initial timestep.
	r->integrator		= REB_INTEGRATOR_IAS15;
	r->gravity		= REB_GRAVITY_NONE;

	// Setup callback function for velocity dependent forces.
	r->additional_forces 	= additional_forces;
	r->force_is_velocitydependent = 1;
	// Setup callback function for outputs.
	r->heartbeat		= heartbeat;
	
	struct reb_particle p; 
	p.m  = 0;	// massless
	p.x = 1; 	p.y = 0; 	p.z = 0;
	p.vx = -1; 	p.vy = 0; 	p.vz = 0;
	p.ax = 0; 	p.ay = 0; 	p.az = 0;
	reb_add(r, p); 

	// Delete previous output
	system("rm -v r.txt");	

	// Do the integration
	reb_integrate(r, tmax);
}
Example #9
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->G			= 1;		// Gravitational constant
	r->integrator		= REB_INTEGRATOR_IAS15;
	r->heartbeat		= heartbeat;

	double e_testparticle 	= 1.-1e-7;	
	double mass_scale	= 1.;		// Some integrators have problems when changing the mass scale, IAS15 does not. 
	double size_scale	= 1;		// Some integrators have problems when changing the size scale, IAS15 does not.

	struct reb_particle star = {0}; 
	star.m  = mass_scale;
	reb_add(r, star); 
	
	struct reb_particle planet; 
	planet.m  = 0;
	planet.x  = size_scale*(1.-e_testparticle); 
	planet.vy = sqrt((1.+e_testparticle)/(1.-e_testparticle)*mass_scale/size_scale);
	reb_add(r, planet); 
	
	reb_move_to_com(r);
	
	// initial timestep
	r->dt 			= 1e-13*sqrt(size_scale*size_scale*size_scale/mass_scale); 
	tmax			= 1e2*2.*M_PI*sqrt(size_scale*size_scale*size_scale/mass_scale);

	reb_integrate(r, tmax);	
}
Example #10
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	r->dt 			= 0.01*2.*M_PI;				// initial timestep
	r->integrator 		= REB_INTEGRATOR_IAS15;
	r->collision		= REB_COLLISION_DIRECT;
	r->collision_resolve 	= collision_resolve_merger;		// Setup our own collision routine.
	r->heartbeat		= heartbeat;

	struct reb_particle star = {0};
	star.m = 1;
	star.r = 0.1;
	reb_add(r, star);
	
	// Add planets
	int N_planets = 7;
	for (int i=0;i<N_planets;i++){
		double a = 1.+(double)i/(double)(N_planets-1);		// semi major axis in AU
		double v = sqrt(1./a); 					// velocity (circular orbit)
		struct reb_particle planet = {0};
		planet.m = 1e-4; 
		planet.r = 4e-2; 					// radius in AU (it is unphysically large in this example)
		planet.lastcollision = 0;				// The first time particles can collide with each other
		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.

	reb_integrate(r, INFINITY);
}
Example #11
0
int main(int argc, char* argv[]) {
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->dt 		= 10;			// initial timestep (in days)
	//r->integrator	= IAS15;
	r->integrator	= REB_INTEGRATOR_WHFAST;
	const double k	= 0.01720209895;	// Gaussian constant 
	r->G		= k*k;			// These are the same units that mercury6 uses

	// Initial conditions
	for (int i=0;i<3;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);
	// Add megno particles 
	reb_tools_megno_init(r);  // N = 6 after this function call. 
	// The first half of particles are real particles, the second half are particles following the variational equations.
	
	// Set callback for outputs.
	r->heartbeat = heartbeat;

	reb_integrate(r, tmax);
}
Example #12
0
/***********************************************************************************
 * Miscellaneous Functions
***********************************************************************************/
double install_test(void){
    struct reb_simulation* sim = reb_create_simulation();
    struct reb_particle p = {0};
    p.m = 1.; 
    reb_add(sim, p); 
    struct reb_particle p1 = reb_tools_orbit2d_to_particle(sim->G, p, 0., 1., 0.2, 0., 0.);
    reb_add(sim, p1);
    reb_integrate(sim, 1.);
    return sim->particles[1].x;
}
Example #13
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->integrator		= REB_INTEGRATOR_WHFAST;
	r->boundary		= REB_BOUNDARY_OPEN;
	r->softening		= 1e-6;
	r->dt 			= 1.0e-2*2.*M_PI;
	r->N_active 		= 2; 	// Only the star and the planet have non-zero mass
	r->heartbeat		= heartbeat;

	reb_configure_box(r,8.,1,1,1); // Box with size 8 AU
	
	// Initial conditions for star
	struct reb_particle star;
	star.x  = 0; 	star.y  = 0; 	star.z  = 0; 
	star.vx = 0; 	star.vy = 0; 	star.vz = 0;
	star.m  = 1;
	reb_add(r, star);

	// Initial conditions for planet
	double planet_e = 0.;
	struct reb_particle planet;
	planet.x  = 1.-planet_e; 	planet.y  = 0; 				planet.z  = 0; 
	planet.vx = 0; 			planet.vy = sqrt(2./(1.-planet_e)-1.); 	planet.vz = 0;
	planet.m  = 1e-2;
	reb_add(r, planet);
	reb_move_to_com(r);
	
	while(r->N<10000){
		double x 	= ((double)rand()/(double)RAND_MAX-0.5)*8.;
		double y 	= ((double)rand()/(double)RAND_MAX-0.5)*8.;
		double a 	= sqrt(x*x+y*y);
		double phi 	= atan2(y,x);
		if (a<.1) continue;
		if (a>4.) continue;

		double vkep = sqrt(r->G*star.m/a);
		struct reb_particle testparticle;
		testparticle.x  = x;
		testparticle.y  = y; 
		testparticle.z  = 1.0e-2*x*((double)rand()/(double)RAND_MAX-0.5);
		testparticle.vx = -vkep*sin(phi);
		testparticle.vy = vkep*cos(phi);
		testparticle.vz = 0;
		testparticle.ax = 0; 
		testparticle.ay = 0; 
		testparticle.az = 0;
		testparticle.m  = 0;
		reb_add(r, testparticle);
	}

	reb_integrate(r, INFINITY);
}
Example #14
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->integrator		= REB_INTEGRATOR_IAS15;
	r->dt 			= 1e-4;	// Initial timestep.
	r->N_active		= 2; 	// Only the star and the planet are massive.
	r->additional_forces 	= force_radiation;
	r->heartbeat	 	= heartbeat;
	
	// Star
	struct reb_particle star;
	star.x  = 0; star.y  = 0; star.z  = 0;
	star.vx = 0; star.vy = 0; star.vz = 0;
	star.ax = 0; star.ay = 0; star.az = 0;
	star.m  = 1.;
	reb_add(r, star);


	// planet 
	struct reb_particle planet;
	planet.m  = 1e-3;
	planet.x  = 1; planet.y  = 0.; planet.z  = 0.;
	planet.ax = 0; planet.ay = 0; planet.az = 0;
	planet.vx = 0;
	planet.vy = sqrt(r->G*(star.m+planet.m)/planet.x);
	planet.vz = 0;
	reb_add(r, planet);
	
	

	// Dust particles
	while(r->N<3){ 	// Three particles in total (star, planet, dust particle) 
		struct reb_particle p; 
		p.m  = 0;		// massless
		double _r = 0.001;	// distance from planet planet
		double v = sqrt(r->G*planet.m/_r);
		p.x  = _r; p.y  = 0; p.z  = 0; 
		p.vx = 0; p.vy = v; p.vz = 0;
		p.x += planet.x; 	p.y += planet.y; 	p.z += planet.z;
		p.vx += planet.vx; 	p.vy += planet.vy; 	p.vz += planet.vz;
		p.ax = 0; p.ay = 0; p.az = 0;
		reb_add(r, p); 
	}
	
	reb_move_to_com(r);

	system("rm -v a.txt");	

	reb_integrate(r, tmax);
}
Example #15
0
int main(int argc, char* argv[]) {
	struct reb_simulation* r = reb_create_simulation();
	r->dt = 0.1;
	r->heartbeat = heartbeat;
	r->exact_finish_time = 1; // Finish exactly at tmax in reb_integrate(). Default is already 1.

	struct reb_particle p1 = {0};
	p1.m = 1.;
	reb_add(r, p1);
	
	struct reb_particle p2 = {0};
	p2.x = 1;
	p2.vy = 1;
	reb_add(r, p2);

	reb_integrate(r,100.);
}
Example #16
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->integrator	= REB_INTEGRATOR_WHFAST;
	//r->integrator	= REB_INTEGRATOR_IAS15;
	r->dt 		= 1e-2*2.*M_PI;		// in year/(2*pi)
	r->additional_forces = migration_forces; 	//Set function pointer to add dissipative forces.
	r->heartbeat = heartbeat;  
	r->force_is_velocity_dependent = 1;
	tmax		= 2.0e4*2.*M_PI;	// in year/(2*pi)

	// Initial conditions
	// Parameters are those of Lee & Peale 2002, Figure 4. 
	struct reb_particle star = {0};
	star.m  = 0.32;			// This is a sub-solar mass star
	reb_add(r, star); 
	
	struct reb_particle p1 = {0};	// Planet 1
	p1.x 	= 0.5;
	p1.m  	= 0.56e-3;
	p1.vy 	= sqrt(r->G*(star.m+p1.m)/p1.x);
	reb_add(r, p1); 
	
	struct reb_particle p2 = {0};	// Planet 2
	p2.x 	= 1;
	p2.m  	= 1.89e-3;
	p2.vy 	= sqrt(r->G*(star.m+p2.m)/p2.x);
	reb_add(r, p2); 

	tau_a = calloc(sizeof(double),r->N);
	tau_e = calloc(sizeof(double),r->N);

	tau_a[2] = 2.*M_PI*20000.0;	// Migration timescale of planet 2 is 20000 years.
	tau_e[2] = 2.*M_PI*200.0; 	// Eccentricity damping timescale is 200 years (K=100). 

	reb_move_to_com(r);  		

	system("rm -v orbits.txt"); // delete previous output file

	reb_integrate(r, tmax);
}
Example #17
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);
}
Example #18
0
int main(int argc, char* argv[]){
    struct reb_simulation* sim = reb_create_simulation();
    struct reb_particle p = {0}; 
    p.m     = 1.;   
    reb_add(sim, p); 

    double m = 0.;
    double a1 = 1.;
    double a2 = 2.;
    double e = 0.4;
    double omega = 0.;
    double f = 0.;

    struct reb_particle p1 = reb_tools_orbit2d_to_particle(sim->G, p, m, a1, e, omega, f);
    struct reb_particle p2 = reb_tools_orbit2d_to_particle(sim->G, p, m, a2, e, omega, f);
    reb_add(sim,p1);
    reb_add(sim,p2);
    reb_move_to_com(sim);

    struct rebx_extras* rebx = rebx_init(sim);  // first initialize rebx

    /* We now add our custom post_timestep_modification
     * We pass rebx, a name, and the function that should be called.
     * For a custom force, we also have to pass force_is_velocity_dependent,
     * which should be 1 if our function uses particle velocities, and 0 otherwise. 
     */

    struct rebx_effect* effect = rebx_add_custom_post_timestep_modification(rebx, "simple_drag", simple_drag);
    //struct rebx_effect* effect = rebx_add_custom_force(rebx, "stark_force", stark_force, 0);
    
    double* c = rebx_add_param(effect, "c", REBX_TYPE_DOUBLE);
    *c = 1.e-5;                                 // we wrote both our functions to read a parameter c, so we set it.
    
    double tmax = 5.e4;
    reb_integrate(sim, tmax);
    rebx_free(rebx);                            // Free all the memory allocated by rebx
}
Example #19
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;
        }
    }
}
Example #20
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->dt 			= M_PI*1e-2; 	// initial timestep
	r->integrator		= REB_INTEGRATOR_IAS15;
	r->heartbeat		= heartbeat;

	// Initial conditions
	
	struct reb_particle star = {0}; 
	star.m  = 1;
	reb_add(r, star); 
	
	// The planet (a zero mass test particle)
	struct reb_particle planet = {0}; 
	double e_testparticle = 0;
	planet.m  = 0.;
	planet.x  = 1.-e_testparticle;
	planet.vy = sqrt((1.+e_testparticle)/(1.-e_testparticle));
	reb_add(r, planet); 
	
	// The perturber
	struct reb_particle perturber = {0}; 
	perturber.x  = 10; 
	double inc_perturber = 89.9;
	perturber.m  = 1;
	perturber.vy = cos(inc_perturber/180.*M_PI)*sqrt((star.m+perturber.m)/perturber.x); 
	perturber.vz = sin(inc_perturber/180.*M_PI)*sqrt((star.m+perturber.m)/perturber.x); 
	reb_add(r, perturber); 

	reb_move_to_com(r);
	
	system("rm -v orbits.txt");		// delete previous output file

	reb_integrate(r, tmax);
}
Example #21
0
int main(int argc, char* argv[]){
    struct reb_simulation* sim = reb_create_simulation();
    // Setup constants 
    sim->integrator     = REB_INTEGRATOR_IAS15;
    sim->G              = 6.674e-11;    // Use SI units
    sim->dt             = 1e4;          // Initial timestep in sec
    sim->N_active       = 2;            // Only the sun and the planet affect other particles gravitationally
    sim->heartbeat      = heartbeat;
    sim->usleep     = 1000;             // Slow down integration (for visualization only)
    
    // sun
    struct reb_particle sun = {0};
    sun.m  = 1.99e30;                   // mass of Sun in kg
    reb_add(sim, sun);
    
    struct rebx_extras* rebx = rebx_init(sim); 
    struct rebx_effect* rad_params = rebx_add(rebx, "radiation_forces");
    double* c = rebx_add_param(rad_params, "c", REBX_TYPE_DOUBLE);
    *c = 3.e8;                          // speed of light in SI units 
    // Will assume particles[0] is the radiation source by default. You can also add a flag to a particle explicitly
    int* source = rebx_add_param(&sim->particles[0], "radiation_source", REBX_TYPE_INT);

    // Saturn (simulation set up in Saturn's orbital plane, i.e., inc=0, so only need 4 orbital elements 
    double mass_sat = 5.68e26;          // Mass of Saturn 
    double a_sat = 1.43e12;             // Semimajor axis of Saturn in m
    double e_sat = 0.056;               // Eccentricity of Saturn
    double pomega_sat = 0.;             // Angle from x axis to pericenter
    double f_sat = 0.;                  // True anomaly of Saturn
    struct reb_particle saturn = reb_tools_orbit2d_to_particle(sim->G, sun, mass_sat, a_sat, e_sat, pomega_sat, f_sat);

    reb_add(sim, saturn);

    /* Dust particles
     Here we imagine particles launched from Saturn's irregular Satellite Phoebe.
     Such grains will inherit the moon's orbital elements (e.g. Tamayo et al. 2011) 
        
     In order for a particle to feel radiation forces, we have to set their beta parameter, 
     the ratio of the radiation pressure force to the gravitional force from the star (Burns et al. 1979). 
     We do this in two ways below.*/
        
    double a_dust = 1.30e10;            // semimajor axis of satellite Phoebe, in m
    double e_dust = 0.16;               // eccentricity of Phoebe
    double inc_dust = 175.*M_PI/180.;   // inclination of Phoebe to Saturn's orbital plane
    double Omega_dust = 0.;             // longitude of ascending node
    double omega_dust = 0.;             // argument of pericenter
    double f_dust = 0.;                 // true anomaly

    // We first set up the orbit and add the particles
    double m_dust = 0.;                 // treat dust particles as massless
    struct reb_particle p = reb_tools_orbit_to_particle(sim->G, sim->particles[1], m_dust, a_dust, e_dust, inc_dust, Omega_dust, omega_dust, f_dust); 
    reb_add(sim, p); 

    // For the first particle we simply specify beta directly.
    double* beta = rebx_add_param(&sim->particles[2], "beta", REBX_TYPE_DOUBLE);    
    *beta = 0.1;

    // We now add a 2nd particle on the same orbit, but set its beta using physical parameters.  
    struct reb_particle p2 = reb_tools_orbit_to_particle(sim->G, sim->particles[1], 0., a_dust, e_dust, inc_dust, Omega_dust, omega_dust, f_dust); 
    reb_add(sim, p2);

    /* REBOUNDx has a convenience function to calculate beta given the gravitational constant G, the star's luminosity and mass, and the grain's physical radius, density and radiation pressure coefficient Q_pr (Burns et al. 1979). */
   
    // Particle parameters
    double radius = 1.e-5;              // in meters
    double density = 1.e3;              // kg/m3 = 1g/cc 
    double Q_pr = 1.;                   // Equals 1 in limit where particle radius >> wavelength of radiation
    double L = 3.85e26;                 // Luminosity of the sun in Watts

    beta = rebx_add_param(&sim->particles[3], "beta", REBX_TYPE_DOUBLE);    
    *beta = rebx_rad_calc_beta(sim->G, *c, sim->particles[0].m, L, radius, density, Q_pr);

    printf("Particle 2 has beta = %f\n", *beta);

    reb_move_to_com(sim);

    printf("Time\t\tEcc (p)\t\tEcc (p2)\n");
    reb_integrate(sim, tmax);
    rebx_free(rebx);                /* free memory allocated by REBOUNDx */
}
Example #22
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);


}
Example #23
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); 
}
Example #24
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));
}
Example #25
0
int main(int argc, char* argv[]) {
    int np = 20;
    omp_set_num_threads(np);
    FILE *fp2;
    char hash_name[] = "hash.csv";
    fp2 = fopen(hash_name, "w+");
    fprintf(fp2, "Hash, Mass, Radius\n");
    char filename[512] = "veras_no_frag.bin";
    // Trying to restart from the Simulation Archive.
    struct reb_simulation* r = reb_create_simulation_from_simulationarchive(filename);
    printf("Loaded Simulation Successfully\n");
    printf("Time is: %.16f\n", r->t);
    printf("N_active is: %i\n", r->N);
    printf("Timestep is: %.3f\n", r->dt);
    r->heartbeat	= heartbeat;
    r->dt = 10.0;
    r->gravity = REB_GRAVITY_TREE;
    r->integrator = REB_INTEGRATOR_WHFAST;
    r->collision = REB_COLLISION_TREE;
    r->boundary     = REB_BOUNDARY_OPEN;
    const double boxsize = 2.5e10; // about 0.15 AU, with fragments at 0.0054 AU
    reb_configure_box(r,boxsize,1,1,1);
    struct rebx_extras* rebx = rebx_init(r);
    /*
    struct rebx_effect* rad_params = rebx_add(rebx, "radiation_forces");
    double* c = rebx_add_param(rad_params, "c", REBX_TYPE_DOUBLE);
    *c = 3.e8;                          // speed of light in SI units    */


    struct reb_particle* wd = reb_get_particle_by_hash(r, reb_hash("wd"));
    int wd_index = reb_get_particle_index(wd);
    /*
    int* rad_source = rebx_add_param(&r->particles[wd_index], "radiation_source", REBX_TYPE_INT);
    *rad_source = 1;    */


    struct rebx_effect* gr_params = rebx_add(rebx, "gr");
    double* c_2 = rebx_add_param(gr_params, "c", REBX_TYPE_DOUBLE);
    *c_2 = 3.e8;
    int* source = rebx_add_param(&r->particles[wd_index], "gr_source", REBX_TYPE_INT);
    *source = 1;
    double wd_rad = wd->r;
    double disk_rad_in = 10.0*wd_rad;
    double disk_rad_out = 90.0*wd_rad;
    printf("Inner disk radius is: %f AU\n", disk_rad_in/1.496e11);
    printf("Outer disk radius is: %f AU\n", disk_rad_out/1.496e11);
    int N_disk = 2000;
    double disk_inc_low = 0.0;
    double disk_inc_high = 0.0;
    double e_low = 0.0;
    double e_high = 0.0;
    r->N_active = r->N;
    double* add_beta;
    while(r->N<N_disk + r->N_active){
        struct reb_particle pt = {0};
        double a = reb_random_uniform(disk_rad_in, disk_rad_out);
        double e = reb_random_uniform(e_low, e_high);
        double inc = reb_random_uniform(disk_inc_low, disk_inc_high);
        double Omega = reb_random_uniform(0, 2.*M_PI);
        double apsis = reb_random_uniform(0, 2.*M_PI);
        double phi = reb_random_uniform(0.0, 2.*M_PI);
        pt = reb_tools_orbit_to_particle(r->G, r->particles[wd_index], 0.0, a, e, inc, Omega, apsis, phi);
        int N_count = r->N - r->N_active;
        pt.hash = N_count + 8000;
        reb_add(r, pt);
        add_beta = rebx_add_param(&r->particles[N_count], "beta", REBX_TYPE_DOUBLE);
        *add_beta = 0.01;
    }
    r->simulationarchive_interval = 6.32e6;
    char sim_name[1000];
    filename[strlen(filename) - 4] = 0;
    sprintf(sim_name, "%s_months.bin", filename);
    r->simulationarchive_filename = sim_name;

    for (int i=0; i < r->N; i=i+1){
        fprintf(fp2, "%u, %f, %f\n", r->particles[i].hash, r->particles[i].m, r->particles[i].r);
     }
    fclose(fp2);
    reb_integrate(r, 1.6e8); // ~5 years
    rebx_free(rebx);
}
Example #26
0
int main(int argc, char* argv[]){
	struct reb_simulation* r = reb_create_simulation();
	// Setup constants
	r->dt 			= 1e-1;	
	r->gravity		= REB_GRAVITY_NONE;
	r->integrator		= REB_INTEGRATOR_LEAPFROG;
	r->collision		= REB_COLLISION_TREE;
	r->boundary		= REB_BOUNDARY_PERIODIC;
	// Override default collision handling to account for border particles
	r->collision_resolve	 = collision_resolve_hardsphere_withborder;
	r->heartbeat		= heartbeat;
	reb_configure_box(r, 20., 1, 1, 4);
	
	r->nghostx = 1; r->nghosty = 1; r->nghostz = 0; 	
	
	double N_part 	= 0.00937*r->boxsize.x*r->boxsize.y*r->boxsize.z;

	// Add Border Particles
	double radius 		= 1;
	double mass		= 1;
	double border_spacing_x = r->boxsize.x/(floor(r->boxsize.x/radius/2.)-1.);
	double border_spacing_y = r->boxsize.y/(floor(r->boxsize.y/radius/2.)-1.);
	struct reb_particle pt = {0};
	pt.r 		= radius;
	pt.m 		= mass;
	pt.id		= 1;
	for(double x = -r->boxsize.x/2.; x<r->boxsize.x/2.-border_spacing_x/2.;x+=border_spacing_x){
		for(double y = -r->boxsize.y/2.; y<r->boxsize.y/2.-border_spacing_y/2.;y+=border_spacing_y){
			pt.x 		= x;
			pt.y 		= y;
			
			// Add particle to bottom
			pt.z 		= -r->boxsize.z/2.+radius;
			pt.vy 		= 1;
			reb_add(r, pt);

			// Add particle to top
			pt.z 		= r->boxsize.z/2.-radius;
			pt.vy 		= -1;
			reb_add(r, pt);
		}
	}

	N_border = r->N;
	
	// Add real particles
	while(r->N-N_border<N_part){
		struct reb_particle pt = {0};
		pt.x 		= reb_random_uniform(-r->boxsize.x/2.,r->boxsize.x/2.);
		pt.y 		= reb_random_uniform(-r->boxsize.y/2.,r->boxsize.y/2.);
		pt.z 		= 0.758*reb_random_uniform(-r->boxsize.z/2.,r->boxsize.z/2.);
		pt.vx 		= reb_random_normal(0.001);
		pt.vy 		= reb_random_normal(0.001);
		pt.vz 		= reb_random_normal(0.001);
		pt.r 		= radius;						// m
		pt.m 		= 1;
		pt.id		= 2;
		reb_add(r, pt);
	}

	reb_integrate(r, INFINITY);
}