00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "hdyn.h"
00043 #include <star/dstar_to_kira.h>
00044 #include <star/single_star.h>
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 real hdyn::distance_to_sister_squared()
00060 {
00061 vector d_sep = pos - get_binary_sister()->get_pos();
00062 return d_sep * d_sep;
00063 }
00064
00065 local void init_predictor_tree(hdyn * b)
00066 {
00067 if (! b->is_root()) {
00068 b->init_pred();
00069 b->store_old_force();
00070 }
00071 for_all_daughters(hdyn,b,bb) init_predictor_tree(bb);
00072 }
00073
00074
00075
00076
00077 local void synchronize_branch(hdyn * bi, hdyn * ancestor)
00078 {
00079 if (!is_descendent_of(bi, ancestor, 0))
00080 err_exit("synchronize_branch: bi not descended from ancestor");
00081
00082 for (hdyn * bb = bi; bb != ancestor; bb = bb->get_parent()) {
00083
00084
00085
00086 bb->get_binary_sister()->synchronize_node();
00087
00088
00089
00090 bb->get_parent()->synchronize_node();
00091 }
00092 }
00093
00094 local inline real max_mass(hdyn* b)
00095 {
00096 real m_max = 0;
00097 if (b->is_parent()) {
00098 for_all_daughters(hdyn, b, bb)
00099 if (bb->get_mass() > m_max)
00100 m_max = max(m_max, max_mass(bb));
00101 } else
00102 m_max = b->get_mass();
00103
00104 return m_max;
00105 }
00106
00107 local inline real n_mass(hdyn* b)
00108 {
00109
00110
00111
00112
00113
00114
00115
00116
00117 return max_mass(b);
00118 }
00119
00120 local bool number_of_daughter_nodes_exceeds(node * b, int n)
00121 {
00122 int nn = 0;
00123
00124 for_all_daughters(node, b, bb)
00125 if (++nn > n)
00126 return true;
00127
00128 return false;
00129 }
00130
00131 local void halve_timestep(hdyn * b)
00132 {
00133 b->set_timestep(0.5 * b->get_timestep());
00134 }
00135
00136 local void print_relative_energy_and_period(hdyn* bi, hdyn* bj)
00137 {
00138 real E, P;
00139 get_total_energy_and_period(bi, bj, E, P);
00140
00141 cerr << "relative E/mu = " << E << flush;
00142
00143 if (E < 0)
00144 cerr << " P = " << P;
00145 }
00146
00147
00148 local bool too_close(hdyn * bi, hdyn * bj, real limit_sq,
00149 bool print = true)
00150 {
00151 if (bi == bj)
00152 return false;
00153
00154 real gap_sq = square(bi->get_pos() - bj->get_pos());
00155
00156
00157
00158
00159
00160
00161 bool close;
00162 real mass_factor = 1;
00163
00164
00165 if (bi->get_kira_options()->close_criterion > 0) {
00166
00167 mass_factor = 0.5 * (n_mass(bi) + n_mass(bj)) / bi->get_mbar();
00168
00169 if (bi->get_kira_options()->close_criterion == 1) {
00170
00171
00172
00173
00174
00175 mass_factor *= mass_factor;
00176
00177 } else if (bi->get_kira_options()->close_criterion == 2) {
00178
00179
00180
00181
00182
00183 }
00184
00185 }
00186
00187 close = (gap_sq < mass_factor * limit_sq);
00188
00189 if (close && print && bi->get_kira_diag()->tree
00190 && bi->get_kira_diag()->tree_level > 0) {
00191 cerr << endl << "*** "; bi->print_label(cerr);
00192 cerr << " too close to "; bj->print_label(cerr);
00193 cerr << " (criterion " << bi->get_kira_options()->close_criterion
00194 << ")" << endl;
00195 }
00196
00197 return close;
00198 }
00199
00200 local bool too_big(hdyn * bi, real limit_sq)
00201 {
00202 hdyn *od = bi->get_oldest_daughter();
00203 if (od == NULL)
00204 return false;
00205
00206
00207
00208
00209 if (od->get_kepler()) return false;
00210
00211
00212
00213
00214
00215 if (od->get_valid_perturbers()) {
00216 real pert2 = od->get_perturbation_squared();
00217
00218 if (pert2 >= 0 && pert2 <= 1.e-10) return false;
00219 }
00220
00221 bool big = !too_close(od, od->get_younger_sister(), limit_sq, false);
00222
00223
00224
00225
00226 if (big && od->get_slow()) {
00227 if (!od->get_slow()->get_stop()) {
00228 cerr << "too_big: scheduling end of slow motion for "
00229 << bi->format_label() << " at time " << bi->get_system_time()
00230 << endl;
00231 od->get_slow()->set_stop();
00232 }
00233 return false;
00234 }
00235
00236 if (big && bi->get_kira_diag()->tree
00237 && bi->get_kira_diag()->tree_level > 0)
00238 cerr << endl << "*** " << bi->format_label() << " too big" << endl;
00239
00240 return big;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250 hdyn* hdyn::new_sister_node(bool & top_level_combine)
00251 {
00252 top_level_combine = false;
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 if (nn->get_parent() == parent)
00329 return NULL;
00330
00331 real mass_factor = 1;
00332
00333 if (options->close_criterion > 0) {
00334
00335 real m = n_mass(this);
00336 mass_factor = (m + n_mass(get_binary_sister())) / (m + n_mass(nn));
00337
00338 if (options->close_criterion == 1) {
00339
00340
00341
00342 mass_factor *= mass_factor;
00343
00344 } else if (options->close_criterion == 2) {
00345
00346
00347
00348 }
00349 }
00350
00351 bool nn_too_close = (distance_to_sister_squared()
00352 > d_nn_sq * lag_factor * mass_factor);
00353
00354 if (!nn_too_close) {
00355
00356
00357
00358
00359
00360 nn_too_close = (perturbation_squared > 1
00361 && distance_to_sister_squared() > d_nn_sq);
00362
00363 if (nn_too_close && diag->tree && diag->tree_level > 1) {
00364 cerr << "in new_sister_node for " << format_label()
00365 << " at time " << system_time << ":" << endl;
00366 cerr << " candidate new sister for strongly perturbed binary is "
00367 << nn->format_label() << endl;
00368 }
00369
00370 }
00371
00372 if (nn_too_close) {
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 hdyn * new_sister = nn;
00385 hdyn * root = get_root();
00386
00387
00388
00389
00390
00391
00392 hdyn *snn = new_sister->get_nn();
00393
00394 if (snn && snn->is_valid() && !snn->is_leaf()) {
00395
00396
00397
00398
00399
00400 real d_sq_min = VERY_LARGE_NUMBER;
00401 hdyn * local_nn = NULL;
00402 vector s_pos = hdyn_something_relative_to_root(new_sister,
00403 &hdyn::get_pos);
00404
00405 for_all_leaves(hdyn, snn, bb) {
00406 vector b_pos = hdyn_something_relative_to_root(bb,
00407 &hdyn::get_pos);
00408 real d_sq = square(b_pos - s_pos);
00409 if (d_sq < d_sq_min) {
00410 local_nn = bb;
00411 d_sq_min = d_sq;
00412 }
00413 }
00414
00415 if (local_nn) {
00416
00417 snn = local_nn;
00418 new_sister->set_nn(snn);
00419
00420 if (diag->tree && diag->tree_level > 0) {
00421 cerr << "new_sister_node: computed local nn for "
00422 << new_sister->format_label() << endl;
00423 PR(local_nn);
00424 cerr << " (" << snn->format_label() << ")" << endl;
00425 PRC(new_sister->get_d_nn_sq()); PRL(d_sq_min);
00426 }
00427 }
00428 }
00429
00430
00431
00432 if (snn && snn->is_valid() && common_ancestor(snn, this) != this) {
00433
00434 hdyn* ns = new_sister;
00435
00436 do {
00437 new_sister = new_sister->get_parent();
00438 } while(new_sister != root
00439 && new_sister->get_nn() != NULL
00440 && new_sister->get_nn()->is_valid()
00441 && new_sister->parent != parent
00442 && common_ancestor(new_sister->get_nn(), this) != this);
00443
00444 if (new_sister == root
00445 || new_sister->get_nn() == NULL
00446 || !new_sister->get_nn()->is_valid()
00447 || new_sister->parent == parent
00448 || common_ancestor(new_sister, this)== this
00449 || common_ancestor(new_sister, this)== new_sister
00450 ) return NULL;
00451
00452 if (diag->tree && diag->tree_level > 0) {
00453 cerr << "new_sister_node: ascended tree from "
00454 << ns->format_label();
00455 cerr << " to " << new_sister->format_label() << endl;
00456 }
00457 }
00458
00459 hdyn * ancestor = common_ancestor(this, new_sister);
00460
00461 if (ancestor->is_root()) {
00462
00463 top_level_combine = TRUE;
00464 return new_sister;
00465
00466 } else {
00467
00468
00469
00470
00471 if (parent != ancestor) {
00472 while (new_sister->get_parent() != ancestor) {
00473 new_sister = new_sister->get_parent();
00474 }
00475 }
00476
00477 if (new_sister->kep == NULL) {
00478 if (diag->tree && diag->tree_level > 0) {
00479 cerr << "new sister node for "; pretty_print_node(cerr);
00480 cerr << " (nn = "; nn->pretty_print_node(cerr);
00481 cerr << ") is " ; new_sister->pretty_print_node(cerr);
00482 PRI(2); PRL(top_level_combine);
00483 }
00484 return new_sister;
00485 }
00486 }
00487 }
00488 return NULL;
00489 }
00490
00491
00492 local void check_merge_esc_flags(hdyn *bi, hdyn *bj)
00493 {
00494
00495
00496
00497 bool iesc = find_qmatch(bi->get_dyn_story(), "t_esc");
00498 bool jesc = find_qmatch(bj->get_dyn_story(), "t_esc");
00499
00500 if (iesc && jesc) {
00501
00502
00503
00504 real t_esc = max(getrq(bi->get_dyn_story(), "t_esc"),
00505 getrq(bj->get_dyn_story(), "t_esc"));
00506 putrq(bi->get_parent()->get_dyn_story(), "esc", 1);
00507 putrq(bi->get_parent()->get_dyn_story(), "t_esc", t_esc);
00508
00509 } else {
00510
00511
00512
00513 putrq(bi->get_parent()->get_dyn_story(), "esc", 0);
00514
00515 if (iesc) {
00516 putrq(bi->get_dyn_story(), "esc", 0);
00517 rmq(bi->get_dyn_story(), "t_esc");
00518 }
00519
00520 if (jesc) {
00521 putrq(bj->get_dyn_story(), "esc", 0);
00522 rmq(bj->get_dyn_story(), "t_esc");
00523 }
00524 }
00525 }
00526
00527 void combine_top_level_nodes(hdyn * bj, hdyn * bi,
00528 int full_dump)
00529 {
00530
00531
00532
00533
00534
00535
00536 if (bi->get_kira_diag()->tree) {
00537
00538 cerr << endl << "combine_top_level_nodes: attaching ",
00539 bj->pretty_print_node(cerr);
00540 cerr << " to ", bi->pretty_print_node(cerr);
00541 cerr << " at time " << bi->get_system_time();
00542
00543 if (bj->get_kira_diag()->tree_level > 0) {
00544
00545 cerr << endl;
00546 pp2(bi, cerr);
00547 print_binary_from_dyn_pair(bj, bi);
00548 cerr << endl;
00549 if (bj->is_parent()) {
00550 print_binary_from_dyn_pair(bj->get_oldest_daughter(),
00551 bj->get_oldest_daughter()
00552 ->get_younger_sister());
00553 cerr << endl;
00554 }
00555 if (bi->is_parent()) {
00556 print_binary_from_dyn_pair(bi->get_oldest_daughter(),
00557 bi->get_oldest_daughter()
00558 ->get_younger_sister());
00559 cerr << endl;
00560 }
00561
00562 if (bj->get_kira_diag()->tree_level > 1) {
00563
00564
00565
00566
00567
00568
00569
00570 if (bj->get_kira_diag()->tree_level > 2) {
00571 cerr << endl;
00572 put_node(cerr, *bj, bj->get_kira_options()->print_xreal);
00573 put_node(cerr, *bi, bi->get_kira_options()->print_xreal);
00574 }
00575
00576 cerr << endl;
00577 plot_stars(bj);
00578 }
00579
00580 } else {
00581
00582 cerr << endl << " ";
00583 print_relative_energy_and_period(bj, bi);
00584 cerr << endl;
00585 }
00586 }
00587
00588
00589
00590
00591 predict_loworder_all(bi->get_root(), bi->get_system_time());
00592
00593
00594
00595
00596
00597
00598
00599 bi->synchronize_node();
00600 bj->synchronize_node();
00601
00602 if (full_dump) {
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 put_node(cout, *bi, false, 3);
00619 put_node(cout, *bj, false, 3);
00620 }
00621
00622
00623
00624
00625
00626 for (hdyn *bb = bi; bb != bj; bb = bj)
00627 if (bb->get_kappa() > 1) {
00628 hdyn *pnode = bb->find_perturber_node();
00629 if (pnode && pnode->get_valid_perturbers())
00630 for (int k = 0; k < pnode->get_n_perturbers(); k++) {
00631 hdyn *p = pnode->get_perturber_list()[k]
00632 ->get_top_level_node();
00633 if (p->get_sp())
00634 p->remove_slow_perturbed(bb);
00635 }
00636 }
00637
00638 create_binary_from_toplevel_nodes(bi, bj);
00639
00640
00641
00642
00643 bi->copy_slow_perturbed(bi->get_parent());
00644 bi->clear_slow_perturbed();
00645 bj->copy_slow_perturbed(bj->get_parent());
00646 bj->clear_slow_perturbed();
00647
00648
00649
00650
00651 if (bi->get_parent()->get_sp()) {
00652 bi->get_parent()->remove_slow_perturbed(bi);
00653 bi->get_parent()->remove_slow_perturbed(bj);
00654 }
00655
00656
00657
00658
00659
00660
00661 for_all_nodes(hdyn, bj->get_parent(), bb) {
00662 bb->set_valid_perturbers(false);
00663 bb->set_perturbation_squared(-1);
00664 }
00665
00666
00667
00668
00669
00670
00671 halve_timestep(bj->get_parent());
00672
00673
00674
00675
00676 bi->init_pred();
00677 bj->init_pred();
00678 bj->get_parent()->init_pred();
00679
00680 init_predictor_tree(bj->get_parent());
00681
00682 check_merge_esc_flags(bj, bi);
00683
00684 if (full_dump) {
00685
00686
00687
00688
00689 predict_loworder_all(bj->get_parent(), bj->get_system_time());
00690
00691
00692
00693
00694
00695 put_node(cout, *bj->get_parent(), false, 2);
00696 }
00697
00698 bi->get_kira_counters()->top_level_combine++;
00699
00700 if (bi->get_kira_diag()->tree && bi->get_kira_diag()->tree_level > 1)
00701 pp3(bi->get_parent(), cerr);
00702 }
00703
00704 void split_top_level_node(hdyn * bi,
00705 int full_dump)
00706 {
00707
00708
00709
00710
00711 if (!bi->is_top_level_node())
00712 err_exit("split_top_level_node: not at top level");
00713
00714 if (bi->get_oldest_daughter()->get_slow()) {
00715
00716
00717
00718 cerr << "split_top_level_node: warning: trying to split slow binary "
00719 << bi->format_label() << endl
00720 << " at time " << bi->get_system_time() << endl;
00721
00722
00723
00724 bi->get_oldest_daughter()->get_slow()->set_stop();
00725 return;
00726 }
00727
00728 if (bi->get_kira_diag()->tree) {
00729
00730 cerr << endl << "split_top_level_node: splitting ";
00731 bi->pretty_print_node(cerr);
00732 cerr << " at time " << bi->get_system_time();
00733
00734 if (bi->get_kira_diag()->tree_level >= 1) {
00735 cerr << endl;
00736 pp2(bi, cerr);
00737 print_binary_from_dyn_pair(bi->get_oldest_daughter(),
00738 bi->get_oldest_daughter()
00739 ->get_younger_sister());
00740
00741 #if 0
00742 cerr << endl;
00743 PRL(bi->get_oldest_daughter()->get_perturbation_squared());
00744 hdyn *pnode = bi->get_oldest_daughter()->find_perturber_node();
00745 if (pnode && pnode->is_valid()) {
00746 PRL(pnode->format_label());
00747 if (pnode->get_valid_perturbers())
00748 PRL(pnode->get_n_perturbers());
00749 else
00750 cerr << "perturbers unknown" << endl;
00751 } else
00752 cerr << "pnode invalid" << endl;
00753 #endif
00754
00755
00756 cerr << endl << flush;
00757
00758 if (bi->get_kira_diag()->tree_level > 1) {
00759 cerr << endl;
00760 pp3(bi, cerr);
00761
00762
00763
00764 if (bi->get_kira_diag()->tree_level > 2)
00765 put_node(cerr, *bi, bi->get_kira_options()->print_xreal);
00766 }
00767 } else {
00768 cerr << endl << " ";
00769 print_relative_energy_and_period(bi->get_oldest_daughter(),
00770 bi->get_oldest_daughter()
00771 ->get_younger_sister());
00772 cerr << endl;
00773 }
00774 }
00775
00776 hdyn *od = bi->get_oldest_daughter();
00777 hdyn *yd = od->get_younger_sister();
00778
00779
00780
00781 predict_loworder_all(bi->get_root(), bi->get_system_time());
00782
00783
00784
00785
00786
00787 bi->synchronize_node();
00788 od->synchronize_node();
00789 update_binary_sister(od);
00790
00791 if (full_dump) {
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 put_node(cout, *bi, false, 3);
00802 }
00803
00804
00805
00806 od->set_pos(hdyn_something_relative_to_root(od, &hdyn::get_pos));
00807 od->set_vel(hdyn_something_relative_to_root(od, &hdyn::get_vel));
00808 od->set_acc(hdyn_something_relative_to_root(od, &hdyn::get_acc));
00809 od->set_jerk(hdyn_something_relative_to_root(od, &hdyn::get_jerk));
00810 od->store_old_force();
00811
00812 yd->set_pos(hdyn_something_relative_to_root(yd, &hdyn::get_pos));
00813 yd->set_vel(hdyn_something_relative_to_root(yd, &hdyn::get_vel));
00814 yd->set_acc(hdyn_something_relative_to_root(yd, &hdyn::get_acc));
00815 yd->set_jerk(hdyn_something_relative_to_root(yd, &hdyn::get_jerk));
00816 yd->store_old_force();
00817
00818 od->init_pred();
00819 yd->init_pred();
00820
00821
00822
00823
00824
00825 for_all_nodes(hdyn, od, bb) {
00826 bb->set_valid_perturbers(false);
00827 bb->set_perturbation_squared(-1);
00828 }
00829 for_all_nodes(hdyn, yd, bb) {
00830 bb->set_valid_perturbers(false);
00831 bb->set_perturbation_squared(-1);
00832 }
00833
00834
00835
00836 hdyn *root = bi->get_root();
00837
00838 detach_node_from_general_tree(*bi);
00839
00840
00841
00842 if (bi->get_nn()->get_nn() == bi)
00843 bi->get_nn()->set_nn(NULL);
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 if (!RESOLVE_UNPERTURBED_PERTURBERS)
00854 expand_perturber_lists(bi->get_root(), bi,
00855 bi->get_kira_diag()->tree
00856 && bi->get_kira_diag()->tree_level > 0);
00857
00858
00859
00860 bi->copy_slow_perturbed(od, true);
00861 bi->copy_slow_perturbed(yd, true);
00862
00863 delete bi;
00864
00865 add_node(*od, *root);
00866 add_node(*yd, *root);
00867
00868
00869
00870
00871 if (full_dump) {
00872
00873
00874
00875
00876 predict_loworder_all(od, od->get_system_time());
00877 predict_loworder_all(yd, yd->get_system_time());
00878
00879
00880
00881
00882
00883 put_node(cout, *od, false, 2);
00884 put_node(cout, *yd, false, 2);
00885 }
00886
00887 bi->get_kira_counters()->top_level_split++;
00888 }
00889
00890 local void combine_low_level_nodes(hdyn * bi, hdyn * bj,
00891 int full_dump = 0)
00892 {
00893
00894
00895
00896 if (bi->get_slow()) {
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 bi->get_slow()->set_stop();
00915 return;
00916 }
00917
00918 if (bi->get_kira_diag()->tree && bi->get_kira_diag()->tree_level > 0) {
00919 cerr << "\ncombine_low_level_nodes: combining ";
00920 bi->pretty_print_node(cerr);
00921 cerr << " and ";
00922 bj->pretty_print_node(cerr);
00923 cerr << " at time " << bi->get_system_time() << "\n";
00924 }
00925
00926 hdyn *ancestor;
00927 ancestor = common_ancestor(bi, bj);
00928
00929 bool pp3_at_end = false;
00930
00931 #if 0
00932 if (bi->get_time() > 2.6 && bi->get_time() < 2.7) {
00933 cerr << endl << "------------------------------" << endl;
00934 cerr << "combine_low_level_nodes:" << endl;
00935 cerr << "bi = " << bi->format_label() << endl;
00936 cerr << "bj = " << bj->format_label() << endl;
00937 cerr << "ancestor = " << ancestor->format_label() << endl;
00938 pp3(ancestor);
00939 pp3_at_end = true;
00940 }
00941 #endif
00942
00943
00944
00945 predict_loworder_all(bi->get_root(), bi->get_system_time());
00946
00947 bi->synchronize_node();
00948 bj->synchronize_node();
00949
00950 synchronize_branch(bi, ancestor);
00951 synchronize_branch(bj, ancestor);
00952
00953 hdyn* old_top_level_node = bi->get_top_level_node();
00954
00955
00956 if (full_dump) {
00957
00958
00959
00960
00961
00962
00963
00964
00965 put_node(cout, *old_top_level_node, false, 3);
00966 }
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 bool vp = old_top_level_node->get_valid_perturbers();
00989 int np = 0;
00990 real p_sq = -1;
00991 real p_fac = 0;
00992 hdyn** pert_list = NULL;
00993
00994 if (vp) {
00995 np = old_top_level_node->get_n_perturbers();
00996 p_sq = old_top_level_node->get_perturbation_squared();
00997 p_fac = old_top_level_node->get_perturbation_radius_factor();
00998 pert_list = new hdyn *[MAX_PERTURBERS];
00999 for (int i = 0; i < np; i++)
01000 pert_list[i] = old_top_level_node->get_perturber_list()[i];
01001
01002 }
01003
01004 move_node(bi, bj);
01005
01006 hdyn* top_level_node = bi->get_top_level_node();
01007
01008 if (top_level_node != old_top_level_node) {
01009
01010 if (vp) {
01011
01012
01013
01014
01015 top_level_node->remove_perturber_list();
01016 top_level_node->new_perturber_list();
01017
01018 top_level_node->set_valid_perturbers(vp);
01019 top_level_node->set_n_perturbers(np);
01020 top_level_node->set_perturbation_squared(p_sq);
01021 top_level_node->set_perturbation_radius_factor(p_fac);
01022
01023 for (int i = 0; i < np; i++)
01024 top_level_node->get_perturber_list()[i] = pert_list[i];
01025
01026 delete pert_list;
01027 cerr << "restored top-level perturber information, np = "
01028 << np << endl;
01029
01030 } else {
01031
01032 top_level_node->set_valid_perturbers(vp);
01033 top_level_node->set_perturbation_squared(-1);
01034
01035 }
01036 }
01037
01038
01039
01040
01041 predict_loworder_all(bi->get_root(), bi->get_system_time());
01042
01043
01044
01045 for_all_nodes(hdyn, top_level_node, bb) {
01046 if (bb != top_level_node) {
01047
01048 bb->set_valid_perturbers(false);
01049 bb->set_perturbation_squared(-1);
01050
01051
01052
01053 }
01054 }
01055
01056 bi->get_kira_counters()->low_level_combine++;
01057
01058
01059
01060 hdyn *bn = bi->get_parent();
01061 while (bn != bi->get_root()) {
01062 label_binary_node(bn);
01063 bn = bn->get_parent();
01064 }
01065
01066 check_merge_esc_flags(bi, bi->get_binary_sister());
01067
01068
01069 if (full_dump) {
01070
01071
01072
01073
01074 predict_loworder_all(top_level_node, bi->get_system_time());
01075
01076
01077
01078
01079 put_node(cout, *top_level_node, false, 2);
01080 }
01081
01082 if (pp3_at_end) {
01083 cerr << endl << "after combine_low_level_nodes:" << endl;
01084 pp3(bi->get_top_level_node());
01085 cerr << endl << "------------------------------" << endl;
01086 }
01087 }
01088
01089 local int adjust_low_level_node(hdyn * bi, int full_dump = 0)
01090 {
01091 int status = 1;
01092
01093 bool top_level_combine;
01094
01095
01096
01097
01098
01099
01100 hdyn *sister = bi->new_sister_node(top_level_combine);
01101
01102 #if 0
01103 if (sister != NULL) {
01104 cout << "adjust low_level, "; bi->pretty_print_node(cout);
01105 cout << "-- "; sister->pretty_print_node(cout);
01106 cout << "-- "; sister->get_nn()->pretty_print_node(cout); cout<<endl;
01107 }
01108 #endif
01109
01110 if (sister != NULL)
01111 predict_loworder_all(bi->get_root(), bi->get_system_time());
01112
01113 if (top_level_combine) {
01114
01115 if (number_of_daughter_nodes_exceeds(bi->get_root(), 2)) {
01116
01117 if (bi->get_kira_diag()->tree
01118 && bi->get_kira_diag()->tree_level > 1) {
01119 cerr << "\nadjust_low_level_node: "
01120 << "normal top level combine at time "
01121 << bi->get_time() << endl;
01122
01123 }
01124
01125
01126
01127
01128 combine_top_level_nodes(sister->get_top_level_node(),
01129 bi->get_top_level_node(), full_dump);
01130 status = 2;
01131
01132 } else {
01133
01134 if (bi->get_kira_diag()->tree
01135 && bi->get_kira_diag()->tree_level > 1) {
01136 cerr << "adjust_low_level_node:"
01137 << " top level combine with two top level nodes at time "
01138 << bi->get_time() << endl;
01139
01140 }
01141
01142 hdyn* t = bi->get_top_level_node();
01143 hdyn* od = t->get_oldest_daughter();
01144
01145 if (!od)
01146 status = 0;
01147 else {
01148
01149 if (od->get_slow()) {
01150
01151 if (!od->get_slow()->get_stop()) {
01152 cerr << "adjust_low_level_node: scheduling end "
01153 << "of slow motion for " << bi->format_label()
01154 << " at time " << bi->get_system_time()
01155 << endl;
01156 od->get_slow()->set_stop();
01157 }
01158 status = 0;
01159
01160 } else {
01161
01162
01163
01164 split_top_level_node(t, full_dump);
01165 status = 3;
01166
01167 }
01168 }
01169 }
01170
01171 } else if (sister != NULL)
01172
01173 combine_low_level_nodes(bi, sister, full_dump);
01174
01175 else
01176
01177 status = 0;
01178
01179 return status;
01180 }
01181
01182
01183 local inline bool check_binary_params(hdyn *b)
01184 {
01185 if (b->is_low_level_node()) {
01186
01187 hdyn *od = b->get_oldest_daughter();
01188
01189 if (od
01190 && od->get_perturbation_squared() > 1) {
01191
01192
01193 bool sync = false;
01194 int reason = 0;
01195
01196 if (od->get_timestep()
01197 > 128*b->get_timestep())
01198
01199 sync = true;
01200
01201 else if (b->distance_to_sister_squared()
01202 < od->distance_to_sister_squared()
01203 && od->get_timestep()
01204 > 4*b->get_timestep()) {
01205
01206 sync = true;
01207 reason = 1;
01208
01209 }
01210
01211
01212
01213
01214
01215 if (od->get_time() == b->get_time()) sync = false;
01216
01217 if (sync) {
01218
01219 od->synchronize_node();
01220 od->set_timestep(b->get_timestep());
01221
01222 if (b->get_kira_diag()->tree
01223 && b->get_kira_diag()->tree_level > reason)
01224 cerr << "check_binary_params: synchronizing ("
01225 << reason << ") "
01226 << b->format_label() << " components at time "
01227 << b->get_system_time() << endl;
01228
01229 return true;
01230 }
01231 }
01232 }
01233
01234 return false;
01235 }
01236
01237 local void print_tree_structure(hdyn *bb)
01238 {
01239 hdyn *b = bb->get_top_level_node();
01240 hdyn *od = b->get_oldest_daughter();
01241
01242 if (od) {
01243 hdyn *yd = od->get_younger_sister();
01244
01245 cerr << endl << "tree structure for " << b->format_label()
01246 << " at time " << b->get_system_time() << endl;
01247 cerr << "output triggered by " << bb->format_label() << endl;
01248
01249
01250
01251 cerr << "daughters are " << od->format_label() << " and ";
01252 cerr << yd->format_label();
01253 cerr << ", separation = " << abs(od->get_pos()-yd->get_pos()) << endl;
01254 cerr << "daughter neighbors are " << od->get_nn()->format_label()
01255 << " and ";
01256 cerr << yd->get_nn()->format_label() << endl;
01257
01258
01259
01260 for_all_daughters(hdyn, b, d) {
01261 hdyn *od1 = d->get_oldest_daughter();
01262 if (od1) {
01263 cerr << " daughters of " << d->format_label();
01264 hdyn *od2 = od1->get_younger_sister();
01265 cerr << " (separation = "
01266 << abs(od1->get_pos()-od2->get_pos()) << "):" << endl;
01267 hdyn *s = d->get_binary_sister();
01268 for_all_daughters(hdyn, d, dd) {
01269 if (s->is_parent()) {
01270 for_all_daughters(hdyn, s, ss) {
01271 cerr << " distance from "
01272 << dd->format_label();
01273 cerr << " to " << ss->format_label() << " is ";
01274 cerr << abs(d->get_pos()+dd->get_pos()
01275 -s->get_pos()-ss->get_pos())
01276 << endl;
01277 }
01278 } else {
01279 cerr << " distance from " << dd->format_label();
01280 cerr << " to " << s->format_label() << " is ";
01281 cerr << abs(d->get_pos()+dd->get_pos()-s->get_pos())
01282 << endl;
01283 }
01284 }
01285 }
01286 }
01287 }
01288 }
01289
01290 int hdyn::adjust_tree_structure(int full_dump)
01291 {
01292 int status = 0;
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 hdyn *br = get_root();
01309 if (is_top_level_node()) {
01310
01311 bool cm = false;
01312 if (oldest_daughter) cm = true;
01313
01314 if (nn == NULL) {
01315 pretty_print_node(cerr); cerr << " nn is NULL " << endl;
01316 return 0;
01317 }
01318
01319 hdyn *nn_top = nn->get_top_level_node();
01320
01321 if (too_close(this, nn_top, d_min_sq)) {
01322
01323 if (number_of_daughter_nodes_exceeds(parent, 2)) {
01324
01325 predict_loworder_all(get_root(), system_time);
01326
01327
01328
01329
01330
01331
01332
01333
01334 combine_top_level_nodes(nn_top, this, full_dump);
01335
01336
01337
01338
01339
01340 status = 2;
01341
01342 } else {
01343
01344 status = 0;
01345 }
01346
01347 } else if (too_big(this, d_min_sq * lag_factor)) {
01348
01349
01350
01351 predict_loworder_all(get_root(), system_time);
01352
01353
01354
01355
01356
01357
01358 split_top_level_node(this, full_dump);
01359
01360
01361
01362 status = 3;
01363
01364 } else {
01365
01366 status = 0;
01367 }
01368
01369 } else {
01370
01371 if (kep == NULL) {
01372
01373 hdyn *s = get_binary_sister();
01374 hdyn *old_top_level_node = get_top_level_node();
01375
01376 status = adjust_low_level_node(this, full_dump);
01377 if (!status) status = adjust_low_level_node(s, full_dump);
01378
01379 if (status) {
01380
01381 if (status > 1) status += 2;
01382 if (old_top_level_node != get_top_level_node())
01383 get_top_level_node()->zero_perturber_list();
01384
01385 } else {
01386
01387
01388
01389
01390
01391
01392
01393 if (check_binary_params(this) || check_binary_params(s))
01394 status = 6;
01395 }
01396
01397 #if 0
01398 if (system_time > 2295.905
01399 && node_contains(get_top_level_node(), "9530"))
01400 print_tree_structure(this);
01401 #endif
01402
01403 } else {
01404
01405 status = 0;
01406 }
01407 }
01408
01409 return status;
01410 }