00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "hdyn.h"
00014 #include "util_io.h"
00015 #include "../evolve/kira_defaults.h"
00016
00017 #ifndef TOOLBOX
00018
00019
00020
00021 kira_counters *hdyn::kc = NULL;
00022 kira_options *hdyn::options = NULL;
00023 kira_diag *hdyn::diag = NULL;
00024
00025 bool hdyn::use_dstar = false;
00026
00027 real hdyn::stellar_encounter_criterion_sq = 0;
00028 real hdyn::stellar_merger_criterion_sq = 0;
00029 real hdyn::stellar_capture_criterion_sq = 0;
00030
00031 hdyn** hdyn::perturbed_list = NULL;
00032 int hdyn::n_perturbed = 0;
00033
00034 real hdyn::eta = DEFAULT_ETA;
00035 real hdyn::eps = DEFAULT_EPS;
00036 real hdyn::eps2 = (DEFAULT_EPS*DEFAULT_EPS);
00037
00038 real hdyn::d_min_fac = DEFAULT_D_MIN_FAC;
00039 real hdyn::d_min_sq = 0;
00040 real hdyn::lag_factor = DEFAULT_LAG_FACTOR;
00041 real hdyn::mbar = 0;
00042
00043 real hdyn::gamma2 = DEFAULT_GAMMA;
00044 real hdyn::gamma23 = VERY_LARGE_NUMBER;
00045
00046 real hdyn::initial_step_limit = 0;
00047 real hdyn::step_limit = 0;
00048 real hdyn::unpert_step_limit = 1;
00049
00050 real hdyn::scaled_stripping_radius = -1;
00051
00052 int hdyn::max_slow_factor = DEFAULT_MAX_SLOW_FACTOR;
00053 real hdyn::max_slow_perturbation = DEFAULT_MAX_SLOW_PERTURBATION;
00054 real hdyn::max_slow_perturbation_sq = DEFAULT_MAX_SLOW_PERTURBATION_SQ;
00055
00056
00057 void check_sanity_of_timestep(xreal & time, real & timestep)
00058 {
00059 if (timestep > 0) {
00060
00061
00062
00063 if (fmod(time, timestep) != 0.0) {
00064
00065 cerr << " impossible timestep error \n";
00066
00067 cerr.precision(HIGH_PRECISION);
00068 PRL(time);
00069 PRL(timestep);
00070 PRL(1.0/timestep);
00071 PRL(fmod(time, timestep));
00072 cerr << " Perform correction... \n";
00073
00074 real corrected_timestep = 1.0;
00075 while (corrected_timestep > timestep*1.1)
00076 corrected_timestep *= 0.5;
00077
00078 timestep = corrected_timestep;
00079 real err;
00080 if ((err = fmod(time, timestep)) != 0.0) {
00081 time = time - err;
00082 if (err > 0.5*timestep)
00083 time += timestep;
00084 }
00085 PRL(time);
00086 PRL(timestep);
00087 }
00088 }
00089 }
00090
00091 static bool read_xreal = false;
00092
00093 void hdyn::print_static(ostream& s)
00094 {
00095 _dyn:_:print_static(s);
00096
00097 s << "kc = " << kc << endl;
00098 s << "options = " << options << endl;
00099 s << "diag = " << diag << endl;
00100
00101 s << "use_dstar = " << use_dstar << endl;
00102
00103 s << "stellar_encounter_criterion_sq = "
00104 << stellar_encounter_criterion_sq << endl;
00105 s << "stellar_merger_criterion_sq = "
00106 << stellar_merger_criterion_sq << endl;
00107 s << "stellar_capture_criterion_sq = "
00108 << stellar_capture_criterion_sq << endl;
00109
00110 s << "perturbed_list = " << perturbed_list << endl;
00111 s << "n_perturbed = " << n_perturbed << endl;
00112
00113 s << "eta = " << eta << endl;
00114 s << "eps = " << eps << endl;
00115 s << "eps2 = " << eps2 << endl;
00116
00117 s << "d_min_fac = " << d_min_fac << endl;
00118 s << "d_min_sq = " << d_min_sq << endl;
00119 s << "lag_factor = " << lag_factor << endl;
00120 s << "mbar = " << mbar << endl;
00121
00122 s << "gamma2 = " << gamma2 << endl;
00123 s << "gamma23 = " << gamma23 << endl;
00124
00125 s << "initial_step_limit = " << initial_step_limit << endl;
00126 s << "step_limit = " << step_limit << endl;
00127 s << "unpert_step_limit = " << unpert_step_limit << endl;
00128
00129 s << "scaled_stripping_radius = " << scaled_stripping_radius << endl;
00130
00131 s << "max_slow_factor = " << max_slow_factor << endl;
00132 s << "max_slow_perturbation = " << max_slow_perturbation << endl;
00133 s << "max_slow_perturbation_sq = " << max_slow_perturbation_sq << endl;
00134 }
00135
00136 istream & hdyn::scan_dyn_story(istream & s)
00137 {
00138 char input_line[MAX_INPUT_LINE_LENGTH];
00139 real last_real = false;
00140
00141 while (get_line(s, input_line), strcmp(END_DYNAMICS, input_line)) {
00142
00143 char keyword[MAX_INPUT_LINE_LENGTH];
00144 const char *val = getequals(input_line, keyword);
00145
00146
00147
00148 if (!strcmp("real_system_time", keyword)) {
00149
00150 read_xreal = true;
00151 last_real = true;
00152
00153 } else if (!strcmp("system_time", keyword)) {
00154
00155
00156
00157 if (!last_real) read_xreal = false;
00158
00159 if (read_xreal) {
00160
00161
00162
00163
00164
00165 set_system_time(get_xreal_from_input_line(input_line));
00166
00167 } else {
00168
00169 if (sizeof(xreal) != sizeof(real))
00170 cerr << "hdyn::scan_dyn_story: input "
00171 << "time data type is real"
00172 << endl;
00173
00174 real_system_time = system_time = strtod(val, NULL);
00175
00176 }
00177
00178
00179 } else {
00180
00181 last_real = false;
00182
00183 if (!strcmp("t", keyword)) {
00184
00185 if (read_xreal)
00186 time = get_xreal_from_input_line(input_line);
00187 else
00188 time = strtod(val, NULL);
00189
00190 } else if (!strcmp("dt", keyword))
00191 timestep = strtod(val, NULL);
00192 else if (!strcmp("m", keyword))
00193 mass = strtod(val, NULL);
00194 else if (!strcmp("r", keyword))
00195 set_vector_from_input_line(pos, input_line);
00196 else if (!strcmp("v", keyword)) {
00197 set_vector_from_input_line(vel, input_line);
00198 posvel = pos*vel;
00199 } else if (!strcmp("a", keyword))
00200 set_vector_from_input_line(acc, input_line);
00201 else if (!strcmp("pot", keyword))
00202 pot = strtod(val, NULL);
00203 else if (!strcmp("R_eff", keyword))
00204 radius = strtod(val, NULL);
00205 else if (!strcmp("steps", keyword))
00206 steps = strtod(val, NULL);
00207 else if (!strcmp("dir_f", keyword))
00208 direct_force = strtod(val, NULL);
00209 else if (!strcmp("indir_f", keyword))
00210 indirect_force = strtod(val, NULL);
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 else if (!strcmp("dt_u", keyword))
00221 unperturbed_timestep = strtod(val, NULL);
00222 else if (!strcmp("full_u", keyword))
00223 fully_unperturbed = strtol(val, NULL, 10);
00224
00225
00226
00227 else if (!strcmp("slow_kappa", keyword)) {
00228
00229
00230
00231
00232
00233 int k = strtol(val, NULL, 10);
00234
00235 if (k > 1) {
00236
00237
00238
00239
00240 slow = new slow_binary(k);
00241 slow->set_dtau(timestep/k);
00242
00243
00244
00245 }
00246
00247 } else if (!strcmp("slow_t_init", keyword)) {
00248
00249 if (slow) {
00250 slow->set_t_init( strtod(val,NULL) );
00251 }
00252
00253 } else if (!strcmp("slow_t_apo", keyword)) {
00254
00255 if (slow) {
00256 slow->set_t_apo( strtod(val,NULL) );
00257 }
00258
00259 } else if (!strcmp("slow_tau", keyword)) {
00260
00261 if (slow) {
00262 slow->set_tau( strtod(val,NULL) );
00263 slow->init_tau_pred();
00264 }
00265
00266 } else
00267
00268 add_story_line(dyn_story, input_line);
00269 }
00270 }
00271
00272 check_sanity_of_timestep(time, timestep);
00273
00274 return s;
00275 }
00276
00277
00278
00279 static bool write_unformatted = false;
00280
00281
00282
00283 void set_write_unformatted(bool u)
00284 {
00285 write_unformatted = u;
00286 }
00287
00288 bool get_write_unformatted()
00289 {
00290 return write_unformatted;
00291 }
00292
00293
00294
00295
00296
00297 static bool complete_system_dump = false;
00298
00299 void set_complete_system_dump(bool d)
00300 {
00301 complete_system_dump = d;
00302 }
00303
00304 ostream & hdyn::print_dyn_story(ostream & s,
00305 bool print_xreal,
00306 int short_output)
00307 {
00308
00309
00310 int precision = 0;
00311 int use_floats = 0;
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 bool short_short = (short_output && short_output != 4);
00334
00335 if (write_unformatted && short_short) {
00336
00337
00338
00339
00340
00341
00342 if (is_root()) put_real_number(s, " system_time = ",
00343 real_system_time);
00344
00345
00346
00347
00348
00349
00350
00351 vector putpos = pos;
00352 vector putvel = vel;
00353
00354 if (short_output > 1) {
00355 putpos = pred_pos;
00356 putvel = pred_vel;
00357 }
00358
00359 if (use_floats) {
00360
00361
00362
00363 s << "t64mpv32 =" << endl;
00364 write_unformatted_real(s, system_time);
00365 write_unformatted32_real(s, mass);
00366 write_unformatted32_vector(s, putpos);
00367 write_unformatted32_vector(s, putvel);
00368
00369 } else {
00370
00371
00372
00373 s << "tmpv =" << endl;
00374 write_unformatted_real(s, system_time);
00375 write_unformatted_real(s, mass);
00376 write_unformatted_vector(s, putpos);
00377 write_unformatted_vector(s, putvel);
00378 }
00379
00380 } else {
00381
00382
00383
00384
00385 _dyn_::print_dyn_story(s, print_xreal, short_output);
00386
00387 if (!short_short) {
00388
00389 put_real_number(s, " steps = ", steps);
00390 put_real_number(s, " dir_f = ", direct_force);
00391 put_real_number(s, " indir_f = ", indirect_force);
00392
00393
00394
00395 if (kep) {
00396
00397
00398
00399
00400
00401
00402
00403
00404 put_integer(s, " full_u = ", fully_unperturbed);
00405 put_real_number(s, " dt_u = ", unperturbed_timestep);
00406 }
00407
00408 if (slow) {
00409
00410
00411
00412
00413
00414 if (!elder_sister) {
00415 put_integer(s, " slow_kappa = ", get_kappa());
00416 put_real_number(s, " slow_t_init = ",
00417 slow->get_t_init());
00418 put_real_number(s, " slow_t_apo = ",
00419 slow->get_t_apo());
00420 put_real_number(s, " slow_tau = ", slow->get_tau());
00421 }
00422 }
00423 }
00424 }
00425
00426 if (short_output) {
00427
00428
00429
00430
00431
00432
00433 if (use_sstar && sbase) {
00434
00435
00436
00437
00438
00439
00440 put_integer(s, " S = ", (int)sbase->get_element_type());
00441
00442 if (write_unformatted && short_short) {
00443
00444
00445
00446 s << "TL =" << endl;
00447 write_unformatted32_real(s, sbase->temperature());
00448 write_unformatted32_real(s, sbase->get_luminosity());
00449
00450 } else {
00451 put_real_number(s, " T = ", sbase->temperature());
00452 put_real_number(s, " L = ", sbase->get_luminosity());
00453 }
00454 }
00455
00456
00457
00458 if (kep)
00459 put_integer(s, " kep = ", 1);
00460 #if 1
00461 else {
00462
00463
00464
00465
00466 if (this != root
00467 && is_low_level_node()
00468 && get_perturbation_squared() < SMALL_TDYN_PERT_SQ)
00469 put_integer(s, " kep = ", 2);
00470 }
00471 #endif
00472
00473
00474
00475 if (short_output == 3)
00476 put_integer(s, " defunct = ", 1);
00477
00478
00479
00480
00481
00482 if (is_root()) {
00483
00484 vector pos, vel;
00485 int which = get_std_center(this, pos, vel);
00486 put_real_vector(s, " center_pos = ", pos);
00487 put_real_vector(s, " center_vel = ", vel);
00488 put_integer(s, " center_type = ", which);
00489
00490
00491
00492 if (get_external_field() > 0) {
00493 refine_cluster_mass2(this);
00494 if (find_qmatch(get_dyn_story(), "bound_center_pos")) {
00495 vector bound_pos = getvq(get_dyn_story(),
00496 "bound_center_pos");
00497 vector bound_vel = getvq(get_dyn_story(),
00498 "bound_center_vel");
00499 put_real_vector(s, " bound_center_pos = ", bound_pos);
00500 put_real_vector(s, " bound_center_vel = ", bound_vel);
00501 }
00502 }
00503 }
00504
00505
00506
00507 if (complete_system_dump) {
00508
00509 if (external_field) {
00510
00511
00512
00513
00514 if (short_output != 4) {
00515
00516 if (!is_root()) {
00517 hdyn *top = get_top_level_node();
00518
00519
00520
00521 bool esc = false;
00522 if (find_qmatch(top->get_dyn_story(), "esc"))
00523 esc = getiq(top->get_dyn_story(), "esc");
00524 put_integer(s, " esc = ", esc);
00525
00526 if (find_qmatch(top->get_dyn_story(), "t_esc"))
00527 put_real_number(s, "t_esc = ",
00528 getrq(top->get_dyn_story(),
00529 "t_esc"));
00530 }
00531 }
00532 }
00533 }
00534 }
00535
00536 return s;
00537 }
00538
00539 typedef struct
00540 {
00541 hdyn* b;
00542 real d;
00543 } bd_pair, *bd_pair_ptr;
00544
00545 local int compare(const void * pi, const void * pj)
00546 {
00547 if (((bd_pair_ptr) pi)->d > ((bd_pair_ptr) pj)->d)
00548 return 1;
00549 else if (((bd_pair_ptr)pi)->d < ((bd_pair_ptr)pj)->d)
00550 return -1;
00551 else
00552 return 0;
00553 }
00554
00555 void hdyn::print_perturber_list(ostream & s, char* pre)
00556 {
00557
00558
00559 s << pre << "perturber list of " << format_label()
00560 << " [" << perturber_list << "]" << flush;
00561
00562 if (!valid_perturbers || perturber_list == NULL) {
00563 s << " is invalid" << endl;
00564 return;
00565 }
00566
00567 int np = n_perturbers;
00568
00569 if (np <= 0) {
00570 s << " is empty (no perturbers)" << endl;
00571 return;
00572 }
00573
00574
00575
00576 hdyn* top = get_top_level_node();
00577
00578
00579
00580 bd_pair_ptr bd_list = new bd_pair[np];
00581 for (int i = 0; i < np; i++) {
00582 bd_list[i].b = perturber_list[i];
00583 if (perturber_list[i] && perturber_list[i]->is_valid()) {
00584 bd_list[i].d = square(perturber_list[i]
00585 ->get_top_level_node()->pos
00586 - top->pos);
00587 } else
00588 bd_list[i].d = VERY_LARGE_NUMBER;
00589 }
00590
00591
00592
00593 qsort((void *)bd_list, (size_t)np, sizeof(bd_pair), compare);
00594
00595 s << " (" << np << " perturbers):";
00596 s << endl << pre << " ";
00597 for (int i = 0; i < np; i++) {
00598 if (bd_list[i].b)
00599 bd_list[i].b->print_label(s);
00600 else
00601 s << "(null)";
00602 if ((i+1)%10 == 0) {
00603 if (i < np-1)
00604 s << endl << pre << " ";
00605 } else
00606 s << " ";
00607 }
00608 s << endl;
00609
00610 delete [] bd_list;
00611
00612
00613 }
00614
00615 void hdyn::find_print_perturber_list(ostream & s, char* pre)
00616 {
00617 s << pre << "perturber list node for " << format_label() << " is ";
00618
00619 hdyn* pnode = find_perturber_node();
00620
00621 if (!pnode) {
00622 s << "NULL" << endl;
00623 return;
00624 } else
00625 s << pnode->format_label() << endl;
00626
00627 pnode->print_perturber_list(s, pre);
00628 }
00629
00630 #else
00631
00632 main(int argc, char** argv)
00633 {
00634 hdyn * b;
00635 check_help();
00636
00637 while (b = get_hdyn(cin)) {
00638 cout << "TESTING put_hdyn:" << endl;
00639 put_node(cout, *b);
00640 cout << "TESTING pp2() :" << endl;
00641 pp2(b);
00642 delete b;
00643 }
00644 cerr << "Normal exit" << endl;
00645 }
00646
00647 #endif