Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

helium_star.C

Go to the documentation of this file.
00001 //
00002 // helium_star.C
00003 //
00004 
00005 #include "helium_star.h"
00006 #include "main_sequence.h"
00007 #include "hyper_giant.h"
00008 #include "sub_giant.h"
00009 #include "horizontal_branch.h"
00010 #include "super_giant.h"
00011 #include "hertzsprung_gap.h"
00012 
00013 helium_star::helium_star(main_sequence & m) : single_star(m) {
00014 
00015     delete &m;
00016 
00017     lose_envelope_decent();
00018 
00019     adjust_next_update_age();
00020 // (GN+SPZ May  4 1999) last update age is time of previous type change
00021 // in NEW raltive_age units!!!
00022     last_update_age = 0;
00023     relative_age = 0;
00024 
00025     // core_mass is CO core (SPZ+GN: 27 Jul 2000)
00026     real m_tot = get_total_mass();
00027     // (SPZ+GN: 28 Jul 2000) was helium core but is now the CO core.
00028     core_mass = 0;
00029     final_core_mass = final_CO_core_mass(m_tot);
00030     core_mass = COcore_mass = CO_core_mass();
00031     envelope_mass =  m_tot - core_mass;
00032 
00033 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00034 //    update_wind_constant();
00035 
00036     instantaneous_element();
00037     update();
00038 
00039     post_constructor();
00040     
00041 }
00042 
00043 helium_star::helium_star(hyper_giant & w) : single_star(w) {
00044 
00045     delete &w;
00046 
00047     lose_envelope_decent();
00048 
00049 
00050 //  PRC(relative_age);PRC(main_sequence_time());PRL(next_update_age);
00051 // fraction of Hyper_Giant phase spend before stripped
00052     real t_frac = (relative_age - main_sequence_time())
00053                / (nucleair_evolution_time()-main_sequence_time());
00054 
00055 //    PRC(nucleair_evolution_time());PRL(t_frac);
00056     adjust_next_update_age();
00057     relative_age = t_frac*next_update_age;
00058 //    PRC(relative_age);PRL(next_update_age);
00059     
00060 // (GN+SPZ May  4 1999) last update age is time of previous type change
00061 // in NEW relative_age units!!
00062     last_update_age = relative_age;
00063 
00064     // core_mass is CO core (SPZ+GN: 27 Jul 2000)
00065     real m_tot = get_total_mass();
00066     // (SPZ+GN: 28 Jul 2000) was helium core but is now the CO core.
00067     core_mass = 0;
00068     final_core_mass = final_CO_core_mass(m_tot);
00069     core_mass = COcore_mass = CO_core_mass();
00070     envelope_mass =  m_tot - core_mass;
00071 
00072 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00073 //    update_wind_constant();
00074 
00075     instantaneous_element();
00076     update();
00077     
00078     post_constructor();
00079 
00080 }
00081 
00082 helium_star::helium_star(hertzsprung_gap & h) : single_star(h) {
00083 
00084     delete &h;
00085 
00086     lose_envelope_decent();
00087 
00088 // (GN+SPZ May  4 1999) last update age is time of previous type change
00089 // in NEW relative_age uits!!!!
00090     last_update_age = 0.;
00091 
00092     adjust_next_update_age();
00093     relative_age = 0;
00094 
00095     // core_mass is CO core (SPZ+GN: 27 Jul 2000)
00096     real m_tot = get_total_mass();
00097     // (SPZ+GN: 28 Jul 2000) was helium core but is now the CO core.
00098     core_mass = 0;
00099     final_core_mass = final_CO_core_mass(m_tot);
00100     core_mass = COcore_mass = CO_core_mass();
00101     envelope_mass =  m_tot - core_mass;
00102 
00103 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00104 //    update_wind_constant();
00105     
00106     instantaneous_element();
00107     update();
00108     
00109     post_constructor();
00110 
00111 }
00112 
00113 helium_star::helium_star(sub_giant & g) : single_star(g) {
00114 
00115     delete &g;
00116     lose_envelope_decent();
00117 
00118 // (GN+SPZ May  4 1999) last update age is time of previous type change
00119 // in NEW relative_age uits!!!!
00120     last_update_age = 0.;
00121 
00122     adjust_next_update_age();
00123     relative_age = 0;
00124 
00125     // core_mass is CO core (SPZ+GN: 27 Jul 2000)
00126     real m_tot = get_total_mass();
00127     // (SPZ+GN: 28 Jul 2000) was helium core but is now the CO core.
00128     core_mass = 0;
00129     final_core_mass = final_CO_core_mass(m_tot);
00130     core_mass = COcore_mass = CO_core_mass();
00131     envelope_mass =  m_tot - core_mass;
00132 
00133 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00134 //    update_wind_constant();
00135 
00136     instantaneous_element();
00137     update();
00138     
00139     post_constructor();
00140 
00141 }
00142 
00143 helium_star::helium_star(horizontal_branch & h) : single_star(h) {
00144 
00145     delete &h;
00146 
00147     lose_envelope_decent();
00148 
00149     real t_ms = main_sequence_time();
00150     real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00151                  + base_giant_branch_time(t_ms);
00152     real t_he = helium_giant_time(t_ms);
00153     real t_frac = min(0.9,(relative_age - t_giant)/t_he);
00154 
00155 
00156     adjust_next_update_age();
00157     relative_age = t_frac* next_update_age;
00158 
00159 // (GN+SPZ May  4 1999) last update age is time of previous type change
00160 // in NEW relative_age uits!!!!
00161     last_update_age = relative_age;
00162 
00163     // core_mass is CO core (SPZ+GN: 27 Jul 2000)
00164     real m_tot = get_total_mass();
00165     // (SPZ+GN: 28 Jul 2000) was helium core but is now the CO core.
00166     core_mass = 0;
00167     final_core_mass = final_CO_core_mass(m_tot);
00168     core_mass = COcore_mass = CO_core_mass();
00169     envelope_mass =  m_tot - core_mass;
00170 
00171 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00172 //    update_wind_constant();
00173 
00174     instantaneous_element();
00175     update();
00176     
00177     post_constructor();
00178 
00179  }
00180 
00181 #if 0
00182 void helium_star::adjust_initial_star() {
00183 
00184   update_wind_constant();
00185 
00186   if(relative_age<=0)
00187     relative_age = max(current_time, 0.0);
00188 }
00189 #endif
00190 
00191 // Use only in constructors.
00192 void helium_star::adjust_next_update_age() {
00193 
00194   next_update_age = cnsts.parameters(helium_star_lifetime_fraction)
00195                   * helium_time();
00196 }
00197 
00198 void helium_star::instantaneous_element() {
00199 
00200   
00201     real temp;
00202     real m_tot = get_total_mass();
00203 
00204     temp = log10(m_tot)
00205       * (0.4509 - 0.1085*log10(m_tot)) + 4.7143;
00206     luminosity  = 8.33*temp - 36.8;
00207     temp = 1.e-3*pow(10., temp);
00208     luminosity  = pow(10., luminosity);
00209     effective_radius = radius = 33.45*sqrt(luminosity)/(temp*temp);
00210     core_radius  = 0.2*radius;
00211 
00212     if (envelope_mass <= 0) {
00213       effective_radius = radius  = core_radius;
00214     }
00215 
00216     if (final_core_mass <= 0)
00217       final_core_mass = final_CO_core_mass(m_tot);
00218 }
00219 
00220 void helium_star::evolve_element(const real end_time)
00221 {
00222     real dt = end_time - current_time;
00223     current_time = end_time;
00224     relative_age += dt;
00225     
00226     real m_tot = get_total_mass();
00227     if (relative_age>next_update_age) {
00228 
00229       core_mass = COcore_mass = CO_core_mass();
00230       envelope_mass = m_tot - core_mass;
00231         
00232       stellar_wind(dt);
00233 
00234       star_transformation_story(Helium_Giant);
00235       new helium_giant(*this);
00236       return;
00237     }
00238     else if (m_tot < cnsts.parameters(helium_dwarf_mass_limit) &&
00239              relative_mass < cnsts.parameters(
00240                              upper_ZAMS_mass_for_degenerate_core)) {
00241 
00242       // low-mass degenerate core has no envelope (SPZ+GN: 4 Oct 1998)
00243       core_mass = get_total_mass();
00244       envelope_mass = 0;
00245 
00246       if (is_binary_component()) 
00247         get_binary()->dump("binev.data", false);
00248       else
00249         dump("binev.data", false);
00250       
00251       star_transformation_story(Helium_Dwarf);
00252       new white_dwarf(*this);
00253       return;
00254     }
00255     else { // normal helium star evolution
00256         real tmp = log10(m_tot)
00257         * (0.4509 - 0.1085*log10(m_tot)) + 4.7143;
00258         luminosity  = pow(10., 8.33*tmp - 36.8);
00259         tmp = pow(1.e-3*pow(10., tmp), 2);
00260         radius = 33.45*sqrt(luminosity)/tmp;
00261         core_radius  = 0.2*radius;
00262 
00263 // (GN+SPZ May  3 1999) according to Savonije et al 1986
00264 // semi-degenerate helium_stars; have r = 0.029 m^-0.19 and live forever
00265         if (m_tot < 0.2) { 
00266           radius = 0.029 * pow(m_tot, -0.19);
00267           next_update_age = relative_age + cnsts.safety(maximum_timestep);
00268         }
00269 
00270         if (envelope_mass <= 0) {
00271             radius  = core_radius;
00272         }
00273     }
00274 
00275     core_mass = COcore_mass = CO_core_mass();
00276     
00277     envelope_mass = m_tot - core_mass;
00278     //core_radius = helium_core_radius();
00279     
00280     update();
00281     stellar_wind(dt);
00282 
00283 }
00284 
00285 void helium_star::update() {
00286     
00287     detect_spectral_features();
00288 // (GN+SPZ May  4 1999) last_update_age now used as time of last type change
00289 //  last_update_age = relative_age;
00290     effective_radius = radius;
00291 
00292 }
00293 
00294 #if 0
00295 void helium_star::create_remnant() {
00296 
00297 /*
00298 //cout<<"void helium_star::create_remnant() called"<<endl;
00299        // core_mass = get_total_mass();
00300         stellar_type type = NAS;
00301         if (get_total_mass()>=cnsts.parameters(helium2black_hole))
00302            type = Black_Hole;
00303 //                      was 1.3*M_NS
00304         else if((core_mass>=1.2*cnsts.mass.neutron_star     &&
00305                  relative_mass>=10) ||
00306                 get_total_mass()>=cnsts.mass.helium2neutron_star)
00307            type = Neutron_Star;
00308 //        else if(get_total_mass()>=1.3*M_NS && relative_mass>=8) 
00309 //           type = Disintegrated;
00310         else
00311            type = White_Dwarf;
00312 
00313 //        base_element * s = make(type, this);
00314        switch (type) {
00315           case Black_Hole : if (is_binary_component())
00316                                get_binary()->dump("sn.dat");
00317                             else dump("sn.dat");
00318                             
00319                             star_transformation_story(this,Black_Hole);
00320                             new black_hole(*this); 
00321                             break;
00322           case Neutron_Star : 
00323                            if (is_binary_component()) get_binary()->dump("sn.dat");
00324                            else dump("sn.dat");
00325                            star_transformation_story(this,Neutron_Star);
00326                            new neutron_star(*this);
00327                            break;
00328           case Disintegrated : if (is_binary_component()) get_binary()->dump("sn.dat");
00329                                else dump("sn.dat");
00330                                star_transformation_story(this,Disintegrated);
00331                                new disintegrated(*this);
00332                                break;
00333          case White_Dwarf : star_transformation_story(this,White_Dwarf);
00334                             new white_dwarf(*this);
00335                             break;
00336           default : ;//error << "helium_star::create_remnant()" <<endl;
00337                     //error << "star_type not recognized." << endl;
00338                     //error << "Action: Proceed normally." << endl;
00339        }
00340 
00341 */
00342      }
00343 #endif
00344 
00345 /*
00346 real helium_star::helium_time() {
00347 
00348 //              Helium Star lifetime from
00349      real t_ms = main_sequence_time();
00350      real t_he;
00351      real m_tot = get_total_mass();
00352 
00353      if (exp_HE_lifetime) {
00354 //              Iben I., 1967 ??; en Iben and Tutukov, 1985, ApJSS, 58, 661.
00355         t_he =  0.56*t_ms/pow(relative_mass, 0.52);
00356      }
00357      else {
00358 //              Pols O., 1993, proefschrift, P13, Eq. 2.15
00359      if (m_tot<=0.7) t_he = 10.76*pow(m_tot, -3.75);
00360      else if(m_tot<=1.6) t_he = 17.1*pow(m_tot, -2.45);
00361      else if(m_tot<=4.8) t_he = 11.48*pow(m_tot, -1.6);
00362      else                    t_he = 2.37*pow(m_tot, -0.6);
00363      }
00364 
00365      if(t_he>t_ms) t_he=t_ms;
00366      return t_he;
00367 }
00368 */
00369 
00370 star* helium_star::subtrac_mass_from_donor(const real dt, real& mdot) {
00371 
00372     mdot = relative_mass*dt/get_binary()->get_donor_timescale();
00373 
00374     mdot = mass_ratio_mdot_limit(mdot);
00375 
00376     if (envelope_mass >= mdot)
00377       envelope_mass -= mdot;
00378     else {
00379       mdot = envelope_mass;
00380       envelope_mass = 0;
00381       
00382       //           star_transformation_story(this,White_Dwarf);
00383       //return dynamic_cast(star*, new white_dwarf(*this));
00384     }
00385 
00386     return this;
00387 }
00388 
00389 star* helium_star::reduce_mass(const real mdot) {
00390 
00391     if (envelope_mass >= mdot)
00392       envelope_mass -= mdot;
00393     else {
00394       real mass_reduced = mdot;
00395       mass_reduced -= envelope_mass;
00396       envelope_mass = 0;
00397       if (core_mass>mass_reduced) {
00398         if (core_mass-mass_reduced<=cnsts.parameters(minimum_helium_star)) {
00399             core_mass -= mass_reduced;
00400 //               star_transformation_story(this,White_Dwarf);
00401 //                 new white_dwarf(*this);
00402 //                 return;
00403         }
00404         else {
00405           core_mass -= mass_reduced;
00406           COcore_mass = core_mass;
00407         }
00408       }
00409       else {
00410         cerr<<"ERROR!:"<<endl;
00411         cerr<<"void helium_star::reduce_mass(mdot="
00412             <<mass_reduced<<")"<<endl;
00413         cerr<<"mdot exceeds helium core mass ("<<core_mass
00414             <<")"<<endl;
00415         cerr<<"Decision: Disintegrate helium star!"<<endl;
00416         //new disintegrated(*this);
00417         //return;
00418       }
00419     }
00420     
00421     return this;
00422 }
00423 
00424 
00425 real helium_star::add_mass_to_accretor(const real mdot) {
00426 
00427         if (mdot<0) {
00428            cerr << "helium_star::add_mass_to_accretor(mdot=" 
00429                  << mdot << ")"<<endl;
00430            cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00431            return 0;
00432         }
00433 
00434         adjust_accretor_age(mdot);
00435         if (relative_mass<get_total_mass() + mdot)
00436           relative_mass = get_total_mass() + mdot;
00437 
00438 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00439 //      update_wind_constant();
00440         
00441         envelope_mass += mdot;
00442         
00443         set_spec_type(Accreting);
00444         
00445         return mdot;
00446 
00447 }
00448 
00449 real helium_star::add_mass_to_accretor(real mdot, const real dt) {
00450 
00451         if (mdot<0) {
00452            cerr << "helium_star::add_mass_to_accretor(mdot=" 
00453                  << mdot << ")"<<endl;
00454            cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00455            return 0;
00456         }
00457 
00458         mdot = accretion_limit(mdot, dt);
00459         adjust_accretor_age(mdot);
00460         if (relative_mass<get_total_mass() + mdot)
00461            relative_mass = get_total_mass() + mdot;
00462 
00463 // (GN+SPZ May  3 1999) Langer wind: see helium_star::stellar_wind
00464 //      update_wind_constant();
00465 
00466         envelope_mass += mdot;
00467 
00468         set_spec_type(Accreting);
00469 
00470         return mdot;
00471 
00472      }
00473 
00474 real helium_star::accretion_limit(const real mdot, const real dt) {
00475        
00476         real eddington = 1.5e-08*cnsts.parameters(solar_radius)*radius*dt;
00477 
00478         if(mdot>=eddington) return eddington;
00479 
00480         return mdot;
00481 }
00482 
00483 
00484 
00485 void helium_star::adjust_accretor_age(const real mdot,
00486                                       const bool rejuvenate) {
00487 
00488     relative_age *= (1-pow(mdot/(get_total_mass()+mdot),
00489                     cnsts.parameters(rejuvenation_exponent)));
00490 
00491 }
00492 
00493 // Helium stars have radiative envelopes.
00494 // this requires more research (SPZ+GN: 3 Oct 1998)
00495 real helium_star::zeta_adiabatic() {
00496 
00497   real z = 15;
00498   
00499   return z;
00500 
00501 }
00502 
00503 real helium_star::zeta_thermal() {
00504 
00505 // (GN+SPZ May  3 1999) see evolve_element; mass - radius relation
00506   if (get_total_mass() < 0.2 ) {
00507     return -0.19;
00508   } else {
00509     return 1;
00510   }
00511 }
00512 
00513 real helium_star::final_CO_core_mass(const real initial_mass) {
00514 
00515   // Implementation of Nelemans YPZV 2000 (A&A submitted)
00516   // Itroduces discontinuity at relative_mass = 2.2
00517   // bases on Habets 1986 & IT85
00518   // (SPZ+GN: 27 Jul 2000)
00519   real final_coremass_fraction;
00520   if(relative_mass >= cnsts.parameters(maximum_main_sequence))
00521     final_coremass_fraction = 1;
00522   else if(initial_mass <= 0.8) 
00523     final_coremass_fraction = 1;
00524   else if(initial_mass >= cnsts.parameters(helium2neutron_star)) 
00525     final_coremass_fraction = 0.65;
00526   else 
00527     final_coremass_fraction = 1 - 0.32 * (initial_mass - 0.8);
00528 
00529   return final_coremass_fraction*initial_mass;
00530 }
00531 
00532 real helium_star::CO_core_mass() {
00533 
00534   real m_core = final_core_mass * relative_age/next_update_age;
00535   m_core = max(core_mass, m_core);
00536 
00537   return min(m_core, get_total_mass());
00538 }
00539 
00540 void helium_star::stellar_wind(const real dt) {
00541 
00542 //cerr<<"void helium_star::stellar_wind(dt="<<dt<<") = ";
00543 
00544             real kappa = pow(get_total_mass(),2.5);
00545 
00546 //      real kappa = wind_constant;
00547 //        real wmlc = wind_constant;
00548 //        wind_constant = kappa;
00549 
00550 //              WR Wind
00551 //              Langer, N., 1989, AA 220, 135.
00552         if(get_total_mass()>core_mass) {
00553 //           kappa = 0.5*(kappa + wmlc);
00554 //           real wind_mass = 0.005*dt*kappa;
00555 // (GN+SPZ May  3 1999) Lager wind (again)
00556 // Langer: M_dot = 5-10 10^-8 M^2.5
00557 
00558           real wind_mass = 0.05*dt*kappa;
00559 // (GN+SPZ May 12 1999) proper integration
00560           real m = get_total_mass();
00561           real constant = 0.05;
00562 
00563           real m_next = pow((pow(m,-1.5) + 1.5*constant*dt),-1/1.5);
00564           wind_mass = m - m_next;
00565 //        PRC(m);PRC(m_next);PRL(wind_mass);
00566 //           real wind_mass = 0.0025*dt*kappa;
00567 // (GN+SPZ May  3 1999) low mass helium stars have no wind
00568 // helium_giant looses envlope
00569           if (get_total_mass() < 2.5 ) wind_mass = 0.;
00570 
00571            if (wind_mass>=envelope_mass) {
00572               wind_mass = envelope_mass;
00573               radius = core_radius;
00574            }
00575 
00576            if (is_binary_component())
00577               get_binary()->adjust_binary_after_wind_loss(
00578                           this, wind_mass, dt);
00579            else
00580               reduce_mass(wind_mass);
00581               return;
00582         }
00583    } 
00584 
00585 
00586 real helium_star::gyration_radius_sq() {
00587 
00588   return cnsts.parameters(radiative_star_gyration_radius_sq); 
00589 }
00590 
00591 
00592 // (GN+SPZ May  3 1999) NOT USED!, but called by post_constructor
00593 void helium_star::update_wind_constant() {
00594 
00595   wind_constant = (1 - cnsts.parameters(helium_star_final_core_fraction))
00596                       * get_total_mass();
00597 }
00598 
00599 stellar_type helium_star::get_element_type() {
00600   if (envelope_mass <= 0) 
00601     return Carbon_Star;
00602   else
00603     return Helium_Star;
00604 }
00605 
00606 real helium_star::temperature() {
00607   real T_eff = cnsts.parameters(Tsun)
00608              * sqrt(sqrt(luminosity)/effective_radius);
00609   return T_eff;
00610   //return sqrt(33.45*sqrt(luminosity)/effective_radius);
00611 }

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