00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "hdyn.h"
00018 #include "star/dstar_to_kira.h"
00019
00020 #define MINIMUM_MASS_LOSS 1.e-16 // Do not allow for mass loss below
00021
00022
00023 #define MINIMUM_REPORT_MASS_LOSS 1.e-6
00024
00025 local void dissociate_binary(hdyn* bi)
00026 {
00027 if (bi->get_kepler() == NULL) {
00028 cerr << "dissociate_binary: no kepler!\n";
00029 return;
00030 }
00031
00032
00033
00034
00035
00036
00037
00038 if (bi->get_kira_diag()->report_binary_mass_loss) {
00039 int p = cerr.precision(INT_PRECISION);
00040 cerr << "\nsudden mass loss from binary, ";
00041 cerr << bi->format_label() << endl;
00042
00043 PRC(bi->get_time()); PRL(bi->get_system_time());
00044 PRL(bi->get_kepler()->get_time());
00045
00046
00047
00048 if (has_dstar(bi))
00049 ((double_star*)(bi->get_parent()
00050 ->get_starbase()))
00051 ->dump(cerr);
00052
00053 cerr.precision(p);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 bi->update_dyn_from_kepler();
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 delete bi->get_kepler();
00080
00081 bi->set_kepler(NULL);
00082 bi->get_binary_sister()->set_kepler(NULL);
00083
00084 bi->set_unperturbed_timestep(-VERY_LARGE_NUMBER);
00085 bi->get_binary_sister()->set_unperturbed_timestep(-VERY_LARGE_NUMBER);
00086
00087
00088 int p = cerr.precision(HIGH_PRECISION);
00089 cerr << endl << "dissociate_binary: deleted kepler for "
00090 << bi->format_label() << ":" << endl;
00091 PRI(4); PRC(bi->get_time()); PRL(bi->get_system_time());
00092 cerr.precision(p);
00093
00094
00095 if (has_dstar(bi)) {
00096 bool update_dynamics[2] = {false, false};
00097 create_or_delete_binary(bi->get_parent(),
00098 update_dynamics);
00099
00100
00101
00102 }
00103
00104
00105
00106 }
00107
00108
00109
00110 real cpu;
00111
00112 local void print_start_evolution(char* s, real t)
00113 {
00114 cerr << "\n===============\n"
00115 << s << " evolution start at time " << t
00116 << endl;
00117 cpu = cpu_time();
00118 }
00119
00120 local void print_end_evolution(char* s, bool correct_dynamics)
00121 {
00122 real delta_cpu = cpu_time() - cpu;
00123 PRC(delta_cpu);
00124 PRL(correct_dynamics);
00125 cerr << s << " evolution end\n===============\n";
00126 }
00127
00128 bool evolve_stars(hdyn* b,
00129 int full_dump)
00130 {
00131 bool correct_dynamics = false;
00132
00133
00134
00135
00136
00137
00138
00139 if (b->get_use_sstar()) {
00140
00141 if (b->get_kira_diag()->report_stellar_evolution)
00142 print_start_evolution("Stellar", b->get_system_time());
00143
00144 correct_dynamics |= stellar_evolution(b);
00145
00146 if (b->get_kira_diag()->report_stellar_evolution)
00147 print_end_evolution("Stellar", correct_dynamics);
00148
00149 b->get_kira_counters()->step_stellar++;
00150 }
00151
00152 if (b->get_use_dstar()) {
00153
00154 if (b->get_kira_diag()->report_stellar_evolution)
00155 print_start_evolution("Binary", b->get_system_time());
00156
00157 correct_dynamics |= binary_evolution(b, full_dump);
00158
00159 if (b->get_kira_diag()->report_stellar_evolution)
00160 print_end_evolution("Binary", correct_dynamics);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 if (correct_dynamics) {
00170
00171
00172
00173
00174
00175
00176 b->get_kira_counters()->step_correct++;
00177
00178 real time = b->get_system_time();
00179
00180 if (b->get_kira_diag()->report_stellar_evolution) {
00181 cerr << "Correcting dynamics at system time "
00182 << time << endl;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192 synchronize_tree(b);
00193
00194 if (b->get_kira_diag()->report_stellar_evolution)
00195 cerr << "After synchronize_tree" << endl;
00196
00197 predict_loworder_all(b, b->get_system_time());
00198
00199 if (b->get_kira_diag()->report_stellar_evolution)
00200 cerr << "After predict_loworder_all" << endl;
00201
00202 real mass0 = total_mass(b);
00203
00204 real epot0, ekin0, etot0;
00205 calculate_energies_with_external(b, epot0, ekin0, etot0);
00206
00207 if (b->get_kira_diag()->report_stellar_evolution) {
00208 cerr << "After calculate_energies_with_external"<<endl;
00209 PRC(epot0); PRC(ekin0); PRL(etot0);
00210 }
00211
00212
00213
00214 if (b->get_kira_diag()->report_stellar_evolution)
00215 cerr << "\n----------\nCorrecting dynamical masses..." << endl;
00216
00217 real de_kick = 0;
00218
00219 for_all_leaves(hdyn, b, bi) {
00220 real dm = 0;
00221
00222
00223
00224
00225
00226 if (bi->get_kepler()) {
00227 if (has_dstar(bi)) {
00228
00229 hdyn * parent = bi->get_parent();
00230
00231
00232
00233 dm = get_total_mass(parent) - parent->get_mass();
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 real dm1_fast = -sudden_mass_loss(bi);
00245 real dm2_fast = -sudden_mass_loss(bi->get_binary_sister());
00246 real dm_fast = dm1_fast + dm2_fast;
00247 real dm_slow = dm - dm_fast;
00248
00249 if (dm != 0 || dm_slow != 0 || dm_slow != 0) {
00250
00251 if (b->get_kira_diag()->report_stellar_evolution &&
00252 (abs(dm) >= MINIMUM_REPORT_MASS_LOSS ||
00253 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS ||
00254 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS)) {
00255
00256 cerr << "Binary evolution mass loss from "
00257 << bi->format_label();
00258 cerr << ", parent = "
00259 << bi->get_parent()->format_label()
00260 << ", at time " << bi->get_time() << endl;
00261 PRC(dm); PRC(dm_slow); PRC(dm_fast);
00262 cerr << " (" << dm1_fast <<" "<< dm2_fast<<")"
00263 <<endl;
00264 }
00265 }
00266
00267
00268
00269 if (b->get_kira_diag()->report_stellar_evolution &&
00270 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS &&
00271 b->get_kira_diag()->report_binary_mass_loss) {
00272
00273 b->get_kira_counters()->step_dmslow++;
00274
00275 int p = cerr.precision(INT_PRECISION);
00276 cerr << "slow mass loss from binary "
00277 << bi->format_label() << " "; PRL(dm_slow);
00278
00279 PRC(bi->get_time()); PRL(bi->get_system_time());
00280 PRL(bi->get_kepler()->get_time());
00281
00282
00283
00284 ((double_star*)(parent->get_starbase()))->dump(cerr);
00285
00286
00287 cerr.precision(p);
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 update_kepler_from_binary_evolution(parent, dm_fast);
00299
00300 if (b->get_kira_diag()->report_stellar_evolution &&
00301 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS &&
00302 b->get_kira_diag()->report_binary_mass_loss)
00303 cerr << "After kepler update..." << flush;
00304
00305 update_dyn_from_binary_evolution(parent, bi, dm1_fast,
00306 dm2_fast);
00307
00308 if (b->get_kira_diag()->report_stellar_evolution &&
00309 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS &&
00310 b->get_kira_diag()->report_binary_mass_loss)
00311 cerr << "dyn updated..." << flush;
00312
00313
00314
00315
00316
00317
00318 correct_leaf_for_change_of_mass(parent, dm_slow);
00319
00320
00321
00322
00323 if (b->get_kira_diag()->report_stellar_evolution &&
00324 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS &&
00325 b->get_kira_diag()->report_binary_mass_loss) {
00326 cerr << "leaf corrected" << endl;
00327
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 bi->set_unperturbed_timestep(false);
00337
00338 if (b->get_kira_diag()->report_stellar_evolution &&
00339 abs(dm_slow) >= MINIMUM_REPORT_MASS_LOSS &&
00340 b->get_kira_diag()->report_binary_mass_loss) {
00341
00342 cerr << "After unperturbed timestep: "<<endl;
00343
00344 PRC(bi->get_time());
00345 PRL(bi->get_unperturbed_timestep());
00346 PRL(bi->get_time() + bi->get_unperturbed_timestep());
00347 PRL(bi->get_system_time());
00348 }
00349
00350
00351
00352
00353
00354 if (dm_fast != 0) {
00355 if (b->get_kira_diag()->report_stellar_evolution) {
00356 cerr << "SN in binary: ";
00357 PRL(dm_fast);
00358 }
00359
00360 b->get_kira_counters()->step_dmfast++;
00361 dissociate_binary(bi);
00362 }
00363
00364 } else if (bi->is_leaf() && !bi->get_use_dstar()) {
00365
00366
00367
00368
00369
00370 if (b->get_kira_diag()->report_stellar_evolution)
00371 cerr << "SN in non-dstar binary "
00372 << bi->format_label() << endl;
00373 dissociate_binary(bi);
00374 }
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 if (bi->is_valid()) {
00386
00387 vector dv = anomalous_velocity(bi);
00388 real dv_sq = square(dv);
00389
00390 dm = get_total_mass(bi) - bi->get_mass();
00391
00392 hdyn *bt = NULL;
00393 if (full_dump && dv_sq > 0) {
00394
00395
00396
00397 bt = bi->get_top_level_node();
00398 put_node(cout, *bt, false, 1);
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 if (abs(dm) > MINIMUM_MASS_LOSS && bi->get_kepler() == NULL) {
00410
00411 correct_leaf_for_change_of_mass(bi, dm);
00412
00413 if (b->get_kira_diag()->report_stellar_evolution &&
00414 b->get_kira_diag()->report_stellar_mass_loss &&
00415 abs(dm) >= MINIMUM_REPORT_MASS_LOSS) {
00416
00417 cerr << "Single star " << bi->format_label()
00418 << " lost mass: dm = " << dm << endl;
00419 if (bi->is_low_level_node()) {
00420 cerr << "star is leaf" << endl;
00421
00422 }
00423 }
00424
00425 if (bi->get_mass() < 0) {
00426 cerr << "\nEvolved star: negative mass of star "
00427 << bi->format_label()
00428 << ", dm = " << dm << endl;
00429
00430 hdyn * btop = bi->get_top_level_node();
00431
00432 ((star*)btop->get_starbase())->dump(cerr);
00433 }
00434 }
00435
00436
00437
00438 if (dv_sq > 0) {
00439
00440 b->get_kira_counters()->total_kick++;
00441
00442 if (full_dump) {
00443
00444
00445
00446 put_node(cout, *bt, false, 1);
00447 }
00448
00449 correct_leaf_for_change_of_vector(bi, dv, &hdyn::get_vel,
00450 &hdyn::inc_vel);
00451
00452 vector vnew = hdyn_something_relative_to_root(bi,
00453 &hdyn::get_vel);
00454 real dde_kick = 0.5 * bi->get_mass()
00455 * (square(vnew) - square(vnew-dv));
00456
00457 de_kick += dde_kick;
00458
00459 cerr << endl;
00460 PRC(bi->format_label()), PRL(dde_kick);
00461 PRL(dv);
00462 pp3(bi->get_top_level_node(), cerr);
00463 }
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 real epot, ekin, etot;
00476 calculate_energies_with_external(b, epot, ekin, etot);
00477
00478 real de_total = etot - etot0;
00479
00480 if (b->get_kira_diag()->report_stellar_evolution) {
00481 cerr << "End of correction: "; PRL(de_total);
00482 PRC(epot); PRC(ekin); PRL(etot);
00483 }
00484
00485
00486
00487 b->get_kira_counters()->dm_massloss += mass0 - total_mass(b);
00488
00489 b->get_kira_counters()->de_total += de_total;
00490 b->get_kira_counters()->de_massloss += de_total - de_kick;
00491 b->get_kira_counters()->de_kick += de_kick;
00492
00493 predict_loworder_all(b, b->get_system_time());
00494
00495 if (b->get_kira_diag()->report_stellar_evolution)
00496 cerr << "initialize_system_phase2 called from evolve_stars\n";
00497 initialize_system_phase2(b, 5);
00498
00499 b->set_mass(total_mass(b));
00500
00501
00502 }
00503
00504
00505
00506 if (b->get_kira_diag()->report_stellar_evolution) {
00507 cerr << "\nEnd of evolve_stars: "; PRL(correct_dynamics);
00508 PRL(b->get_kira_counters()->de_kick);
00509 cerr << "---------\n\n";
00510 }
00511
00512 return correct_dynamics;
00513 }
00514