Include
Include
// initialize MPI
int rank, size;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
int n;
real t;
MPI_Datatype particletype;
Particle *p = get_snapshot(n, t, particletype);
real noutp = 1;
real dt;
put_snapshot(p, n, t, particletype);
bool read_options(int argc, char *argv[], real & dt_param, real & dt_dia,
real & dt_out, real & dt_tot, bool & i_flag, bool &
x_flag)
{
int c;
while ((c = getopt(argc, argv, "hd:e:o:t:ix")) != -1)
switch(c){
case 'h': cerr << "usage: " << argv[0]
<< " [-h (for help)]"
<< " [-d step_size_control_parameter]\n"
<< " [-e diagnostics_interval]"
<< " [-o output_interval]\n"
<< " [-t total_duration]"
<< " [-i (start output at t = 0)]\n"
<< " [-x (extra debugging
diagnostics)]"
<< endl;
return false; // execution should stop after
help
case 'd': dt_param = atof(optarg);
break;
case 'e': dt_dia = atof(optarg);
break;
case 'i': i_flag = true;
break;
case 'o': dt_out = atof(optarg);
break;
case 't': dt_tot = atof(optarg);
break;
case 'x': x_flag = true;
break;
case '?': cerr << "usage: " << argv[0]
<< " [-h (for help)]"
<< " [-d step_size_control_parameter]\n"
<< " [-e diagnostics_interval]"
<< " [-o output_interval]\n"
<< " [-t total_duration]"
<< " [-i (start output at t = 0)]\n"
<< " [-x (extra debugging
diagnostics)]"
<< endl;
return false; // execution should stop after
error
}
return true; // ready to continue program
execution
}
Particle *p_tmp;
if(rank==root) {
cerr << "Reading snapshot" << endl;
cin >> n;
cin >> t;
MPI_Scatter(p_tmp,n_local,particletype,p,n_local,particletype,root,MPI_COM
M_WORLD);
n = n_local;
MPI_Bcast(&t,1,MPI_DOUBLE,root,MPI_COMM_WORLD);
delete []p_tmp;
return p;
}
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
int ntot;
MPI_Allreduce(&n, &ntot, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
Particle *p_all;
if(rank==root) {
p_all = new Particle[ntot];
}
MPI_Gather(p,n,particletype,p_all,n,particletype,root,MPI_COMM_WORLD);
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
real ekin;
MPI_Allreduce(&ekin_local, &ekin, 1, MPI_DOUBLE, MPI_SUM,
MPI_COMM_WORLD );
real epot;
MPI_Allreduce(&epot_local, &epot, 1, MPI_DOUBLE, MPI_SUM,
MPI_COMM_WORLD );
epot *= 0.5; // against double counting
cerr << "at time t = " << t << ", after " << nsteps
<< " steps (CPU = " << tcpu << "): \n E_kin = " << ekin
<< " , E_pot = " << epot
<< " , E_tot = " << etot << endl;
cerr << " "
<< "absolute energy error: E_tot - E_init = "
<< etot - einit << endl;
cerr << " "
<< "relative energy error: (E_tot - E_init) / E_init = "
<< (etot - einit) / einit << endl;
}
if (x_flag){
cerr << " for debugging purposes, here is the internal data "
<< "representation:\n";
for (int i = 0; i < n ; i++){
cerr << " internal data for particle " << i+1 << " : " <<
endl;
cerr << " ";
cerr << p[i].id << " " << p[i].mass;
for (int k = 0; k < NDIM; k++)
cerr << ' ' << p[i].pos[k];
for (int k = 0; k < NDIM; k++)
cerr << ' ' << p[i].vel[k];
for (int k = 0; k < NDIM; k++)
cerr << ' ' << p[i].acc[k];
for (int k = 0; k < NDIM; k++)
cerr << ' ' << p[i].jerk[k];
cerr << endl;
}
}
}
if(rank==root)
cerr << "Starting a Hermite integration for a " << n*size
<< "-body system,\n from time t = " << t
<< " with time step control parameter dt_param = " << dt_param
<< " until time " << t + dt_tot
<< " ,\n with diagnostics output interval dt_dia = "
<< dt_dia << ",\n and snapshot output interval dt_out = "
<< dt_out << "." << endl;
while (true){
while (t < t_dia && t < t_out && t < t_end){
real dt_local = dt_param * coll_time;
real dt;
MPI_Allreduce(&dt_local, &dt, 1, MPI_DOUBLE, MPI_MIN,
MPI_COMM_WORLD); // synchronize time step
evolve_step(p, n, t, dt, epot, coll_time, pipe);
nsteps++;
}
if (t >= t_dia){
write_diagnostics(p, n, t, epot, nsteps,
einit, false, x_flag, tcpu);
t_dia += dt_dia;
}
if (t >= t_out){
put_snapshot(p, n, t, particletype);
t_out += dt_out;
}
if (t >= t_end)
break;
}
}
predict_step(p, n, dt);
get_acc_jerk_pot_coll(p, n, epot, coll_time, pipe);
correct_step(p, po, n, dt);
t += dt;
delete[] po;
}
// add the {i,j} contribution to the total potential energy for the
system:
epot -= pl[i].mass * po[j].mass / r;
coll_est_q = r2/da2;
if (coll_time_q > coll_est_q)
coll_time_q = coll_est_q;
}
}
}
// from q for quartic back to linear collision time and taking the
minimum
coll_time = min(coll_time, sqrt(sqrt(coll_time_q)));
}
int rlen;
Particle *recvbuf;
// Compute forces
get_acc_jerk_pot_coll(p, n, recvbuf, rlen, epot, coll_time);
}
}