Beispiel #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);
}
Beispiel #2
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);
}
Beispiel #3
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);	
}
Beispiel #4
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);
}
Beispiel #5
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);
}
Beispiel #6
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;
}
Beispiel #7
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);
}
Beispiel #8
0
// This function creates a simulation with one star, one planet and one test particle.
struct reb_simulation* create_sim(){
	struct reb_simulation* r = reb_create_simulation();
    // r->integrator = REB_INTEGRATOR_WHFAST;  Only first order variational equations supported in WHFast.
    struct reb_particle star = {0.};
    star.m = 1;
    reb_add(r, star);
    struct reb_particle planet = reb_tools_orbit_to_particle(1.,star,1e-3,1.,0.,0.,0.,0.,0.);
    reb_add(r, planet);
    struct reb_particle testparticle = reb_tools_orbit_to_particle(1.,star,0.,1.7,0.1,0.2,0.3,0.4,0.5);
    reb_add(r, testparticle);
    return r;
}
Beispiel #9
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);
}
Beispiel #10
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);

}
Beispiel #11
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);
}
Beispiel #12
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);
}
Beispiel #13
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");
	}
}
Beispiel #14
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);
}
Beispiel #15
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);
}
Beispiel #16
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.);
}
Beispiel #17
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);
}
Beispiel #18
0
int main(int argc, char* argv[]){
	// Setup constants
	G 		= 1;		
	integrator	= LEAPFROG;
	softening 	= 0.01;		
	dt 		= 3e-3;
	boxsize 	= 1.2;
	root_nx = 1; root_ny = 1; root_nz = 1;
	nghostx = 0; nghosty = 0; nghostz = 0; 		
	init_box();

	// Setup particles
	double disc_mass = 2e-1;
	int _N = 10000;
	// Initial conditions
	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);
	while(N<_N){
		struct reb_particle pt;
		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(G*mu/a);
		pt.vx 		=  vkep * sin(phi);
		pt.vy 		= -vkep * cos(phi);
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		pt.m 		= disc_mass/(double)_N;
		reb_add(r, pt);
	}
}
Beispiel #19
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);
}
Beispiel #20
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
}
Beispiel #21
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);
}
void reb_communication_mpi_distribute_particles(struct reb_simulation* const r){
	// Distribute the number of particles to be transferred.
	for (int i=0;i<r->mpi_num;i++){
		MPI_Scatter(r->particles_send_N, 1, MPI_INT, &(r->particles_recv_N[i]), 1, MPI_INT, i, MPI_COMM_WORLD);
	}
	// Allocate memory for incoming particles
	for (int i=0;i<r->mpi_num;i++){
		if  (i==r->mpi_id) continue;
		while (r->particles_recv_Nmax[i]<r->particles_recv_N[i]){
			r->particles_recv_Nmax[i] += 32;
			r->particles_recv[i] = realloc(r->particles_recv[i],sizeof(struct reb_particle)*r->particles_recv_Nmax[i]);
		}
	}

	// Exchange particles via MPI.
	// Using non-blocking receive call.
	MPI_Request request[r->mpi_num];
	for (int i=0;i<r->mpi_num;i++){
		if (i==r->mpi_id) continue;
		if (r->particles_recv_N[i]==0) continue;
		MPI_Irecv(r->particles_recv[i], r->particles_recv_N[i], r->mpi_particle, i, i*r->mpi_num+r->mpi_id, MPI_COMM_WORLD, &(request[i]));
	}
	// Using blocking send call.
	for (int i=0;i<r->mpi_num;i++){
		if (i==r->mpi_id) continue;
		if (r->particles_send_N[i]==0) continue;
		MPI_Send(r->particles_send[i], r->particles_send_N[i], r->mpi_particle, i, r->mpi_id*r->mpi_num+i, MPI_COMM_WORLD);
	}
	// Wait for all particles to be received.
	for (int i=0;i<r->mpi_num;i++){
		if (i==r->mpi_id) continue;
		if (r->particles_recv_N[i]==0) continue;
		MPI_Status status;
		MPI_Wait(&(request[i]), &status);
	}
	// Add particles to local tree
	for (int i=0;i<r->mpi_num;i++){
		for (int j=0;j<r->particles_recv_N[i];j++){
			reb_add(r,r->particles_recv[i][j]);
		}
	}
	// Bring everybody into sync, clean up. 
	MPI_Barrier(MPI_COMM_WORLD);
	for (int i=0;i<r->mpi_num;i++){
		r->particles_send_N[i] = 0;
		r->particles_recv_N[i] = 0;
	}
}
Beispiel #23
0
void reb_tools_init_plummer(struct reb_simulation* r, int _N, double M, double R) {
	// Algorithm from:	
	// http://adsabs.harvard.edu/abs/1974A%26A....37..183A
	
	double E = 3./64.*M_PI*M*M/R;
	for (int i=0;i<_N;i++){
		struct reb_particle star = {0};
		double _r = pow(pow(reb_random_uniform(0,1),-2./3.)-1.,-1./2.);
		double x2 = reb_random_uniform(0,1);
		double x3 = reb_random_uniform(0,2.*M_PI);
		star.z = (1.-2.*x2)*_r;
		star.x = sqrt(_r*_r-star.z*star.z)*cos(x3);
		star.y = sqrt(_r*_r-star.z*star.z)*sin(x3);
		double x5,g,q;
		do{
			x5 = reb_random_uniform(0.,1.);
			q = reb_random_uniform(0.,1.);
			g = q*q*pow(1.-q*q,7./2.);
		}while(0.1*x5>g);
		double ve = pow(2.,1./2.)*pow(1.+_r*_r,-1./4.);
		double v = q*ve;
		double x6 = reb_random_uniform(0.,1.);
		double x7 = reb_random_uniform(0.,2.*M_PI);
		star.vz = (1.-2.*x6)*v;
		star.vx = sqrt(v*v-star.vz*star.vz)*cos(x7);
		star.vy = sqrt(v*v-star.vz*star.vz)*sin(x7);
		
		star.x *= 3.*M_PI/64.*M*M/E;
		star.y *= 3.*M_PI/64.*M*M/E;
		star.z *= 3.*M_PI/64.*M*M/E;
		
		star.vx *= sqrt(E*64./3./M_PI/M);
		star.vy *= sqrt(E*64./3./M_PI/M);
		star.vz *= sqrt(E*64./3./M_PI/M);

		star.m = M/(double)_N;

		reb_add(r, star);
	}
}
Beispiel #24
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 */
}
Beispiel #25
0
void reb_tools_megno_init(struct reb_simulation* const r, double delta){
	int N_var = r->N;
	r->calculate_megno = 1;
	r->megno_Ys = 0.;
	r->megno_Yss = 0.;
	r->megno_cov_Yt = 0.;
	r->megno_var_t = 0.;
	r->megno_n = 0;
	r->megno_mean_Y = 0;
	r->megno_mean_t = 0;
        for (int i=0;i<N_var;i++){ 
                struct reb_particle megno = {
			.m  = r->particles[i].m,
			.x  = reb_random_normal(1.),
			.y  = reb_random_normal(1.),
			.z  = reb_random_normal(1.),
			.vx = reb_random_normal(1.),
			.vy = reb_random_normal(1.),
			.vz = reb_random_normal(1.) };
		double deltad = delta/sqrt(megno.x*megno.x + megno.y*megno.y + megno.z*megno.z + megno.vx*megno.vx + megno.vy*megno.vy + megno.vz*megno.vz); // rescale
		megno.x *= deltad;
		megno.y *= deltad;
		megno.z *= deltad;
		megno.vx *= deltad;
		megno.vy *= deltad;
		megno.vz *= deltad;

                reb_add(r, megno);
        }
	r->N_var = N_var;
}
double reb_tools_calculate_megno(struct reb_simulation* r){ // Returns the MEGNO <Y>
	if (r->t==0.) return 0.;
	return r->megno_Yss/r->t;
}
double reb_tools_calculate_lyapunov(struct reb_simulation* r){ // Returns the largest Lyapunov characteristic number (LCN), or maximal Lyapunov exponent
	if (r->t==0.) return 0.;
	return r->megno_cov_Yt/r->megno_var_t;
}
double reb_tools_megno_deltad_delta(struct reb_simulation* const r){
	const struct reb_particle* restrict const particles = r->particles;
	const int N = r->N;
	const int N_var = r->N_var;
        double deltad = 0;
        double delta2 = 0;
        for (int i=N-N_var;i<N;i++){
                deltad += particles[i].vx * particles[i].x; 
                deltad += particles[i].vy * particles[i].y; 
                deltad += particles[i].vz * particles[i].z; 
                deltad += particles[i].ax * particles[i].vx; 
                deltad += particles[i].ay * particles[i].vy; 
                deltad += particles[i].az * particles[i].vz; 
                delta2 += particles[i].x  * particles[i].x; 
                delta2 += particles[i].y  * particles[i].y;
                delta2 += particles[i].z  * particles[i].z;
                delta2 += particles[i].vx * particles[i].vx; 
                delta2 += particles[i].vy * particles[i].vy;
                delta2 += particles[i].vz * particles[i].vz;
        }
        return deltad/delta2;
}

