Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

helium_giant.C

Go to the documentation of this file.
00001 //
00002 // helium_giant.C
00003 //
00004 
00005 #include "super_giant.h"
00006 #include "helium_star.h"
00007 #include "helium_giant.h"
00008 
00009 
00010 // (GN+SPZ May  3 1999) only for stars more massive than 
00011 // super_giant2neutron_star, below become white_dwarf
00012 // to be done (SPZ+GN: 27 Jul 2000)
00013 helium_giant::helium_giant(super_giant & g) : single_star(g) {
00014 
00015     delete &g;
00016 
00017 // (GN+SPZ May  4 1999) last update age is time of previous type change
00018   last_update_age = next_update_age;
00019 
00020     real second_dredge_up_time = next_update_age 
00021                           * min(1., relative_mass
00022                           / cnsts.parameters(super_giant2neutron_star));
00023 
00024     real remaining_time = second_dredge_up_time - relative_age;
00025     next_update_age = helium_time();
00026     relative_age = next_update_age - remaining_time;
00027     last_update_age = relative_age;
00028 
00029     // (SPZ+GN: 27 Jul 2000)
00030     // core mass has been set in super_giant before construcor is called.
00031 
00032     instantaneous_element();
00033     update();
00034     
00035     post_constructor();
00036  }
00037 
00038 helium_giant::helium_giant(helium_star & h) : single_star(h) {
00039 
00040     delete &h;
00041     
00042 // (GN+SPZ May  4 1999) last update age is time of previous type change
00043     last_update_age = next_update_age;
00044 
00045     adjust_next_update_age();
00046 
00047     update_wind_constant();
00048     
00049     instantaneous_element();
00050     update();
00051 
00052     post_constructor();
00053 
00054 }
00055 
00056 void helium_giant::instantaneous_element() {
00057 
00058   real m_tot = get_total_mass();
00059 
00060   real temp = log10(m_tot)
00061             * (0.4509 - 0.1085*log10(m_tot)) + 4.7143;
00062   luminosity  = 8.33*temp - 36.8;
00063   temp = 1.e-3*pow(10., temp);
00064   luminosity  = pow(10., luminosity);
00065   effective_radius = radius = 33.45*sqrt(luminosity)/(temp*temp);
00066   core_radius = 0.2*radius;
00067   
00068   if (envelope_mass > 0) {
00069     if (m_tot>=2.7)
00070       radius = 12./get_total_mass();
00071     else if (m_tot>=2.0) 
00072       radius *= 250;
00073     else if (m_tot>=1.0) 
00074       radius *= 150;
00075     else radius *= 6;
00076   }
00077   else {
00078     effective_radius = radius = core_radius;
00079   }
00080 }
00081 
00082 void helium_giant::evolve_element(const real end_time) {
00083 
00084         real dt = end_time - current_time;
00085         current_time = end_time;
00086         relative_age += dt;
00087   
00088         real m_tot = get_total_mass();
00089 
00090         if (relative_age<=next_update_age) {
00091             real tmp = log10(m_tot)
00092                 * (0.4509 - 0.1085*log10(m_tot)) + 4.7143;
00093             luminosity  = pow(10., 8.33*tmp - 36.8);
00094             tmp = pow(1.e-3*pow(10., tmp), 2);
00095             radius = 33.45*sqrt(luminosity)/tmp;
00096             core_radius = 0.2*radius;
00097 
00098 //              Helium giant branch.
00099 //              Imitate: Habets, GMHJ, 1986, A&A 167, 61.
00100             if (envelope_mass > cnsts.safety(minimum_mass_step)) {
00101                   if (m_tot>=2.7)
00102                      radius = 12./get_total_mass();
00103                   else if (m_tot>=2.0) 
00104                      radius *= 250;
00105                   else if (m_tot>=1.0) 
00106                      radius *= 150;
00107                   else radius *= 6;
00108             }
00109             else {
00110                radius = core_radius;
00111             }
00112          }
00113          else {
00114             stellar_wind(dt);
00115             create_remnant();
00116             return;
00117          }
00118 
00119          update();
00120          stellar_wind(dt);
00121 
00122 }
00123 
00124 void helium_giant::update() {
00125 
00126   real m_tot = get_total_mass();
00127   core_mass = COcore_mass = CO_core_mass();
00128   envelope_mass = m_tot - core_mass;
00129 
00130   // removed (SPZ+GN:10 Nov 1998)
00131   //core_radius = helium_core_radius();
00132 
00133   detect_spectral_features();
00134 // (GN+SPZ May  4 1999) last_update_age now used as time of last type change
00135 //  last_update_age = relative_age;
00136   effective_radius = radius;
00137 }
00138 
00139 // should only be used in constructors.
00140 // (SPZ+GN:30 Sep 1998)
00141 void helium_giant::adjust_next_update_age() {
00142 
00143   next_update_age /= cnsts.parameters(helium_star_lifetime_fraction);
00144 
00145 }
00146 
00147 
00148 void helium_giant::create_remnant() {
00149 
00150      if (is_binary_component()) 
00151        get_binary()->dump("binev.data", false);
00152      else
00153        dump("binev.data", false);
00154 
00155         stellar_type type = NAS;
00156      //if (get_total_mass() >= cnsts.parameters(helium2black_hole)) 
00157 //           type = Black_Hole;
00158 
00159      if (relative_mass >= cnsts.parameters(maximum_main_sequence) &&
00160          relative_mass < 300)
00161        type = Disintegrated;
00162      else if (core_mass >= cnsts.parameters(COcore2black_hole)) 
00163        type = Black_Hole;
00164      else if(core_mass >= cnsts.parameters(Chandrasekar_mass))
00165        type = Neutron_Star;
00166      else
00167        type = Carbon_Dwarf;
00168 
00169 #if 0 //(SPZ+GN: 27 Jul 2000)
00170      // (GN+SPZ May  3 1999) core mass > 1.4 or total mass > 2.2 
00171         else if(core_mass >= cnsts. //(GN+SPZ May  3 1999) was 1.3 * cnsts
00172                              parameters(Chandrasekar_mass) ||
00173                 get_total_mass() >= cnsts.parameters(helium2neutron_star))
00174           type = Neutron_Star;
00175         
00176         // else if(get_total_mass()>=
00177         //         1.3*cnsts.parameters(kanonical_neutron_star_mass) &&
00178         //         relative_mass>=8) 
00179         // type = Disintegrated;
00180         else
00181            type = Carbon_Dwarf;
00182 #endif // (SPZ+GN: 27 Jul 2000)
00183 
00184         switch (type) {
00185           case Black_Hole : star_transformation_story(Black_Hole);
00186                             new black_hole(*this); 
00187                             break;
00188           case Neutron_Star : star_transformation_story(Neutron_Star);
00189                             new neutron_star(*this);
00190                             break;
00191           case Disintegrated : star_transformation_story(Disintegrated);
00192                                new disintegrated(*this);
00193                                break;
00194           case Carbon_Dwarf : star_transformation_story(Carbon_Dwarf);
00195                               new white_dwarf(*this);
00196                               break;
00197           default :   cerr << "helium_star::create_remnant()" <<endl;
00198                       cerr << "star_type not recognized." << endl;
00199        }
00200 
00201      }
00202 
00203 
00204 star* helium_giant::subtrac_mass_from_donor(const real dt, real& mdot) {
00205 
00206       mdot = relative_mass*dt/get_binary()->get_donor_timescale();
00207 
00208       mdot = mass_ratio_mdot_limit(mdot);
00209       
00210       if (mdot<envelope_mass)
00211          envelope_mass -= mdot;
00212       else {
00213          mdot = envelope_mass;
00214          envelope_mass = 0;
00215         
00216          if (core_mass <= cnsts.parameters(minimum_helium_star)) {
00217             star_transformation_story(Carbon_Dwarf);
00218             return dynamic_cast(star*, new white_dwarf(*this));
00219          }
00220       }
00221 
00222       return this;
00223 }
00224 
00225 star* helium_giant::reduce_mass(const real mdot) {
00226 
00227       if (mdot < envelope_mass)
00228         envelope_mass -= mdot;
00229       else {
00230         real rest_mdot = mdot;
00231         rest_mdot -= envelope_mass;
00232         envelope_mass = 0;
00233            
00234         if (core_mass>rest_mdot) {
00235           if (core_mass-rest_mdot<=
00236               cnsts.parameters(minimum_helium_star)) {
00237             core_mass -= rest_mdot;
00238             COcore_mass = core_mass;
00239           }
00240           else {
00241             core_mass -= rest_mdot;
00242             COcore_mass = core_mass;
00243           }
00244         }
00245         else {
00246           cerr << "ERROR!:"<<endl;
00247           cerr << "void helium_giant::reduce_mass(mdot="
00248                << rest_mdot<<")"<<endl;
00249           cerr << "mdot exceeds helium core mass ("<<core_mass
00250                << ")"<<endl;
00251           cerr << "Decision: Disintegrate helium star!"<<endl;
00252           
00253           star_transformation_story(Disintegrated);
00254           return dynamic_cast(star*, new disintegrated(*this));
00255         }
00256       }
00257 
00258       return this;
00259 }
00260 
00261 
00262 real helium_giant::add_mass_to_accretor(const real mdot) {
00263 
00264         if (mdot<0) {
00265 
00266            cerr << "helium_star::add_mass_to_accretor(mdot=" 
00267                 << mdot << ")"<<endl;
00268            cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00269 
00270            return 0;
00271 
00272         }
00273 
00274         adjust_accretor_age(mdot);
00275         envelope_mass += mdot;
00276         relative_mass = max(relative_mass, get_total_mass());
00277 
00278         // next_update_age should nog be altered here (SPZ+GN: 3 Oct 1998)
00279 
00280 // (GN+SPZ May  5 1999) wind_constant must be zero-age envelope mass, 
00281 // not current
00282 //      update_wind_constant();
00283         wind_constant += mdot;
00284 
00285         set_spec_type(Accreting);
00286         
00287         return mdot;
00288 
00289      }
00290 
00291 real helium_giant::add_mass_to_accretor(real mdot, const real dt) {
00292 
00293         if (mdot<0) {
00294 
00295           cerr << "helium_star::add_mass_to_accretor(mdot=" 
00296                << mdot << ")" <<endl;
00297           cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00298         }
00299 
00300         mdot = accretion_limit(mdot, dt);
00301         adjust_accretor_age(mdot);
00302         envelope_mass += mdot;
00303 // (GN+SPZ May  5 1999) wind_constant must be zero-age envelope mass, 
00304 // not current
00305 //      update_wind_constant();
00306         wind_constant += mdot;
00307         relative_mass = max(relative_mass, get_total_mass());
00308 
00309         set_spec_type(Accreting);
00310         
00311         return mdot;
00312 
00313      }
00314 
00315 real helium_giant::accretion_limit(const real mdot, const real dt) {
00316        
00317      real mdot_limit = mdot;
00318 
00319      real eddington = 1.5e-08*cnsts.parameters(solar_radius)*radius*dt;
00320      if (mdot>=eddington)
00321        mdot_limit =  eddington;
00322 
00323      if (envelope_mass<=0)
00324        mdot_limit = 0;
00325 
00326      return mdot_limit;
00327 
00328 }
00329 
00330 void helium_giant::adjust_accretor_age(const real mdot,
00331                                        const bool rejuvenate) {
00332 
00333       real frac = (1-pow(mdot/(get_total_mass()+mdot),
00334                              cnsts.parameters(rejuvenation_exponent)));
00335       last_update_age *= frac;
00336       relative_age *= frac;
00337 
00338      }
00339 
00340 // see helium_star.C
00341 real helium_giant::zeta_adiabatic() {
00342 
00343      real z = 0;
00344 //      Hjellming and Webbink 1987 ApJ, 318, 804
00345      real x = core_mass/get_total_mass();
00346      real A = -0.220823;
00347      real B = -2.84699;
00348      real C = 32.0344;
00349      real D = -75.6863;
00350      real E = 57.8109;
00351 
00352      if (get_total_mass()<=0.4)
00353         z = -cnsts.mathematics(one_third);
00354      else
00355         z = A + x*(B + x*(C + x*(D + x*E)));
00356 
00357      return z;
00358 
00359    }
00360 
00361 real helium_giant::zeta_thermal() {
00362 
00363     real z = -2;
00364 
00365     if (get_core_mass()<=0.4)  // like a white dwarf
00366         z = -cnsts.mathematics(one_third);
00367 
00368     return z;
00369 
00370 }
00371 
00372 real helium_giant::CO_core_mass() {
00373       // C/O core of helium star grows linearly with time
00374       // (SPZ+GN:26 Sep 1998)
00375 
00376 // (GN+SPZ May  4 1999) core groth totally in helium_star phase: core constant
00377 //  real m_core = get_total_mass()*relative_age/next_update_age;
00378 //  m_core = max(core_mass,m_core);
00379 //    return min(m_core, get_total_mass());
00380 
00381   return min(core_mass, get_total_mass());
00382 }
00383 
00384 void helium_giant::stellar_wind(const real dt) {
00385 
00386 //  PRL(last_update_age);
00387 //  PRL(next_update_age);
00388 //  PRL(relative_age);
00389 //  PRL(previous.relative_age);
00390 //  PRL(dt);
00391 // (GN+SPZ Apr 28 1999) wind for low mass stars per phase
00392     real end_time = next_update_age - last_update_age;
00393     real prev_rel_time = max(0.,previous.relative_age - last_update_age);
00394     real relative_time = min(relative_age - last_update_age, end_time);
00395 
00396 //    PRL(end_time);
00397 //    PRL(relative_time);
00398 //    PRL(prev_rel_time);
00399 //    PRL(wind_constant);
00400     
00401     real wind_mass = wind_constant 
00402                    * (pow(relative_time/end_time,
00403                         cnsts.parameters(massive_star_mass_loss_law))
00404                    -  pow((relative_time-dt)/end_time,
00405                         cnsts.parameters(massive_star_mass_loss_law)));
00406 
00407 // (GN+SPZ May  6 1999) try low wind: 
00408 //    wind_mass = 0.;
00409 
00410 //    PRL(wind_mass);
00411 //    PRL(envelope_mass);
00412 
00413   if (wind_mass>=envelope_mass) {
00414     wind_mass = envelope_mass;
00415     effective_radius = radius = core_radius;
00416   }
00417 
00418   if (is_binary_component())
00419     get_binary()->adjust_binary_after_wind_loss(this, wind_mass, dt);
00420   else
00421     reduce_mass(wind_mass);
00422   return;
00423 }
00424 
00425 real helium_giant::gyration_radius_sq() {
00426 
00427   return cnsts.parameters(radiative_star_gyration_radius_sq); 
00428 }
00429 
00430 // (GN+SPZ May  3 1999) helium_giants loose complete envelope in wind
00431 void helium_giant::update_wind_constant() {
00432 
00433 //  wind_constant = (1 - cnsts.parameters(helium_star_final_core_fraction))
00434 //                * get_total_mass(); 
00435 
00436 // (GN+SPZ May  7 1999) envelope is about 30% of total mass,
00437 // we loose 10% of total mass ....
00438   wind_constant = 0.3*envelope_mass;
00439 
00440 }
00441 
00442 stellar_type helium_giant::get_element_type() {
00443 
00444      stellar_type type = Helium_Giant;
00445      if (envelope_mass <= 0)
00446          type = Carbon_Star;
00447 
00448      return type;
00449      }
00450 
00451 real helium_giant::temperature() {
00452 
00453   real T_eff = cnsts.parameters(Tsun)
00454              * sqrt(sqrt(luminosity)/effective_radius);
00455   
00456   return T_eff;
00457 
00458   //return sqrt(33.45*sqrt(luminosity)/effective_radius);
00459 }
00460 
00461 
00462 bool helium_giant::giant_star() {
00463 
00464   if (envelope_mass > cnsts.safety(minimum_mass_step))
00465     return TRUE;
00466   else
00467     return FALSE;
00468 
00469 }
00470 
00471 bool helium_giant::remnant() {
00472 
00473   if (envelope_mass > cnsts.safety(minimum_mass_step))
00474     return FALSE;
00475   else
00476     return TRUE;
00477 
00478 }
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 

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