00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "worldline.h"
00031 #include "inline.h"
00032
00033 #define NEW 1
00034
00035 #ifndef TOOLBOX
00036
00037
00038 #include "print_local.C"
00039
00040
00041
00042
00043
00044 #include "print_local2.C"
00045
00046
00047
00048 #include "attach_new_node.C"
00049
00050
00051
00052 #include "update_node.C"
00053
00054
00055 #if 0
00056 local void dealloc_tree(pdyn *b,
00057 bool delete_b = true)
00058 {
00059
00060
00061
00062 pdyn* d = b->get_oldest_daughter();
00063 while (d) {
00064 pdyn* tmp = d->get_younger_sister();
00065 dealloc_tree(d);
00066 d = tmp;
00067 }
00068 if (delete_b) dealloc_pdyn(b);
00069 }
00070 #endif
00071
00072 local INLINE void clean_up_subtree(worldbundle *wb, pdyn *old, bool debug)
00073 {
00074 if (old) {
00075 old = old->get_top_level_node();
00076
00077
00078 if (debug)
00079 cerr << "cleanup below " << old->format_label() << endl;
00080
00081
00082
00083
00084 int ndel = 0;
00085
00086 for_all_nodes(pdyn, old, o) {
00087
00088 if (debug)
00089 cerr << "deleting " << o->format_label() << endl;
00090 ndel++;
00091
00092 int wi = o->get_worldline_index();
00093
00094 if (wi <= 0)
00095 cerr << "clean_up_subtree: error: "
00096 << "deleting node with no worldline index." << endl;
00097 else {
00098 wb->get_bundle()[wi]->clear_tree_node();
00099 wb->get_bundle()[wi]->set_t_curr(-VERY_LARGE_NUMBER);
00100 }
00101 }
00102
00103 detach_node_from_general_tree(*old);
00104
00105
00106
00107
00108 rmtree(old);
00109
00110
00111
00112 if (debug)
00113 cerr << "deleted " << ndel << " nodes" << endl;
00114 }
00115 }
00116
00117 local INLINE void update_interpolated_tree(worldbundle *wb,
00118 worldline *w, segment *s,
00119 pdyn *root, real t, real t_int,
00120 bool vel, bool debug)
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 bool rebuild = (t_int < s->get_t_start() || t_int > s->get_t_end()
00146 || w->get_current_segment() != s);
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 tdyn *bn = s->get_first_event();
00158 tdyn *top = bn;
00159
00160 while (top->get_parent()
00161 && unique_id(top->get_parent()) > 0)
00162 top = top->get_parent();
00163
00164 if (debug) {
00165 cerr << "s = " << s << endl
00166 << "first event = " << bn << " "
00167 << bn->format_label() << " "
00168 << bn->get_time() << endl;
00169
00170 print_details(wb, bn, t);
00171
00172 PRC(top); PRL(top->format_label());
00173
00174 }
00175
00176
00177
00178
00179
00180
00181 for_all_nodes(tdyn, top, bb) {
00182
00183
00184
00185 worldline *ww;
00186
00187 if (bb == bn)
00188 ww = w;
00189 else {
00190 ww = wb->find_worldline(bb);
00191 if (!ww)
00192 cerr << "update_interpolated_tree: error:"
00193 << "can't find worldline of subtree member."
00194 << endl;
00195 }
00196
00197 if (ww) {
00198
00199
00200
00201 if (rebuild) {
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 if (bb == top || !bb->get_elder_sister()) {
00215
00216
00217
00218
00219 clean_up_subtree(wb, ww->get_tree_node(), debug);
00220 attach_new_node(wb, ww, root, top, bb, debug);
00221
00222 if (debug)
00223 cerr << "attached " << bb->format_label()
00224 << " at time " << t << endl;
00225
00226 if (bb != top) {
00227
00228
00229
00230 tdyn *bbsis = bb->get_younger_sister();
00231 worldline *wwsis = wb->find_worldline(bbsis);
00232
00233 clean_up_subtree(wb, wwsis->get_tree_node(), debug);
00234 attach_new_node(wb, wwsis, root, top, bbsis, debug);
00235
00236 if (debug)
00237 cerr << "attached " << bbsis->format_label()
00238 << " at time " << t << endl;
00239 }
00240 }
00241 }
00242
00243
00244
00245
00246 if (ww->get_tree_node())
00247 update_node(wb, ww, t, bb, top, vel, debug);
00248 else {
00249 cerr << "update_interpolated_tree: no tree_node"
00250 << " for " << bb->format_label() << " at time " << t
00251 << " t_int = " << t_int
00252 << endl;
00253 PRL(rebuild);
00254 }
00255 }
00256 }
00257
00258 w->set_current_segment(s);
00259
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 static int n_center = 2;
00269 static int which_center = 0;
00270 static int which_std = 0;
00271
00272 static char *center_id[] = {"standard-center", "bound-center"};
00273 static char *std_center_id[] = {"density-center", "modified-com"};
00274
00275 int get_n_center() {return n_center;}
00276 int get_center() {return which_center;}
00277
00278 char *get_center_id(int center_number)
00279 {
00280
00281
00282
00283 if (center_number < 0)
00284 return get_center_id(which_center);
00285 else if (center_number >= n_center)
00286 return NULL;
00287 else if (center_number == 0) {
00288 if (which_std == 1)
00289 return std_center_id[0];
00290 else if (which_std == 2)
00291 return std_center_id[1];
00292 else
00293 return center_id[center_number];
00294 } else
00295 return center_id[center_number];
00296 }
00297
00298 local bool scan_root_nodes(worldbundleptr wh[],
00299 int nh,
00300 bool verbose,
00301 char *pos_id,
00302 char *vel_id,
00303 bool check)
00304 {
00305 for (int ih = 0; ih < nh; ih++) {
00306
00307 worldbundle *wb = wh[ih];
00308 worldline *w = wb->get_bundle()[0];
00309
00310
00311
00312
00313 segment *s = w->get_first_segment();
00314 int is = 0;
00315
00316 while (s) {
00317
00318 tdyn *b = s->get_first_event();
00319 int ie = 0;
00320
00321 while (b) {
00322
00323 if (check) {
00324
00325
00326
00327 if (!find_qmatch(b->get_dyn_story(), pos_id)
00328 || !find_qmatch(b->get_dyn_story(), vel_id))
00329 return false;
00330 } else {
00331
00332
00333
00334
00335 b->set_pos(getvq(b->get_dyn_story(), pos_id));
00336 b->set_vel(getvq(b->get_dyn_story(), vel_id));
00337 b->clear_acc();
00338 b->clear_jerk();
00339
00340 if (which_center != 0)
00341 which_std = 0;
00342 else if (which_std == 0)
00343 which_std = getiq(b->get_dyn_story(), "center_type");
00344 }
00345
00346 b = b->get_next();
00347 ie++;
00348 }
00349
00350 if (verbose & ie == 1)
00351 cerr << "warning: set_next_center: segment "
00352 << is << "is a single event" << endl;
00353
00354 s = s->get_next();
00355 is++;
00356 }
00357
00358 if (verbose & is != 1)
00359 cerr << "warning: set_next_center: root worldline "
00360 << ih << "contains more than one segment" << endl;
00361 }
00362
00363 return true;
00364 }
00365
00366 char *set_center(worldbundleptr wh[],
00367 int nh,
00368 int new_center,
00369 bool verbose)
00370 {
00371
00372
00373
00374 if (new_center < 0 || new_center >= n_center) {
00375 if (verbose)
00376 cerr << "set_next_center: invalid center number" << endl;
00377 return NULL;
00378 }
00379
00380 int old_center = which_center;
00381 which_center = new_center;
00382
00383 char center_pos_id[128], center_vel_id[128];
00384 if (which_center == 0) {
00385 strcpy(center_pos_id, "center_pos");
00386 strcpy(center_vel_id, "center_vel");
00387 } else if (which_center == 1) {
00388 strcpy(center_pos_id, "bound_center_pos");
00389 strcpy(center_vel_id, "bound_center_vel");
00390 }
00391
00392
00393
00394
00395 bool change = scan_root_nodes(wh, nh, verbose,
00396 center_pos_id, center_vel_id, true);
00397 if (change) {
00398 scan_root_nodes(wh, nh, false, center_pos_id, center_vel_id, false);
00399 if (verbose)
00400 cerr << "set_next_center: new center is "
00401 << get_center_id(which_center) << endl;
00402 } else {
00403 if (verbose)
00404 cerr << "set_next_center: unable to change center to "
00405 << get_center_id(which_center) << endl;
00406 which_center = old_center;
00407 }
00408
00409 return get_center_id(which_center);
00410 }
00411
00412 static vector center_pos = 0;
00413 vector get_center_pos() {return center_pos;}
00414
00415 static vector center_vel = 0;
00416 vector get_center_vel() {return center_vel;}
00417
00418
00419
00420 bool is_member(worldbundle *wb, pdyn *p)
00421 {
00422
00423
00424
00425 for_all_leaves(pdyn, p, pp) {
00426 worldline *w = wb->find_worldline(pp);
00427 if (w && w->is_member(p->get_system_time())) return true;
00428 }
00429 return false;
00430 }
00431
00432 local void interpolate_tree(worldbundle *wb, real t, real t_int,
00433 pdynptr& root, bool vel, bool debug)
00434 {
00435
00436
00437
00438
00439
00440
00441 worldlineptr *bundle = wb->get_bundle();
00442
00443
00444
00445
00446
00447
00448
00449 if (!root) {
00450 root = new pdyn(NULL, NULL, false);
00451
00452 root->set_name("root");
00453 root->set_worldline_index(wb->find_index(root));
00454 }
00455
00456 root->set_system_time(t);
00457
00458 root->set_pos(0);
00459 root->set_vel(0);
00460
00461
00462
00463
00464
00465 root->set_root(root);
00466 bundle[0]->set_tree_node(root);
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 for (int i = 0; i < wb->get_nw(); i++) {
00481
00482 worldline *w = bundle[i];
00483
00484 if (w->get_t_curr() != t) {
00485
00486
00487
00488 unique_id_t id = w->get_id();
00489
00490 if (i == 0 || id_n_clump(id) == 1) {
00491
00492
00493
00494 if (debug) {
00495 cerr.precision(16);
00496 cerr << endl
00497 << "updating worldline " << i << ", id = "
00498 << w->get_id() << endl;
00499 }
00500
00501
00502
00503
00504
00505 segment *s;
00506 #if 1
00507 s = w->get_current_segment();
00508 if (!s || s->get_t_start() > t)
00509 #endif
00510 s = w->get_first_segment();
00511
00512 while (s && s->get_t_end() < t) s = s->get_next();
00513
00514 if (debug) {
00515 PRC(w); cerr << "segment "; PRC(s);
00516 print_events(s, t);
00517 }
00518
00519
00520
00521
00522
00523 if (s) {
00524 if (i == 0) {
00525
00526
00527
00528 tdyn *b = s->get_first_event();
00529 update_node(wb, w, t, b, b, vel, debug);
00530
00531 center_pos = root->get_pos();
00532 center_vel = root->get_vel();
00533
00534
00535
00536
00537 } else
00538
00539
00540
00541 update_interpolated_tree(wb, w, s,
00542 root, t, t_int,
00543 vel, debug);
00544 } else if (debug)
00545 cerr << "NULL segment for leaf..." << endl;
00546 }
00547 }
00548 }
00549 }
00550
00551 #define EPS 1.e-12
00552 #define EPS1 1.e-12 // kludge -- should be 0
00553
00554 local bool trim(worldbundle *wb, real& t)
00555 {
00556
00557
00558
00559
00560
00561
00562 real dt = t - wb->get_t_max();
00563 if (dt > EPS)
00564 return false;
00565 else if (dt > -EPS1)
00566 t = wb->get_t_max() - EPS1;
00567
00568 dt = t - wb->get_t_min();
00569 if (dt < -EPS)
00570 return false;
00571 else if (dt < EPS1)
00572 t = wb->get_t_min() + EPS1;
00573
00574 return true;
00575 }
00576
00577 pdyn *create_interpolated_tree2(worldbundle *wb, real t,
00578 bool vel)
00579 {
00580 static worldbundle *wb_last = NULL;
00581 static real t_int = -VERY_LARGE_NUMBER;
00582
00583 static pdyn *root = NULL;
00584
00585
00586 if (!wb_last) set_kepler_fast_flag();
00587
00588
00589
00590 if (!trim(wb, t)) return NULL;
00591
00592 if (wb != wb_last) {
00593 if (wb->get_pdyn_root()) {
00594 root = wb->get_pdyn_root();
00595 t_int = wb->get_t_int();
00596 } else {
00597 root = NULL;
00598 t_int = -VERY_LARGE_NUMBER;
00599 }
00600 }
00601
00602 if (t == t_int && root) return root;
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 bool debug = false;
00613
00614
00615
00616 interpolate_tree(wb, t, t_int, root, vel, debug);
00617
00618 wb->set_t_int(t);
00619 if (wb != wb_last) wb->set_pdyn_root(root);
00620
00621 wb_last = wb;
00622 t_int = t;
00623
00624 return root;
00625 }
00626
00627 void preload_pdyn(worldbundleptr wh[], int nh,
00628 bool verbose)
00629 {
00630 for (int i = 0; i < nh; i++) {
00631 create_interpolated_tree2(wh[i], wh[i]->get_t_min());
00632 if (verbose)
00633 cerr << "allocated memory for worldbundle " << i
00634 << ", t_min = " << wh[i]->get_t_min() << endl;
00635 }
00636 }
00637
00638 #else
00639
00640 main(int argc, char *argv[])
00641 {
00642
00643
00644 if (argc <= 2) exit(1);
00645
00646 ifstream s(argv[1]);
00647 if (!s) exit(2);
00648
00649 real t = atof(argv[2]);
00650
00651 worldbundle *wb = read_bundle(s);
00652
00653 pdyn *root = create_interpolated_tree2(wb, t, true);
00654 put_node(cout, *root, false);
00655
00656 #if 0
00657
00658
00659 wb->print();
00660
00661 cerr << wb->get_nw() << " worldlines, "
00662 << count_segments(wb) << " segments, "
00663 << count_events(wb) << " events, t = "
00664 << wb->get_t_min() << " to " << wb->get_t_max()
00665 << endl;
00666 #endif
00667
00668 #if 0
00669
00670
00671 char name[128];
00672 real t;
00673 while (1) {
00674 cerr << endl << "time, name: "; cin >> t >> name;
00675 if (cin.eof()) {
00676 cerr << endl;
00677 break;
00678 }
00679 int loc = wb->find_index(name);
00680 if (loc >= 0) {
00681 PRC(unique_id(name)); PRL(loc);
00682 worldline *w = wb->get_bundle()[loc];
00683 segment *s = w->get_first_segment();
00684 while (s && s->get_t_start() > t) s = s->get_next();
00685 print_event(w, s->get_first_event(), t);
00686 } else
00687 cerr << "not found" << endl;
00688 }
00689 #endif
00690
00691 #if 0
00692
00693
00694
00695 real dt;
00696 char name[128];
00697 while (1) {
00698
00699 cerr << endl << "dt, name: " << flush; cin >> dt >> name;
00700 if (cin.eof()) {
00701 cerr << endl;
00702 break;
00703 }
00704
00705 wb->print_worldline(name, dt);
00706 }
00707 #endif
00708
00709 #if 0
00710 real t = 0.8;
00711 while (t < 0.85) {
00712 pdyn *root = create_interpolated_tree2(wb, t);
00713 put_node(cout, *root, false);
00714 t += 0.01;
00715 }
00716 #endif
00717
00718 }
00719
00720 #endif