void reb_tools_megno_update(struct reb_simulation* r, double dY){
	// Calculate running Y(t)
	r->megno_Ys += dY;
	double Y = r->megno_Ys/r->t;
	// Calculate averge <Y> 
	r->megno_Yss += Y * r->dt;
	// Update covariance of (Y,t) and variance of t
	r->megno_n++;
	double _d_t = r->t - r->megno_mean_t;
	r->megno_mean_t += _d_t/(double)r->megno_n;
	double _d_Y = reb_tools_calculate_megno(r) - r->megno_mean_Y;
	r->megno_mean_Y += _d_Y/(double)r->megno_n;
	r->megno_cov_Yt += ((double)r->megno_n-1.)/(double)r->megno_n 
					*(r->t-r->megno_mean_t)
					*(reb_tools_calculate_megno(r)-r->megno_mean_Y);
	r->megno_var_t  += ((double)r->megno_n-1.)/(double)r->megno_n 
					*(r->t-r->megno_mean_t)
					*(r->t-r->megno_mean_t);
}
Beispiel #26
0
static void reb_integrator_hermes_check_for_encounter(struct reb_simulation* global){
    struct reb_simulation* mini = global->ri_hermes.mini;
    const int _N_active = ((global->N_active==-1)?global->N:global->N_active) - global->N_var;
    struct reb_particle* global_particles = global->particles;
    struct reb_particle p0 = global_particles[0];
    double hill_switch_factor = global->ri_hermes.hill_switch_factor;
    double hill_switch_factor2 = hill_switch_factor*hill_switch_factor;
    double min_dt_enc2 = INFINITY;
    for (int i=0; i<_N_active; i++){
        struct reb_particle pi = global_particles[i];
        double radius_check = global->ri_hermes.radius_switch_factor*pi.r;
        double radius_check2 = radius_check*radius_check;
        const double dxi = p0.x - pi.x;
        const double dyi = p0.y - pi.y;
        const double dzi = p0.z - pi.z;
        const double r0i2 = dxi*dxi + dyi*dyi + dzi*dzi;
        const double mi = pi.m/(p0.m*3.);
        double rhi = pow(mi*mi*r0i2*r0i2*r0i2,1./6.);
        for(int j=i+1;j<global->N;j++){
            struct reb_particle pj = global_particles[j];
            
            const double dxj = p0.x - pj.x;
            const double dyj = p0.y - pj.y;
            const double dzj = p0.z - pj.z;
            const double r0j2 = dxj*dxj + dyj*dyj + dzj*dzj;
            const double mj = pj.m/(p0.m*3.);
            double rhj = pow(mj*mj*r0j2*r0j2*r0j2,1./6.);
            const double rh_sum = rhi+rhj;
            const double rh_sum2 = rh_sum*rh_sum;
            
            const double dx = pi.x - pj.x;
            const double dy = pi.y - pj.y;
            const double dz = pi.z - pj.z;
            const double rij2 = dx*dx + dy*dy + dz*dz;

            if(rij2 < hill_switch_factor2*rh_sum2 || rij2 < radius_check2){
                global->ri_hermes.mini_active = 1;
                // Monitor hill radius/relative velocity
                const double dvx = pi.vx - pj.vx;
                const double dvy = pi.vy - pj.vy;
                const double dvz = pi.vz - pj.vz;
                const double vij2 = dvx*dvx + dvy*dvy + dvz*dvz;
                const double dt_enc2 = hill_switch_factor2*rh_sum2/vij2;
                min_dt_enc2 = MIN(min_dt_enc2,dt_enc2);
                if (j>=_N_active && global->ri_hermes.is_in_mini[j]==0){//make sure not already added
                    // Add particle to mini simulation
                    reb_add(mini,pj);
                    global->ri_hermes.is_in_mini[j] = 1;
                    if (global->ri_hermes.global_index_from_mini_index_N>=global->ri_hermes.global_index_from_mini_index_Nmax){
                        while(global->ri_hermes.global_index_from_mini_index_N>=global->ri_hermes.global_index_from_mini_index_Nmax) global->ri_hermes.global_index_from_mini_index_Nmax += 32;
                        global->ri_hermes.global_index_from_mini_index = realloc(global->ri_hermes.global_index_from_mini_index,global->ri_hermes.global_index_from_mini_index_Nmax*sizeof(int));
                    }
                    global->ri_hermes.global_index_from_mini_index[global->ri_hermes.global_index_from_mini_index_N] = j;
                    global->ri_hermes.global_index_from_mini_index_N++;
                }
            }
        }
    }
    if (global->ri_hermes.timestep_too_large_warning==0 && min_dt_enc2 < 16.*global->dt*global->dt){
        global->ri_hermes.timestep_too_large_warning = 1;
        reb_warning(global,"The timestep is likely too large. Close encounters might be missed. Decrease the timestep or increase the switching radius. This warning will appear only once.");
    }
}
Beispiel #27
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);
}
Beispiel #28
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); 
}
Beispiel #29
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));
}
Beispiel #30
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);
}