33 #define ASSUME_PROPAGATOR_USES_STD_COORDINATES 0
35 namespace swarm {
namespace cpu {
51 template<
class Monitor >
54 typedef Monitor monitor_t;
55 typedef typename monitor_t::params mon_params_t;
58 mon_params_t _mon_params;
61 #include "../propagators/keplerian.hpp"
65 _time_step = cfg.
require(
"time_step", 0.0);
70 for(
int i = 0; i <
_ens.
nsys(); i++){
76 inline static double inner_product(
const double a[3],
const double b[3]){
77 return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
81 void calcForces(ensemble::SystemRef& sys,
double acc[][3]){
82 const int nbod = sys.nbod();
85 for(
int b = 0; b < nbod; b++)
for(
int c =0;
c < 3;
c++)
89 for(
int i=0; i < nbod-1; i++)
for(
int j = i+1; j < nbod; j++) {
91 double dx[3] = { sys[j][0].pos()-sys[i][0].pos(),
92 sys[j][1].pos()-sys[i][1].pos(),
93 sys[j][2].pos()-sys[i][2].pos()
95 double dv[3] = { sys[j][0].vel()-sys[i][0].vel(),
96 sys[j][1].vel()-sys[i][1].vel(),
97 sys[j][2].vel()-sys[i][2].vel()
101 double r2 = dx[0]*dx[0] + dx[1]*dx[1] + dx[2] * dx[2];
102 double rinv = 1. / ( sqrt(r2) * r2 ) ;
106 const double scalar_i = +rinv*sys[j].mass();
107 for(
int c = 0;
c < 3;
c++) {
108 acc[i][
c] += dx[
c]* scalar_i;
112 const double scalar_j = -rinv*sys[i].mass();
113 for(
int c = 0;
c < 3;
c++) {
114 acc[j][
c] += dx[
c]* scalar_j;
133 const int nbod = sys.nbod();
135 double sump = 0., sumv = 0., mtot = 0.;
138 pc0 = sys[0][
c].pos();
140 for(
int j=0;j<nbod;++j) {
141 const double mj = sys[j].mass();
143 sump += mj*sys[j][
c].pos();
144 sumv += mj*sys[j][
c].vel();
148 sys[b][
c].vel() = sumv;
149 sys[b][
c].pos() = sump/mtot;
153 sys[b][
c].vel() -= sumv;
154 sys[b][
c].pos() -= pc0;
162 const int nbod = sys.nbod();
163 double sump = 0., sumv = 0., mtot;
164 double m0 = sys[0].mass();
169 pc0 = sys[0][
c].pos();
170 vc0 = sys[0][
c].vel();
172 for(
int j=1;j<nbod;++j)
174 const double mj = sys[j].mass();
176 sump += mj*sys[j][
c].pos();
177 sumv += mj*sys[j][
c].vel();
182 sys[b][
c].pos() -= sump;
183 sys[b][
c].vel() -= sumv/m0;
185 for(
int b=1;b<nbod;++b)
187 sys[b][
c].pos() += pc0 - sump;
188 sys[b][
c].vel() += vc0;
198 const double hby2m = hby2/sys[0].mass();
199 const int nbod = sys.nbod();
203 sys[b][
c].pos() += hby2*sys[b][
c].vel();
205 for(
int j=1;j<nbod;++j)
206 mv += sys[j].mass() * sys[j][
c].vel();
209 sys[b][
c].pos() += mv*hby2m;
216 const int nbod = sys.nbod();
220 monitor_t montest(_mon_params,sys,*
_log) ;
223 const double sqrtGM = sqrt(sys[0].mass());
228 for(
int iter = 0 ; (iter <
_max_iterations) && sys.is_active() ; iter ++ )
238 for(
int b=1;b<nbod;++b)
240 sys[b][
c].vel() += hby2 * acc[b][
c];
245 for(
int b=1;b<nbod;++b)
246 drift_kepler( sys[b][0].pos(),sys[b][1].pos(),sys[b][2].pos(),sys[b][0].vel(),sys[b][1].vel(),sys[b][2].vel(),sqrtGM, 2.0*hby2 );
253 for(
int b=1;b<nbod;++b)
255 sys[b][
c].vel() += hby2 * acc[b][
c];
261 sys.time() += 2.0*hby2;
265 const int thread_in_system_for_monitor = 0;
266 #if ASSUME_PROPAGATOR_USES_STD_COORDINATES
267 montest( thread_in_system_for_monitor );
269 bool using_std_coord =
false;
270 bool needs_std_coord = montest.pass_one( thread_in_system_for_monitor );
275 using_std_coord =
true;
279 int new_state = montest.pass_two ( thread_in_system_for_monitor );
281 if( montest.need_to_log_system() )
288 using_std_coord =
false;
293 if( sys.is_active() )
296 { sys.set_inactive(); }