34 namespace swarm {
namespace cpu {
45 template<
class Monitor >
48 typedef Monitor monitor_t;
49 typedef typename monitor_t::params mon_params_t;
52 mon_params_t _mon_params;
56 _time_step = cfg.
require(
"time_step", 0.0);
61 #pragma omp parallel for
63 for(
int i = 0; i <
_ens.
nsys(); i++){
69 inline static double inner_product(
const double a[3],
const double b[3]){
70 return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
74 void calcForces(ensemble::SystemRef& sys,
double acc[][3],
double jerk[][3]){
75 const int nbod = sys.nbod();
78 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++)
79 acc[b][
c] = 0, jerk[b][
c] = 0;
82 for(
int i=0; i < nbod-1; i++)
for(
int j = i+1; j < nbod; j++) {
84 double dx[3] = { sys[j][0].pos()-sys[i][0].pos(),
85 sys[j][1].pos()-sys[i][1].pos(),
86 sys[j][2].pos()-sys[i][2].pos()
88 double dv[3] = { sys[j][0].vel()-sys[i][0].vel(),
89 sys[j][1].vel()-sys[i][1].vel(),
90 sys[j][2].vel()-sys[i][2].vel()
94 double r2 = dx[0]*dx[0] + dx[1]*dx[1] + dx[2] * dx[2];
95 double rinv = 1 / ( sqrt(r2) * r2 ) ;
99 const double scalar_i = +rinv*sys[j].mass();
100 for(
int c = 0;
c < 3;
c++) {
101 acc[i][
c] += dx[
c]* scalar_i;
102 jerk[i][
c] += (dv[
c] - dx[
c] * rv) * scalar_i;
106 const double scalar_j = -rinv*sys[i].mass();
107 for(
int c = 0;
c < 3;
c++) {
108 acc[j][
c] += dx[
c]* scalar_j;
109 jerk[j][
c] += (dv[
c] - dx[
c] * rv) * scalar_j;
116 const int nbod = sys.nbod();
117 double pre_pos[nbod][3];
118 double pre_vel[nbod][3];
119 double acc0[nbod][3];
120 double acc1[nbod][3];
121 double jerk0[nbod][3];
122 double jerk1[nbod][3];
126 monitor_t montest (_mon_params,sys,*
_log);
129 for(
int iter = 0 ; (iter <
_max_iterations) && sys.is_active() ; iter ++ ) {
130 double h = _time_step;
137 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++) {
138 sys[b][
c].pos() += h * (sys[b][
c].vel()+h*0.5*(acc0[b][
c]+h/3*jerk0[b][
c]));
139 sys[b][
c].vel() += h * (acc0[b][
c]+h*0.5*jerk0[b][
c]);
143 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++)
144 pre_pos[b][
c] = sys[b][
c].pos(), pre_vel[b][
c] = sys[b][
c].vel();
151 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++) {
152 sys[b][
c].pos() = pre_pos[b][
c]
153 + (.1-.25) * (acc0[b][
c] - acc1[b][
c]) * h * h
154 - 1/60.0 * ( 7 * jerk0[b][
c] + 2 * jerk1[b][
c] ) * h * h * h;
156 sys[b][
c].vel() = pre_vel[b][
c]
157 + ( -.5 ) * (acc0[b][c] - acc1[b][c] ) * h
158 - 1/12.0 * ( 5 * jerk0[b][
c] + jerk1[b][
c] ) * h * h;
167 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++) {
168 sys[b][
c].pos() = pre_pos[b][
c]
169 + (.1-.25) * (acc0[b][
c] - acc1[b][
c]) * h * h
170 - 1/60.0 * ( 7 * jerk0[b][
c] + 2 * jerk1[b][
c] ) * h * h * h;
172 sys[b][
c].vel() = pre_vel[b][
c]
173 + ( -.5 ) * (acc0[b][c] - acc1[b][c] ) * h
174 - 1/12.0 * ( 5 * jerk0[b][
c] + jerk1[b][
c] ) * h * h;
178 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++)
179 acc0[b][
c] = acc1[b][
c], jerk0[b][c] = jerk1[b][c];
183 if( sys.is_active() ) {