void reb_integrator_hermes_reset(struct reb_simulation* r){ //r->ri_hermes.timestep_too_large_warning = 0.; //Don't think we want to reset the warning. r->ri_hermes.steps = 0; r->ri_hermes.steps_miniactive = 0; r->ri_hermes.steps_miniN = 0; reb_integrator_whfast_reset(r); if (r->ri_hermes.mini){ reb_free_simulation(r->ri_hermes.mini); r->ri_hermes.mini = NULL; } if(r->ri_hermes.global_index_from_mini_index){ free(r->ri_hermes.global_index_from_mini_index); r->ri_hermes.global_index_from_mini_index = NULL; r->ri_hermes.global_index_from_mini_index_Nmax = 0; } if(r->ri_hermes.is_in_mini){ free(r->ri_hermes.is_in_mini); r->ri_hermes.is_in_mini = NULL; r->ri_hermes.is_in_mini_Nmax = 0; } if(r->ri_hermes.a_i){ free(r->ri_hermes.a_i); } if(r->ri_hermes.a_f){ free(r->ri_hermes.a_f); } r->ri_hermes.a_Nmax = 0; }
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"); } }
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* 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); }
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); }