43 #define SYNC cudaThreadSynchronize()
46 using namespace swarm;
53 fprintf(stderr,
"%d %d: %lg (%lg %lg %lg) (%lg %lg %lg) \n", sys, bod,
55 ens[sys][bod][0].pos(),
56 ens[sys][bod][1].pos(),
57 ens[sys][bod][2].pos(),
58 ens[sys][bod][0].vel(),
59 ens[sys][bod][1].vel(),
60 ens[sys][bod][2].vel()
66 double time_init = cfg.
optional(
"time_init", 0.0);
67 const bool use_jacobi = cfg.
optional(
"use_jacobi", 0);
68 bool keplerian_ephemeris = cfg.
optional(
"use_keplerian", 1);
69 bool transit_ephemeris = cfg.
optional(
"use_transit", 0);
70 if(transit_ephemeris) keplerian_ephemeris = 0;
71 assert(!(keplerian_ephemeris && transit_ephemeris));
73 ens[sysidx].id() =
sysid;
74 ens[sysidx].time() = time_init;
75 ens[sysidx].set_active();
77 double mass_star = cfg.
optional(
"mass_star", 1.);
78 double x=0, y=0, z=0, vx=0, vy=0, vz=0;
79 ens.set_body(sysidx, 0, mass_star, x, y, z, vx, vy, vz);
80 if(ens[sysidx][0].num_attributes()>=1)
81 ens[sysidx][0].attribute(0) = cfg.
optional(
"radius_star", 1.) * 0.00464912633;
83 double mass_enclosed = mass_star;
84 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
86 double mass_planet = draw_value_from_config(cfg,
"mass",bod,0.,mass_star);
87 mass_enclosed += mass_planet;
89 if(ens[sysidx][bod].num_attributes()>=1)
90 ens[sysidx][bod].attribute(0) = draw_value_from_config(cfg,
"radius",bod,0.,200.) * 4.26349283e-5;
93 double a, e, i, O, w, M;
96 double period = draw_value_from_config(cfg,
"period",bod,0.2,365250.);
97 double epoch = draw_value_from_config(cfg,
"epoch",bod,0.2,365250.);
98 a = pow((period/365.25)*(period/365.25)*mass_enclosed,1.0/3.0);
99 e = draw_value_from_config(cfg,
"ecc",bod,0.,1.);
100 i = draw_value_from_config(cfg,
"inc",bod,-180.,180.);
101 O = draw_value_from_config(cfg,
"node",bod,-720.,720.);
102 w = draw_value_from_config(cfg,
"omega",bod,-720.,720.);
108 double T = (0.5*M_PI-w)+2.0*M_PI*((epoch/period)-floor(epoch/period));
109 double E = atan2(sqrt(1.-e)*(1.+e)*sin(T),e+cos(T));
112 else if (keplerian_ephemeris)
114 a = draw_value_from_config(cfg,
"a",bod,0.001,10000.);
115 e = draw_value_from_config(cfg,
"ecc",bod,0.,1.);
116 i = draw_value_from_config(cfg,
"inc",bod,-180.,180.);
117 O = draw_value_from_config(cfg,
"node",bod,-720.,720.);
118 w = draw_value_from_config(cfg,
"omega",bod,-720.,720.);
119 M = draw_value_from_config(cfg,
"meananom",bod,-720.,720.);
127 double mass = use_jacobi ? mass_enclosed : mass_star+mass_planet;
128 if(cfg.count(
"verbose")&&(sysid<10))
129 std::cout <<
"# Drawing sysid= " << sysid <<
" bod= " << bod <<
' ' << mass_planet <<
" " << a <<
' ' << e <<
' ' << i*180./M_PI <<
' ' << O*180./M_PI <<
' ' << w*180./M_PI <<
' ' << M*180./M_PI <<
'\n';
131 calc_cartesian_for_ellipse(x,y,z,vx,vy,vz, a, e, i, O, w, M, mass);
137 double bx, by, bz, bvx, bvy, bvz;
139 x += bx; y += by; z += bz;
140 vx += bvx; vy += bvy; vz += bvz;
144 ens.set_body(sysidx, bod, mass_planet, x, y, z, vx, vy, vz);
146 if(cfg.count(
"verbose")&&(sysid<10))
148 double x_t = ens.x(sysidx,bod);
149 double y_t = ens.y(sysidx,bod);
150 double z_t = ens.z(sysidx,bod);
151 double vx_t = ens.vx(sysidx,bod);
152 double vy_t = ens.vy(sysidx,bod);
153 double vz_t = ens.vz(sysidx,bod);
155 std::cout <<
" x= " << x <<
"=" << x_t <<
" ";
156 std::cout <<
" y= " << y <<
"=" << y_t <<
" ";
157 std::cout <<
" z= " << z <<
"=" << z_t <<
" ";
158 std::cout <<
"vx= " << vx <<
"=" << vx_t <<
" ";
159 std::cout <<
"vy= " << vy <<
"=" << vy_t <<
" ";
160 std::cout <<
"vz= " << vz <<
"=" << vz_t <<
"\n";
167 for(
unsigned int bod=0;bod<ens.
nbod();++bod)
169 ens.set_body(sysidx, bod, ens.mass(sysidx,bod),
170 ens.x(sysidx,bod)-
x, ens.y(sysidx,bod)-y, ens.z(sysidx,bod)-z,
171 ens.vx(sysidx,bod)-vx, ens.vy(sysidx,bod)-vy, ens.vz(sysidx,bod)-vz);
192 std::cerr <<
"# nsystems = " << ens.
nsys() <<
" nbodies/system = " << ens.
nbod() <<
"\n";
195 double time_init = cfg.
optional(
"time_init", 0.0);
198 const bool use_jacobi = cfg.
optional(
"use_jacobi", 0);
199 bool keplerian_ephemeris = cfg.
optional(
"use_keplerian", 1);
200 bool transit_ephemeris = cfg.
optional(
"use_transit", 0);
201 if(transit_ephemeris) keplerian_ephemeris = 0;
202 assert(!(keplerian_ephemeris && transit_ephemeris));
204 for(
unsigned int sys=0;sys<ens.
nsys();++sys)
206 generate_initial_conditions_for_system(cfg,ens,sys,sys);
212 void print_system(
const swarm::ensemble& ens,
const int systemid, std::ostream &os = std::cout)
215 JACOBI, BARYCENTRIC, ASTROCENTRIC
216 } COORDINATE_SYSTEM = BARYCENTRIC;
217 const bool use_jacobi = cfg.
optional(
"use_jacobi", 0);
218 if(use_jacobi) COORDINATE_SYSTEM = JACOBI;
220 std::streamsize cout_precision_old = os.precision();
222 os <<
"sys_idx= " << systemid <<
" sys_id= " << ens[systemid].id() <<
" time= " << ens.time(systemid) <<
"\n";
223 double star_mass = ens.mass(systemid,0);
224 double mass_effective = star_mass;
225 double bx, by, bz, bvx, bvy, bvz;
226 switch(COORDINATE_SYSTEM)
237 ens.get_body(systemid,0,star_mass,bx,by,bz,bvx,bvy,bvz);
241 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
244 double mass = ens.mass(systemid,bod);
246 switch(COORDINATE_SYSTEM)
250 mass_effective += mass;
254 mass_effective = star_mass + mass;
258 mass_effective = star_mass + mass;
261 double x = ens.x(systemid,bod)-bx;
262 double y = ens.y(systemid,bod)-by;
263 double z = ens.z(systemid,bod)-bz;
264 double vx = ens.vx(systemid,bod)-bvx;
265 double vy = ens.vy(systemid,bod)-bvy;
266 double vz = ens.vz(systemid,bod)-bvz;
268 double a, e, i, O, w, M;
269 calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
275 os << ens[systemid].id() <<
" " << bod <<
" " << mass <<
" " << a <<
" " << e <<
" " << i <<
" " << O <<
" " << w <<
" " << M <<
"\n";
278 os.precision(cout_precision_old);
283 void print_selected_systems(
swarm::ensemble& ens, std::vector<unsigned int> systemindices, std::ostream &os = std::cout)
285 for(
unsigned int i=0; i<systemindices.size(); ++i)
286 print_system(ens,systemindices[i], os);
289 void print_selected_systems_for_demo(
swarm::ensemble& ens,
unsigned int nprint, std::ostream &os = std::cout)
291 if(nprint>ens.
nsys()) nprint = ens.
nsys();
292 for(
unsigned int systemid = 0; systemid< nprint; ++systemid)
293 print_system(ens,systemid,os);
302 std::vector<unsigned int> stable_system_indices, unstable_system_indices;
303 for(
int i = 0; i < ens.
nsys() ; i++ )
305 if(ens[i].is_disabled())
306 unstable_system_indices.push_back(i);
308 stable_system_indices.push_back(i);
312 if(cfg.count(
"stable_init_output"))
314 ofstream stable_init_output( cfg.
optional(
"stable_init_output",
string(
"stable_init_output.txt")).c_str() );
315 print_selected_systems(ens_init,stable_system_indices, stable_init_output);
318 if(cfg.count(
"stable_final_output"))
320 ofstream stable_final_output( cfg.
optional(
"stable_final_output",
string(
"stable_final_output.txt")).c_str() );
321 print_selected_systems(ens,stable_system_indices, stable_final_output);
324 if(cfg.count(
"unstable_init_output"))
326 ofstream unstable_init_output( cfg.
optional(
"unstable_init_output",
string(
"unstable_init_output.txt")).c_str() );
327 print_selected_systems(ens_init,unstable_system_indices, unstable_init_output);
330 if(cfg.count(
"unstable_final_output"))
332 ofstream unstable_final_output( cfg.
optional(
"unstable_final_output",
string(
"unstable_final_output.txt")).c_str() );
333 print_selected_systems(ens,unstable_system_indices, unstable_final_output);
341 std::vector<std::vector<double> > semimajor_axes(ens.
nsys(),std::vector<double>(ens.
nbod(),0.));
343 for(
int sys_idx = 0; sys_idx < ens.
nsys() ; sys_idx++)
345 int sys_id = ens[sys_idx].id();
347 assert(sys_id<ens.
nsys());
348 double star_mass = ens.mass(sys_idx,0);
349 double mass_effective = star_mass;
350 double bx, by, bz, bvx, bvy, bvz;
352 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
354 double mass = ens.mass(sys_idx,bod);
355 mass_effective += mass;
357 double x = ens.x(sys_idx,bod)-bx;
358 double y = ens.y(sys_idx,bod)-by;
359 double z = ens.z(sys_idx,bod)-bz;
360 double vx = ens.vx(sys_idx,bod)-bvx;
361 double vy = ens.vy(sys_idx,bod)-bvy;
362 double vz = ens.vz(sys_idx,bod)-bvz;
363 double a, e, i, O, w, M;
364 calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
365 semimajor_axes[sys_id][bod-1] = a;
368 return semimajor_axes;
371 void disable_unstable_systems(
defaultEnsemble& ens,
const std::vector<std::vector<double> >& semimajor_axes_init,
const double deltaa_threshold )
373 for(
int sys_idx = 0; sys_idx < ens.
nsys() ; sys_idx++)
375 if(ens[sys_idx].is_disabled() )
continue;
376 bool disable =
false;
377 int sys_id = ens[sys_idx].id();
378 double star_mass = ens.mass(sys_idx,0);
379 double mass_effective = star_mass;
380 double bx, by, bz, bvx, bvy, bvz;
382 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
386 double mass = ens.mass(sys_idx,bod);
387 mass_effective += mass;
389 double x = ens.x(sys_idx,bod)-bx;
390 double y = ens.y(sys_idx,bod)-by;
391 double z = ens.z(sys_idx,bod)-bz;
392 double vx = ens.vx(sys_idx,bod)-bvx;
393 double vy = ens.vy(sys_idx,bod)-bvy;
394 double vz = ens.vz(sys_idx,bod)-bvz;
395 double a, e, i, O, w, M;
396 calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
402 if(!((e>=0.)&&(e<1.0))) { disable =
true; }
403 if(!((a>0.)&&(a<10.0))) { disable =
true; }
405 assert(sys_id<semimajor_axes_init.size());
407 assert(bod-1<semimajor_axes_init[sys_id].size());
408 double da = a - semimajor_axes_init[sys_id][bod-1];
409 if(fabs(da) >= deltaa_threshold * semimajor_axes_init[sys_id][bod-1])
414 if(cfg.count(
"verbose"))
415 std::cout <<
"# Disabling idx=" << sys_idx <<
" id=" << sys_id <<
" b=" << bod <<
" a= " << a <<
" e= " << e <<
" i= " << i <<
" Omega= " << O <<
" omega= " << w <<
" M= " << M <<
"\n";
419 if(disable) ens[sys_idx].set_disabled();
428 const double critical_ratio = 0.75;
431 double ratio = double(count_disabled) / double( ens.
nsys() );
433 return ratio > critical_ratio;
455 int nsys = ens.
nsys();
458 if(active_nsys==0)
return ens;
459 int nbod = ens.
nbod();
464 for(
int i = 0, j = 0; (i < nsys) && (j < active_nsys); i++)
466 if( !ens[i].is_disabled() )
468 ens[i].
copyTo( active_ens[j] );
479 for(
int i = 0; i < ens.
nsys() ; i++)
481 if(ens[i].is_inactive())
486 volatile bool integration_loop_not_aborted_yet =
true;
495 fprintf(stderr,
"# Break requested... Finishing the current GPU kernel call and will then save the results before exitting.\n");
496 integration_loop_not_aborted_yet =
false;
503 int main(
int argc,
char* argv[] )
510 if(argc < 3) cout <<
"Usage: montecarlo <integration configuration> <initial conditions configuration>" << endl;
513 string integ_configfile = argv[1];
516 string initc_configfile = argv[2];
526 if( cfg.count(
"input") )
532 if(cfg.count(
"initial_snapshot"))
540 double destination_time = cfg.
optional(
"destination_time", 1.0E6);
545 integ->set_ensemble(ens);
546 integ->set_destination_time ( destination_time );
551 int max_kernel_calls_per_integrate = cfg.
optional(
"max_kernel_calls_per_integrate",1);
553 int max_itterations_per_kernel_call = cfg.
optional(
"max_itterations_per_kernel_call",20000);
554 integ->set_max_attempts( max_kernel_calls_per_integrate );
555 integ->set_max_iterations ( max_itterations_per_kernel_call );
567 reactivate_systems(ens);
584 const double deltaa_frac_threshold = cfg.
optional(
"deltaa_frac_threshold", 0.5);
585 disable_unstable_systems( ens, semimajor_axes_init, deltaa_frac_threshold );
588 std::cerr << active_ones <<
"\n";
597 if ( needs_shrinking( ens ) )
614 integ->set_ensemble( ens );