00001
00002 #define T_DEBUG 169.5 // track progress through the main integration
00003 #undef T_DEBUG // loop after time T_DEBUG if defined
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 #ifdef TOOLBOX
00186
00187 #include "hdyn.h"
00188 #include "star/dstar_to_kira.h"
00189
00190 #define INITIAL_STEP_LIMIT 0.0625 // Arbitrary limit on the first step
00191
00192
00193
00194 static kira_counters kc_prev;
00195 static bool dbg = false;
00196
00197
00198
00199
00200
00201 #ifdef USE_TREE
00202 #include "/work6/starlab/Tree++/kira_tree_include.C"
00203 #else
00204 #include "kira_grape_include.C"
00205 #endif
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 local bool match_label(hdyn* b, char* label)
00216 {
00217 if (b->name_is(label))
00218 return true;
00219 #if 0
00220
00221
00222
00223 if (b->get_index() >= 0) {
00224 char id[64];
00225 sprintf(id, "%d", b->get_index());
00226 if (streq(id, label))
00227 return true;
00228 }
00229 #endif
00230 return false;
00231 }
00232
00233
00234
00235
00236
00237 local bool match_label_tree(hdyn* b, char* label)
00238 {
00239 for_all_nodes(hdyn, b, bi)
00240 if (match_label(bi, label)) return true;
00241 return false;
00242 }
00243
00244
00245
00246
00247
00248 local void cond_print_nn(hdyn** list, int n, char* label, char* header = NULL)
00249 {
00250 for (int i = 0; i < n; i++) {
00251 hdyn* b = list[i];
00252 if (b) {
00253 if (match_label_tree(b->get_top_level_node(), label)) {
00254 if (header) cerr << header << endl;
00255 cerr << "print_nn triggered by node "
00256 << b->format_label() << endl;
00257 for_all_leaves(hdyn, b, bi)
00258 print_nn(bi, 2);
00259 }
00260 }
00261 }
00262 }
00263
00264 local void test_kepler(hdyn *b)
00265 {
00266 for_all_nodes(hdyn,b,bi) {
00267 if (bi->get_kepler()) {
00268 if (bi->is_top_level_node()) {
00269 cerr << " test_kepler: top level ";
00270 bi->pretty_print_node(cerr); cerr << "has kepler \n";
00271 pp3(bi, cerr);
00272 }
00273 }
00274 }
00275 }
00276
00277
00278
00279
00280
00281 local void print_triple_stats(hdyn* root, hdyn* b)
00282 {
00283 if (!b->is_top_level_node()) return;
00284 if (b->n_leaves() != 3) return;
00285
00286 hdyn* ss = b->get_oldest_daughter();
00287 hdyn* bs = ss->get_younger_sister();
00288 if (ss->is_parent()) {
00289 hdyn* tmp = ss;
00290 ss = bs;
00291 bs = tmp;
00292 }
00293
00294
00295
00296 real mss = ss->get_mass();
00297 vector pos_ss = b->get_pos() + ss->get_pos();
00298 vector vel_ss = b->get_vel() + ss->get_vel();
00299 hdyn* bs1 = bs->get_oldest_daughter();
00300 hdyn* bs2 = bs1->get_younger_sister();
00301 real mb1 = bs1->get_mass();
00302 real mb2 = bs2->get_mass();
00303 vector pos_bs1 = b->get_pos() + bs->get_pos() + bs1->get_pos();
00304 vector vel_bs1 = b->get_vel() + bs->get_vel() + bs1->get_vel();
00305 vector pos_bs2 = b->get_pos() + bs->get_pos() + bs2->get_pos();
00306 vector vel_bs2 = b->get_vel() + bs->get_vel() + bs2->get_vel();
00307
00308 real pot_1 = -mss * (mb1+mb2) / abs(ss->get_pos() - bs->get_pos());
00309 real pot_2 = -mss * mb1 / abs(pos_ss - pos_bs1)
00310 -mss * mb2 / abs(pos_ss - pos_bs2);
00311 real pot_b = -mb1 * mb2 / abs(pos_bs1 - pos_bs2);
00312
00313 real pot_ext = 0;
00314 for_all_daughters(hdyn, root, x) {
00315 if (x != b)
00316 pot_ext -= x->get_mass() * (mss/abs(x->get_pos() - pos_ss)
00317 + mb1/abs(x->get_pos() - pos_bs1)
00318 + mb2/abs(x->get_pos() - pos_bs2));
00319 }
00320
00321 real ke = 0.5 * (mss*square(vel_ss) + mb1*square(vel_bs1)
00322 + mb2*square(vel_bs2));
00323
00324
00325
00326
00327
00328
00329 cerr << endl << "Triple " << b->format_label() << " at time "
00330 << b->get_system_time() << ":" << endl
00331 << " Eint = " << pot_2 + pot_b + ke
00332 << " Eint + phi_ext = " << pot_2 + pot_b + ke + pot_ext << endl;
00333 }
00334
00335
00336
00337 local void print_binary_diagnostics(hdyn* bi)
00338 {
00339 bool diag = true;
00340
00341 kepler *kep;
00342 hdyn *s = bi->get_binary_sister();
00343 real M = bi->get_parent()->get_mass();
00344
00345 if (bi->get_kepler() == NULL) {
00346 kep = new kepler;
00347 kep->set_time(bi->get_time());
00348 kep->set_total_mass(M);
00349 kep->set_rel_pos(bi->get_pos() - s->get_pos());
00350 kep->set_rel_vel(bi->get_vel() - s->get_vel());
00351 kep->initialize_from_pos_and_vel();
00352 } else
00353 kep = bi->get_kepler();
00354
00355
00356
00357
00358 if (diag) {
00359
00360 #if 0
00361 cerr << "\nLow-level node bi = ", bi->print_label(cerr);
00362 cerr << endl;
00363 PRI(4); PRL(bi->get_time());
00364
00365 int p = cerr.precision(INT_PRECISION);
00366 PRI(4); cerr << "top-level: ",
00367 PRL(bi->get_top_level_node()->get_time());
00368 cerr.precision(p);
00369
00370 pp2(bi->get_top_level_node(), cerr, 2);
00371 PRI(4);
00372 PRL(bi->get_top_level_node()->get_valid_perturbers());
00373 PRI(4); PRL(bi->get_top_level_node()->get_n_perturbers());
00374 #endif
00375
00376 if (bi->get_kepler())
00377 cerr << " bi unperturbed";
00378 else
00379 cerr << " bi perturbed";
00380
00381 real r = kep->get_separation();
00382 real E = kep->get_energy();
00383 real a = r;
00384 if (E < 0) a = min(r, kep->get_semi_major_axis());
00385
00386 cerr << ", -E/mu = " << -E
00387 << " P = " << 2*M_PI * sqrt(a*a*a/M)
00388 << " e = " << kep->get_eccentricity()
00389 << endl
00390 << " sma = " << kep->get_semi_major_axis()
00391 << " r = " << r
00392 << endl;
00393
00394 PRI(4);
00395 if (bi->get_kepler()) PRC(bi->get_unperturbed_timestep());
00396 PRL(bi->get_timestep());
00397 }
00398
00399 if (bi->get_kepler() == NULL) delete kep;
00400 }
00401
00402
00403
00404 local void check_unperturbed(hdyn* bi, bool& tree_changed)
00405 {
00406
00407
00408
00409
00410
00411
00412
00413
00414 if (bi->get_kepler() == NULL && bi->get_eps2() == 0
00415 && (bi->is_unperturbed_and_approaching())) {
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 if (bi->is_parent() || bi->get_binary_sister()->is_parent()) {
00429
00430 bool synch = false;
00431
00432 if (bi->is_parent()) {
00433 bool sync = false;
00434 for_all_nodes(hdyn, bi, bb) {
00435 if (bb->get_time() < bi->get_time())
00436 sync = true;
00437 }
00438 if (sync)
00439 synchronize_tree(bi);
00440 synch |= sync;
00441 }
00442
00443 if (bi->get_binary_sister()->is_parent()) {
00444 bool sync = false;
00445 for_all_nodes(hdyn, bi->get_binary_sister(), bb) {
00446 if (bb->get_time()
00447 < bi->get_binary_sister()->get_time())
00448 sync = true;
00449
00450 }
00451 if (sync)
00452 synchronize_tree(bi->get_binary_sister());
00453 synch |= sync;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 if (synch)
00463 tree_changed = true;
00464 }
00465
00466
00467
00468 bi->startup_unperturbed_motion();
00469
00470 }
00471 }
00472
00473
00474
00475
00476
00477 local inline void check_set_slow(hdyn *bi)
00478 {
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 if (bi->get_max_slow_factor() > 1
00497 && (bi->is_leaf() || bi->get_oldest_daughter()->get_kepler())
00498 && (bi->get_younger_sister()->is_leaf()
00499 || bi->get_younger_sister()->get_kepler())
00500 && bi->get_valid_perturbers()
00501 && bi->get_perturbation_squared()
00502 < bi->get_max_slow_perturbation_sq()/2
00503 && bi->passed_apo()
00504 && get_total_energy(bi, bi->get_younger_sister()) < 0) {
00505
00506
00507
00508
00509 #if 0
00510
00511
00512
00513 if (has_binary_perturbers(bi)) {
00514 cerr << "suppressing slow motion for "
00515 << bi->get_parent()->format_label()
00516 << " because of binary perturbers" << endl;
00517 return;
00518 }
00519 #endif
00520
00521 bi->startup_slow_motion();
00522 }
00523 }
00524
00525 local inline void check_extend_slow(hdyn *bi)
00526 {
00527
00528
00529
00530
00531
00532
00533
00534
00535 if (bi->passed_apo()) {
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 real P = get_period(bi, bi->get_younger_sister());
00547
00548 if (bi->get_time() - bi->get_slow()->get_t_apo() > 0.9 * P)
00549
00550 bi->extend_or_end_slow_motion(P);
00551 }
00552 }
00553
00554
00555
00556 local void merge_and_correct(hdyn* b, hdyn* bi, hdyn* bcoll, int full_dump)
00557 {
00558
00559
00560
00561 cerr << endl << "----------" << endl
00562 << "merge_and_correct: merging node "
00563 << bi->format_label();
00564 cerr << " with node " << bcoll->format_label()
00565 << " at time " << bi->get_system_time() << endl;
00566
00567 PRC(bi), PRC(bcoll), PRC(bi->get_parent()); PRL(cpu_time());
00568
00569
00570
00571
00572
00573
00574 hdyn* cm = bi->merge_nodes(bcoll, full_dump);
00575
00576 delete bi;
00577 delete bcoll;
00578
00579 b->get_kira_counters()->leaf_merge++;
00580
00581 cerr << "after merge_nodes ";
00582 PRC(cm); PRL(cpu_time());
00583
00584 cerr << "----------" << endl;
00585 }
00586
00587 local inline void check_periapo(hdyn * bi) {
00588
00589
00590
00591 #ifdef CHECK_PERI_APO_CLUSTER
00592 bi->check_periapo_node();
00593 #endif
00594 }
00595
00596 local hdyn* check_and_merge(hdyn* bi, int full_dump)
00597 {
00598 hdyn * bcoll;
00599 if ((bcoll = bi->check_merge_node()) != NULL) {
00600
00601
00602
00603 hdyn* b = bi->get_root();
00604
00605 merge_and_correct(b, bi, bcoll, full_dump);
00606
00607
00608
00609
00610
00611
00612
00613 bool merge_flag = true;
00614 while (merge_flag) {
00615
00616 merge_flag = false;
00617
00618 for (hdyn* bb = b;
00619 (bb != NULL) && !merge_flag;
00620 bb = (hdyn*) bb->next_node(b)) {
00621
00622 if (bb->is_leaf()) {
00623 hdyn* bcoll2 = bb->check_merge_node();
00624 if (bcoll2 != NULL) {
00625
00626 merge_and_correct(b, bb, bcoll2, full_dump);
00627 merge_flag = true;
00628 }
00629 }
00630 }
00631 }
00632 }
00633
00634
00635 return bcoll;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644 local int integrate_list(hdyn * b,
00645 hdyn ** next_nodes, int n_next,
00646 bool exact, bool & tree_changed,
00647 int full_dump,
00648 real r_reflect)
00649 {
00650 static bool restart_grape = true;
00651 static bool reset_force_correction = true;
00652
00653 int return_fac = 1;
00654
00655 int i, steps = 0;
00656 xreal sys_t = next_nodes[0]->get_system_time();
00657
00658
00659
00660
00661
00662 real cpu0, cpu1;
00663
00664 #ifdef TIME_LIST
00665
00666 int kmax = 1;
00667
00668 for (int k = 0; k < n_next; k++) {
00669 hdyn* bi = next_nodes[k];
00670
00671 if (bi->name_is("(13a,13b)")
00672 && bi->get_kepler() == NULL
00673 && bi->find_perturber_node()
00674 && bi->find_perturber_node()->get_n_perturbers() > 0
00675 ) {
00676
00677
00678
00679 for (int kk = 0; kk < n_next; kk++)
00680 if (kk != k)
00681 next_nodes[kk]->set_timestep(VERY_LARGE_NUMBER);
00682 n_next = 1;
00683 next_nodes[0] = bi;
00684
00685 int p = cerr.precision(HIGH_PRECISION);
00686 cerr << endl << "timing " << bi->format_label()
00687 << " at time " << bi->get_system_time() << endl;
00688 if (bi->is_low_level_node()) {
00689 PRL(bi->get_top_level_node()->format_label());
00690 if (bi->find_perturber_node()) {
00691 PRL(bi->find_perturber_node()->format_label());
00692 PRL(bi->find_perturber_node()->get_n_perturbers());
00693 }
00694 }
00695 cerr.precision(p);
00696
00697 kmax = 25000;
00698 cpu0 = cpu_time();
00699 }
00700 }
00701 #endif
00702
00703
00704
00705 xreal t_next = next_nodes[0]->get_next_time();
00706
00707 #ifdef TIME_LIST
00708 for (int k = 0; k < kmax; k++) {
00709 #endif
00710
00711 #ifdef T_DEBUG
00712
00713 #endif
00714
00715 calculate_acc_and_jerk_for_list(b, next_nodes, n_next, t_next,
00716 exact, tree_changed,
00717 reset_force_correction,
00718 restart_grape);
00719
00720 #ifdef T_DEBUG
00721
00722 #endif
00723
00724 #ifdef TIME_LIST
00725 }
00726 if (kmax > 1) cpu1 = cpu_time();
00727 #endif
00728
00729
00730
00731 bool reinitialize = false;
00732
00733 #ifdef TIME_LIST
00734 for (int k = 0; k < kmax; k++) {
00735 #endif
00736
00737 bool diag = false;
00738
00739 for (i = 0; i < n_next; i++) {
00740
00741 hdyn *bi = next_nodes[i];
00742
00743 if (bi && bi->is_valid()) {
00744
00745 if (!bi->get_kepler()) {
00746
00747 if (diag) cerr << " perturbed correction for "
00748 << bi->format_label() << endl;
00749
00750 #ifdef T_DEBUG
00751
00752 #endif
00753
00754 if (!bi->correct_and_update()) {
00755
00756 #ifdef T_DEBUG
00757
00758 #endif
00759
00760
00761
00762
00763
00764
00765
00766 if (bi->get_kira_diag()->grape
00767 && bi->get_kira_diag()->grape_level > 0)
00768 cerr << "retrying force calculation for "
00769 << bi->format_label() << endl;
00770
00771
00772
00773
00774
00775 bi->clear_interaction();
00776 bi->calculate_acc_and_jerk(true);
00777 bi->set_valid_perturbers(false);
00778
00779 if (bi->is_top_level_node()
00780 && b->get_external_field() > 0) {
00781 vector acc, jerk;
00782 real pot;
00783 get_external_acc(bi,
00784 bi->get_pred_pos(),
00785 bi->get_pred_vel(),
00786 pot, acc, jerk);
00787 bi->inc_pot(pot);
00788 bi->inc_acc(acc);
00789 bi->inc_jerk(jerk);
00790 }
00791
00792 if (!bi->correct_and_update()) {
00793
00794 cerr << endl
00795 << "Failed to correct hardware error for "
00796 << bi->format_label() << " at time "
00797 << bi->get_system_time() << endl << endl;
00798 err_exit("Run terminated in integrate_list");
00799
00800 } else {
00801
00802
00803
00804
00805 cerr << endl
00806 << "Corrected apparent GRAPE"
00807 << " error for "
00808 << bi->format_label() << " at time "
00809 << bi->get_system_time();
00810 #if defined(STARLAB_HAS_GRAPE4)
00811 cerr << " (chip " << get_grape_chip(bi) << ")";
00812 #endif
00813 cerr << endl;
00814
00815 if (bi->get_kira_diag()->grape) {
00816 if (bi->get_kira_diag()->grape_level > 0) {
00817 cerr << "recomputed "; PRL(bi->get_acc());
00818 PRI(12); PRL(bi->get_jerk());
00819
00820
00821 cerr << endl;
00822 }
00823 return_fac = -1;
00824 }
00825 }
00826 }
00827
00828 bi->init_pred();
00829 bi->store_old_force();
00830
00831
00832
00833
00834 #if 0000
00835 if (bi->is_parent()
00836 && (bi->name_is("(5394,21337)")
00837 || bi->name_is("(21337,5394)"))) {
00838 cerr << endl;
00839 pp3(bi);
00840 cerr << endl;
00841 print_nn(bi, 1);
00842 PRC(bi->get_nn()); PRL(bi->get_d_nn_sq());
00843 cerr << endl;
00844 bi->print_pert();
00845 cerr << endl;
00846 }
00847 #endif
00848
00849
00850 } else {
00851
00852 if (bi->get_eps2() != 0)
00853 err_exit("integrate_list invoked with non-zero softening");
00854
00855 if (diag) {
00856 cerr << "unperturbed motion for "
00857 << bi->format_label() << endl;
00858 if (bi->get_nn())
00859 cerr << "nn = " << bi->get_nn()->format_label()
00860 << endl;
00861 }
00862
00863
00864
00865
00866 hdyn* parent = bi->get_parent();
00867 bool top_level = parent->is_top_level_node();
00868
00869 bool pert = bi->is_perturbed_cpt();
00870
00871
00872 if (!bi->integrate_unperturbed_motion(reinitialize)) {
00873
00874
00875
00876
00877 if (bi->is_valid()) {
00878
00879
00880
00881
00882
00883
00884 if (top_level && !pert)
00885 parent->add_to_perturbed_list(1);
00886
00887 } else {
00888
00889
00890
00891
00892 if (top_level && pert)
00893 parent->remove_from_perturbed_list(1);
00894
00895 }
00896 }
00897
00898
00899
00900
00901
00902 if (!bi->is_valid())
00903 next_nodes[i] = NULL;
00904
00905 }
00906 }
00907 }
00908
00909 #ifdef TIME_LIST
00910 }
00911
00912
00913 if (kmax > 1) {
00914 cerr << "CPU times: "
00915 << (cpu1-cpu0)/kmax << " "
00916 << (cpu_time()-cpu1)/kmax << endl;
00917 exit(0);
00918 }
00919 #endif
00920
00921 #ifdef T_DEBUG
00922
00923 #endif
00924
00925 #if 111111
00926 if (r_reflect > 0) {
00927 for (i = 0; i < n_next; i++) {
00928 hdyn *bi = next_nodes[i];
00929 if (bi && bi->is_valid()) {
00930 real ri2 = square(bi->get_pos());
00931
00932
00933
00934
00935
00936
00937
00938 if (ri2 > 1) {
00939 real vr = bi->get_pos() * bi->get_vel();
00940 bi->set_vel(bi->get_vel() - 2*vr*bi->get_pos()/ri2);
00941 }
00942
00943
00944
00945 }
00946 }
00947 }
00948 #endif
00949
00950 #ifdef T_DEBUG
00951
00952 #endif
00953
00954
00955
00956 diag = false;
00957 for (i = 0; i < n_next; i++) {
00958
00959 hdyn *bi = next_nodes[i];
00960
00961 if (bi && bi->is_valid()) {
00962
00963 if (!bi->is_low_level_node()) {
00964
00965
00966
00967 if (bi->is_leaf())
00968 b->get_kira_counters()->step_top_single++;
00969 else
00970 b->get_kira_counters()->step_top_cm++;
00971
00972
00973
00974 if (diag) {
00975 cerr << "\nTop-level node bi = " << bi->format_label()
00976 << " at time " << bi->get_time() << endl;
00977 cerr << "timestep = " << bi->get_timestep() << endl;
00978 PRL(bi->get_acc());
00979 PRL(bi->get_jerk());
00980 }
00981
00982 } else {
00983
00984 update_binary_sister(bi);
00985
00986 b->get_kira_counters()->step_low_level++;
00987
00988 if (bi->get_slow())
00989 b->get_kira_counters()->inc_slow(bi->get_kappa());
00990
00991
00992
00993
00994
00995 if (!bi->get_kepler()) {
00996
00997 if (bi->get_eps2() == 0) {
00998
00999
01000
01001 check_unperturbed(bi, tree_changed);
01002
01003
01004
01005
01006 if (bi->get_parent()->is_top_level_node()
01007 && !bi->is_perturbed_cpt())
01008 bi->get_parent()->remove_from_perturbed_list(2);
01009 }
01010 }
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 if (!bi->get_kepler()) {
01022
01023
01024
01025
01026 if (!bi->get_elder_sister()) {
01027
01028 if (bi->get_slow())
01029 check_extend_slow(bi);
01030 else
01031 check_set_slow(bi);
01032
01033
01034 }
01035 }
01036 }
01037
01038 steps++;
01039 }
01040 }
01041
01042 #ifdef T_DEBUG
01043
01044 #endif
01045
01046
01047
01048
01049 if (b->get_stellar_encounter_criterion_sq() > 0)
01050 for (i = 0; i < n_next; i++)
01051 check_print_close_encounter(next_nodes[i]);
01052
01053
01054
01055
01056
01057
01058
01059 for (i = 0; i < n_next; i++) {
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 hdyn *bi = next_nodes[i];
01076
01077 if (bi && bi->is_valid()) {
01078
01079
01080
01081 check_periapo(bi);
01082
01083 hdyn* bcoll = check_and_merge(bi, full_dump);
01084
01085
01086
01087 if (bcoll) {
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 tree_changed = true;
01104 restart_grape = true;
01105 reset_force_correction = true;
01106
01107 kira_synchronize_tree(b);
01108 steps += b->n_leaves();
01109
01110 cerr << "call initialize_system_phase2() "
01111 << "from integrate_list [1]"
01112 << " at time " << b->get_system_time() << endl;
01113
01114 initialize_system_phase2(b, 1, true);
01115 b->reconstruct_perturbed_list();
01116
01117 PRL(tree_changed);
01118
01119
01120
01121
01122
01123
01124 next_nodes[i] = NULL;
01125 for (int j = 0; j < n_next; j++) {
01126 if (next_nodes[j] == bcoll)
01127 next_nodes[j] = NULL;
01128 }
01129
01130 return return_fac* steps;
01131 }
01132 }
01133 }
01134
01135 #ifdef T_DEBUG
01136
01137 #endif
01138
01139 if (reinitialize) {
01140
01141 kira_synchronize_tree(b);
01142 steps += b->n_leaves();
01143
01144 cerr << "call initialize_system_phase2() from integrate_list [2]"
01145 << " at time " << b->get_system_time() << endl;
01146
01147 initialize_system_phase2(b, 2, true);
01148 b->reconstruct_perturbed_list();
01149
01150 tree_changed = true;
01151 restart_grape = true;
01152 reset_force_correction = true;
01153
01154 } else {
01155
01156 for (i = 0; i < n_next; i++) {
01157
01158 hdyn *bi = next_nodes[i];
01159
01160 if (bi && bi->is_valid()) {
01161
01162 hdynptr* cm_list = NULL;
01163 int n_list = 0;
01164
01165 if (bi->is_low_level_node() || bi->is_parent()) {
01166
01167
01168
01169 for_all_nodes(hdyn, bi, bb)
01170 if (bb->is_parent()) n_list++;
01171
01172 if (n_list > 0) {
01173 cm_list = new hdynptr[n_list];
01174 n_list = 0;
01175 for_all_nodes(hdyn, bi, bb)
01176 if (bb->is_parent()) cm_list[n_list++] = bb;
01177 }
01178 }
01179
01180
01181
01182
01183 hdyn *top_level = bi->get_top_level_node();
01184 hdyn *od = NULL, *yd = NULL;
01185 bool pert = false;
01186
01187 if (top_level->is_parent()) {
01188 od = top_level->get_oldest_daughter();
01189 yd = od->get_younger_sister();
01190 pert = od->is_perturbed_cpt();
01191 }
01192
01193 int adjust_tree = bi->adjust_tree_structure(full_dump);
01194
01195 if (adjust_tree) {
01196
01197 b->get_kira_counters()->tree_change++;
01198
01199 reset_force_correction = true;
01200 restart_grape = true;
01201 tree_changed = true;
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 if (adjust_tree == 1) {
01227
01228
01229
01230
01231 if (bi->get_top_level_node() != top_level
01232 && pert) {
01233 top_level->remove_from_perturbed_list(3);
01234 bi->get_top_level_node()->add_to_perturbed_list(2);
01235 }
01236
01237 } else if (adjust_tree == 2) {
01238
01239
01240
01241
01242
01243 if (pert) bi->remove_from_perturbed_list(4);
01244
01245 if (bi->is_perturbed_cpt())
01246 bi->get_parent()->add_to_perturbed_list(3);
01247
01248 yd = bi->get_binary_sister();
01249
01250 if (yd->is_perturbed_cm())
01251 yd->remove_from_perturbed_list(5);
01252
01253 } else if (adjust_tree == 3) {
01254
01255
01256
01257
01258
01259
01260
01261 if (pert) top_level->remove_from_perturbed_list(6);
01262
01263 if (od->is_perturbed_cm())
01264 od->add_to_perturbed_list(4);
01265
01266 if (yd->is_perturbed_cm())
01267 yd->add_to_perturbed_list(5);
01268
01269 } else if (adjust_tree == 4) {
01270
01271
01272
01273
01274
01275
01276 top_level = bi->get_top_level_node();
01277 od = top_level->get_oldest_daughter();
01278 yd = od->get_younger_sister();
01279
01280 if (od->is_perturbed_cm())
01281 od->remove_from_perturbed_list(7);
01282
01283 if (yd->is_perturbed_cm())
01284 yd->remove_from_perturbed_list(8);
01285
01286 if (od->is_perturbed_cpt())
01287 top_level->add_to_perturbed_list(6);
01288
01289 } else if (adjust_tree == 5) {
01290
01291
01292
01293
01294
01295
01296 if (pert) top_level->remove_from_perturbed_list(9);
01297
01298 if (od->is_perturbed_cm())
01299 od->add_to_perturbed_list(7);
01300
01301 if (yd->is_perturbed_cm())
01302 yd->add_to_perturbed_list(8);
01303
01304 }
01305
01306 #ifndef USE_GRAPE
01307
01308 if (b->get_kira_diag()->kira_main) {
01309 cerr << "\nAfter adjusting tree structure... \n";
01310 cerr << "Time = " << next_nodes[0]->get_system_time()
01311 << " single_steps = "
01312 << b->get_kira_counters()->step_top_single
01313 << endl;
01314 print_recalculated_energies(b);
01315
01316 flush(cerr);
01317 }
01318
01319 #endif
01320
01321
01322
01323
01324
01325
01326 if (cm_list && n_list > 0) {
01327 for (int j = 0; j < n_next; j++) {
01328 if (!next_nodes[j]->is_valid()) {
01329
01330
01331
01332
01333
01334 next_nodes[j] = NULL;
01335 } else
01336 for (int k = 0; k < n_list; k++)
01337 if (next_nodes[j] == cm_list[k]) {
01338 next_nodes[j] = NULL;
01339 break;
01340 }
01341 }
01342 }
01343 if (cm_list) delete [] cm_list;
01344
01345 return return_fac*steps;
01346
01347
01348
01349
01350
01351 }
01352 if (cm_list) delete [] cm_list;
01353 }
01354 }
01355 }
01356
01357 return return_fac*steps;
01358 }
01359
01360
01361
01362 local void full_reinitialize(hdyn* b, xreal t, bool verbose)
01363 {
01364 cerr << "\nReinitializing system at time " << t << endl;
01365
01366 real cpu_0 = cpu_time();
01367
01368 b->set_system_time(t);
01369
01370 initialize_system_phase1(b, t);
01371 initialize_system_phase2(b, 3,
01372 false);
01373
01374
01375
01376
01377 int n = 0;
01378 real mass = 0;
01379 real pot = 0;
01380 for_all_daughters(hdyn, b, bb) {
01381 n++;
01382 mass += bb->get_mass();
01383 pot += bb->get_mass()*bb->get_pot();
01384 }
01385
01386
01387
01388 pot -= get_external_pot(b);
01389 pot /= 2;
01390 PRC(mass); PRC(pot);
01391
01392 real rvirial = -0.5*mass*mass/pot;
01393 PRC(rvirial); PRL(n);
01394
01395 cerr << "old "; PRC(b->get_d_min_sq());
01396 real d_min_sq = square(b->get_d_min_fac()*rvirial/n);
01397 b->set_d_min_sq(d_min_sq);
01398 cerr << "new "; PRL(b->get_d_min_sq());
01399
01400 putrq(b->get_log_story(), "kira_d_min_sq", d_min_sq);
01401
01402 b->reconstruct_perturbed_list();
01403
01404
01405
01406
01407 b->initialize_unperturbed();
01408
01409 if (verbose) {
01410 cerr << "CPU time for reinitialization = "
01411 << cpu_time() - cpu_0 << endl;
01412 }
01413 }
01414
01415 local bool check_sync(hdyn* b)
01416 {
01417 bool need_new_list = false;
01418
01419 for_all_nodes(hdyn, b, bb)
01420 if (bb->get_time() != b->get_system_time()
01421 && bb->get_kepler() == NULL) {
01422 cerr << "check_sync warning: node "
01423 << bb->format_label() << " not synchronized at time "
01424 << b->get_system_time() << "; node time = " << bb->get_time()
01425 << endl;
01426 need_new_list = true;
01427 }
01428
01429 return need_new_list;
01430 }
01431
01432 local void backward_step_exit(hdyn* b, real ttmp, real t,
01433 hdyn** next_nodes, int n_next)
01434 {
01435
01436 cerr << "evolve_system: time went backwards!\n";
01437
01438 cerr.precision(HIGH_PRECISION);
01439 PRC(ttmp); PRC(b->get_system_time()); PRL(t);
01440
01441 for (int i = 0; i < n_next; i++) {
01442 cerr << endl;
01443 PRC(i); next_nodes[i]->pretty_print_node(cerr);
01444 cerr << " "<< next_nodes[i]->get_time()<< " ";
01445 cerr << next_nodes[i]->get_next_time()<<endl;
01446 pp3(next_nodes[i]->get_top_level_node(), cerr);
01447 }
01448 put_node(cerr, *b, b->get_kira_options()->print_xreal);
01449 exit(0);
01450 }
01451
01452 local void check_binary_scheduling(hdyn* b,
01453 hdyn** next_nodes,
01454 int n_next)
01455 {
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484 for (int i = 0; i < n_next; i++) {
01485 hdyn *bi = next_nodes[i];
01486 if (bi->is_low_level_node()) {
01487
01488 hdyn *od = bi->get_elder_sister();
01489 if (od) {
01490
01491
01492
01493 if (od->get_timestep() != bi->get_timestep())
01494
01495 od->set_timestep(bi->get_timestep());
01496
01497 if (od->get_time() != bi->get_time())
01498 od->set_time(bi->get_time());
01499
01500 next_nodes[i] = od;
01501 }
01502 }
01503 }
01504 }
01505
01506 local inline void update_step(real t, real& ts, real dts)
01507 {
01508 while (ts < t)
01509 ts += dts;
01510 }
01511
01512
01513
01514 local real internal_potential(hdyn* bb)
01515 {
01516 real epot, ekin, etot;
01517 calculate_energies(bb, bb->get_eps2(), epot, ekin, etot);
01518 return epot;
01519 }
01520
01521 local void print_energy_from_pot(hdyn* b)
01522 {
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 return;
01539
01540 real top_pot = 0, int_pot = 0;
01541
01542 for_all_daughters(hdyn, b, bb) {
01543 top_pot += bb->get_mass()*bb->get_pot();
01544 if (bb->is_parent())
01545 int_pot += internal_potential(bb);
01546 }
01547
01548 real kin = 0;
01549
01550 for_all_leaves(hdyn, b, bb) {
01551 vector vel = hdyn_something_relative_to_root(bb, &hdyn::get_vel);
01552 kin += bb->get_mass()*square(vel);
01553 }
01554
01555 top_pot *= 0.5;
01556 kin *= 0.5;
01557
01558 int p = cerr.precision(INT_PRECISION);
01559 PRC(top_pot), PRC(int_pot), PRL(kin);
01560 PRL(get_external_pot(b));
01561 cerr << "energy_from_pot = " << kin+top_pot+int_pot+0.5*get_external_pot(b)
01562 << endl;
01563 cerr.precision(p);
01564 }
01565
01566
01567
01568 static hdyn **next_nodes = NULL;
01569
01570 local void evolve_system(hdyn * b,
01571 real delta_t,
01572 real dt_log,
01573 int long_binary_out,
01574 real dt_snap,
01575 real dt_sstar,
01576
01577 real dt_esc,
01578 real dt_reinit,
01579 real dt_fulldump,
01580 bool exact,
01581 real cpu_time_limit,
01582 bool verbose,
01583 bool save_snap_at_log,
01584 char* snap_save_file,
01585 int n_stop)
01586 {
01587
01588
01589
01590
01591
01592
01593
01594
01595 clean_up_files();
01596 cpu_init();
01597
01598 real r_reflect = -1;
01599 if (find_qmatch(b->get_log_story(), "r_reflect")) {
01600 r_reflect = getrq(b->get_log_story(), "r_reflect");
01601 cerr << endl
01602 << "*** Reflecting boundary at radius " << r_reflect << " ***"
01603 << endl;
01604 }
01605
01606 initialize_counters_from_log(b);
01607 kc_prev = *b->get_kira_counters();
01608
01609 kira_options *ko = b->get_kira_options();
01610 kira_diag *kd = b->get_kira_diag();
01611
01612 real count = 0;
01613 real steps = 0;
01614 int grape_steps = 0;
01615 int snaps = 0;
01616
01617 next_nodes = new hdyn *[2 * b->n_daughters()];
01618
01619
01620 bool *next_flag = new bool[2 * b->n_daughters()];
01621 real *last_dt = new real[2 * b->n_daughters()];
01622
01623 set_n_top_level(b);
01624
01625
01626
01627
01628
01629 real dt_max = min(dt_log, dt_sstar);
01630
01631 dt_max = min(dt_max, dt_reinit);
01632 dt_max = min(dt_max, dt_fulldump);
01633 b->set_unpert_step_limit(dt_max);
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659 int full_dump = 0;
01660 real n_dump = 1.0;
01661
01662 bool first_full_dump = false;
01663
01664 if (dt_snap <= 0) {
01665
01666
01667
01668
01669
01670 n_dump = -dt_snap;
01671 dt_snap = VERY_LARGE_NUMBER;
01672
01673 if (n_dump > 0)
01674 full_dump = 1;
01675 else
01676 full_dump = 2;
01677
01678
01679
01680
01681 first_full_dump = true;
01682 PRC(n_dump); PRL(full_dump);
01683 }
01684
01685
01686
01687
01688
01689 real initial_step_limit = min(INITIAL_STEP_LIMIT, dt_max);
01690 initial_step_limit = min(initial_step_limit, dt_snap);
01691
01692 real step_limit = min(dt_max, dt_snap);
01693
01694 b->set_mbar(b->get_mass()/b->n_leaves());
01695 b->set_initial_step_limit(initial_step_limit);
01696 b->set_step_limit(step_limit);
01697
01698
01699
01700
01701
01702
01703
01704
01705 real dt_sync = step_limit;
01706
01707
01708
01709 if (dt_reinit < dt_sync)
01710 err_exit("dt_reinit < dt_sync.");
01711 if (dt_esc < dt_sync)
01712 err_exit("dt_esc < dt_sync.");
01713 if (dt_sstar < dt_sync)
01714 err_exit("dt_sstar < dt_sync.");
01715 if (dt_fulldump < dt_sync)
01716 err_exit("dt_fulldump < dt_sync.");
01717
01718 if (verbose) {
01719 if (dt_log < dt_sync)
01720 cerr << "Warning: dt_log < dt_sync, quoted errors unpredictable."
01721 << endl;
01722 if (dt_snap < dt_sync)
01723 cerr << "Warning: dt_snap < dt_sync, no restart possible."
01724 << endl;
01725 else if (dt_snap < dt_reinit)
01726 cerr << "Warning: dt_snap < dt_reinit, restart unpredictable."
01727 << endl;
01728 }
01729
01730 xreal t = b->get_time();
01731
01732 real tt = t;
01733
01734
01735
01736
01737
01738 real t_end = tt + delta_t;
01739 real t_log = tt;
01740
01741 real t_snap = tt + dt_snap;
01742 real t_sync = tt + dt_sync;
01743
01744
01745
01746 real t_esc = tt;
01747
01748 real t_reinit = tt;
01749
01750
01751
01752 real dt_esc_check = min(dt_sync, 1.0/16);
01753 real t_esc_check = tt + dt_esc_check;
01754
01755
01756
01757 real t_fulldump = tt;
01758
01759 if (verbose) {
01760 cerr << endl;
01761 PRC(t), PRL(t_end);
01762 PRL(dt_sync);
01763 PRL(dt_log);
01764 PRL(long_binary_out);
01765 PRL(dt_snap);
01766 PRL(dt_esc);
01767 PRL(dt_reinit);
01768 PRL(dt_sstar);
01769 PRL(dt_sync);
01770 PRL(dt_fulldump);
01771
01772 PRC(t_snap); PRC(t_log); PRC(t_sync); PRC(t_esc); PRL(t_fulldump);
01773
01774 ko->print();
01775 kd->print();
01776 }
01777
01778 #ifdef DUMP_DATA
01779 ofstream tmp_dump("TMP_DUMP");
01780 #endif
01781
01782
01783
01784
01785
01786 full_reinitialize(b, t, verbose);
01787
01788 bool tree_changed = true;
01789
01790
01791
01792
01793 real *xxx = NULL;
01794 hdynptr *yyy = NULL;
01795 PRC(xxx); PRL(yyy);
01796
01797
01798
01799 while (t <= t_end) {
01800
01801 #ifdef T_DEBUG
01802 if (b->get_system_time() >= T_DEBUG) {
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816 cerr << "0000" << endl << flush;
01817
01818 cerr << "about to make a new real array" << endl << flush;
01819 xxx = new real[MAX_PERTURBERS];
01820 PRL(xxx);
01821 delete [] xxx;
01822
01823 cerr << "about to make a new hdynptr array" << endl << flush;
01824 yyy = new hdynptr[MAX_PERTURBERS];
01825 PRL(yyy);
01826 delete [] yyy;
01827
01828 if (b->get_system_time() >= 170.5) exit(0);
01829 }
01830 #endif
01831
01832 int n_next;
01833 xreal ttmp;
01834
01835
01836
01837 fast_get_nodes_to_move(b, next_nodes, n_next, ttmp, tree_changed);
01838
01839
01840 #ifdef T_DEBUG
01841 if (ttmp > T_DEBUG) {
01842
01843 cerr << 1 << endl << flush;
01844
01845 int p = cerr.precision(HIGH_PRECISION);
01846 cerr << "evolve_system: "; PRC(n_next); PRL(ttmp);
01847 if (n_next < 4) {
01848 PRI(15);
01849 for (int ii = 0; ii < n_next; ii++)
01850 cerr << next_nodes[ii]->format_label() << " ";
01851 cerr << endl << flush;
01852 }
01853 cerr.precision(p);
01854 }
01855 #endif
01856
01857 bool quit_now = false;
01858 hdyn *bad = NULL;
01859 for (int ii = 0; ii < n_next; ii++) {
01860 if (!next_nodes[ii]->is_valid()) {
01861 cerr << "next_node[" << ii << "] = " << next_nodes[ii]
01862 << " is invalid" << endl << flush;
01863 bad = next_nodes[ii];
01864 quit_now = true;
01865 }
01866 }
01867 if (quit_now) {
01868 for_all_nodes(hdyn, b, bb)
01869 if (bb == bad) cerr << "invalid node contained within the tree"
01870 << endl;
01871 err_exit("invalid node(s) on timestep list.");
01872 }
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888 bool save_snap = false;
01889
01890 if (ttmp > t_log) {
01891
01892
01893
01894
01895
01896
01897
01898 real cpu0 = cpu_time();
01899
01900
01901
01902 int long_bin = 0;
01903 if (long_binary_out > 0 && dt_log > 0) {
01904 int nlog = (int)rint((real)ttmp/dt_log);
01905 if (nlog%long_binary_out == 0)
01906 long_bin = 2;
01907 else
01908 long_bin = 1;
01909 }
01910
01911 log_output(b, count, steps, &kc_prev, long_bin);
01912
01913
01914
01915 save_snap = save_snap_at_log;
01916
01917 cerr << endl << "Total CPU time for log output = "
01918 << cpu_time() - cpu0 << endl;
01919
01920 cerr << endl; flush(cerr);
01921 update_step(ttmp, t_log, dt_log);
01922 }
01923
01924
01925
01926 if (full_dump && ttmp > t_esc_check) {
01927
01928
01929
01930
01931 refine_cluster_mass(b, 0);
01932 update_step(ttmp, t_esc_check, dt_esc_check);
01933 }
01934
01935
01936
01937 if (ttmp > t_sync) {
01938
01939
01940
01941
01942 if (check_file("STOP")) {
01943
01944 t_end = ttmp - 1;
01945
01946
01947 cerr << endl << "***** Calculation STOPped by user at time "
01948 << t << " *****" << endl << endl;
01949 }
01950
01951 tree_changed |= check_sync(b);
01952 update_step(ttmp, t_sync, dt_sync);
01953 }
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963 bool reg_snap = (ttmp > t_snap
01964 || (dt_snap < VERY_LARGE_NUMBER && ttmp > t_end)
01965 || (fmod(steps, 1000) == 0 && check_file("DUMP")));
01966
01967 if (reg_snap || save_snap) {
01968
01969
01970
01971 snap_output(b, steps, snaps,
01972 reg_snap, save_snap, snap_save_file,
01973 t, ttmp, t_end, t_snap, dt_snap, verbose);
01974
01975 if (reg_snap)
01976 update_step(ttmp, t_snap, dt_snap);
01977 }
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999 bool full_dump_now = (full_dump
02000 && (t >= t_fulldump || t >= t_end));
02001 if (full_dump)
02002 update_step(ttmp, t_fulldump, dt_fulldump);
02003
02004
02005
02006
02007 if (full_dump_now && !first_full_dump) {
02008
02009
02010
02011
02012
02013 int short_output = 1;
02014 if (ttmp > t_end) short_output = 4;
02015
02016 set_complete_system_dump(true);
02017 put_node(cout, *b,
02018 false,
02019 short_output);
02020 set_complete_system_dump(false);
02021
02022 cerr << "Full dump (";
02023 if (short_output == 1) cerr << "t";
02024 else cerr << "h";
02025 cerr << "dyn format) at time " << t << endl;
02026 }
02027
02028 first_full_dump = false;
02029
02030 #if 0
02031 real tcheck1 = 17.0;
02032 real tcheck2 = 17.5;
02033 real tcheck3 = 18.0;
02034 real tcheck4 = 19.0;
02035 if ( t <= tcheck1 && ttmp > tcheck1
02036 || t <= tcheck2 && ttmp > tcheck2
02037 || t <= tcheck3 && ttmp > tcheck3
02038 || t <= tcheck4 && ttmp > tcheck4 ) {
02039
02040 char name[10];
02041 sprintf(name, "TMP_%.1f", (real)t);
02042 ofstream f(name);
02043 if (f) {
02044
02045
02046 pp3(b, f);
02047 cerr << "wrote TMP file " << name << endl;
02048
02049 f.close();
02050 }
02051 }
02052 #endif
02053
02054
02055
02056 if (ttmp > t_end) return;
02057
02058
02059
02060 bool reinit = (ttmp > t_reinit);
02061 if (reinit) update_step(ttmp, t_reinit, dt_reinit);
02062
02063
02064
02065 bool esc = false;
02066
02067 if (ttmp > t_esc) {
02068
02069
02070
02071
02072
02073
02074
02075
02076 int n_prev = b->n_leaves();
02077
02078 if (b->get_scaled_stripping_radius() > 0)
02079 check_and_remove_escapers(b, ttmp, next_nodes,
02080 n_next, tree_changed);
02081
02082 int n_new = b->n_leaves();
02083
02084 if (n_new <= n_stop) {
02085 cerr << "N_stop reached\n";
02086 exit(0);
02087 }
02088
02089 if (n_new != n_prev) {
02090 reinit = true;
02091 esc = true;
02092 }
02093
02094 update_step(ttmp, t_esc, dt_esc);
02095 }
02096
02097
02098
02099 if (reinit) {
02100
02101
02102
02103
02104
02105 full_reinitialize(b, t, verbose);
02106 tree_changed = true;
02107
02108 fast_get_nodes_to_move(b, next_nodes, n_next, ttmp, tree_changed);
02109
02110 if (esc) cerr << endl << flush;
02111 }
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122 if (full_dump_now) {
02123
02124 set_complete_system_dump(true);
02125 put_node(cout, *b, false, 1);
02126 set_complete_system_dump(false);
02127
02128 cerr << endl << "Full dump (tdyn format) at time " << t << endl;
02129 }
02130
02131
02132
02133
02134
02135 #ifdef T_DEBUG
02136 if (ttmp > T_DEBUG) cerr << 2 << endl << flush;
02137 #endif
02138
02139 if (ttmp < t)
02140 backward_step_exit(b, ttmp, t, next_nodes, n_next);
02141
02142
02143
02144 check_binary_scheduling(b, next_nodes, n_next);
02145
02146 xreal t_prev = b->get_system_time();
02147
02148 b->set_system_time(t = ttmp);
02149 b->set_time(t);
02150
02151
02152
02153 #ifdef T_DEBUG
02154 if (ttmp > T_DEBUG) cerr << 3 << endl << flush;
02155 #endif
02156
02157 #ifndef USE_GRAPE
02158
02159
02160
02161
02162
02163
02164
02165 bool predict_all = false;
02166 for (int i = 0; i < n_next; i++) {
02167 hdyn* n = next_nodes[i];
02168 if (n->is_top_level_node()
02169 || !n->get_top_level_node()->get_valid_perturbers()) {
02170 predict_all = true;
02171 break;
02172 }
02173 }
02174
02175 if (predict_all)
02176 predict_loworder_all(b, t);
02177
02178
02179
02180 #endif
02181
02182
02183
02184
02185
02186
02187 if (0 && full_dump) {
02188 cerr << endl << "integration list (n_next = "
02189 << n_next << "):" << endl;
02190 for (int i = 0; i < n_next; i++) {
02191 PRI(4); PRC(i); cerr << next_nodes[i]->format_label() << endl;
02192 }
02193 }
02194
02195 if (full_dump == 1) {
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 for (int i = 0; i < n_next; i++) {
02206
02207 if (next_nodes[i]->get_kepler())
02208 next_flag[i] = true;
02209 else
02210 next_flag[i] = false;
02211
02212 last_dt[i] = next_nodes[i]->get_timestep();
02213 }
02214
02215 }
02216
02217 #ifdef T_DEBUG
02218 if (ttmp > T_DEBUG) {
02219
02220 cerr << 4 << endl << flush;
02221
02222
02223
02224
02225
02226
02227
02228 }
02229 #endif
02230
02231 int ds = integrate_list(b, next_nodes, n_next, exact,
02232 tree_changed, full_dump,
02233 r_reflect);
02234
02235
02236
02237
02238
02239
02240
02241
02242 #ifdef T_DEBUG
02243 if (ttmp > T_DEBUG) cerr << 49 << endl << flush;
02244 #endif
02245
02246 bool force_energy_check = false;
02247 if (ds < 0) {
02248 ds = -ds;
02249 if (kd->check_heartbeat) force_energy_check = true;
02250 }
02251
02252 steps += ds;
02253 grape_steps += ds;
02254 count += 1;
02255
02256 if (force_energy_check)
02257 count = 4*kd->n_check_heartbeat
02258 * (floor(count / (4*kd->n_check_heartbeat)) + 1);
02259
02260 #ifdef T_DEBUG
02261 if (ttmp > T_DEBUG) cerr << 5 << endl << flush;
02262 #endif
02263
02264 if (full_dump == 1) {
02265
02266
02267
02268 for (int i = 0; i < n_next; i++) {
02269
02270 hdyn *curr = next_nodes[i];
02271
02272 if (curr && curr->is_valid()) {
02273
02274
02275
02276
02277
02278
02279 bool dump_now = (fmod(curr->get_steps(), n_dump) == 0);
02280
02281
02282
02283 dump_now |=
02284 (next_flag[i] && !curr->get_kepler()
02285 || (!next_flag[i] && curr->get_kepler()));
02286
02287 #if 0
02288
02289
02290
02291 if (curr->is_low_level_node()
02292 && !curr->get_kepler()
02293 && curr->get_perturbation_squared()
02294 < SMALL_TDYN_PERT_SQ) {
02295
02296
02297
02298 int which = 2;
02299
02300 if (which == 1) {
02301
02302
02303
02304
02305 real t_par = curr->get_parent()->get_time();
02306 dump_now = (t >= t_par && t - last_dt[i] < t_par);
02307
02308
02309
02310
02311
02312
02313
02314
02315 } else if (which == 2) {
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325 dump_now = (fmod(curr->get_steps(),
02326 10*n_dump) == 0);
02327 }
02328
02329 if (dump_now && !curr->get_elder_sister()) {
02330 cerr << endl
02331 << curr->get_parent()->format_label()
02332 << " is lightly perturbed; get_steps = "
02333 << curr->get_steps() << endl;
02334 PRL(sqrt(max(0.0,
02335 curr->get_perturbation_squared())));
02336 real ratio = curr->get_parent()->get_timestep()
02337 / curr->get_timestep();
02338 PRL(curr->get_parent()->get_timestep());
02339 PRC(curr->get_timestep());
02340 PRL(ratio);
02341 }
02342 }
02343 #endif
02344
02345 if (dump_now) {
02346
02347
02348
02349
02350
02351 put_single_node(cout, *curr, false, 1);
02352
02353
02354
02355
02356
02357 if (curr->is_low_level_node()) {
02358
02359
02360
02361
02362
02363
02364 put_single_node(cout,
02365 *(curr->get_binary_sister()),
02366 false, 1);
02367 }
02368 }
02369 }
02370 }
02371 }
02372
02373 #ifdef DUMP_DATA
02374 if (tmp_dump && t >= 17.0 && t <= 17.5) {
02375
02376
02377
02378 tmp_dump << endl << "n_next = " << n_next << endl;
02379 for (int i = 0; i < n_next; i++)
02380 if (next_nodes[i] && next_nodes[i]->is_valid()) {
02381 tmp_dump << "i = " << i << " (" << next_nodes[i] << "):"
02382 << endl;
02383 pp3(next_nodes[i], tmp_dump, -1);
02384 } else
02385 tmp_dump << "i = " << i << " (" << next_nodes[i]
02386 << "): invalid" << endl;
02387 }
02388 #endif
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408 if (kd->check_heartbeat && fmod(count, kd->n_check_heartbeat) == 0) {
02409 PRC(count), PRC(t), PRC(t-t_prev), PRL(cpu_time());
02410 if (fmod(count, 4*kd->n_check_heartbeat) == 0)
02411 print_recalculated_energies(b);
02412 }
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430 #ifdef T_DEBUG
02431 if (ttmp > T_DEBUG) cerr << 6 << endl << flush;
02432 #endif
02433
02434 if (fmod(b->get_system_time(), dt_sstar) == 0.0
02435 && b->get_use_sstar()) {
02436
02437
02438
02439
02440 bool tmp = evolve_stars(b, full_dump);
02441
02442
02443
02444 tree_changed |= tmp;
02445
02446
02447
02448
02449
02450
02451 }
02452
02453 if (tree_changed) set_n_top_level(b);
02454
02455 #ifdef USE_GRAPE
02456
02457
02458
02459 if (grape_steps > ko->grape_check_count) {
02460 grape_steps = 0;
02461 check_release_grape(ko, t);
02462 }
02463
02464 #endif
02465
02466 #ifdef T_DEBUG
02467 if (ttmp > T_DEBUG) cerr << 7 << endl << flush;
02468 #endif
02469
02470
02471
02472 if (fmod(count, kd->n_check_runtime) == 0) {
02473
02474 if (cpu_time() > cpu_time_limit) {
02475 cerr << endl
02476 << "***** CPU time limit of " << cpu_time_limit
02477 << " seconds exceeded"
02478 << endl;
02479 return;
02480 }
02481
02482 real new_dt_log = 0;
02483 real new_dt_snap = 0;
02484 char* new_snap_save_file = new char[128];
02485 new_snap_save_file[0] = '\0';
02486
02487 bool status
02488 = check_kira_runtime(b, t_end,
02489 new_dt_log, new_dt_snap,
02490 long_binary_out, new_snap_save_file,
02491 tree_changed);
02492
02493 if (new_dt_log > 0) {
02494 dt_log = new_dt_log;
02495 int i = (int)((real)b->get_system_time() / dt_log);
02496 t_log = (i+1) * dt_log;
02497 }
02498
02499 if (new_dt_snap > 0) {
02500 dt_snap = new_dt_snap;
02501 int i = (int)((real)b->get_system_time() / dt_snap);
02502 t_snap = (i+1) * dt_snap;
02503 }
02504
02505 if (new_snap_save_file[0] != '\0') {
02506 save_snap_at_log = true;
02507 snap_save_file = new_snap_save_file;
02508 } else
02509 delete [] new_snap_save_file;
02510
02511 if (status) return;
02512
02513 ko = b->get_kira_options();
02514 kd = b->get_kira_diag();
02515 }
02516 }
02517 }
02518
02519
02520
02521 #include <unistd.h>
02522 #include <signal.h>
02523
02524 main(int argc, char **argv)
02525 {
02526 check_help();
02527
02528
02529
02530 hdyn *b;
02531
02532
02533
02534 real delta_t;
02535 real dt_log;
02536 real dt_snap;
02537 real dt_sstar;
02538 real dt_esc;
02539 real dt_reinit;
02540 real dt_fulldump;
02541
02542 int long_binary_out;
02543
02544 real cpu_time_limit;
02545
02546 bool exact;
02547 bool verbose;
02548
02549 bool save_snap_at_log = false;
02550 char snap_save_file[256];
02551 int n_stop;
02552
02553 if (!kira_initialize(argc, argv,
02554 b, delta_t, dt_log, long_binary_out,
02555 dt_snap, dt_sstar,
02556 dt_esc, dt_reinit, dt_fulldump,
02557 exact, cpu_time_limit, verbose,
02558 save_snap_at_log, snap_save_file, n_stop))
02559 get_help();
02560
02561
02562
02563
02564
02565 set_kepler_tolerance(2);
02566 set_kepler_print_trig_warning(b->get_kira_diag()
02567 ->report_kepler_trig_error);
02568
02569 evolve_system(b, delta_t, dt_log, long_binary_out,
02570 dt_snap, dt_sstar, dt_esc, dt_reinit, dt_fulldump,
02571 exact, cpu_time_limit,
02572 verbose, save_snap_at_log, snap_save_file, n_stop);
02573
02574 cerr << endl << "End of run at time " << b->get_system_time()
02575 << endl
02576 << "Total CPU time for this segment = " << cpu_time()
02577 << endl;
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592 cerr << endl << "cleaning up hdyn_schedule" << endl << flush;
02593 clean_up_hdyn_schedule();
02594
02595 cerr << "cleaning up hdyn_ev" << endl << flush;
02596 clean_up_hdyn_ev();
02597
02598 cerr << "cleaning up kira_ev" << endl << flush;
02599 clean_up_kira_ev();
02600
02601 #if defined(USE_GRAPE)
02602 cerr << "cleaning up hdyn_grape" << endl << flush;
02603 clean_up_hdyn_grape();
02604 #endif
02605
02606 cerr << "cleaning up next_nodes" << endl << flush;
02607 if (next_nodes) delete [] next_nodes;
02608
02609 cerr << "cleaning up kira_counters" << endl << flush;
02610 if (b->get_kira_counters()) delete b->get_kira_counters();
02611
02612 cerr << "cleaning up perturbed_list" << endl << flush;
02613 if (b->get_perturbed_list()) delete [] b->get_perturbed_list();
02614
02615 cerr << "cleanup complete" << endl << flush;
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625 }
02626
02627 #endif