Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

kira_stellar.C

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 // Functions associated with stellar evolution.
00012 //
00013 // Externally visible function:
00014 //
00015 //      bool evolve_stars
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                                   // the numerical precision
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     // Discard kepler if sudden mass loss took place.
00033 
00034     // The orbital phase of the binary is effectively randomized
00035     // before the sudden mass loss is applied, since the binary
00036     // dynamics is evolved forward to the current system time.
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         // pp3(bi->get_top_level_node(), cerr);
00047 
00048         if (has_dstar(bi))
00049             ((double_star*)(bi->get_parent()
00050                               ->get_starbase()))
00051                               ->dump(cerr);
00052         // bi->get_kepler()->print_all(cerr);
00053         cerr.precision(p);
00054     }
00055 
00056     // The kepler structure has not yet been modified due
00057     // to rapid binary evolution (e.g. supernova), so the
00058     // component positions and velocities retain their values
00059     // prior to the start of the evolution step in which the
00060     // supernova occurred.  Any mass transfer occurring during
00061     // the step, but prior to the supernova, has already been
00062     // accounted for.  Component masses will be adjusted
00063     // individually later (as two single stars).
00064 
00065     // A combination of fast and several slow mass-loss episodes
00066     // is currently handled as a single slow episode followed by
00067     // a fast episode.
00068 
00069     bi->update_dyn_from_kepler();
00070 
00071     // Note that this update will in general produce a tidal error since it
00072     // changes the phase of an unperturbed binary.  However, this error will
00073     // be absorbed in "kira_counters->de_total" after reinitialization.
00074 
00075     // bi->set_first_timestep();
00076     // Not necessary because entire system is scheduled
00077     // to be reinitialized.
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 //    if (bi->get_kira_diag()->report_binary_mass_loss) {
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);       // Defaults probably
00099                                                         // safe here because
00100                                                         // merger won't occur.
00101         
00102     }
00103                 
00104     // NOTE: In case of sudden mass loss, probably have
00105     // to recompute accs and jerks, at least of neighbors.
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)        // default = 0
00130 {
00131     bool correct_dynamics = false;
00132 
00133     // The following if statement was moved to evolve_system() 4/99.
00134     // All stars (sstar and dstar) are now updated once we enter
00135     // this function.
00136 
00137     // if (fmod(b->get_system_time(), dt_sstar) == 0.0 &&
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     // Evolution is over.  See if we need to correct the system for
00164     // mass loss, mergers, etc.  By construction, dynamics is synchronized
00165     // (apart from unperturbed binaries) before entering this function.
00166     // Binary evolution has just updated unperturbed binaries to their
00167     // current times ( < system_time in most cases).
00168 
00169     if (correct_dynamics) {
00170 
00171         // Correct_dynamics is true only if a significant change in
00172         // the mass or semi-major axis of some star or binary has
00173         // occurred.  However, once triggered, *all* pending binary
00174         // mass loss is corrected for.
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         // Shouldn't be necessary to synchronize, since all nodes
00186         // but unperturbed binaries will just have been advanced
00187         // (see evolve_system in kira.C).
00188         //
00189         // Note that (kira_)synchronize_tree() does NOT touch unperturbed
00190         // binaries (handles only top-level nodes.)
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());      // unnecessary??
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         // Change stellar masses after evolution.
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             // Order of business:       slow mass loss
00223             //                          fast mass loss and dissociation
00224             //                          single stars
00225 
00226             if (bi->get_kepler()) {
00227                 if (has_dstar(bi)) {    // elder binary component only...
00228 
00229                     hdyn * parent = bi->get_parent();
00230 
00231                     // Update all binaries for slow mass loss.
00232 
00233                     dm = get_total_mass(parent) - parent->get_mass();
00234 
00235                     // Note: dm is the CHANGE in mass of the binary system.
00236                     // It may be positive or negative.
00237                     // Sudden_mass_loss is the mass LOST by the system
00238                     // in an impulsive fashion.  It is always positive,
00239                     // by convention.
00240 
00241                     // Determine mass changes due to fast and slow processes
00242                     // (positive numbers mean mass increase!).
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                     // Note: sudden_mass_loss() is reset to 0 after use.
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                         // pp3(bi->get_top_level_node(), cerr);
00283 
00284                         ((double_star*)(parent->get_starbase()))->dump(cerr);
00285 
00286                         // bi->get_kepler()->print_all(cerr);
00287                         cerr.precision(p);
00288                     }
00289 
00290                     // The kepler and dyn structures currently reflect the
00291                     // binary configuration at the start of the current
00292                     // evolution step.  Update them now to reflect changes
00293                     // due to binary evolution.
00294 
00295                     // Only correct for slow mass loss here.  Fast mass loss
00296                     // is accounted for after the binary is dissociated.
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                     // Neither update_kepler_from_binary_evolution nor
00314                     // update_dyn_from_binary_evolution modify the parent
00315                     // mass.  Correct it here, changing component offsets
00316                     // accordingly.
00317 
00318                     correct_leaf_for_change_of_mass(parent, dm_slow);
00319 
00320                     // Correcting the parent but not the components in this
00321                     // way effectively isotropizes the mass loss.
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                         // pp3(bi->get_top_level_node(), cerr);
00328                     }
00329 
00330                     // Set the new unperturbed timestep (must extend at least
00331                     // as far as system_time).
00332 
00333                     // Assume that the binary is still unperturbed and
00334                     // approaching.
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                     // Start to handle any fast evolution by dissociating
00351                     // the binary.  (The rest is done by treating the
00352                     // components as single stars.)
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                     // Pretty suspect to have stellar evolution with
00367                     // no binary evolution, although it is possible
00368                     // that the dstar has already been deleted...
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             // Deal with mass loss (single stars or binary CM).
00378 
00379             // If a merger occurred, everything except a possible change
00380             // in mass of the parent node should have been taken care of
00381             // in binary_evolution.  The old center of mass is now a leaf;
00382             // its stellar mass should reflect the effects of mass loss,
00383             // just as with other single stars.
00384 
00385             if (bi->is_valid()) {
00386 
00387                 vector dv = anomalous_velocity(bi);  // |dv| > 0 <==> supernova
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                     // Print out the state of bi before the supernova.
00396 
00397                     bt = bi->get_top_level_node();
00398                     put_node(cout, *bt, false, 1);
00399                 }
00400 
00401                 // For single stars, dm is the total mass loss.  We draw no
00402                 // distinction between fast and slow evolution.
00403 
00404                 // For ex-binary components, dm is the fast mass loss only.
00405                 // (Slow mass loss was completely accounted for in the
00406                 // preceding loop.)  Check for a kepler to avoid applying
00407                 // rounding error corrections to binary component masses.
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                             // pp3(bi->get_top_level_node(), cerr);
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                         // pp3(bi, cerr);
00430                         hdyn * btop = bi->get_top_level_node();
00431                         // pp3(btop, cerr);
00432                         ((star*)btop->get_starbase())->dump(cerr);
00433                     }
00434                 }
00435         
00436                 // Add kick velocity, if any...
00437         
00438                 if (dv_sq > 0) {
00439 
00440                     b->get_kira_counters()->total_kick++;
00441 
00442                     if (full_dump) {
00443 
00444                         // Print out the state of bi after the supernova.
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         // *Don't* reset center of mass; recompute accs and jerks
00468         // on top-level nodes (latter not needed?).
00469 
00470         // b->to_com();
00471 
00472         // calculate_acc_and_jerk_on_all_top_level_nodes(b);
00473         // predict_loworder_all(b, b->get_system_time());
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         // Update statistics on mass and energy change components:
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         // print_recalculated_energies(b);
00502     }
00503 
00504     // test_kepler(b);
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 

Generated at Sun Feb 24 09:57:07 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001