Beispiel #1
0
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)
    }
Beispiel #2
0
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)
	}
Beispiel #3
0
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);
	}
}