00001 local INLINE void set_kepler_from_tdyn_pair(kepler *k, tdyn *b, tdyn *sis)
00002 {
00003 k->set_time(b->get_time());
00004 k->set_total_mass(b->get_mass() + sis->get_mass());
00005 k->set_rel_pos(sis->get_pos() - b->get_pos());
00006 k->set_rel_vel(sis->get_vel() - b->get_vel());
00007 k->initialize_from_pos_and_vel();
00008 }
00009
00010 local INLINE void update_node(worldbundle *wb,
00011 worldline *ww, real t,
00012 tdyn *bb, tdyn *top, bool vel,
00013 bool debug)
00014 {
00015
00016
00017
00018
00019 tdyn *b = find_event(ww, bb, t);
00020
00021 pdyn *curr = ww->get_tree_node();
00022
00023
00024 if (debug) {
00025 cerr << "current node " << b << " "
00026 << b->get_time() << " "
00027 << b->format_label() << endl;
00028 cerr << "base node " << bb << " "
00029 << bb->get_time() << " "
00030 << bb->format_label() << endl;
00031 }
00032
00033
00034
00035
00036
00037 if (NEW == 0) {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 if (b->get_name()) {
00057 curr->set_name(b->get_name());
00058 curr->set_index(atoi(b->get_name()));
00059 }
00060 if (b->get_index() >= 0)
00061 curr->set_index(b->get_index());
00062
00063
00064
00065 curr->set_worldline_index(wb->find_index(b));
00066 }
00067
00068
00069
00070 curr->set_mass(b->get_mass());
00071
00072
00073
00074
00075
00076
00077
00078
00079 tdyn *bbsis = NULL;
00080 worldline *wwsis = NULL;
00081 tdyn *sis = NULL;
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 if (b->get_kepler() == (kepler*)1) {
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 kepler *k = curr->get_kepler();
00112
00113 if (!k) {
00114
00115
00116
00117 curr->set_kepler((kepler*)1);
00118
00119 if (NEW == 1) {
00120
00121
00122
00123
00124
00125 if (!bb->get_elder_sister()) {
00126
00127 bbsis = bb->get_younger_sister();
00128 wwsis = wb->find_worldline(bbsis);
00129 sis = find_event(wwsis, bbsis, t);
00130
00131
00132
00133 if (sis->get_time() != b->get_time())
00134 cerr << "warning: unsynchronized binary nodes" << endl;
00135
00136 if (!sis->get_kepler())
00137 cerr << "warning: binary sister has kep = NULL" << endl;
00138
00139
00140
00141
00142
00143
00144 k = new kepler;
00145
00146 k->set_circular_binary_limit(1.e-6);
00147 set_kepler_tolerance(2);
00148
00149 set_kepler_from_tdyn_pair(k, b, sis);
00150 curr->set_kepler(k);
00151
00152 if (debug)
00153 cerr << "created kepler for " << curr->format_label()
00154 << " at time " << b->get_time() << endl;
00155 }
00156 }
00157
00158 } else {
00159
00160 if (NEW == 1) {
00161
00162
00163
00164
00165
00166
00167 if (!bb->get_elder_sister()) {
00168
00169
00170
00171
00172
00173
00174 bbsis = bb->get_younger_sister();
00175 wwsis = wb->find_worldline(bbsis);
00176 sis = find_event(wwsis, bbsis, t);
00177
00178
00179
00180 if (sis->get_time() != b->get_time())
00181 cerr << "warning: unsynchronized binary nodes" << endl;
00182
00183 if (!sis->get_kepler())
00184 cerr << "warning: binary sister has kep = NULL" << endl;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 vector ang_mom = square(1+b->get_mass()/sis->get_mass())
00199 * (b->get_pos() ^ b->get_vel());
00200
00201 #define TWFAC 1.e-6
00202 if (!twiddles(square(ang_mom),
00203 square(curr->get_kepler()
00204 ->get_angular_momentum()), TWFAC)) {
00205
00206
00207
00208
00209
00210 set_kepler_from_tdyn_pair(k, b, sis);
00211
00212 if (debug)
00213 cerr << "recreated kepler for "
00214 << curr->format_label()
00215 << " at time " << b->get_time() << endl;
00216 }
00217 }
00218 }
00219 }
00220
00221 #if 0 // turn this on to enable new kep2 stuff, but the new code
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 } else if (b->get_kepler() == (kepler*)2) {
00273
00274
00275
00276
00277
00278
00279 if (!bb->get_elder_sister()) {
00280
00281
00282
00283 bool createkep = true, createkep2 = true;
00284 tdyn *next = b->get_next();
00285
00286 if (curr->get_kepler2()) {
00287
00288
00289
00290
00291 tdyn *event = curr->get_kepevent();
00292 tdyn *event2 = curr->get_kepevent2();
00293
00294 if (event == b)
00295
00296 createkep = false;
00297
00298 else if (event == next) {
00299
00300
00301
00302
00303 delete curr->get_kepler2();
00304
00305
00306
00307 curr->set_kepler2(curr->get_kepler());
00308 pdyn *sister = curr->get_younger_sister();
00309 sister->set_kepler2(curr->get_kepler());
00310
00311 curr->set_kepler(NULL);
00312 sister->set_kepler(NULL);
00313
00314 createkep2 = false;
00315 }
00316
00317 if (event2 == next)
00318
00319 createkep2 = false;
00320
00321 else if (event2 == b) {
00322
00323
00324
00325
00326 delete curr->get_kepler();
00327
00328
00329
00330 curr->set_kepler(curr->get_kepler2());
00331 pdyn *sister = curr->get_binary_sister();
00332 sister->set_kepler(curr->get_kepler2());
00333
00334 curr->set_kepler2(NULL);
00335 sister->set_kepler2(NULL);
00336
00337 createkep = false;
00338 }
00339 }
00340
00341 if (createkep || createkep2) {
00342
00343
00344
00345 bbsis = bb->get_younger_sister();
00346 wwsis = wb->find_worldline(bbsis);
00347 sis = find_event(wwsis, bbsis, t);
00348
00349
00350
00351
00352 if (sis->get_time() != b->get_time())
00353 cerr << "warning: unsynchronized binary nodes" << endl;
00354
00355 if (!sis->get_kepler())
00356 cerr << "warning: binary sister has kep = NULL" << endl;
00357
00358 if (createkep) {
00359 curr->rmkepler();
00360 kepler *k = new kepler;
00361 set_kepler_from_tdyn_pair(k, b, sis);
00362 curr->set_kepler(k);
00363 }
00364
00365 if (createkep2) {
00366 curr->rmkepler2();
00367 kepler *k = new kepler;
00368 set_kepler_from_tdyn_pair(k, next, sis->get_next());
00369
00370
00371
00372 curr->set_kepler2(k);
00373 }
00374 }
00375
00376 curr->set_kepevent(b);
00377 curr->set_kepevent2(next);
00378 }
00379
00380 #endif
00381
00382 } else {
00383
00384
00385
00386 if (curr->get_kepler() == (kepler*)2)
00387 PRL(curr->get_kepler());
00388
00389 if (curr->get_kepler()
00390 && curr->get_kepler() != (kepler*)1
00391 && curr->get_kepler() != (kepler*)2) {
00392
00393 curr->rmkepler();
00394
00395 if (debug &&
00396 !bb->get_elder_sister())
00397 cerr << "deleted kepler for " << curr->format_label()
00398 << " at time " << t << " (" << b->get_time() << ")"
00399 << endl;
00400 }
00401
00402 if (curr->get_kepler2()) {
00403
00404 curr->rmkepler2();
00405
00406 if (debug &&
00407 !bb->get_elder_sister())
00408 cerr << "deleted kepler2 for " << curr->format_label()
00409 << " at time " << t << " (" << b->get_time() << ")"
00410 << endl;
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419 kepler *k = curr->get_kepler();
00420
00421 if (!k || k == (kepler*)2) {
00422
00423
00424
00425
00426
00427 if (NEW == 0 || bb == top || !bb->get_elder_sister())
00428 #ifndef NEW_INTERP
00429 curr->set_pos(interpolate_pos(b, t, bb));
00430 #else
00431 set_interpolated_pos(b, t, curr, bb);
00432 #endif
00433
00434
00435
00436 if (vel || (bb != top && (NEW == 0 || !bb->get_elder_sister())))
00437 curr->set_vel(interpolate_vel(b, t, bb));
00438
00439 #if 0
00440 if (!bb->get_elder_sister())
00441 print_binary_diagnostics(t, b, bb, curr);
00442 #endif
00443
00444 } else if (k != (kepler*)1 && !bb->get_elder_sister()) {
00445
00446
00447
00448
00449 k->transform_to_time(t);
00450
00451
00452
00453
00454 real mass_fac = 1 - curr->get_mass()/k->get_total_mass();
00455 curr->set_pos(-mass_fac * k->get_rel_pos());
00456 curr->set_vel(-mass_fac * k->get_rel_vel());
00457
00458 } else
00459
00460 if (NEW == 0) {
00461
00462
00463
00464 curr->set_pos(b->get_pos());
00465 curr->set_vel(b->get_vel());
00466 }
00467
00468
00469
00470 pdyn *csis = NULL;
00471
00472 if (NEW == 1) {
00473
00474
00475
00476 if (bb != top && !bb->get_elder_sister()) {
00477
00478
00479
00480
00481 if (!bbsis) {
00482 bbsis = bb->get_younger_sister();
00483 wwsis = wb->find_worldline(bbsis);
00484 }
00485
00486 if (bbsis && wwsis) {
00487
00488 pdyn *csis = wwsis->get_tree_node();
00489
00490 if (csis) {
00491 if (csis->get_mass() > 0) {
00492 real mass_fac = -curr->get_mass()/csis->get_mass();
00493 csis->set_pos(mass_fac*curr->get_pos());
00494 csis->set_vel(mass_fac*curr->get_vel());
00495 } else
00496 cerr << "update_node: "
00497 << "error: sister mass <= 0" << endl;
00498 } else
00499 cerr << "update_node: "
00500 << "error: sister tree node NULL for "
00501 << bbsis->format_label() << " at " << t << endl;
00502 } else
00503 cerr << "update_node: "
00504 << "error: sister base node sister NULL" << endl;
00505 }
00506 }
00507
00508
00509
00510
00511
00512 curr->set_stellar_type(b->get_stellar_type());
00513 curr->set_temperature(b->get_temperature());
00514 curr->set_luminosity(b->get_luminosity());
00515
00516 ww->set_t_curr(t);
00517 ww->set_current_event(b);
00518
00519 if (bbsis) {
00520 if (!sis) sis = find_event(wwsis, bbsis, t);
00521 wwsis->set_t_curr(t);
00522 wwsis->set_current_event(sis);
00523 if (csis) {
00524 csis->set_stellar_type(sis->get_stellar_type());
00525 csis->set_temperature(sis->get_temperature());
00526 csis->set_luminosity(sis->get_luminosity());
00527 }
00528 }
00529
00530 if (debug)
00531 cerr << "updated " << curr->format_label() << endl;
00532 }