00001 
00002 
00003 
00004 
00005 #include "super_giant.h"
00006 #include "horizontal_branch.h"
00007 
00008 
00009 
00010 
00011 super_giant::super_giant(horizontal_branch & h) : single_star(h) {
00012 
00013     delete &h;
00014 
00015 
00016   last_update_age = next_update_age;
00017 
00018     adjust_next_update_age();
00019 
00020     
00021     COcore_mass = initial_CO_core_mass(core_mass);
00022 
00023     second_dredge_up_time = last_update_age 
00024                           + (next_update_age-last_update_age) 
00025                           * min(1., relative_mass
00026                           / cnsts.parameters(super_giant2neutron_star));
00027 
00028 
00029     instantaneous_element(); update();
00030 
00031     post_constructor();
00032 }
00033 
00034 #if 0
00035 void super_giant::adjust_initial_star() {
00036 
00037   if(relative_age<=0) {
00038     real t_ms = main_sequence_time();
00039     real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00040       + base_giant_branch_time(t_ms);
00041     real t_he = helium_giant_time(t_ms);
00042     relative_age = max(t_giant + t_he, relative_age);
00043    }
00044 }
00045 #endif
00046 
00047 void super_giant::instantaneous_element() {
00048 
00049   real l_g  = giant_luminosity();
00050   real t_ms = main_sequence_time();
00051   real t_gs = 0.15*t_ms;
00052   real t_b  = base_giant_time(t_ms);
00053 
00054   if (next_update_age + t_b - relative_age<=0)
00055     luminosity = l_g*pow(t_gs/t_b, 1.17);
00056   else
00057     luminosity = l_g*pow(t_gs/(next_update_age 
00058                              + t_b - relative_age), 1.17);
00059 
00060   luminosity = min(luminosity, maximum_luminosity());
00061 
00062   
00063   
00064   
00065   
00066   radius = (0.25*pow(luminosity, 0.4)
00067          + 0.8*pow(luminosity, 0.67))/pow(relative_mass, 0.27);
00068 
00069   if(second_dredge_up_time<=0) 
00070     second_dredge_up_time = last_update_age 
00071                           + (next_update_age-last_update_age) 
00072                           * min(1., relative_mass
00073                           / cnsts.parameters(super_giant2neutron_star));
00074 
00075 }
00076 
00077 
00078 
00079 void super_giant::evolve_element(const real end_time) {
00080 
00081       real dt = end_time - current_time;
00082       current_time = end_time;
00083       relative_age += dt;
00084 
00085       if (relative_age<=next_update_age) {
00086          real l_g = giant_luminosity();
00087          real t_ms = main_sequence_time();
00088          real t_gs = 0.15*t_ms;
00089          real t_b  = base_giant_time(t_ms);
00090 
00091          real tau = t_gs
00092                   / (next_update_age + t_b - relative_age);
00093          real tau_prev = t_gs
00094                       / (next_update_age + t_b - (relative_age-dt));
00095                 
00096          luminosity = l_g*pow(tau, 1.17);
00097          luminosity = min(luminosity, maximum_luminosity());
00098 
00099          radius = (0.25*pow(luminosity, 0.4)
00100                 + 0.8*pow(luminosity, 0.67))/pow(relative_mass, 0.27);
00101 
00102          real m_tot = get_total_mass();
00103 
00104          real new_mcore;
00105          if(relative_mass >= cnsts.parameters(super_giant2neutron_star) ||
00106             core_mass     >= cnsts.parameters(helium2neutron_star)) {
00107            
00108              new_mcore = core_mass;
00109 
00110 
00111              real dmdt  = (core_mass - COcore_mass)
00112                         / (second_dredge_up_time-(relative_age-dt));
00113              COcore_mass += dmdt * dt;
00114 
00115          }
00116          else {
00117            if(relative_age <= second_dredge_up_time) {
00118            
00119              new_mcore = core_mass;
00120              
00121              
00122              real dmdt  = (core_mass - COcore_mass)
00123                         / (second_dredge_up_time-(relative_age-dt));
00124              COcore_mass += dmdt * dt;
00125 
00126 
00127            }
00128            else {
00129              if (luminosity < 15725.) {                     
00130                new_mcore = sqrt(luminosity/47488. + 0.1804)+0.015;
00131              }
00132              else {
00133                
00134                new_mcore = luminosity/(46818*pow(relative_mass, 0.25)) + 0.46;
00135              }
00136            }
00137          }
00138 
00139          
00140          
00141          
00142          core_mass = min(m_tot, new_mcore);
00143          envelope_mass = m_tot - core_mass;
00144 
00145 #if 0 // (SPZ+GN: 27 Jul 2000)
00146          
00147          if (relative_mass > cnsts.parameters(super_giant2neutron_star)) { 
00148            real X = cnsts.parameters(hydrogen_fraction);
00149            new_mcore = core_mass 
00150                      + l_g*6*t_gs*(pow(tau,1./6.)-pow(tau_prev,1./6.))
00151                      / (X*cnsts.parameters(energy_to_mass_in_internal_units));
00152          }
00153          else {  
00154            if (luminosity < 15725.) {                     
00155              new_mcore = sqrt(luminosity/47488. + 0.1804)+0.015;
00156            }
00157            else {
00158              
00159              new_mcore = luminosity/(46818*pow(relative_mass, 0.25)) + 0.46;
00160            }
00161          }
00162 
00163          new_mcore = max(new_mcore, core_mass);
00164          
00165          core_mass = min(m_tot-cnsts.safety(minimum_mass_step), new_mcore);
00166          envelope_mass = m_tot - core_mass;
00167 #endif
00168 
00169       }
00170       else {
00171          create_remnant();
00172          return;
00173       }
00174   
00175       update();
00176       stellar_wind(dt);
00177 }
00178 
00179 real super_giant::initial_CO_core_mass(const real initial_mass) {
00180 
00181 
00182 
00183 
00184   
00185   
00186   
00187   
00188   real final_coremass_fraction;
00189   if(initial_mass <= 0.8) 
00190     final_coremass_fraction = 1;
00191   else if(initial_mass >= cnsts.parameters(helium2neutron_star)) 
00192     final_coremass_fraction = 0.65;
00193   else 
00194     final_coremass_fraction = 1 - 0.32 * (initial_mass - 0.8);
00195 
00196   return cnsts.parameters(helium_star_lifetime_fraction)
00197          * final_coremass_fraction*initial_mass;
00198 }
00199 
00200 #if 0
00201 void super_giant::evolve_without_wind(const real end_time) {
00202 
00203       real dt = end_time - current_time;
00204       current_time = end_time;
00205       relative_age += dt;
00206 
00207       if (relative_age<=next_update_age) {
00208          real l_g = giant_luminosity();
00209          real t_ms = main_sequence_time();
00210          real t_gs = 0.15*t_ms;
00211          real t_b  = base_giant_time(t_ms);
00212 
00213          luminosity = l_g*pow(t_gs/(next_update_age
00214                     + t_b - relative_age), 1.17);
00215          real l_max = maximum_luminosity();
00216          if(luminosity>l_max) luminosity = l_max;
00217 
00218          radius = (0.25*pow(luminosity, 0.4)
00219                 + 0.8*pow(luminosity, 0.67))/pow(relative_mass, 0.27);
00220       }
00221       else {
00222          create_remnant();
00223          return;
00224       }
00225 
00226       update();
00227    }
00228 #endif
00229 
00230 #if 0
00231 
00232 void super_giant::stellar_wind(const real dt) {
00233 
00234       real kappa = wind_constant;
00235       real wind_mass = 1.e6*dt*pow(kappa, 1.43)/pow(10., 13.6);
00236 
00237 
00238       if (wind_mass>envelope_mass) 
00239          wind_mass = 0.9*envelope_mass;
00240 
00241       if (is_binary_component())
00242          get_binary()->adjust_binary_after_wind_loss(this, 
00243                      wind_mass, dt);
00244       else
00245          reduce_mass(wind_mass);
00246    }
00247 #endif
00248 
00249 #if 0
00250 
00251 
00252 
00253 
00254 
00255 
00256 real super_giant::helium_core_mass() {
00257 
00258 
00259       real m_core = (log10(luminosity) - 1.55)/3.56;
00260 
00261       real m1_core = 0.073*(1 + cnsts.parameters(core_overshoot))
00262                    * pow(relative_mass, 1.42);
00263 
00264       real m2_core = 0.058*(1 + cnsts.parameters(core_overshoot))
00265                    * pow(relative_mass, 1.57);
00266 
00267       m_core = max(max(m_core, m1_core), m2_core);
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275       if (m_core>=cnsts.parameters(helium2neutron_star) &&
00276           m_core<cnsts.parameters(minimum_helium_star))
00277         m_core = m_core<cnsts.parameters(minimum_helium_star);
00278       
00279       m_core = min(m_core, get_total_mass());
00280 
00281       return max(m_core, core_mass);
00282    }
00283 #endif
00284 
00285 void super_giant::create_remnant() {
00286 
00287      if (is_binary_component()) 
00288        get_binary()->dump("binev.data", false);
00289      else
00290        dump("binev.data", false);
00291 
00292      real COcore_mass = 0.65 * core_mass;
00293      stellar_type type;
00294      if (relative_mass >= cnsts.parameters(maximum_main_sequence) &&
00295          relative_mass < 300)
00296        type = Disintegrated;
00297      else if (COcore_mass >= cnsts.parameters(COcore2black_hole)) 
00298        type = Black_Hole;
00299      else if(core_mass >= cnsts.parameters(Chandrasekar_mass))
00300        type = Neutron_Star;
00301      else
00302        type = Carbon_Dwarf;
00303 
00304      switch (type) {
00305        case Black_Hole : star_transformation_story(Black_Hole);
00306                          new black_hole(*this); 
00307                          return;
00308        case Neutron_Star : star_transformation_story(Neutron_Star);
00309                            new neutron_star(*this);
00310                            return;
00311        case Disintegrated : star_transformation_story(Disintegrated);
00312                             new disintegrated(*this);
00313                             return;
00314        case Carbon_Dwarf : star_transformation_story(Carbon_Dwarf);
00315                            new white_dwarf(*this);
00316                             return;
00317        default :   cerr << "super_giant::create_remnant()" <<endl;
00318                    cerr << "star_type not recognized." << endl;
00319                    exit(-1);
00320      }
00321 
00322 
00323 #if 0 // (SPZ+GN: 27 Jul 2000)
00324         if (relative_mass >= cnsts.parameters(super_giant2black_hole) ||
00325             core_mass     >= cnsts.parameters(helium2black_hole)) {
00326         
00327         star_transformation_story(Black_Hole);
00328         new black_hole(*this);
00329         return;
00330       }
00331       else if(relative_mass >= cnsts.parameters(super_giant2neutron_star) ||
00332               core_mass     >= cnsts.parameters(Chandrasekhar_mass)) {
00333         
00334         
00335         
00336         star_transformation_story(Neutron_Star);
00337         new neutron_star(*this);
00338         return;
00339       }
00340       else if(cnsts.parameters(super_giant_disintegration)) {
00341         if (relative_mass >= 6 &&
00342             relative_mass <= cnsts.parameters(super_giant2neutron_star)) {
00343 
00344           star_transformation_story(Disintegrated);
00345           new disintegrated(*this);
00346           return;
00347         }
00348       }
00349       else {
00350         if (core_mass<=cnsts.parameters(helium_dwarf_mass_limit)) {
00351           cerr << "ERROR in super_giant::create_remnant()" << endl;
00352           cerr << "Supergiants shoud not become helum dwarfs" << endl;
00353           star_transformation_story(Helium_Dwarf);
00354         }
00355         else 
00356           star_transformation_story(Carbon_Dwarf);
00357 
00358         new white_dwarf(*this);
00359         return;
00360       }
00361 #endif // (SPZ+GN: 27 Jul 2000)
00362 
00363 }
00364 
00365 star* super_giant::reduce_mass(const real mdot) {
00366 
00367   if (envelope_mass<=mdot) {
00368         envelope_mass = 0;
00369 
00370 
00371 
00372          if(relative_mass >= cnsts.parameters(super_giant2neutron_star) ||
00373             core_mass     >= cnsts.parameters(helium2neutron_star)) {
00374 
00375            
00376            
00377            
00378            
00379            real m_tot = core_mass;
00380            core_mass = COcore_mass;
00381            envelope_mass = m_tot - core_mass;
00382 
00383            star_transformation_story(Helium_Giant);
00384            return dynamic_cast(star*, new helium_giant(*this));
00385          }
00386          else {
00387 
00388            
00389            if(relative_age <= second_dredge_up_time) {
00390 
00391            real m_tot = core_mass;
00392            core_mass = COcore_mass;
00393            envelope_mass = m_tot - core_mass;
00394 
00395              star_transformation_story(Helium_Giant);
00396              return dynamic_cast(star*, new helium_giant(*this));
00397            }
00398            else {
00399              star_transformation_story(Carbon_Dwarf);      
00400              return dynamic_cast(star*, new white_dwarf(*this));
00401            }
00402          }
00403   }
00404 
00405   envelope_mass -= mdot;
00406   return this;
00407 }
00408 
00409 star* super_giant::subtrac_mass_from_donor(const real dt, real& mdot) {
00410 
00411       real mdot_temp = relative_mass*dt/get_binary()->get_donor_timescale();
00412       mdot = mass_ratio_mdot_limit(mdot_temp);
00413 
00414       if (envelope_mass<=mdot) {
00415          mdot = envelope_mass;
00416          envelope_mass = 0;
00417          
00418 
00419 
00420          if(relative_mass >= cnsts.parameters(super_giant2neutron_star) ||
00421             core_mass     >= cnsts.parameters(helium2neutron_star)) {
00422 
00423            real m_tot = core_mass;
00424            core_mass = COcore_mass;
00425            envelope_mass = m_tot - core_mass;
00426 
00427            star_transformation_story(Helium_Giant);
00428            return dynamic_cast(star*, new helium_giant(*this));
00429          }
00430          else {
00431            
00432            
00433            if(relative_age <= second_dredge_up_time) {
00434 
00435            real m_tot = core_mass;
00436            core_mass = COcore_mass;
00437            envelope_mass = m_tot - core_mass;
00438 
00439              star_transformation_story(Helium_Giant);
00440              return dynamic_cast(star*, new helium_giant(*this));
00441            }
00442            else {
00443              star_transformation_story(Carbon_Dwarf);      
00444              return dynamic_cast(star*, new white_dwarf(*this));
00445            }
00446          }
00447 
00448       }
00449 
00450 
00451       adjust_donor_radius(mdot);
00452 
00453       envelope_mass -= mdot;
00454       return this;
00455 }
00456 
00457 
00458 void super_giant::adjust_accretor_age(const real mdot, const bool rejuvenate=true) {
00459 
00460       real m_tot_new = get_total_mass() + mdot;
00461       real m_rel_new = max(m_tot_new, relative_mass);
00462 
00463       real t_ms = main_sequence_time();
00464       real t_hg = hertzsprung_gap_time(t_ms);
00465       real t_bgb = base_giant_branch_time(t_ms);
00466       real t_he = helium_giant_time(t_ms);
00467       real t_super_old = t_ms + t_hg + t_bgb + t_he;
00468       real t_nuc = nucleair_evolution_time();
00469       real t_sg_old = t_nuc - t_super_old; 
00470 
00471            t_ms = main_sequence_time(m_rel_new);
00472            t_hg = hertzsprung_gap_time(m_rel_new, t_ms);
00473            t_bgb = base_giant_branch_time(m_rel_new, t_ms);
00474            t_he = helium_giant_time(m_rel_new, t_ms);
00475       real t_super_new = t_ms + t_hg + t_bgb + t_he;
00476            t_nuc = nucleair_evolution_time(m_rel_new);
00477       real t_sg_new = t_nuc - t_super_new; 
00478 
00479       real dtime = relative_age - t_super_old;
00480 
00481 
00482       last_update_age = t_super_new;
00483       relative_age = t_super_new
00484                    + dtime*(t_sg_new/t_sg_old);
00485       if (rejuvenate)
00486          relative_age *= rejuvenation_fraction(mdot/m_tot_new);
00487 
00488        relative_age = max(relative_age, 
00489                           last_update_age + cnsts.safety(minimum_timestep));
00490       
00491 
00492       
00493       
00494    }
00495 
00496 void super_giant::adjust_next_update_age() {
00497 
00498       next_update_age = nucleair_evolution_time();
00499    }
00500 
00501 #if 0
00502 
00503 
00504 real super_giant::zeta_adiabatic() {
00505 
00506       real x = core_mass/get_total_mass();
00507       real a = -0.220823;
00508       real b = -2.84699;
00509       real c = 32.0344;
00510       real d = -75.6863;
00511       real e = 57.8109;
00512 
00513       real z = a + b*x + c*x*x + d*x*x*x + e*x*x*x*x;
00514 
00515       return z;
00516    }
00517 #endif
00518 
00519 real super_giant::zeta_thermal() {
00520 
00521   real z = 0.; 
00522                
00523 
00524       return z;
00525    }
00526 
00527 #if 0
00528 real super_giant::stellar_radius(const real mass, const real age) {
00529 
00530       real t_nuc = nucleair_evolution_time(mass);
00531 
00532       real l_g = giant_luminosity();
00533       real t_ms = main_sequence_time();
00534       real t_gs = 0.15*t_ms;
00535       real t_b  = base_giant_time(t_ms);
00536 
00537       real l_agb = l_g*pow(t_gs/(t_nuc + t_b - age), 1.17);
00538       l_agb = min(l_agb, maximum_luminosity(mass));
00539 
00540       real r_agb = (0.25*pow(l_agb, 0.4)
00541              + 0.8*pow(l_agb, 0.67))/pow(mass, 0.27);
00542 
00543       return r_agb;
00544    }
00545 #endif
00546 
00547 
00548 real super_giant::gyration_radius_sq() {
00549 
00550   return cnsts.parameters(convective_star_gyration_radius_sq); 
00551 }
00552 
00553 void super_giant::update_wind_constant() {
00554   
00555 
00556 
00557 
00558   if (relative_mass >= cnsts.parameters(super_giant2neutron_star)) {
00559 
00560     real meader_fit_dm = 0.01*pow(relative_mass,2.);
00561     wind_constant = meader_fit_dm;
00562 
00563   }
00564   else {
00565 
00566 
00567 
00568 
00569 
00570     
00571     
00572     wind_constant = 0.8*(relative_mass - final_core_mass());
00573   }
00574   
00575   wind_constant = max(wind_constant, 0.0);
00576 
00577 }