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); }
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); }
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); }
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); }
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); }
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); }
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); }
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"); } }
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); }
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); }
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); }
/*********************************************************************************** * 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; }
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); }
// 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; }
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); }
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.); }
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); }
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); }
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 }
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); }
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 */ }
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); }
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)); }
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); }
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); }