00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "scatter3.h"
00063
00064 #ifdef TOOLBOX
00065
00066
00067
00068 local void check_init(initial_state3 & init)
00069 {
00070 if (init.m2 > 1) err_exit("check_init: m2 > 1");
00071 if (init.m2 < 0) err_exit("check_init: m2 < 0");
00072 if (init.m3 > 1) err_exit("check_init: m3 > 0");
00073 if (init.m3 < 0) err_exit("check_init: m3 < 0");
00074 if (init.r1 < 0) err_exit("check_init: r1 < 0");
00075 if (init.r2 < 0) err_exit("check_init: r2 < 0");
00076 if (init.r3 < 0) err_exit("check_init: r3 < 0");
00077 if (init.eta <= 0) err_exit("check_init: eta <= 0");
00078 }
00079
00080
00081
00082
00083 void bound3(sdyn3 * b,
00084 initial_state3 & init,
00085 intermediate_state3 & inter,
00086 final_state3 & final,
00087 real cpu_time_check,
00088 real dt_out,
00089 real dt_snap,
00090 real snap_cube_size)
00091 {
00092 inter.id = final.id = init.id;
00093
00094 mksphere(b, 3);
00095 initialize_bodies(inter.system);
00096 initialize_bodies(final.system);
00097
00098
00099
00100 sdyn3_to_system(b, init.system);
00101
00102
00103
00104
00105 real e_init = energy(b);
00106 real cpu_init = cpu_time();
00107 real cpu = cpu_init;
00108
00109 real kinetic, potential;
00110 get_top_level_energies(b, 0.0, potential, kinetic);
00111
00112
00113
00114
00115
00116 inter.n_kepler = 0;
00117
00118 do {
00119
00120 int n_stars = 0;
00121 for_all_daughters(sdyn3, b, bb) n_stars++;
00122
00123 real check_int = CHECK_INTERVAL;
00124
00125
00126 tree3_evolve(b, check_int, dt_out, dt_snap, snap_cube_size,
00127 init.eta, cpu_time_check);
00128
00129
00130
00131
00132 if (cpu_time() - cpu > cpu_time_check) {
00133 if (cpu == cpu_init) cerr << endl;
00134
00135 int p = cerr.precision(STD_PRECISION);
00136 cerr << "bound3: CPU time = " << cpu_time() - cpu_init
00137 << " time = " << b->get_time()
00138 << " n_steps = " << b->get_n_steps()
00139 << endl;
00140 cerr << " n_osc = " << b->get_n_ssd_osc()
00141 << " n_kepler = " << inter.n_kepler
00142 << endl << flush;
00143 cpu = cpu_time();
00144 cerr.precision(p);
00145 }
00146
00147 inter.n_osc = b->get_n_ssd_osc();
00148
00149 sdyn3_to_system(b, inter.system);
00150 merge_collisions(b);
00151
00152
00153
00154 for_all_daughters(sdyn3, b, bbb) n_stars--;
00155 if (n_stars > 0) {
00156 if (dt_snap < VERY_LARGE_NUMBER
00157 && system_in_cube(b, snap_cube_size)) {
00158 put_node(cout, *b);
00159 cout << flush;
00160 }
00161 }
00162
00163
00164
00165 } while (
00166 !extend_or_end_scatter(b, init, &inter, &final));
00167
00168
00169
00170 inter.r_min_min = VERY_LARGE_NUMBER;
00171 inter.n_stars = 0;
00172
00173 for_all_daughters(sdyn3, b, bb) {
00174 inter.index[inter.n_stars] = bb->get_index();
00175 inter.r_min[inter.n_stars] = sqrt(bb->get_min_nn_dr2());
00176 inter.r_min_min = min(inter.r_min_min, inter.r_min[inter.n_stars]);
00177 inter.n_stars++;
00178 }
00179
00180 if (b->get_n_ssd_osc() <= 1)
00181 inter.descriptor = non_resonance;
00182 else {
00183 int n_no_nn_change = 0;
00184 for_all_daughters(sdyn3, b, bbb)
00185 if (bbb->get_nn_change_flag() == 0)
00186 n_no_nn_change++;
00187 if (n_no_nn_change >= 2)
00188 inter.descriptor = hierarchical_resonance;
00189 else
00190 inter.descriptor = democratic_resonance;
00191 }
00192
00193
00194
00195 final.time = b->get_time();
00196 final.n_steps = (int) b->get_n_steps();
00197 final.error = energy(b) - e_init;
00198
00199 sdyn3_to_system(b, final.system);
00200
00201
00202
00203 if (abs(final.error) > ENERGY_TOLERANCE)
00204 if (( final.descriptor != merger_binary_1
00205 && final.descriptor != merger_binary_2
00206 && final.descriptor != merger_binary_3
00207 && final.descriptor != merger_escape_1
00208 && final.descriptor != merger_escape_2
00209 && final.descriptor != merger_escape_3
00210 && final.descriptor != triple_merger)
00211 || abs(final.error)
00212 > MERGER_ENERGY_TOLERANCE * abs(potential_energy(b)))
00213 final.descriptor = error;
00214
00215
00216
00217
00218
00219 if (dt_snap < VERY_LARGE_NUMBER && system_in_cube(b, snap_cube_size)) {
00220 put_node(cout, *b);
00221 cout << flush;
00222 }
00223 }
00224
00225
00226
00227
00228
00229 void make_standard_bound_init(initial_state3 & init)
00230 {
00231 init.m2 = 1.0/3;
00232 init.m3 = 1.0/3;
00233 init.r1 = 0;
00234 init.r2 = 0;
00235 init.r3 = 0;
00236
00237 init.r_stop
00238 = VERY_LARGE_NUMBER;
00239 init.tidal_tol_factor = DEFAULT_TIDAL_TOL_FACTOR;
00240 init.eta
00241 = DEFAULT_ETA;
00242
00243 initialize_bodies(init.system);
00244 init.id = get_initial_seed() + get_n_rand();
00245 }
00246
00247 main(int argc, char **argv)
00248 {
00249 initial_state3 init;
00250 make_standard_bound_init(init);
00251
00252 int seed = 0;
00253 int n_rand = 0;
00254
00255 int n_experiments = 1;
00256 real dt_out =
00257 VERY_LARGE_NUMBER;
00258 real dt_snap =
00259 VERY_LARGE_NUMBER;
00260
00261 real cpu_time_check = 3600;
00262 real snap_cube_size = 10;
00263
00264 int planar_flag = 0;
00265 real psi = 0;
00266
00267 bool b_flag = FALSE;
00268 bool q_flag = FALSE;
00269 bool Q_flag = FALSE;
00270 bool i_flag = true;
00271 bool s_flag = false;
00272
00273 check_help();
00274
00275 extern char *poptarg;
00276 int c;
00277 char* param_string = "A:bc:C:d:D:e:g:L:m:M:n:N:o:pPqQr:R:s:S:U:v:x:y:z:";
00278
00279 while ((c = pgetopt(argc, argv, param_string)) != -1)
00280 switch(c) {
00281
00282 case 'A': init.eta = atof(poptarg);
00283 break;
00284 case 'b': b_flag = 1 - b_flag;
00285 break;
00286 case 'c': cpu_time_check = 3600*atof(poptarg);
00287 break;
00288 case 'C': snap_cube_size = atof(poptarg);
00289 break;
00290 case 'd': dt_out = atof(poptarg);
00291 if (dt_out < 0) dt_out = pow(2.0, dt_out);
00292 break;
00293 case 'D': dt_snap = atof(poptarg);
00294 if (dt_snap < 0) dt_snap = pow(2.0, dt_snap);
00295 break;
00296 case 'e': init.ecc = atof(poptarg);
00297 break;
00298 case 'g': init.tidal_tol_factor = atof(poptarg);
00299 break;
00300 case 'i': i_flag = !i_flag;
00301 break;
00302 case 'L': init.r_init_min = atof(poptarg);
00303 break;
00304 case 'm': init.m2 = atof(poptarg);
00305 break;
00306 case 'M': init.m3 = atof(poptarg);
00307 break;
00308 case 'n': n_experiments = atoi(poptarg);
00309 break;
00310 case 'N': n_rand = atoi(poptarg);
00311 break;
00312 case 'p': planar_flag = 1;
00313 break;
00314 case 'P': planar_flag = -1;
00315 break;
00316 case 'q': q_flag = 1 - q_flag;
00317 break;
00318 case 'Q': Q_flag = 1 - Q_flag;
00319 break;
00320 case 'r': init.rho = atof(poptarg);
00321 break;
00322 case 'R': init.r_stop = atof(poptarg);
00323 init.r_init_min = init.r_init_max = abs(init.r_stop);
00324 break;
00325 case 's': seed = atoi(poptarg);
00326 s_flag = true;
00327 break;
00328 case 'S': init.r_stop = atof(poptarg);
00329 break;
00330 case 'U': init.r_init_max = atof(poptarg);
00331 break;
00332 case 'v': init.v_inf = atof(poptarg);
00333 break;
00334 case 'x': init.r1 = atof(poptarg);
00335 break;
00336 case 'y': init.r2 = atof(poptarg);
00337 break;
00338 case 'z': init.r3 = atof(poptarg);
00339 break;
00340 case '?': params_to_usage(cerr, argv[0], param_string);
00341 get_help();
00342 }
00343
00344 if (Q_flag) q_flag = TRUE;
00345
00346 if (init.m2 + init.m3 > 1) {
00347 cerr << "bound3: "; PRC(init.m2); PRL(init.m3);
00348 exit(1);
00349 }
00350
00351 check_init(init);
00352
00353
00354
00355 sdyn3 *b, *by, *bo;
00356 b = new sdyn3();
00357 bo = new sdyn3();
00358 if (i_flag) bo->set_label(1);
00359 b->set_oldest_daughter(bo);
00360 bo->set_parent(b);
00361
00362
00363
00364 bo->set_mass(1);
00365 bo->set_pos(vector(-0.97000436, 0.24308753, 0));
00366 bo->set_vel(-0.5*vector(0.93240737, 0.86473146, 0));
00367
00368 for (int i = 1; i < 3; i++) {
00369 by = new sdyn3();
00370 if (i_flag) by->set_label(i+1);
00371 bo->set_younger_sister(by);
00372 by->set_elder_sister(bo);
00373 by->set_parent(b);
00374
00375 if (i == 1) {
00376 by->set_mass(1);
00377 by->set_pos(-bo->get_pos());
00378 by->set_vel(bo->get_vel());
00379 } else {
00380 by->set_mass(1);
00381 by->set_pos(0);
00382 by->set_vel(-2*bo->get_vel());
00383 }
00384 bo = by;
00385 }
00386
00387 b->log_history(argc, argv);
00388
00389 if (s_flag == FALSE) seed = 0;
00390 int random_seed = srandinter(seed, n_rand);
00391
00392 cpu_init();
00393
00394 for (int i = 0; i < n_experiments; i++) {
00395
00396 if (n_experiments > 1) cerr << i+1 << ": ";
00397
00398 cerr << "Random seed = " << get_initial_seed()
00399 << " n_rand = " << get_n_rand() << flush;
00400 init.id = get_initial_seed() + get_n_rand();
00401
00402 intermediate_state3 inter;
00403 final_state3 final;
00404
00405 real cpu = cpu_time();
00406 bound3(b, init, inter, final, cpu_time_check,
00407 dt_out, dt_snap, snap_cube_size);
00408 cpu = cpu_time() - cpu;
00409
00410 cerr << ": ";
00411
00412 print_final(cerr, final);
00413 }
00414 }
00415
00416 #endif