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