void reb_step(struct reb_simulation* const r){ // Update walltime struct timeval time_beginning; gettimeofday(&time_beginning,NULL); // A 'DKD'-like integrator will do the first 'D' part. PROFILING_START() if (r->pre_timestep_modifications){ reb_integrator_synchronize(r); r->pre_timestep_modifications(r); r->ri_whfast.recalculate_coordinates_this_timestep = 1; r->ri_mercurius.recalculate_coordinates_this_timestep = 1; } reb_integrator_part1(r); PROFILING_STOP(PROFILING_CAT_INTEGRATOR) // Update and simplify tree. // Prepare particles for distribution to other nodes. // This function also creates the tree if called for the first time. if (r->tree_needs_update || r->gravity==REB_GRAVITY_TREE || r->collision==REB_COLLISION_TREE){ // Check for root crossings. PROFILING_START() reb_boundary_check(r); PROFILING_STOP(PROFILING_CAT_BOUNDARY) // Update tree (this will remove particles which left the box) PROFILING_START() reb_tree_update(r); PROFILING_STOP(PROFILING_CAT_GRAVITY) }
EXPORTIT void reb_step(struct reb_simulation* const r){ // A 'DKD'-like integrator will do the first 'D' part. PROFILING_START() reb_integrator_part1(r); PROFILING_STOP(PROFILING_CAT_INTEGRATOR) // Update and simplify tree. // Prepare particles for distribution to other nodes. // This function also creates the tree if called for the first time. if (r->tree_needs_update || r->gravity==REB_GRAVITY_TREE || r->collision==REB_COLLISION_TREE){ // Check for root crossings. PROFILING_START() reb_boundary_check(r); PROFILING_STOP(PROFILING_CAT_BOUNDARY) // Update tree (this will remove particles which left the box) PROFILING_START() reb_tree_update(r); PROFILING_STOP(PROFILING_CAT_GRAVITY) }
void iterate(void){ // A 'DKD'-like integrator will do the first 'D' part. PROFILING_START() integrator_part1(); PROFILING_STOP(PROFILING_CAT_INTEGRATOR) // Check for root crossings. PROFILING_START() boundaries_check(); PROFILING_STOP(PROFILING_CAT_BOUNDARY) // Update and simplify tree. // Prepare particles for distribution to other nodes. // This function also creates the tree if called for the first time. PROFILING_START() #ifdef TREE tree_update(); #endif //TREE #ifdef MPI // Distribute particles and add newly received particles to tree. communication_mpi_distribute_particles(); #endif // MPI #ifdef GRAVITY_TREE // Update center of mass and quadrupole moments in tree in preparation of force calculation. tree_update_gravity_data(); #ifdef MPI // Prepare essential tree (and particles close to the boundary needed for collisions) for distribution to other nodes. tree_prepare_essential_tree_for_gravity(); // Transfer essential tree and particles needed for collisions. communication_mpi_distribute_essential_tree_for_gravity(); #endif // MPI #endif // GRAVITY_TREE // Calculate accelerations. gravity_calculate_acceleration(); if (N_megno){ gravity_calculate_variational_acceleration(); } // Calculate non-gravity accelerations. if (problem_additional_forces) problem_additional_forces(); if (problem_additional_forces_with_parameters) problem_additional_forces_with_parameters(particles, t, dt, G, N, N_megno); PROFILING_STOP(PROFILING_CAT_GRAVITY) // A 'DKD'-like integrator will do the 'KD' part. PROFILING_START() integrator_part2(); if (problem_post_timestep_modifications){ integrator_synchronize(); problem_post_timestep_modifications(); if (integrator == WHFAST || integrator == HYBRID){ integrator_whfast_recalculate_jacobi_this_timestep = 1; } } if (problem_post_timestep_modifications_with_parameters){ integrator_synchronize(); problem_post_timestep_modifications_with_parameters(particles, t, dt, G, N, N_megno); if (integrator == WHFAST || integrator == HYBRID){ integrator_whfast_recalculate_jacobi_this_timestep = 1; } } PROFILING_STOP(PROFILING_CAT_INTEGRATOR) // Do collisions here. We need both the positions and velocities at the same time. #ifndef COLLISIONS_NONE // Check for root crossings. PROFILING_START() boundaries_check(); PROFILING_STOP(PROFILING_CAT_BOUNDARY) // Search for collisions using local and essential tree. PROFILING_START() collisions_search(); // Resolve collisions (only local particles are affected). collisions_resolve(); PROFILING_STOP(PROFILING_CAT_COLLISION) #endif // COLLISIONS_NONE #ifdef OPENGL PROFILING_START() display(); PROFILING_STOP(PROFILING_CAT_VISUALIZATION) #endif // OPENGL problem_output(); // Check if the simulation finished. #ifdef MPI int _exit_simulation = 0; MPI_Allreduce(&exit_simulation, &_exit_simulation,1,MPI_INT,MPI_MAX,MPI_COMM_WORLD); exit_simulation = _exit_simulation; #endif // MPI // @TODO: Adjust timestep so that t==tmax exaclty at the end. if((t+dt>tmax && tmax!=0.0) || exit_simulation==1){ #ifdef GRAVITY_GRAPE gravity_finish(); #endif // GRAVITY_GRAPE problem_finish(); struct timeval tim; gettimeofday(&tim, NULL); double timing_final = tim.tv_sec+(tim.tv_usec/1000000.0); printf("\nComputation finished. Total runtime: %f s\n",timing_final-timing_initial); #ifdef MPI MPI_Finalize(); #endif // MPI exit(0); } }