00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "star/dstar_to_kira.h"
00019 #include "kira_defaults.h"
00020
00021 #define LONG_BINARY_OUT 10
00022 #define SEED_STRING_LENGTH 60
00023
00024 #define Rsun_pc 2.255e-8 // R_sun/1 parsec = 6.960e+10/3.086e+18;
00025
00026 local void initialize_index(node * b, bool verbose)
00027 {
00028
00029
00030 if (b->is_root() && b->get_index() < 0 && !b->get_name())
00031 b->set_name("root");
00032
00033
00034
00035 int index = 0;
00036
00037 for_all_nodes(node, b, bb)
00038 if (bb != b)
00039 if (bb->get_index() > 0)
00040 index = max(index, bb->get_index());
00041
00042
00043
00044 index = 1000 * (index / 1000 + 1);
00045
00046 for_all_nodes(node, b, bb)
00047 if (bb != b && bb->get_index() < 0 && bb->get_name() == NULL) {
00048 if (verbose) {
00049 cerr << "Attached index " << index << " to unnamed ";
00050 if (bb->is_parent())
00051 cerr << "node\n";
00052 else
00053 cerr << "leaf\n";
00054 }
00055 bb->set_index(index++);
00056 }
00057 }
00058
00059 local void correct_multiples(hdyn* b,
00060 bool verbose)
00061 {
00062
00063
00064
00065 for_all_nodes(hdyn, b, bb) {
00066 if (bb->get_elder_sister() == NULL
00067 && bb->get_kepler() != NULL) {
00068 if (bb->is_parent()) {
00069 if (verbose) {
00070 cerr << "unperturbed " << bb->format_label() << endl;
00071 cerr << " multiple system, ";
00072 }
00073 if (bb->get_oldest_daughter()->get_kepler() == NULL) {
00074 if (verbose)
00075 cerr << "daughter node "
00076 << bb->get_oldest_daughter()->format_label()
00077 << " not unperturbed. Correcting...\n";
00078 bb->get_oldest_daughter()->
00079 reinitialize_kepler_from_hdyn();
00080 } else
00081 if (verbose)
00082 cerr << "daughter node uperturbed.\n";
00083 }
00084 }
00085 }
00086 }
00087
00088 local void choose_param(hdyn* b, bool verbose,
00089 real& x, bool x_flag, char* x_id,
00090 bool zero_OK = false)
00091 {
00092
00093
00094
00095 static bool skip_line = true;
00096
00097 char kira_x[128];
00098 strcpy(kira_x, "kira_");
00099 strcat(kira_x, x_id);
00100
00101 bool x_in_snap = find_qmatch(b->get_log_story(), kira_x);
00102
00103 if (x_flag) {
00104
00105
00106
00107
00108
00109 if (x_in_snap && verbose) {
00110 if (skip_line) cerr << endl;
00111 cerr << "command-line " << x_id << " = " << x;
00112 if (twiddles(x, getrq(b->get_log_story(), kira_x)))
00113 cerr << " is identical to value";
00114 else
00115 cerr << " overrides value "
00116 << getrq(b->get_log_story(), kira_x);
00117 cerr << " in input snapshot"
00118 << endl;
00119 skip_line = false;
00120 }
00121
00122 } else {
00123
00124 if (x_in_snap) {
00125
00126 real x_snap = getrq(b->get_log_story(), kira_x);
00127
00128 if ((x_snap > 0 || x_snap == 0 && zero_OK)) {
00129
00130 x = x_snap;
00131 if (verbose) {
00132 if (skip_line) cerr << endl;
00133 cerr << "Taking " << x_id << " = " << x
00134 << " from input snapshot"
00135 << endl;
00136 skip_line = false;
00137 }
00138
00139 } else {
00140
00141 if (verbose) {
00142 if (skip_line) cerr << endl;
00143 cerr << "Error reading " << x_id
00144 << " from input snapshot;"
00145 << " using default = " << x
00146 << endl;
00147 skip_line = false;
00148 }
00149 }
00150
00151 } else {
00152
00153 if (verbose) {
00154 if (skip_line) cerr << endl;
00155 cerr << "Using default " << x_id << " = " << x
00156 << endl;
00157 skip_line = false;
00158 }
00159 }
00160 }
00161
00162 if (x < 0 || (x == 0 && !zero_OK)) {
00163 char tmp[128];
00164 strcpy(tmp, "Error setting ");
00165 strcat(tmp, x_id);
00166 err_exit(tmp);
00167 }
00168
00169
00170
00171 putrq(b->get_log_story(), kira_x, x);
00172 }
00173
00174 local void choose_param(hdyn* b, bool verbose,
00175 int& ix, bool x_flag, char* x_id,
00176 bool zero_OK = false)
00177 {
00178
00179
00180
00181 real x = ix;
00182 choose_param(b, verbose, x, x_flag, x_id, zero_OK);
00183 ix = (int)(x+0.1);
00184 }
00185
00186 local void set_runtime_params(hdyn *b, bool verbose,
00187 real eta, bool eta_flag,
00188 real eps, bool eps_flag,
00189 real d_min, bool d_min_flag,
00190 real lag_factor, bool lag_flag,
00191 real gamma, bool gamma_flag,
00192 int max_slow, bool max_slow_flag)
00193 {
00194
00195
00196
00197
00198
00199
00200 choose_param(b, verbose, eta, eta_flag, "eta");
00201 b->set_eta(eta);
00202
00203 choose_param(b, verbose, eps, eps_flag, "eps", true);
00204 b->set_eps(eps);
00205
00206 choose_param(b, verbose, d_min, d_min_flag, "d_min_fac");
00207 b->set_d_min_fac(d_min);
00208
00209
00210
00211
00212 int nbody = b->n_daughters();
00213
00214 real d_min_sq = square(d_min/nbody);
00215
00216
00217
00218 choose_param(b, verbose, d_min_sq, false, "d_min_sq");
00219 b->set_d_min_sq(d_min_sq);
00220
00221
00222
00223
00224 real ratio = d_min_sq / square(d_min/nbody);
00225 if (ratio < 0.0002 || ratio > 5.e3)
00226 cerr << endl
00227 << "*** warning: d_min_sq ratio = " << ratio << " ***"
00228 << endl;
00229
00230 choose_param(b, verbose, lag_factor, lag_flag, "lag_factor");
00231 b->set_lag_factor(square(lag_factor));
00232
00233 choose_param(b, verbose, gamma, gamma_flag, "gamma");
00234 b->set_gamma2(square(gamma));
00235
00236 choose_param(b, verbose, max_slow, max_slow_flag, "log_max_slow", true);
00237 if (max_slow >= 0) {
00238 int kappa_max = (int) pow(2, max_slow);
00239 cerr << "Setting maximum slowdown factor = " << kappa_max << endl;
00240 b->set_max_slow_factor(kappa_max);
00241 if (kappa_max > 1)
00242 cerr << "Maximum slow perturbation = "
00243 << b->get_max_slow_perturbation() << endl;
00244 putiq(b->get_log_story(), "log_max_slow", max_slow);
00245 }
00246 }
00247
00248 local real get_scaled_stripping_radius(hdyn* b,
00249 bool verbose,
00250 real input_stripping_radius,
00251 real initial_r_jacobi,
00252 real initial_r_virial,
00253 real initial_mass)
00254 {
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 real scaled_stripping_radius = 0;
00271
00272
00273
00274
00275
00276 if (find_qmatch(b->get_log_story(), "kira_scaled_stripping_radius")) {
00277
00278 real kira_scaled_stripping_radius
00279 = getrq(b->get_log_story(), "kira_scaled_stripping_radius");
00280
00281 if (kira_scaled_stripping_radius > 0) {
00282
00283 scaled_stripping_radius = kira_scaled_stripping_radius;
00284
00285 if (verbose) {
00286 cerr << "Using scaled stripping radius ";
00287 PRL(kira_scaled_stripping_radius);
00288 cerr << " from input snapshot" << endl;
00289
00290 if (input_stripping_radius > 0)
00291 cerr << "Ignoring \"-G " << input_stripping_radius
00292 << "\" found on command line"
00293 << endl;
00294 }
00295
00296 } else {
00297
00298 if (verbose)
00299 cerr << "Warning: error reading "
00300 << "kira_initial_jacobi_radius"
00301 << " from input snapshot"
00302 << endl;
00303 else
00304 err_exit(
00305 "Error reading kira_initial_jacobi_radius from input snapshot");
00306
00307 }
00308 }
00309
00310 if (scaled_stripping_radius <= 0) {
00311
00312
00313
00314
00315 if (input_stripping_radius > 0) {
00316
00317 if (initial_r_jacobi > 0) {
00318
00319 if (verbose)
00320 cerr << "command-line -G " << input_stripping_radius
00321 << " used as scaling factor for initial Jacobi radius"
00322 << endl;
00323
00324 input_stripping_radius *= initial_r_jacobi;
00325
00326 } else {
00327
00328
00329
00330 real r_jacobi_over_r_virial
00331 = getrq(b->get_log_story(),
00332 "initial_rtidal_over_rvirial");
00333
00334 if (r_jacobi_over_r_virial > 0) {
00335
00336 input_stripping_radius *= r_jacobi_over_r_virial;
00337
00338 if (verbose)
00339 cerr << "command-line -G " << input_stripping_radius
00340 << " used as scaling factor for tidal radius"
00341 << endl;
00342
00343 } else
00344
00345 if (verbose)
00346 cerr << "command-line -G " << input_stripping_radius
00347 << " used as scaling factor for virial radius"
00348 << endl;
00349
00350 input_stripping_radius *= initial_r_virial;
00351
00352 }
00353
00354 cerr << "rescaled "; PRL(input_stripping_radius);
00355
00356 scaled_stripping_radius = input_stripping_radius
00357 / pow(initial_mass, 1.0/3.0);
00358
00359
00360
00361 if (scaled_stripping_radius > 0)
00362 putrq(b->get_log_story(), "kira_scaled_stripping_radius",
00363 scaled_stripping_radius);
00364 }
00365 }
00366
00367 return scaled_stripping_radius;
00368 }
00369
00370 local void get_physical_scales(hdyn* b,
00371 bool verbose,
00372 real initial_mass,
00373 real initial_r_virial,
00374 bool M_flag, real m_tot,
00375 bool R_flag, real r_vir,
00376 bool T_flag, real t_vir,
00377 real q_vir,
00378 int nbody)
00379 {
00380
00381
00382
00383
00384
00385
00386 real initial_t_virial
00387 = sqrt(2*q_vir*pow(initial_r_virial, 3) / initial_mass);
00388
00389
00390
00391
00392
00393
00394
00395
00396 real old_m_tot
00397 = b->get_starbase()->conv_m_dyn_to_star(initial_mass);
00398
00399
00400
00401
00402 real old_r_vir
00403 = b->get_starbase()->conv_r_dyn_to_star(initial_r_virial)
00404 * Rsun_pc;
00405
00406
00407
00408 real old_t_vir
00409 = b->get_starbase()->conv_t_dyn_to_star(initial_t_virial);
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 bool M_set = M_flag;
00429
00430 if (M_set) {
00431 if (verbose)
00432 if (old_m_tot > 0) {
00433 cerr << "command-line -M " << m_tot;
00434 if (twiddles(m_tot, old_m_tot))
00435 cerr << " is identical to value";
00436 else
00437 cerr << " overrides value " << old_m_tot;
00438 cerr << " in input snapshot" << endl;
00439 } else
00440 cerr << "Taking total mass = " << m_tot
00441 << " Msun from command line" << endl;
00442 } else
00443 if (old_m_tot > 0) {
00444 m_tot = old_m_tot;
00445 cerr << "Taking total mass = " << m_tot
00446 << " Msun from input snapshot" << endl;
00447 M_set = true;
00448 }
00449
00450
00451
00452
00453 if (!M_set) err_exit("Physical mass not specified");
00454
00455
00456
00457 bool R_set = R_flag;
00458
00459 if (R_set) {
00460 if (verbose) {
00461 if (old_r_vir > 0) {
00462 cerr << "command-line -R " << r_vir;
00463 if (twiddles(r_vir, old_r_vir))
00464 cerr << " is identical to value";
00465 else
00466 cerr << " overrides value " << old_r_vir;
00467 cerr << " in input snapshot" << endl;
00468 } else
00469 cerr << "Taking virial radius = " << r_vir
00470 << " pc from command line" << endl;
00471 }
00472 } else
00473 if (old_r_vir > 0) {
00474 r_vir = old_r_vir;
00475 cerr << "Taking virial radius = " << r_vir
00476 << " pc from input snapshot" << endl;
00477 R_set = true;
00478 }
00479
00480 if (!R_set && !T_flag && old_t_vir <= 0)
00481 err_exit("Physical virial radius not specified");
00482
00483
00484
00485
00486
00487
00488 if (!T_flag) {
00489
00490
00491
00492
00493
00494
00495 if (old_t_vir > 0 && old_m_tot > 0 && old_r_vir > 0
00496 && !M_flag && !R_flag) {
00497
00498 t_vir = old_t_vir;
00499 if (verbose) cerr << "Taking virial time scale = " << t_vir
00500 << " from input snapshot" << endl;
00501
00502 } else {
00503
00504
00505
00506
00507
00508
00509 t_vir = 21.0 * sqrt(q_vir*pow(r_vir, 3)/m_tot);
00510
00511 if (verbose) {
00512 if (old_t_vir > 0) {
00513 cerr << "Recomputed virial time scale " << t_vir;
00514 if (twiddles(t_vir, old_t_vir))
00515 cerr << " is identical to value";
00516 else
00517 cerr << " overrides value " << old_t_vir;
00518 cerr << " in input snapshot" << endl;
00519 } else
00520 cerr << "Computed virial time scale = " << t_vir
00521 << endl;
00522 }
00523 }
00524
00525 } else if (verbose) {
00526
00527 if (old_t_vir > 0) {
00528 cerr << "command-line -T " << t_vir;
00529 if (twiddles(t_vir, old_t_vir))
00530 cerr << " is identical to value";
00531 else
00532 cerr << " overrides value " << old_t_vir;
00533 cerr << " in input snapshot" << endl;
00534 } else
00535 cerr << "Taking virial time scale = " << t_vir
00536 << " from command line" << endl;
00537
00538 }
00539
00540
00541
00542 if (!R_set || (!R_flag && T_flag)) {
00543
00544
00545
00546
00547
00548
00549 r_vir = pow(t_vir / (21.0 * sqrt(q_vir/m_tot)), 2.0/3);
00550
00551 if (verbose) {
00552 if (!R_set)
00553 cerr << "Computed";
00554 else
00555 cerr << "Recomputed";
00556 cerr << " virial radius = " << r_vir << endl;
00557 }
00558 }
00559
00560
00561
00562
00563
00564
00565 if (verbose) {
00566 cerr << endl;
00567 cerr << "Units (N-body / physical):" << endl;
00568 cerr << " <m>: " << initial_mass/nbody
00569 << " / " << m_tot/nbody << " M_sun" << endl;
00570 cerr << " [M]: " << initial_mass
00571 << " / " << m_tot << " M_sun" << endl;
00572 cerr << " [T]: " << initial_t_virial << " / " << t_vir
00573 << " Myr" << endl;
00574 cerr << " [L]: " << initial_r_virial << " / " << r_vir
00575 << " pc" << endl;
00576 }
00577
00578
00579
00580
00581
00582
00583 if (verbose) {
00584 real tv = 21.0 * sqrt(q_vir*pow(r_vir, 3)/m_tot);
00585 if (abs(1 - t_vir/tv) > 1.e-4) {
00586 cerr << "Warning: inconsistent units: ";
00587 PRC(t_vir); PRL(tv);
00588 }
00589 }
00590
00591
00592
00593 b->get_starbase()
00594 ->set_stellar_evolution_scaling(m_tot/initial_mass,
00595 r_vir/initial_r_virial,
00596 t_vir/initial_t_virial);
00597 }
00598
00599 local char* stredit(char* s, char c1, char c2)
00600 {
00601 if (!s) return NULL;
00602
00603 char* s1 = new char[strlen(s)+1];
00604 if (!s1) return NULL;
00605
00606 strcpy(s1, s);
00607
00608 char* ss = s1;
00609 while (*ss != '\0') {
00610 if (*ss == c1) *ss = c2;
00611 ss++;
00612 }
00613
00614 return s1;
00615 }
00616
00617 local void kira_system_id(int argc, char** argv)
00618 {
00619 cerr << "Starlab version " << STARLAB_VERSION;
00620
00621 char* s = stredit(_COMPILE_DATE_, '_', ' ');
00622 if (s) {
00623 cerr << "; kira created on " << s;
00624 delete s;
00625 }
00626 cerr << endl;
00627
00628 cerr << "Command line reference: " << argv[0] << endl;
00629 cerr << "Arguments: ";
00630 for (int i = 1; i < argc; i++) cerr << " " << argv[i];
00631 cerr << endl;
00632
00633 if ( (argv[0][0] == '.' && argv[0][1] == '/')
00634 || (argv[0][0] == '~' && argv[0][1] == '/')
00635 || argv[0][0] == '/') {
00636 } else {
00637
00638 cerr << "System `which " << argv[0] << "` = ";
00639
00640 char tmp[256];
00641 sprintf(tmp, "which %s > KIRA_TEMP", argv[0]);
00642
00643 system(tmp);
00644
00645
00646
00647 ifstream file("KIRA_TEMP");
00648 if (file) {
00649
00650 file >> tmp;
00651 cerr << tmp << endl;
00652
00653 file.close();
00654 sprintf(tmp, "rm KIRA_TEMP");
00655 system(tmp);
00656 }
00657
00658 }
00659
00660 cerr << "Current directory = " << getenv("PWD") << endl;
00661
00662
00663 }
00664
00665 #define MASS_TOL 1.e-12
00666
00667 local void check_total_mass(hdyn *b, bool reset = true)
00668 {
00669
00670
00671
00672 real total_mass = 0;
00673 for_all_leaves(hdyn, b, bi) total_mass += bi->get_mass();
00674
00675 if (total_mass > 0) {
00676 if (abs(b->get_mass()/total_mass - 1) > MASS_TOL) {
00677 cerr << endl
00678 << "*** Root mass disagrees with total mass"
00679 << endl;
00680 PRI(4); PRC(b->get_mass()); PRL(total_mass);
00681 if (reset) {
00682 cerr << " resetting..." << endl;
00683 b->set_mass(total_mass);
00684 }
00685 }
00686 }
00687 }
00688
00689
00690 bool kira_initialize(int argc, char** argv,
00691 hdynptr& b,
00692 real& delta_t,
00693 real& dt_log,
00694 int& long_binary_out,
00695 real& dt_snap,
00696 real& dt_sstar,
00697 real& dt_esc,
00698 real& dt_reinit,
00699 real& dt_fulldump,
00700 bool& exact,
00701 real& cpu_time_limit,
00702 bool& verbose,
00703 bool& save_snap_at_log,
00704 char* snap_save_file,
00705 int& n_stop)
00706 {
00707
00708
00709
00710
00711
00712
00713 real eta = DEFAULT_ETA;
00714 real eps = DEFAULT_EPS;
00715 real d_min = DEFAULT_D_MIN_FAC;
00716 real lag_factor = DEFAULT_LAG_FACTOR;
00717 real gamma = DEFAULT_GAMMA;
00718
00719 bool eta_flag = false, eps_flag = false, d_min_flag = false,
00720 lag_flag = false, gamma_flag = false;
00721
00722 delta_t = DEFAULT_DT;
00723
00724 dt_log = DEFAULT_DT_LOG;
00725 dt_snap = VERY_LARGE_NUMBER;
00726 dt_sstar = DEFAULT_DT_SSTAR;
00727 dt_esc = VERY_LARGE_NUMBER;
00728 dt_reinit = DEFAULT_DT_REINIT;
00729 dt_fulldump = DEFAULT_DT_FULLDUMP;
00730
00731 bool binary_zero = false;
00732
00733
00734
00735 long_binary_out = LONG_BINARY_OUT;
00736
00737 bool log_flag = false, snap_flag = false, sstar_flag = false,
00738 esc_flag = false, reinit_flag = false, fulldump_flag = false;
00739
00740 cpu_time_limit = VERY_LARGE_NUMBER;
00741
00742 exact = false;
00743 verbose = true;
00744
00745 save_snap_at_log = false;
00746 n_stop = 10;
00747
00748 int max_slow = 0;
00749 bool max_slow_flag = false;
00750
00751
00752
00753 real input_stripping_radius = 0;
00754 char *comment;
00755
00756 int input_seed, actual_seed;
00757
00758
00759
00760 real m_tot = 1;
00761 real r_vir = 1;
00762 real t_vir = 1;
00763 real q_vir = 0.5;
00764 real T_start = 0;
00765
00766 real friction_beta = 0;
00767
00768 real sec = 0, smc = 0, stc = 0;
00769 bool sec_flag = false;
00770 bool smc_flag = false;
00771 bool stc_flag = false;
00772
00773 bool B_flag = false;
00774 bool G_flag = false;
00775 bool S_flag = false;
00776 bool c_flag = false;
00777 bool s_flag = false;
00778
00779 bool allow_kira_override = true;
00780
00781 bool ignore_internal = false;
00782
00783 bool r_virial_set = false;
00784 real input_r_virial;
00785
00786 char seedlog[SEED_STRING_LENGTH];
00787
00788 extern char *poptarg, *poparr[];
00789
00790 int c;
00791 char* param_string =
00792 "*:a:b.Bc:C:d:D:e:E:f:F.g:G:h:iI:k:K:L:m:M:n:N:oO:q:Qr:R:s:St:T:uUvW:xX:y:z:Z:";
00793
00794
00795
00796 kira_system_id(argc, argv);
00797
00798
00799
00800
00801 char infile[256];
00802 bool read_from_file = false;
00803
00804 for (int i = 0; i < argc; i++)
00805 if (argv[i][0] == '-' && argv[i][1] == 'R') {
00806 strcpy(infile, argv[++i]);
00807 read_from_file = true;
00808 }
00809
00810
00811
00812 if (read_from_file) {
00813 ifstream s(infile);
00814 if (!s) {
00815 cerr << "Data file " << infile << " not found." << endl;
00816 exit(1);
00817 }
00818 cerr << "Input file is " << infile << endl;
00819 b = get_hdyn(s);
00820 } else {
00821 cerr << "Reading input from stdin" << endl;
00822 b = get_hdyn(cin);
00823 }
00824
00825 if (b == NULL) err_exit("Can't read input snapshot");
00826
00827
00828
00829
00830
00831
00832
00833 int nbody = b->n_leaves();
00834 if (nbody <= 0) err_exit("kira: N <= 0!");
00835
00836
00837
00838 b->set_kira_counters(new kira_counters);
00839 b->set_kira_options(new kira_options);
00840 b->set_kira_diag(new kira_diag);
00841
00842 check_kira_init(b);
00843
00844 b->log_history(argc, argv);
00845
00846
00847
00848 while ((c = pgetopt(argc, argv, param_string)) != -1) {
00849 switch (c) {
00850 case 'a': eta = atof(poptarg);
00851 eta_flag = true;
00852 break;
00853 case 'b': if (poptarg)
00854 long_binary_out = max(0, atoi(poptarg));
00855 else
00856 long_binary_out = 0;
00857 break;
00858 case 'B': S_flag = true;
00859 B_flag = true;
00860 break;
00861 case 'c': c_flag = TRUE;
00862 comment = poptarg;
00863 break;
00864 case 'C': b->get_kira_options()->grape_max_cpu = atof(poptarg);
00865 break;
00866 case 'd': dt_log = atof(poptarg);
00867 if (dt_log < 0) dt_log = pow(2.0, dt_log);
00868 log_flag = true;
00869 break;
00870 case 'D': if (streq(poptarg, "all") || streq(poptarg, "full")) {
00871
00872
00873
00874 dt_snap = -1;
00875 set_write_unformatted(false);
00876
00877 } else if (*poptarg == 'x') {
00878
00879
00880
00881
00882 dt_snap = -atoi(poptarg+1);
00883 set_write_unformatted(false);
00884
00885 } else if (*poptarg == 'X') {
00886
00887
00888
00889
00890
00891 dt_snap = -atoi(poptarg+1);
00892 set_write_unformatted(true);
00893
00894 } else if (*poptarg == 'B' || *poptarg == 'b') {
00895
00896
00897
00898 dt_snap = 0;
00899 binary_zero = true;
00900
00901 if (*poptarg == 'b')
00902 set_write_unformatted(false);
00903 else
00904 set_write_unformatted(true);
00905
00906 cerr << endl
00907 << "*** binary tracking on ***"
00908 << endl;
00909
00910 } else{
00911 dt_snap = atof(poptarg);
00912 if (dt_snap < 0) dt_snap = pow(2.0, dt_snap);
00913 }
00914 snap_flag = true;
00915 break;
00916 case 'e': eps = atof(poptarg);
00917 eps_flag = true;
00918 break;
00919 case 'E': if (atoi(poptarg)) exact = true;
00920 break;
00921 case 'f': d_min = atof(poptarg);
00922 d_min_flag = true;
00923 break;
00924 case 'F':
00925 if (poptarg)
00926 friction_beta = atof(poptarg);
00927 else
00928 friction_beta = 1;
00929 if (friction_beta < 0) friction_beta = 0;
00930 break;
00931 case 'g': lag_factor = atof(poptarg);
00932 lag_flag = true;
00933 break;
00934 case 'G': G_flag = true;
00935 input_stripping_radius = atof(poptarg);
00936 break;
00937 case 'h': dt_sstar = atof(poptarg);
00938 if (dt_sstar < 0) dt_sstar = pow(2.0, dt_sstar);
00939 sstar_flag = true;
00940 break;
00941 case 'i': ignore_internal = !ignore_internal;
00942 break;
00943 case 'I': dt_reinit = atof(poptarg);
00944 if (dt_reinit < 0) dt_reinit = pow(2.0, dt_reinit);
00945 reinit_flag = true;
00946 break;
00947 case 'J': err_exit("kira: -J option removed: use add_tidal");
00948 break;
00949 case 'k': gamma = atof(poptarg);
00950 gamma_flag = true;
00951 break;
00952 case 'K': max_slow = atoi(poptarg);
00953 max_slow_flag = true;
00954 break;
00955 case 'L': cpu_time_limit = atof(poptarg);
00956 break;
00957 case 'M': err_exit("kira: -M option removed: use add_star");
00958 break;
00959 case 'n': n_stop = atoi(poptarg);
00960 break;
00961 case 'N': b->get_kira_diag()->check_heartbeat = true;
00962 b->get_kira_diag()->n_check_heartbeat = atoi(poptarg);
00963 break;
00964 case 'o': allow_kira_override = false;
00965 break;
00966 case 'O': save_snap_at_log = true;
00967 strcpy(snap_save_file, poptarg);
00968 break;
00969 case 'q': q_vir = atof(poptarg);
00970 break;
00971 case 'Q': err_exit("kira: -Q option removed: use add_tidal");
00972 break;
00973 case 'r':
00974
00975
00976
00977
00978 r_virial_set = true;
00979 input_r_virial = atof(poptarg);
00980 break;
00981 case 'R':
00982 break;
00983 case 's': s_flag = true;
00984 input_seed = atoi(poptarg);
00985 break;
00986 case 'S': S_flag = true;
00987 break;
00988 case 't': delta_t = atof(poptarg);
00989 break;
00990 case 'T': err_exit("kira: -T option removed: use add_star");
00991 break;
00992 case 'u': toggle_unperturbed(b, 1);
00993 break;
00994 case 'U': toggle_unperturbed(b, 0);
00995 break;
00996 case 'v': verbose = !verbose;
00997 break;
00998 case 'W': dt_fulldump = atof(poptarg);
00999 if (dt_fulldump < 0)
01000 dt_fulldump = pow(2.0, dt_fulldump);
01001 fulldump_flag = true;
01002 break;
01003 case 'x': b->get_kira_options()->print_xreal
01004 = !b->get_kira_options()->print_xreal;
01005 break;
01006 case 'X': dt_esc = atof(poptarg);
01007 if (dt_esc < 0) dt_esc = pow(2.0, dt_esc);
01008 esc_flag = true;
01009 break;
01010 case 'y': sec_flag = true;
01011 sec = atof(poptarg);
01012 break;
01013 case 'z': smc_flag = true;
01014 smc = atof(poptarg);
01015 break;
01016 case 'Z': stc_flag = true;
01017 stc = atof(poptarg);
01018 break;
01019 case '*': b->get_kira_diag()->kira_runtime_flag = atoi(poptarg);
01020 break;
01021 default:
01022 case '?': params_to_usage(cerr, argv[0], param_string);
01023 return false;
01024 }
01025 }
01026
01027 if (c_flag)
01028 b->log_comment(comment);
01029
01030 correct_multiples(b, verbose);
01031 initialize_index(b, verbose);
01032
01033 set_friction_beta(friction_beta);
01034 cerr << "Dynamical friction beta = " << friction_beta << endl;
01035
01036 check_set_ignore_internal(b, verbose);
01037 bool snap_ignore_internal = b->get_ignore_internal();
01038
01039 if (ignore_internal || snap_ignore_internal) {
01040 if (!snap_ignore_internal) {
01041 cerr << "Command-line \"-i\" flag forces ignore_internal mode"
01042 << endl;
01043 putiq(b->get_log_story(), "ignore_internal", 1);
01044
01045 } else
01046
01047 cerr << endl
01048 << "*** Ignoring internal forces "
01049 << "-- external field only ***"
01050 << endl;
01051
01052 b->set_ignore_internal(true);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 bool need_skip = true;
01068
01069 if (check_kira_flag(b, "kira_evolve_stars") && !S_flag)
01070 if (check_allowed(allow_kira_override,
01071 "stellar evolution",
01072 verbose, need_skip))
01073 S_flag = true;
01074
01075 if (check_kira_flag(b, "kira_evolve_binaries") && !B_flag)
01076 if (check_allowed(allow_kira_override,
01077 "binary evolution",
01078 verbose, need_skip))
01079 B_flag = true;
01080
01081
01082
01083
01084 if (check_kira_flag(b, "kira_allow_unperturbed")
01085 && !b->get_kira_options()->allow_unperturbed)
01086 if (check_allowed(allow_kira_override,
01087 "unperturbed binary motion",
01088 verbose, need_skip))
01089 set_allow_unperturbed(b);
01090
01091 if (check_kira_flag(b, "kira_allow_multiples")
01092 && !b->get_kira_options()->allow_multiples)
01093 if (check_allowed(allow_kira_override,
01094 "unperturbed multiple motion",
01095 verbose, need_skip))
01096 set_allow_multiples(b);
01097
01098 putiq(b->get_log_story(), "kira_allow_unperturbed",
01099 b->get_kira_options()->allow_unperturbed);
01100 putiq(b->get_log_story(), "kira_allow_multiples",
01101 b->get_kira_options()->allow_multiples);
01102
01103 if (verbose) {
01104 if (need_skip) cerr << endl;
01105 print_unperturbed_options(b);
01106 }
01107
01108
01109
01110
01111
01112 if (B_flag) S_flag = true;
01113 if (!S_flag) B_flag = false;
01114
01115 if (!S_flag) dt_sstar = VERY_LARGE_NUMBER;
01116
01117 if (S_flag && dt_sstar == VERY_LARGE_NUMBER)
01118 dt_sstar = DEFAULT_DT_SSTAR;
01119
01120 b->set_use_sstar(S_flag);
01121 b->set_use_dstar(B_flag);
01122
01123
01124
01125 if (S_flag) {
01126 if (s_flag == FALSE)
01127 input_seed = 0;
01128 actual_seed = srandinter(input_seed);
01129 sprintf(seedlog,
01130 " random number generator seed = %d",actual_seed);
01131 b->log_comment(seedlog);
01132 cerr << "Initial random seed = " << actual_seed << endl;
01133 }
01134
01135
01136
01137 if (!snap_flag) dt_snap = delta_t;
01138 if (dt_snap == 0 && !binary_zero)
01139 dt_snap = VERY_LARGE_NUMBER;
01140
01141 if (!esc_flag) dt_esc = dt_reinit;
01142
01143 if (!fulldump_flag) dt_fulldump = dt_esc;
01144
01145
01146
01147
01148
01149 set_runtime_params(b, verbose,
01150 eta, eta_flag,
01151 eps, eps_flag,
01152 d_min, d_min_flag,
01153 lag_factor, lag_flag,
01154 gamma, gamma_flag,
01155 max_slow, max_slow_flag);
01156
01157
01158
01159
01160
01161
01162
01163 choose_param(b, verbose, dt_log, log_flag, "dt_log");
01164 choose_param(b, verbose, dt_sstar, sstar_flag, "dt_sstar");
01165 choose_param(b, verbose, dt_esc, esc_flag, "dt_esc");
01166 choose_param(b, verbose, dt_reinit, reinit_flag, "dt_reinit");
01167
01168
01169
01170
01171
01172
01173 choose_param(b, verbose, sec, sec_flag,
01174 "stellar_encounter_criterion", true);
01175 choose_param(b, verbose, smc, smc_flag,
01176 "stellar_merger_criterion", true);
01177 choose_param(b, verbose, stc, stc_flag,
01178 "stellar_tidal_capture_criterion", true);
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 if (stc < smc) stc = smc;
01189
01190 b->set_stellar_encounter_criterion_sq(pow(sec, 2));
01191 b->set_stellar_merger_criterion_sq(pow(smc, 2));
01192 b->set_stellar_capture_criterion_sq(pow(stc, 2));
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202 if (verbose) cerr << endl;
01203
01204 real initial_mass = get_initial_mass(b, verbose);
01205
01206 real initial_r_virial = get_initial_virial_radius(b, verbose,
01207 r_virial_set,
01208 input_r_virial);
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220 check_total_mass(b);
01221
01222
01223
01224
01225
01226
01227
01228 check_set_external(b, verbose);
01229
01230 if (friction_beta > 0 && !b->get_pl())
01231 cerr << "warning: dynamical friction, but no external field." << endl;
01232
01233
01234
01235
01236
01237 real scaled_stripping_radius = 0;
01238
01239
01240 if (check_kira_flag(b, "kira_remove_escapers") && !G_flag)
01241 if (check_allowed(allow_kira_override,
01242 "escaper removal",
01243 verbose, need_skip))
01244 G_flag = true;
01245
01246 if (G_flag) {
01247
01248 if (verbose) cerr << endl;
01249
01250 real initial_r_jacobi
01251 = get_initial_jacobi_radius(b, initial_r_virial);
01252
01253 real scaled_stripping_radius
01254 = get_scaled_stripping_radius(b, verbose,
01255 input_stripping_radius,
01256 initial_r_jacobi,
01257 initial_r_virial,
01258 initial_mass);
01259
01260 if (scaled_stripping_radius <= 0)
01261 err_exit("Unable to determine stripping radius");
01262
01263 PRL(scaled_stripping_radius);
01264 cerr << "current stripping radius = "
01265 << scaled_stripping_radius * pow(total_mass(b), 1.0/3.0)
01266 << endl;
01267
01268 b->set_scaled_stripping_radius(scaled_stripping_radius);
01269
01270 } else
01271
01272 if (verbose) cerr << endl << "No escaper removal" << endl;
01273
01274
01275
01276 putiq(b->get_log_story(), "kira_remove_escapers", G_flag);
01277
01278
01279
01280
01281
01282
01283
01284
01285 if (S_flag) {
01286
01287 if (verbose) cerr << endl;
01288 if (b->get_starbase() == NULL)
01289 err_exit("kira: S_flag and no starbase!");
01290
01291
01292
01293 bool scales_from_snapshot
01294 = b->get_starbase()->get_stellar_evolution_scaling();
01295
01296
01297
01298
01299
01300 if (scales_from_snapshot) {
01301
01302
01303
01304 #if 0
01305
01306
01307
01308
01309
01310
01311
01312 if (R_flag || M_flag || T_flag) {
01313
01314 if (verbose)
01315 cerr << "Overwriting (some) scale factors from"
01316 << " input snapshot"
01317 << endl;
01318
01319 scales_from_snapshot = false;
01320
01321 } else {
01322
01323 if (verbose) {
01324 cerr << "Scale factors taken from input snapshot"
01325 << endl;
01326 b->get_starbase()->print_stellar_evolution_scaling(cerr);
01327 }
01328
01329 }
01330
01331 } else {
01332
01333
01334
01335 get_physical_scales(b, verbose,
01336 initial_mass,
01337 initial_r_virial,
01338 M_flag, m_tot,
01339 R_flag, r_vir,
01340 T_flag, t_vir,
01341 q_vir,
01342 nbody);
01343 }
01344 #else
01345
01346
01347 if (verbose) {
01348 cerr << "Scale factors taken from input snapshot"
01349 << endl;
01350 b->get_starbase()->print_stellar_evolution_scaling(cerr);
01351 }
01352
01353 } else {
01354
01355 if (verbose)
01356 cerr << "Stellar scaling unavailable -- "
01357 << "suppressing stellar evolution." << endl;
01358
01359 B_flag = S_flag = false;
01360 b->set_use_sstar(S_flag);
01361 b->set_use_dstar(B_flag);
01362 }
01363 #endif
01364
01365 if (S_flag) {
01366
01367
01368
01369
01370 putrq(b->get_log_story(), "physical_initial_mass",
01371 b->get_starbase()->conv_m_dyn_to_star(initial_mass));
01372
01373
01374
01375 addstar(b,
01376 T_start,
01377 Main_Sequence,
01378 true);
01379
01380
01381
01382
01383 sec = b->get_starbase()->conv_r_star_to_dyn(sec);
01384 b->set_stellar_encounter_criterion_sq(pow(sec, 2));
01385
01386 if (verbose) {
01387 cerr << endl;
01388 cerr << "stellar_encounter_criterion = "
01389 << sqrt(b->get_stellar_encounter_criterion_sq()) << endl;
01390 cerr << "stellar_merger_criterion = "
01391 << sqrt(b->get_stellar_merger_criterion_sq()) << endl;
01392 cerr << "stellar_capture_criterion = "
01393 << sqrt(b->get_stellar_capture_criterion_sq()) << endl;
01394 }
01395
01396
01397
01398 if (b->get_tidal_field() == 3) {
01399
01400 real initial_r_jacobi
01401 = get_initial_jacobi_radius(b, initial_r_virial);
01402
01403 test_tidal_params(b, verbose,
01404 initial_r_jacobi,
01405 initial_r_virial,
01406 initial_mass);
01407 }
01408 }
01409 }
01410
01411
01412
01413 putiq(b->get_log_story(), "kira_evolve_stars", S_flag);
01414 putiq(b->get_log_story(), "kira_evolve_binaries", B_flag);
01415
01416
01417
01418 return true;
01419 }