00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include "worldline.h"
00064 #include "inline.h"
00065 #include <ctype.h>
00066
00067 #define NEW 0
00068
00069 #ifndef TOOLBOX
00070
00071
00072
00073 #ifndef NEW_UNIQUE_ID_T
00074
00075
00076
00077
00078
00079
00080 # define ID_FAC 0.000001 // easier to read
00081
00082
00083
00084
00085 #else
00086
00087
00088
00089 # define ID_SHIFT 20
00090
00091 #endif
00092
00093
00094
00095 unique_id_t unique_id(int index)
00096 {
00097 #ifndef NEW_UNIQUE_ID_T
00098 return (unique_id_t)(1 + ID_FAC*index);
00099 #else
00100 return (unique_id_t)((1<<ID_SHIFT) + index);
00101 #endif
00102 }
00103
00104 unique_id_t unique_id(char *name)
00105 {
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 int index = atoi(name);
00119 if (index > 0) return unique_id(index);
00120
00121
00122
00123
00124
00125
00126 unique_id_t id = 0;
00127 int n = 0;
00128
00129 #if 0
00130
00131
00132
00133
00134
00135
00136
00137
00138 char tname[1024];
00139 strcpy(tname, name);
00140 int l = strlen(tname);
00141
00142 real fac = 1;
00143 int num = 0;
00144
00145 for (int i = 0; i < l; i++) {
00146 if (tname[i] >= '0' && tname[i] <= '9') {
00147 if (num == 0) {
00148 fac *= ID_FAC;
00149 num = i+1;
00150 }
00151 } else {
00152 if (num > 0) {
00153 tname[i] = '\0';
00154 id += fac*atoi(tname+num-1);
00155 n++;
00156 num = 0;
00157 }
00158 }
00159 }
00160
00161 #else
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 char *c = name, *end;
00172 bool num = false;
00173
00174 while (1) {
00175
00176
00177
00178 while (*c && !isdigit(*c)) c++;
00179
00180 if (*c) {
00181
00182
00183
00184
00185
00186 long int i = strtol(c, &end, 10);
00187 n++;
00188
00189 if (n == 1) {
00190
00191 #ifndef NEW_UNIQUE_ID_T
00192 id = (unique_id_t)(ID_FAC*i);
00193 #else
00194 id = (unique_id_t)(i);
00195 #endif
00196 }
00197
00198 c = end;
00199
00200 } else
00201 break;
00202 }
00203
00204 #endif
00205
00206
00207
00208
00209 #ifndef NEW_UNIQUE_ID_T
00210 id += n;
00211 #else
00212 id += (n<<ID_SHIFT);
00213 #endif
00214
00215 return id;
00216 }
00217
00218 unique_id_t unique_id(node *b)
00219 {
00220
00221
00222
00223
00224
00225
00226
00227
00228 if (b->get_index() > 0)
00229 return unique_id(b->get_index());
00230
00231 else if (b->get_name())
00232 return unique_id(b->format_label());
00233
00234 else
00235 return -1;
00236 }
00237
00238 void print_id(void *id, char *s = NULL, int offset = 0)
00239 {
00240 real *r = (real *)id;
00241 unsigned long long *u = (unsigned long long *)id;
00242
00243 real rr = *r;
00244 unsigned long long uu = *u;
00245
00246 if (offset > 0) PRI(offset);
00247 if (s)
00248 cerr << s << ": ";
00249 else
00250 cerr << " ";
00251
00252 fprintf(stderr, "%.16lf = %qu = %qx\n", rr, uu, uu);
00253 }
00254
00255 void worldline::dump(int offset,
00256 real t1,
00257 real t2)
00258 {
00259
00260
00261 PRI(offset+4); PRC(start_esc_flag); PRC(end_esc_flag); PRL(t_esc);
00262
00263 segment *s = get_first_segment();
00264 int is = 0;
00265 while (s) {
00266 real t_start = s->get_t_start();
00267 real t_end = s->get_t_end();
00268 if (t_start <= t2 && t_end >= t1) {
00269 PRI(offset+4); cerr << "segment " << is << " (" << s << "): ";
00270 PRC(t_start); PRL(t_end);
00271 print_id(&id, "id", offset+8);
00272 }
00273 tdyn *b = s->get_first_event();
00274 int ie = 0;
00275 while (b) {
00276 real t = b->get_time();
00277 if (t >= t1 && t <= t2) {
00278 PRI(offset+8);
00279 cerr << "event " << ie << ": name = "
00280 << b->format_label() << ", ";
00281 PRL(t);
00282 }
00283 b = b->get_next();
00284 ie++;
00285 }
00286 if (t_start <= t2 && t_end >= t1) {
00287 if (ie == 1) {
00288 PRI(offset+8); cerr << "*** single event ***" << endl;
00289 }
00290 }
00291 s = s->get_next();
00292 is++;
00293 }
00294 }
00295
00296 local void check_print_worldline_header(bool& print, int i)
00297 {
00298 cerr << "worldline " << i << ":" << endl;
00299 print = false;
00300 }
00301
00302 void worldline::check(int i)
00303 {
00304
00305
00306 bool print = true;
00307
00308 segment *s = get_first_segment();
00309 int is = 0;
00310 while (s) {
00311 tdyn *b0 = s->get_first_event();
00312 tdyn *b = b0;
00313 int ie = 0;
00314 while (b) {
00315 real t = b->get_time();
00316 if (b != b0) {
00317 tdyn *p = b->get_prev();
00318 if (!p) {
00319 if (print) check_print_worldline_header(print, i);
00320 cerr << " segment " << is << ", event "
00321 << ie << " has prev = NULL" << endl;
00322 } else if (p->get_next() != b) {
00323 if (print) check_print_worldline_header(print, i);
00324 cerr << " segment " << is << ", event "
00325 << ie << " has prev->next != this" << endl;
00326 }
00327 }
00328 b = b->get_next();
00329 ie++;
00330 }
00331 if (ie == 1) {
00332 if (print) check_print_worldline_header(print, i);
00333 cerr << " *** single event in segment " << is << " ***" << endl;
00334 }
00335
00336 s = s->get_next();
00337 is++;
00338 }
00339 }
00340
00341 void segment::print(char *label)
00342 {
00343 if (label == NULL) label = " ";
00344 cerr << label << "name " << first_event->format_label()
00345 << ", id = " << id
00346 << ", t_start = " << t_start
00347 << ", t_end = " << t_end
00348 << endl;
00349 }
00350
00351
00352
00353 local int wlcompare(const void *a, const void *b)
00354
00355 {
00356 worldlineptr wa = *((worldlineptr*)a);
00357 worldlineptr wb = *((worldlineptr*)b);
00358
00359 int result = 0;
00360
00361
00362 if (wa->get_id() < wb->get_id())
00363 result = -1;
00364 else if (wa->get_id() > wb->get_id())
00365 result = 1;
00366
00367
00368 return result;
00369 }
00370
00371 worldbundle::worldbundle(tdyn *b)
00372 {
00373
00374
00375 nw_max = 0;
00376 for_all_nodes(tdyn, b, bb) nw_max++;
00377
00378 nw_max *= 2;
00379
00380 bundle = new worldlineptr[nw_max];
00381 nw = 0;
00382
00383 t_min = VERY_LARGE_NUMBER;
00384 t_max = -VERY_LARGE_NUMBER;
00385
00386 t_int = -VERY_LARGE_NUMBER;
00387 root = NULL;
00388
00389
00390
00391 for_all_nodes(tdyn, b, bb) {
00392
00393
00394
00395 bb->clear_jerk();
00396
00397 real t = bb->get_time();
00398 worldline *w = new worldline(bb);
00399
00400 bundle[nw++] = w;
00401
00402 t_min = min(t_min, t);
00403 t_max = max(t_max, t);
00404 }
00405
00406
00407
00408 qsort((void*)bundle, (size_t)nw, sizeof(worldlineptr), wlcompare);
00409
00410
00411
00412
00413
00414
00415 }
00416
00417 void worldbundle::print()
00418 {
00419
00420
00421 for (int i = 0; i < nw; i++) {
00422
00423 worldline *w = bundle[i];
00424 segment *s = w->get_first_segment();
00425 int segnum = 0;
00426
00427 cerr << i << " (" << s->get_first_event()->format_label();
00428 int p = cerr.precision(HIGH_PRECISION);
00429 cerr << ", id = " << w->get_id() << ")";
00430 cerr.precision(p);
00431 cerr << " t_start = " << w->get_t_start()
00432 << ", t_end = " << w->get_t_end()
00433 << endl;
00434
00435 while (s) {
00436
00437 segnum++;
00438 int nn = 1;
00439
00440 tdyn *b = s->get_first_event();
00441 while (b->get_next()) {
00442 b = b->get_next();
00443 nn++;
00444 }
00445
00446 cerr << " segment " << segnum << ": "
00447 << s->get_t_start() << " (" << nn << ") " << s->get_t_end()
00448 << endl;
00449
00450 s = s->get_next();
00451 }
00452 }
00453 }
00454
00455 void worldbundle::dump(int offset)
00456 {
00457 for (int i = 0; i < get_nw(); i++) {
00458 PRI(offset); cerr << "worldline " << i << ":" << endl;
00459 get_worldline(i)->dump(offset);
00460 }
00461 }
00462
00463 void worldbundle::check()
00464 {
00465 cerr << "checking worldbundle " << this << endl;
00466 for (int i = 0; i < get_nw(); i++)
00467 get_worldline(i)->check(i);
00468 }
00469
00470
00471
00472 int worldbundle::find_index(unique_id_t id)
00473 {
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 int loc;
00486
00487 if (nw <= 0 || id < bundle[0]->get_id()) {
00488 PRC(id); PRL(bundle[0]->get_id());
00489 loc = -1;
00490 }
00491
00492 else if (id > bundle[nw-1]->get_id())
00493 loc = -nw-1;
00494
00495 else {
00496
00497 int low = 0, high = nw-1;
00498 loc = (low+high)/2;
00499
00500 if (bundle[low]->get_id() == id)
00501 loc = low;
00502
00503 else if (bundle[high]->get_id() == id)
00504 loc = high;
00505
00506 else if (bundle[loc]->get_id() != id) {
00507
00508 bool found = false;
00509
00510 while (low < high-1) {
00511
00512 if (bundle[loc]->get_id() < id)
00513 low = loc;
00514 else if (bundle[loc]->get_id() > id)
00515 high = loc;
00516 else {
00517 found = true;
00518 break;
00519 }
00520
00521 loc = (low+high)/2;
00522 }
00523
00524 if (!found) loc = -high - 1;
00525 }
00526 }
00527
00528 return loc;
00529 }
00530
00531 int worldbundle::find_index(char *name) {return find_index(unique_id(name));}
00532 int worldbundle::find_index(_pdyn_ *b) {return find_index(unique_id(b));}
00533
00534 worldline *worldbundle::find_worldline(unique_id_t id)
00535 {
00536 int i = find_index(id);
00537 if (i >= 0 && i < nw)
00538 return bundle[i];
00539 else
00540 return NULL;
00541 }
00542
00543 worldline *worldbundle::find_worldline(char *name)
00544 {return find_worldline(unique_id(name));}
00545
00546 worldline *worldbundle::find_worldline(_pdyn_ *b)
00547 {return find_worldline(unique_id(b));}
00548
00549
00550
00551
00552
00553 void worldbundle::attach(tdyn *bn,
00554 int verbose)
00555 {
00556
00557
00558 if (bn) {
00559
00560 for_all_nodes(tdyn, bn, b) {
00561
00562
00563
00564 b->clear_jerk();
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 unique_id_t id = unique_id(b);
00587
00588 if (id >= 0) {
00589
00590 real t = b->get_time();
00591 int loc = find_index(id);
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 if (loc >= 0) {
00604
00605
00606
00607 worldline *w = bundle[loc];
00608 segment *s = w->get_last_segment();
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 if (s->get_last_event()->is_defunct()) {
00619
00620 if (verbose)
00621 cerr << "starting new segment for "
00622 << b->format_label()
00623 << " (id = " << id
00624 << ") at t = " << t
00625 << endl;
00626
00627
00628
00629 s = new segment(b);
00630 w->add_segment(s, true);
00631
00632
00633 if (verbose)
00634 cerr << "new segment = " << s << endl;
00635
00636 } else {
00637
00638
00639
00640 s->add_event(b, true);
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 }
00657
00658
00659
00660 w->set_t_end(t);
00661
00662 } else {
00663
00664
00665
00666
00667
00668 if (nw >= nw_max) {
00669
00670
00671
00672
00673 nw_max *= 5;
00674 nw_max /= 4;
00675
00676 cerr << "extending bundle array for worldbundle "
00677 << this << ": nw_max = "
00678 << nw_max << endl;
00679
00680 worldlineptr *tmp = new worldlineptr[nw_max];
00681 for (int i = 0; i < nw; i++)
00682 tmp[i] = bundle[i];
00683 delete [] bundle;
00684 bundle = tmp;
00685 }
00686
00687
00688
00689 loc = -loc - 1;
00690
00691 for (int i = nw-1; i >= loc; i--)
00692 bundle[i+1] = bundle[i];
00693
00694 bundle[loc] = new worldline(b);
00695 nw++;
00696
00697 if (verbose)
00698 cerr << "adding " << b->format_label()
00699 << " (id = " << id
00700 << ") at t = " << b->get_time()
00701 << endl;
00702 }
00703
00704 t_max = max(t_max, t);
00705 }
00706 }
00707 }
00708 }
00709
00710
00711
00712 static real physical_mass = 0;
00713
00714 real mass_scale_factor()
00715 {
00716 return physical_mass;
00717 }
00718
00719 local void check_final_escapers(worldbundle *wb, tdyn *b)
00720 {
00721 for_all_nodes(tdyn, b, bb) {
00722 worldline *w = NULL;
00723 if (bb->get_prev()) {
00724 bb->set_prev(NULL);
00725 w = wb->find_worldline(bb);
00726 if (w) w->set_end_esc_flag(1);
00727 }
00728 if (bb->get_next()) {
00729 real *t_esc = (real*)bb->get_next();
00730 bb->set_next(NULL);
00731 if (!w) w = wb->find_worldline(bb);
00732 if (w) w->set_t_esc(*t_esc);
00733 delete t_esc;
00734 }
00735 }
00736 }
00737
00738
00739
00740
00741
00742
00743
00744 worldbundle *read_bundle(istream &s,
00745 int verbose)
00746 {
00747
00748
00749
00750
00751
00752 tdyn *b = get_tdyn(s, NULL, NULL, false);
00753 if (!b || !streq(b->format_label(), "root")) return NULL;
00754
00755
00756
00757
00758
00759
00760 if (b->get_log_story())
00761 physical_mass = getrq(b->get_log_story(), "physical_initial_mass");
00762
00763
00764
00765
00766
00767
00768 worldbundle *wb = new worldbundle(b);
00769
00770 if (verbose)
00771 cerr << endl
00772 << "new worldbundle: created initial list, nw = "
00773 << wb->get_nw() << endl;
00774
00775
00776
00777
00778 while (b = get_tdyn(s, NULL, NULL, false)) {
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 bool stop = (b->get_oldest_daughter()
00789 && streq(b->format_label(), "root"));
00790 if (stop)
00791 check_final_escapers(wb, b);
00792
00793
00794
00795 wb->attach(b, verbose);
00796
00797
00798
00799 if (stop) {
00800 if (verbose)
00801 cerr << "break at t = " << b->get_time() << endl;
00802 break;
00803 }
00804 }
00805
00806 if (verbose) {
00807
00808 cerr << "after last input: nw = " << wb->get_nw()
00809 << endl;
00810
00811
00812
00813 for (int i = 0; i < wb->get_nw(); i++) {
00814 worldline *w = wb->get_bundle()[i];
00815
00816
00817
00818 int seg = 0, nseg = 0;
00819 segment *s = w->get_first_segment();
00820 tdyn *b = s->get_first_event();
00821 real t = s->get_t_start();
00822
00823 while (s) {
00824 nseg++;
00825 s = s->get_next();
00826 }
00827
00828 s = w->get_first_segment();
00829 int n_jump = 0;
00830
00831 while (s) {
00832
00833 if (s->get_t_start() >= s->get_t_end()) {
00834 int p = cerr.precision(HIGH_PRECISION);
00835 cerr << "worldline " << i << " (" << b->format_label()
00836 << "), id = " << w->get_id() << endl;
00837 cerr.precision(p);
00838 PRI(10); cerr << "zero-length segment at t = "
00839 << s->get_t_start()
00840 << "; segment " << seg << " of " << nseg
00841 << endl;
00842 }
00843
00844 if (s->get_t_start() > t) {
00845 n_jump++;
00846 if (verbose > 1) {
00847 int p = cerr.precision(HIGH_PRECISION);
00848 cerr << "worldline " << i << " (" << b->format_label()
00849 << "), id = " << w->get_id() << endl;
00850 cerr.precision(p);
00851 PRI(10); cerr << "jump from " << t
00852 << " to " << s->get_t_start()
00853 << " after segment " << seg
00854 << " of " << nseg
00855 << endl;
00856 }
00857 }
00858
00859 t = s->get_t_end();
00860 seg++;
00861 s = s->get_next();
00862 }
00863
00864 if (verbose == 1 && n_jump > 0) {
00865 cerr << "worldline " << i << " (" << b->format_label()
00866 << "), id = " << w->get_id()
00867 << " has " << n_jump << " jump";
00868 if (n_jump > 1) cerr << "s";
00869 cerr << endl;
00870 }
00871
00872
00873
00874 seg = 0;
00875 s = w->get_first_segment();
00876 while (s) {
00877
00878 b = s->get_first_event();
00879
00880 if (b->get_time() != s->get_t_start()) {
00881 int p = cerr.precision(HIGH_PRECISION);
00882 cerr << "worldline " << i << " (" << b->format_label()
00883 << "), id = " << w->get_id() << endl;
00884 cerr.precision(p);
00885 PRI(10); cerr << "t_start = " << s->get_t_start()
00886 << ", t = "
00887 << b->get_time() << " in segment " << seg
00888 << " of " << nseg << endl;
00889 }
00890
00891 while (b && b->get_next()) b = b->get_next();
00892
00893 if (b->get_time() != s->get_t_end()) {
00894 int p = cerr.precision(HIGH_PRECISION);
00895 cerr << "worldline " << i << " (" << b->format_label()
00896 << "), id = " << w->get_id() << endl;
00897 cerr.precision(p);
00898 PRI(10); cerr << "t_end = " << s->get_t_end() << ", t = "
00899 << b->get_time() << " in segment " << seg
00900 << " of " << nseg << endl;
00901 }
00902
00903 seg++;
00904 s = s->get_next();
00905 }
00906 }
00907 }
00908
00909 return wb;
00910 }
00911
00912 int count_segments(worldbundle *wb)
00913 {
00914 int ns = 0;
00915 for (int i = 0; i < wb->get_nw(); i++) {
00916 worldline *w = wb->get_worldline(i);
00917 segment *s = w->get_first_segment();
00918 while (s) {
00919 ns++;
00920 s = s->get_next();
00921 }
00922 }
00923 return ns;
00924 }
00925
00926 int count_events(worldbundle *wb)
00927 {
00928 int ne = 0;
00929 for (int i = 0; i < wb->get_nw(); i++) {
00930 worldline *w = wb->get_worldline(i);
00931 segment *s = w->get_first_segment();
00932 while (s) {
00933 tdyn *b = s->get_first_event();
00934 while (b) {
00935 ne++;
00936 b = b->get_next();
00937 }
00938 s = s->get_next();
00939 }
00940 }
00941 return ne;
00942 }
00943
00944
00945
00946
00947
00948 tdyn *find_event(worldline *w, tdyn *bn, real t)
00949 {
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 tdyn *b = bn;
00961
00962 if (w) {
00963
00964 tdyn *curr = w->get_current_event();
00965
00966 if (curr) {
00967
00968 real t_curr = curr->get_time();
00969 real t_bn = bn->get_time();
00970
00971
00972
00973 if (t_curr > t) {
00974
00975 if (t > 0.5*(t_bn + t_curr)) {
00976
00977
00978
00979 b = curr;
00980 #if 0
00981 if (b != bn && !b->get_prev()) {
00982 cerr << endl << "prev = NULL for node " << b << endl;
00983 PRC(b); PRL(bn);
00984 cerr << "worldline dump:" << endl;
00985 w->dump();
00986 cerr << "checking worldline..." << endl;
00987 w->check(-1);
00988 }
00989 #endif
00990
00991 tdyn *p;
00992 while (b && (p = b->get_prev()) && b->get_time() > t)
00993 b = p;
00994
00995 return b;
00996 }
00997
00998 } else {
00999
01000
01001
01002
01003
01004 tdyn *n = curr->get_next();
01005 if (!n || n->get_time() >= t) return curr;
01006
01007
01008
01009 b = n;
01010
01011 }
01012 }
01013 }
01014
01015
01016
01017
01018 tdyn *n;
01019 while (b && (n = b->get_next()) && n->get_time() < t)
01020 b = n;
01021
01022
01023
01024 return b;
01025 }
01026
01027 void print_event(worldline *w, tdyn *bn, real t)
01028 {
01029
01030
01031
01032 tdyn *b = find_event(w, bn, t);
01033
01034 if (b) {
01035 PRC(t); PRC(b->get_time()); PRL(b->get_next());
01036 if (b->get_next()) PRL(b->get_next()->get_time());
01037 }
01038 }
01039
01040
01041 #include "print_local.C"
01042
01043
01044 local inline bool check_and_initialize(tdyn *p,
01045 real tp,
01046 real t,
01047 vector& pos,
01048 bool inc,
01049 tdyn *bn)
01050 {
01051 if (tp < t) {
01052
01053 tdyn *n = p->get_next();
01054
01055 if (!n) {
01056
01057 cerr << "interpolate_pos: error 2: next node not found: ";
01058 PRC(p->format_label()); PRL(t);
01059 int pr = cerr.precision(HIGH_PRECISION);
01060 PRL(unique_id(p)); cerr.precision(pr);
01061 PRI(26); PRC(bn); PRL(bn->get_time());
01062 PRI(26); PRC(p); PRL(p->get_time());
01063 PRI(26); PRL(p->get_time()-t);
01064 if (bn) {
01065 PRI(26); PRL(bn->format_label());
01066 pr = cerr.precision(HIGH_PRECISION);
01067 PRL(unique_id(bn)); cerr.precision(pr);
01068 }
01069
01070
01071 if (inc)
01072 pos += p->get_pos();
01073 else
01074 pos = p->get_pos();
01075 return false;
01076
01077 } else if (n->get_time() < t) {
01078
01079 cerr << "interpolate_pos: error 3: specified time above range: ";
01080 PRC(p->format_label()); PRC(t); PRL(p->get_time());
01081
01082
01083 if (inc)
01084 pos += p->get_pos();
01085 else
01086 pos = p->get_pos();
01087 return false;
01088 }
01089
01090
01091
01092
01093
01094 if (p->get_jerk()[0] == 0) {
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 real dt = n->get_time() - tp;
01107 real dti = 1/dt;
01108
01109 if (streq(p->get_name(), "root")) {
01110
01111
01112
01113
01114 p->set_vel(dti*(n->get_pos() - p->get_pos()));
01115 p->set_acc(0);
01116 p->set_jerk(vector(VERY_SMALL_NUMBER, 0, 0));
01117
01118 } else {
01119
01120
01121
01122 p->set_acc((3*(n->get_pos()-p->get_pos())
01123 - dt*(2*p->get_vel()+n->get_vel()))*dti*dti);
01124 p->set_jerk((p->get_vel()+n->get_vel()
01125 - 2*dti*(n->get_pos()-p->get_pos()))*dti*dti);
01126 }
01127 }
01128 return true;
01129
01130 } else if (tp > t) {
01131
01132 cerr << "interpolate_pos: error 1: specified time below range: ";
01133 PRC(p->format_label()); PRC(t); PRL(p->get_time());
01134
01135 }
01136
01137
01138
01139 if (inc)
01140 pos += p->get_pos();
01141 else
01142 pos = p->get_pos();
01143
01144 return false;
01145 }
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159 vector interpolate_pos(tdyn *p, real t,
01160 tdyn *bn)
01161
01162 {
01163
01164
01165
01166
01167
01168 if (p->get_time() > t) {
01169 cerr << "interpolate_pos: error 1: specified time below range: ";
01170 PRC(p->format_label()); PRC(t); PRL(p->get_time());
01171
01172
01173 return p->get_pos();
01174 }
01175
01176
01177
01178 if (p->get_time() == t) return p->get_pos();
01179
01180 tdyn *n = p->get_next();
01181
01182 if (!n) {
01183 cerr << "interpolate_pos: error 2: next node not found: ";
01184 PRC(p->format_label()); PRL(t);
01185 int pr = cerr.precision(HIGH_PRECISION);
01186 PRL(unique_id(p)); cerr.precision(pr);
01187 PRI(26); PRC(bn); PRL(bn->get_time());
01188 PRI(26); PRC(p); PRL(p->get_time());
01189 PRI(26); PRL(p->get_time()-t);
01190 if (bn) {
01191 PRI(26); PRL(bn->format_label());
01192 pr = cerr.precision(HIGH_PRECISION);
01193 PRL(unique_id(bn)); cerr.precision(pr);
01194 }
01195
01196
01197 return p->get_pos();
01198 }
01199
01200 if (n->get_time() < t) {
01201 cerr << "interpolate_pos: error 3: specified time above range: ";
01202 PRC(p->format_label()); PRC(t); PRL(p->get_time());
01203
01204
01205 return p->get_pos();
01206 }
01207
01208
01209
01210
01211
01212
01213
01214 real tp = p->get_time();
01215 real dt = n->get_time() - tp;
01216
01217 if (dt > 0) {
01218
01219
01220
01221
01222
01223
01224 if (p->get_jerk()[0] == 0) {
01225
01226
01227
01228 real dti = 1/dt;
01229
01230 if (streq(p->get_name(), "root")) {
01231
01232
01233
01234
01235 p->set_vel(dti*(n->get_pos() - p->get_pos()));
01236 p->set_acc(0);
01237 p->set_jerk(vector(VERY_SMALL_NUMBER, 0, 0));
01238
01239 } else {
01240
01241
01242
01243 p->set_acc((3*(n->get_pos()-p->get_pos())
01244 - dt*(2*p->get_vel()+n->get_vel()))*dti*dti);
01245 p->set_jerk((p->get_vel()+n->get_vel()
01246 - 2*dti*(n->get_pos()-p->get_pos()))*dti*dti);
01247 }
01248 }
01249
01250 dt = t - tp;
01251
01252 return p->get_pos() + dt * (p->get_vel()
01253 + dt * (p->get_acc()
01254 + dt * p->get_jerk()));
01255 } else
01256
01257 return p->get_pos();
01258 }
01259
01260
01261
01262 void interpolate_pos(tdyn *p,
01263 real t,
01264 vector& pos,
01265 bool inc,
01266 tdyn *bn)
01267
01268 {
01269
01270
01271
01272 real tp = p->get_time();
01273
01274 if (check_and_initialize(p, tp, t, pos, inc, bn)) {
01275
01276 real dt = t - tp;
01277
01278 if (inc)
01279 pos += p->get_pos() + dt * (p->get_vel()
01280 + dt * (p->get_acc()
01281 + dt * p->get_jerk()));
01282 else
01283 pos = p->get_pos() + dt * (p->get_vel()
01284 + dt * (p->get_acc()
01285 + dt * p->get_jerk()));
01286 }
01287 }
01288
01289
01290
01291 void set_interpolated_pos(tdyn *p,
01292 real t,
01293 vector& pos,
01294 tdyn *bn)
01295
01296 {
01297
01298
01299
01300 real tp = p->get_time();
01301
01302 if (check_and_initialize(p, tp, t, pos, false, bn)) {
01303
01304 real dt = t - tp;
01305 pos = p->get_pos() + dt * (p->get_vel()
01306 + dt * (p->get_acc()
01307 + dt * p->get_jerk()));
01308 }
01309 }
01310
01311
01312
01313 void set_interpolated_pos(tdyn *p,
01314 real t,
01315 pdyn *curr,
01316 tdyn *bn)
01317
01318 {
01319
01320
01321
01322 real tp = p->get_time();
01323 vector pos;
01324
01325 if (check_and_initialize(p, tp, t, pos, false, bn)) {
01326
01327 real dt = t - tp;
01328 curr->set_pos(p->get_pos() + dt * (p->get_vel()
01329 + dt * (p->get_acc()
01330 + dt * p->get_jerk())));
01331 } else
01332
01333 curr->set_pos(pos);
01334 }
01335
01336 void inc_interpolated_pos(tdyn *p,
01337 real t,
01338 vector& pos,
01339 tdyn *bn)
01340
01341 {
01342
01343
01344
01345 real tp = p->get_time();
01346
01347 if (check_and_initialize(p, tp, t, pos, true, bn)) {
01348
01349 real dt = t - tp;
01350 pos += p->get_pos() + dt * (p->get_vel()
01351 + dt * (p->get_acc()
01352 + dt * p->get_jerk()));
01353 }
01354 }
01355
01356 vector interpolate_vel(tdyn *p, real t,
01357 tdyn *bn)
01358
01359 {
01360
01361
01362
01363
01364
01365
01366
01367 if (p->get_time() == t) return p->get_vel();
01368
01369 tdyn *n = p->get_next();
01370 real tp = p->get_time();
01371 real dt = n->get_time() - tp;
01372
01373 if (dt > 0) {
01374
01375 dt = t - tp;
01376 return p->get_vel() + dt * (2*p->get_acc()
01377 + dt * 3*p->get_jerk());
01378 } else
01379
01380 return p->get_vel();
01381 }
01382
01383
01384
01385
01386 local vector get_pos(worldline *w,
01387 tdyn *b, tdyn *bn,
01388 real t = VERY_LARGE_NUMBER)
01389 {
01390
01391
01392
01393
01394
01395
01396 if (t == -VERY_LARGE_NUMBER) t = b->get_time();
01397
01398 vector pos;
01399 set_interpolated_pos(b, t, pos, bn);
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 tdyn *bp = bn->get_parent();
01411
01412 while (bp) {
01413
01414
01415
01416 tdyn *p = find_event(w, bp, t);
01417
01418 inc_interpolated_pos(p, t, pos, bn);
01419 bp = bp->get_parent();
01420 }
01421
01422 return pos;
01423 }
01424
01425 void worldbundle::print_worldline(char *name,
01426 real dt)
01427 {
01428
01429
01430
01431 int loc = find_index(name);
01432
01433 if (loc >= 0) {
01434
01435 worldline *w = bundle[loc];
01436 segment *s = w->get_first_segment();
01437
01438 if (dt == 0) {
01439
01440 while (s) {
01441
01442 tdyn *bn = s->get_first_event();
01443 tdyn *b = bn;
01444 while (b) {
01445 cout << " " << b->get_time()
01446 << " " << get_pos(w, b, bn) << endl << flush;
01447 b = b->get_next();
01448 }
01449
01450 s = s->get_next();
01451 }
01452
01453 } else {
01454
01455 real t = get_t_min();
01456 while (t < get_t_max() - 0.5*dt) {
01457
01458
01459
01460
01461 while (s && s->get_t_end() < t) s = s->get_next();
01462
01463 if (s) {
01464 tdyn *bn = s->get_first_event();
01465 tdyn *b = find_event(w, bn, t);
01466 cout << " " << t
01467 << " " << get_pos(w, b, bn) << endl << flush;
01468 }
01469
01470 t += dt;
01471 }
01472 }
01473
01474 } else
01475 cerr << name << " not found" << endl;
01476 }
01477
01478
01479
01480
01481
01482
01483 #include "print_local2.C"
01484
01485
01486
01487 #include "attach_new_node.C"
01488
01489
01490
01491 #include "update_node.C"
01492
01493
01494 local INLINE void add_to_interpolated_tree(worldbundle *wb,
01495 worldline *w, segment *s,
01496 pdyn *root, real t, bool vel,
01497 bool debug)
01498 {
01499
01500
01501
01502
01503
01504
01505 tdyn *bn = s->get_first_event();
01506
01507 if (debug) {
01508 cerr << "s = " << s << endl
01509 << "first event = " << bn << " "
01510 << bn->format_label() << " "
01511 << bn->get_time() << endl;
01512
01513 print_details(wb, bn, t);
01514 }
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525 tdyn *top = bn;
01526 while (top->get_parent()
01527 && unique_id(top->get_parent()) > 0)
01528 top = top->get_parent();
01529
01530 if (debug) {
01531 PRC(top); PRL(top->format_label());
01532
01533 }
01534
01535
01536
01537 for_all_nodes(tdyn, top, bb) {
01538
01539
01540
01541 worldline *ww;
01542
01543 if (bb == bn)
01544 ww = w;
01545 else {
01546 ww = wb->find_worldline(bb);
01547 if (!ww)
01548 cerr << "create_interpolated_tree: error:"
01549 << "can't find worldline of subtree member." << endl;
01550 }
01551
01552 if (ww) {
01553
01554
01555
01556 attach_new_node(wb, ww, root, top, bb, debug);
01557
01558
01559
01560
01561 update_node(wb, ww, t, bb, top, vel, debug);
01562 }
01563 }
01564 }
01565
01566 int id_n_clump(unique_id_t id)
01567 {
01568 #ifndef NEW_UNIQUE_ID_T
01569 return (int) id;
01570 #else
01571 return (id>>ID_SHIFT);
01572 #endif
01573 }
01574
01575 local inline bool id_is_leaf(unique_id_t id)
01576 {
01577 return (id_n_clump(id) == 1);
01578 }
01579
01580 #define EPS 1.e-12
01581
01582 pdyn *create_interpolated_tree(worldbundle *wb, real t,
01583 bool vel)
01584 {
01585
01586
01587
01588
01589 bool debug = false;
01590
01591
01592
01593
01594
01595 real dt = t - wb->get_t_max();
01596 if (dt > EPS)
01597 return NULL;
01598 else if (dt > 0)
01599 t = wb->get_t_max();
01600
01601 dt = t - wb->get_t_min();
01602 if (dt < -EPS)
01603 return NULL;
01604 else if (dt < 0)
01605 t = wb->get_t_min();
01606
01607
01608
01609
01610 worldlineptr *bundle = wb->get_bundle();
01611
01612 for (int i = 0; i < wb->get_nw(); i++)
01613 bundle[i]->clear_tree_node();
01614
01615
01616
01617 pdyn *root = new pdyn(NULL, NULL, false);
01618
01619
01620
01621 root->set_system_time(t);
01622 root->set_pos(0);
01623
01624
01625
01626
01627
01628 root->set_root(root);
01629 bundle[0]->set_tree_node(root);
01630
01631
01632
01633
01634
01635
01636
01637 for (int i = 1; i < wb->get_nw(); i++) {
01638
01639 worldline *w = bundle[i];
01640
01641 if (!w->get_tree_node()) {
01642
01643
01644
01645 unique_id_t id = w->get_id();
01646
01647
01648 if (id_is_leaf(id)) {
01649
01650
01651
01652 if (debug) {
01653 cerr.precision(16);
01654 cerr << endl
01655 << "following worldline " << i << ", id = "
01656 << w->get_id() << endl;
01657 }
01658
01659 segment *s = w->get_first_segment();
01660 while (s && s->get_t_end() < t) s = s->get_next();
01661
01662 if (debug) {
01663 PRC(w); cerr << "segment "; PRC(s);
01664 print_events(s, t);
01665 }
01666
01667
01668
01669
01670
01671 if (s) add_to_interpolated_tree(wb, w, s,
01672 root, t, vel, debug);
01673 }
01674 }
01675 }
01676
01677 return root;
01678 }
01679
01680 #else
01681
01682 main(int argc, char *argv[])
01683 {
01684
01685
01686 if (argc <= 2) exit(1);
01687
01688 ifstream s(argv[1]);
01689 if (!s) exit(2);
01690
01691 real t = atof(argv[2]);
01692
01693 worldbundle *wb = read_bundle(s);
01694
01695 pdyn *root = create_interpolated_tree(wb, t, true);
01696 put_node(cout, *root, false);
01697 rmtree(root);
01698
01699 #if 0
01700
01701
01702 wb->print();
01703
01704 cerr << wb->get_nw() << " worldlines, "
01705 << count_segments(wb) << " segments, "
01706 << count_events(wb) << " events, t = "
01707 << wb->get_t_min() << " to " << wb->get_t_max()
01708 << endl;
01709 #endif
01710
01711 #if 0
01712
01713
01714 char name[128];
01715 real t;
01716 while (1) {
01717 cerr << endl << "time, name: "; cin >> t >> name;
01718 if (cin.eof()) {
01719 cerr << endl;
01720 break;
01721 }
01722 int loc = wb->find_index(name);
01723 if (loc >= 0) {
01724 PRC(unique_id(name)); PRL(loc);
01725 worldline *w = wb->get_bundle()[loc];
01726 segment *s = w->get_first_segment();
01727 while (s && s->get_t_start() > t) s = s->get_next();
01728 print_event(w, s->get_first_event(), t);
01729 } else
01730 cerr << "not found" << endl;
01731 }
01732 #endif
01733
01734 #if 0
01735
01736
01737
01738 real dt;
01739 char name[128];
01740 while (1) {
01741
01742 cerr << endl << "dt, name: " << flush; cin >> dt >> name;
01743 if (cin.eof()) {
01744 cerr << endl;
01745 break;
01746 }
01747
01748 wb->print_worldline(name, dt);
01749 }
01750 #endif
01751
01752 #if 0
01753 real t = 0.8;
01754 while (t < 0.85) {
01755 pdyn *root = create_interpolated_tree(wb, t);
01756 put_node(cout, *root, false);
01757 rmtree(root);
01758 t += 0.01;
01759 }
01760 #endif
01761
01762 }
01763
01764 #endif