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()
68 double time_init = cfg.
optional(
"time_init", 0.0);
69 const bool use_jacobi = cfg.
optional(
"use_jacobi", 0);
70 bool keplerian_ephemeris = cfg.
optional(
"use_keplerian", 1);
71 bool transit_ephemeris = cfg.
optional(
"use_transit", 0);
72 if(transit_ephemeris) keplerian_ephemeris = 0;
73 assert(!(keplerian_ephemeris && transit_ephemeris));
75 ens[sysidx].id() =
sysid;
76 ens[sysidx].time() = time_init;
77 ens[sysidx].set_active();
78 if(sysid>maxsysid) maxsysid =
sysid;
81 double mass_star = draw_value_from_config(cfg,
"mass_star",0.00003,100.);
82 double x=0, y=0, z=0, vx=0, vy=0, vz=0;
83 ens.set_body(sysidx, 0, mass_star, x, y, z, vx, vy, vz);
86 int ecc_body = cfg.
optional(
"ecc_body", 0);
88 { ecc_body = 1+(sysid*(ens.
nbod()-1))/ens.
nsys(); }
89 double mass_enclosed = mass_star;
90 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
92 double mass_planet = draw_value_from_config(cfg,
"mass",bod,0.,mass_star);
93 mass_enclosed += mass_planet;
95 double a, e, i, O, w, M;
98 double period = draw_value_from_config(cfg,
"period",bod,0.2,365250.);
99 double epoch = draw_value_from_config(cfg,
"epoch",bod,-365250.,365250.);
100 a = pow((period/365.25)*(period/365.25)*mass_enclosed,1.0/3.0);
102 e = draw_value_from_config(cfg,
"ecc",bod,0.,1.);
105 i = draw_value_from_config(cfg,
"inc",bod,-180.,180.);
106 O = draw_value_from_config(cfg,
"node",bod,-720.,720.);
107 w = draw_value_from_config(cfg,
"omega",bod,-720.,720.);
113 double T = (0.5*M_PI-w)+2.0*M_PI*((epoch/period)-floor(epoch/period));
114 double E = atan2(sqrt(1.-e)*(1.+e)*sin(T),e+cos(T));
117 else if (keplerian_ephemeris)
119 a = draw_value_from_config(cfg,
"a",bod,0.001,10000.);
121 e = draw_value_from_config(cfg,
"ecc",bod,0.,1.);
124 i = draw_value_from_config(cfg,
"inc",bod,-180.,180.);
125 O = draw_value_from_config(cfg,
"node",bod,-720.,720.);
126 w = draw_value_from_config(cfg,
"omega",bod,-720.,720.);
127 M = draw_value_from_config(cfg,
"meananom",bod,-720.,720.);
135 double mass = use_jacobi ? mass_enclosed : mass_star+mass_planet;
136 if(cfg.count(
"verbose")&&(sysid<10))
137 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';
139 calc_cartesian_for_ellipse(x,y,z,vx,vy,vz, a, e, i, O, w, M, mass);
145 double bx, by, bz, bvx, bvy, bvz;
147 x += bx; y += by; z += bz;
148 vx += bvx; vy += bvy; vz += bvz;
152 ens.set_body(sysidx, bod, mass_planet, x, y, z, vx, vy, vz);
154 if(cfg.count(
"verbose")&&(sysid<10))
156 double x_t = ens.x(sysidx,bod);
157 double y_t = ens.y(sysidx,bod);
158 double z_t = ens.z(sysidx,bod);
159 double vx_t = ens.vx(sysidx,bod);
160 double vy_t = ens.vy(sysidx,bod);
161 double vz_t = ens.vz(sysidx,bod);
163 std::cout <<
" x= " << x <<
"=" << x_t <<
" ";
164 std::cout <<
" y= " << y <<
"=" << y_t <<
" ";
165 std::cout <<
" z= " << z <<
"=" << z_t <<
" ";
166 std::cout <<
"vx= " << vx <<
"=" << vx_t <<
" ";
167 std::cout <<
"vy= " << vy <<
"=" << vy_t <<
" ";
168 std::cout <<
"vz= " << vz <<
"=" << vz_t <<
"\n";
175 for(
unsigned int bod=0;bod<ens.
nbod();++bod)
177 ens.set_body(sysidx, bod, ens.mass(sysidx,bod),
178 ens.x(sysidx,bod)-
x, ens.y(sysidx,bod)-y, ens.z(sysidx,bod)-z,
179 ens.vx(sysidx,bod)-vx, ens.vy(sysidx,bod)-vy, ens.vz(sysidx,bod)-vz);
200 std::cerr <<
"# nsystems = " << ens.
nsys() <<
" nbodies/system = " << ens.
nbod() <<
"\n";
203 double time_init = cfg.
optional(
"time_init", 0.0);
206 const bool use_jacobi = cfg.
optional(
"use_jacobi", 0);
207 bool keplerian_ephemeris = cfg.
optional(
"use_keplerian", 1);
208 bool transit_ephemeris = cfg.
optional(
"use_transit", 0);
209 if(transit_ephemeris) keplerian_ephemeris = 0;
210 assert(!(keplerian_ephemeris && transit_ephemeris));
212 for(
unsigned int sys=0;sys<ens.
nsys();++sys)
214 generate_initial_conditions_for_system(cfg,ens,sys,sys);
220 void print_system(
const swarm::ensemble& ens,
const int systemid, std::ostream &os = std::cout)
223 JACOBI, BARYCENTRIC, ASTROCENTRIC
224 } COORDINATE_SYSTEM = BARYCENTRIC;
225 const bool use_jacobi = cfg.
optional(
"use_jacobi", 0);
226 if(use_jacobi) COORDINATE_SYSTEM = JACOBI;
230 std::streamsize cout_precision_old = os.precision();
232 os <<
"sys_idx= " << systemid <<
" sys_id= " << ens[systemid].id() <<
" time= " << ens.time(systemid) <<
"\n";
233 double star_mass = ens.mass(systemid,0);
234 double mass_effective = star_mass;
235 double bx, by, bz, bvx, bvy, bvz;
236 switch(COORDINATE_SYSTEM)
247 ens.get_body(systemid,0,star_mass,bx,by,bz,bvx,bvy,bvz);
251 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
254 double mass = ens.mass(systemid,bod);
256 switch(COORDINATE_SYSTEM)
260 mass_effective += mass;
264 mass_effective = star_mass + mass;
268 mass_effective = star_mass + mass;
271 double x = ens.x(systemid,bod)-bx;
272 double y = ens.y(systemid,bod)-by;
273 double z = ens.z(systemid,bod)-bz;
274 double vx = ens.vx(systemid,bod)-bvx;
275 double vy = ens.vy(systemid,bod)-bvy;
276 double vz = ens.vz(systemid,bod)-bvz;
278 double a, e, i, O, w, M;
279 calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
285 os << ens[systemid].id() <<
" " << bod <<
" " << mass <<
" " << a <<
" " << e <<
" " << i <<
" " << O <<
" " << w <<
" " << M <<
"\n";
288 os.precision(cout_precision_old);
293 void print_selected_systems(
swarm::ensemble& ens, std::vector<unsigned int> systemindices, std::ostream &os = std::cout)
295 for(
unsigned int i=0; i<systemindices.size(); ++i)
296 print_system(ens,systemindices[i], os);
299 void print_selected_systems_for_demo(
swarm::ensemble& ens,
unsigned int nprint, std::ostream &os = std::cout)
301 if(nprint>ens.
nsys()) nprint = ens.
nsys();
302 for(
unsigned int systemid = 0; systemid< nprint; ++systemid)
303 print_system(ens,systemid,os);
312 std::vector<unsigned int> stable_system_indices, unstable_system_indices;
313 for(
int i = 0; i < ens.
nsys() ; i++ )
315 if(ens[i].is_disabled())
316 unstable_system_indices.push_back(i);
318 stable_system_indices.push_back(i);
322 if(cfg.count(
"stable_init_output"))
324 ofstream stable_init_output( cfg.
optional(
"stable_init_output",
string(
"stable_init_output.txt")).c_str() );
325 print_selected_systems(ens_init,stable_system_indices, stable_init_output);
328 if(cfg.count(
"stable_final_output"))
330 ofstream stable_final_output( cfg.
optional(
"stable_final_output",
string(
"stable_final_output.txt")).c_str() );
331 print_selected_systems(ens,stable_system_indices, stable_final_output);
334 if(cfg.count(
"unstable_init_output"))
336 ofstream unstable_init_output( cfg.
optional(
"unstable_init_output",
string(
"unstable_init_output.txt")).c_str() );
337 print_selected_systems(ens_init,unstable_system_indices, unstable_init_output);
340 if(cfg.count(
"unstable_final_output"))
342 ofstream unstable_final_output( cfg.
optional(
"unstable_final_output",
string(
"unstable_final_output.txt")).c_str() );
343 print_selected_systems(ens,unstable_system_indices, unstable_final_output);
350 std::vector<std::vector<double> > semimajor_axes(ens.
nsys(),std::vector<double>(ens.
nbod(),0.));
352 for(
int sys_idx = 0; sys_idx < ens.
nsys() ; sys_idx++)
354 int sys_id = ens[sys_idx].id();
356 assert(sys_id<ens.
nsys());
357 double star_mass = ens.mass(sys_idx,0);
358 double mass_effective = star_mass;
359 double bx, by, bz, bvx, bvy, bvz;
361 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
363 double mass = ens.mass(sys_idx,bod);
364 mass_effective += mass;
366 double x = ens.x(sys_idx,bod)-bx;
367 double y = ens.y(sys_idx,bod)-by;
368 double z = ens.z(sys_idx,bod)-bz;
369 double vx = ens.vx(sys_idx,bod)-bvx;
370 double vy = ens.vy(sys_idx,bod)-bvy;
371 double vz = ens.vz(sys_idx,bod)-bvz;
372 double a, e, i, O, w, M;
373 calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
374 semimajor_axes[sys_id][bod-1] = a;
377 return semimajor_axes;
380 void disable_unstable_systems(
defaultEnsemble& ens,
const std::vector<std::vector<double> >& semimajor_axes_init,
const double deltaa_threshold )
382 for(
int sys_idx = 0; sys_idx < ens.
nsys() ; sys_idx++)
384 if(ens[sys_idx].is_disabled() )
continue;
385 bool disable =
false;
386 int sys_id = ens[sys_idx].id();
387 double star_mass = ens.mass(sys_idx,0);
388 double mass_effective = star_mass;
389 double bx, by, bz, bvx, bvy, bvz;
391 for(
unsigned int bod=1;bod<ens.
nbod();++bod)
395 double mass = ens.mass(sys_idx,bod);
396 mass_effective += mass;
398 double x = ens.x(sys_idx,bod)-bx;
399 double y = ens.y(sys_idx,bod)-by;
400 double z = ens.z(sys_idx,bod)-bz;
401 double vx = ens.vx(sys_idx,bod)-bvx;
402 double vy = ens.vy(sys_idx,bod)-bvy;
403 double vz = ens.vz(sys_idx,bod)-bvz;
404 double a, e, i, O, w, M;
405 calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
411 if(!((e>=0.)&&(e<1.0))) { disable =
true; }
412 if(!((a>0.)&&(a<10.0))) { disable =
true; }
414 assert(sys_id<semimajor_axes_init.size());
416 assert(bod-1<semimajor_axes_init[sys_id].size());
417 double da = a - semimajor_axes_init[sys_id][bod-1];
418 if(fabs(da) >= deltaa_threshold * semimajor_axes_init[sys_id][bod-1])
423 if(cfg.count(
"verbose"))
424 std::cout <<
"# Disabling idx=" << sys_idx <<
" id=" << sys_id <<
" b=" << bod <<
" a= " << a <<
" e= " << e <<
" i= " << i <<
" Omega= " << O <<
" omega= " << w <<
" M= " << M <<
"\n";
428 if(disable) ens[sys_idx].set_disabled();
437 const double critical_ratio = 0.75;
440 double ratio = double(count_disabled) / double( ens.
nsys() );
442 return ratio > critical_ratio;
464 int nsys = ens.
nsys();
467 if(active_nsys==0)
return ens;
468 int nbod = ens.
nbod();
473 for(
int i = 0, j = 0; (i < nsys) && (j < active_nsys); i++)
475 if( !ens[i].is_disabled() )
477 ens[i].
copyTo( active_ens[j] );
491 int nsys = ens.
nsys();
493 for(
int i = 0; i < nsys; i++)
495 if( ens[i].is_disabled() )
497 generate_initial_conditions_for_system(cfg,ens,i,maxsysid+1);
505 for(
int i = 0; i < ens.
nsys() ; i++)
507 if(ens[i].is_inactive())
512 volatile bool integration_loop_not_aborted_yet =
true;
521 fprintf(stderr,
"# Break requested... Finishing the current GPU kernel call and will then save the results before exitting.\n");
522 integration_loop_not_aborted_yet =
false;
529 int main(
int argc,
char* argv[] )
536 if(argc < 3) cout <<
"Usage: montecarlo_ecclimit <integration configuration> <initial conditions configuration>" << endl;
539 string integ_configfile = argv[1];
542 string initc_configfile = argv[2];
547 int seed_default = (int) time(NULL);
548 seed_default = seed_default ^ (pid + (pid << 15) );
549 int seed = cfg.
optional(
"seed", seed_default);
558 if( cfg.count(
"input") )
566 if(cfg.count(
"initial_snapshot"))
574 double destination_time = cfg.
optional(
"destination_time", 1.0E6);
579 integ->set_ensemble(ens);
580 integ->set_destination_time ( destination_time );
585 int max_kernel_calls_per_integrate = cfg.
optional(
"max_kernel_calls_per_integrate",1);
587 int max_itterations_per_kernel_call = cfg.
optional(
"max_itterations_per_kernel_call",20000);
588 integ->set_max_attempts( max_kernel_calls_per_integrate );
589 integ->set_max_iterations ( max_itterations_per_kernel_call );
601 reactivate_systems(ens);
618 const double deltaa_frac_threshold = cfg.
optional(
"deltaa_frac_threshold", 0.5);
619 disable_unstable_systems( ens, semimajor_axes_init, deltaa_frac_threshold );
624 std::cerr << active_ones <<
" max|dE/E|= " << max_deltaE <<
"\n";
630 if (!cfg.count(
"input") && cfg.count(
"replace_unstable") )
633 if( nsys_to_replace >0 )
636 integ->set_ensemble( ens );
644 if ( needs_shrinking( ens ) )
661 integ->set_ensemble( ens );