Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

hertzsprung_gap.C

Go to the documentation of this file.
00001 #include "hertzsprung_gap.h"
00002 #include "main_sequence.h"
00003 
00004 // A low mass (M<25M_\odot) main_sequence star will transform
00005 // into a hertzsprung_gap star after the exhaustion of hydrogen 
00006 // in the core.
00007 // This constructor 
00008 // copies the old main_sequence star into the newly created 
00009 // hertzsprung_gap star and destroys the old main_sequence star 
00010 // and finally evolves the hertzsprung_gap in order to determine its
00011 // appearence.
00012 //
00013 // ANSI C++ first creates the base class before the derived classes are
00014 // created. 
00015 
00016      hertzsprung_gap::hertzsprung_gap(main_sequence & m) : single_star(m) {
00017 
00018       delete &m;        
00019 
00020       real m_tot    = get_total_mass();
00021       core_mass     = TAMS_helium_core_mass();
00022       envelope_mass = m_tot - core_mass;
00023       core_radius   = helium_core_radius();
00024 
00025 //      PRC(current_time);PRC(relative_age);PRL(next_update_age);
00026 // (GN+SPZ May  4 1999) last update age is time of previous type change
00027       last_update_age = next_update_age;
00028 
00029       adjust_next_update_age();
00030 
00031       instantaneous_element();
00032       update();
00033       
00034       post_constructor();
00035    }
00036 
00037 void hertzsprung_gap::instantaneous_element() {
00038 
00039       real alpha, beta, gamma, delta;
00040 
00041       real log_mass = log10(relative_mass);
00042 
00043       if (relative_mass>1.334) {
00044          alpha = 0.1509 + 0.1709*log_mass;
00045          beta  = 0.06656 - 0.4805*log_mass;
00046          gamma = 0.007395 + 0.5083*log_mass;
00047          delta = (0.7388*pow(relative_mass, 1.679)
00048                - 1.968*pow(relative_mass, 2.887))
00049                / (1.0 - 1.821*pow(relative_mass, 2.337));
00050        }
00051        else {
00052           alpha = 0.08353 + 0.0565*log_mass;
00053           beta  = 0.01291 + 0.2226*log_mass;
00054           gamma = 0.1151 + 0.06267*log_mass;
00055           delta = pow(relative_mass, 1.25)
00056                 * (0.1148 + 0.8604*relative_mass*relative_mass)
00057                 / (0.04651 + relative_mass*relative_mass);
00058        }
00059 
00060       real l_bgb  = base_giant_branch_luminosity();
00061       real rt = delta*pow(10., (alpha + beta + gamma));
00062           
00063       luminosity = l_bgb;
00064       // (SPZ+GN:  1 Aug 2000)
00065       // coming from the main sequence the effective readius should 
00066       // remain the same.
00067 //      effective_radius = radius     = rt;
00068       radius     = rt;
00069 
00070    }
00071 
00072 #if 0
00073 void hertzsprung_gap::adjust_initial_star() {
00074 
00075   if(relative_age<=0)
00076     relative_age = max(main_sequence_time(), relative_age);
00077 }
00078 #endif
00079 
00080 // evolve a hertzsprung_gap star upto time argument according to
00081 // the model described by Eggleton et al. 1989.
00082 void hertzsprung_gap::evolve_element(const real end_time) {
00083 //cerr<<"void hertzsprung_gap::evolve_element(T="<<end_time<<")"<<endl;
00084 //cerr<<luminosity<<" "<<radius<<endl;
00085 
00086       real alpha, beta, gamma, delta;
00087 
00088       real dt = end_time - current_time;
00089       current_time = end_time;
00090       relative_age += dt;
00091 
00092       real log_mass = log10(relative_mass);
00093 
00094       if (relative_mass>1.334) {
00095          alpha = 0.1509 + 0.1709*log_mass;
00096          beta  = 0.06656 - 0.4805*log_mass;
00097          gamma = 0.007395 + 0.5083*log_mass;
00098          delta = (0.7388*pow(relative_mass, 1.679)
00099                - 1.968*pow(relative_mass, 2.887))
00100                / (1.0 - 1.821*pow(relative_mass, 2.337));
00101        }
00102        else {
00103           alpha = 0.08353 + 0.0565*log_mass;
00104           beta  = 0.01291 + 0.2226*log_mass;
00105           gamma = 0.1151 + 0.06267*log_mass;
00106           delta = pow(relative_mass, 1.25)
00107                 * (0.1148 + 0.8604*relative_mass*relative_mass)
00108                 / (0.04651 + relative_mass*relative_mass);
00109        }
00110 
00111        real t_ms   = main_sequence_time();
00112       
00113        if (relative_age<=next_update_age) {
00114 
00115           if(relative_age<t_ms) relative_age = t_ms; // safety
00116           real t_hg   = hertzsprung_gap_time(t_ms);
00117           real l_g    = giant_luminosity();
00118           real l_bgb  = base_giant_branch_luminosity();
00119 
00120           real rt = delta*pow(10., (alpha + beta + gamma));
00121           real rg = (0.25*pow(l_g, 0.4) + 0.8*pow(l_g, 0.67))
00122                   / pow(relative_mass, 0.27);
00123           real ff = (relative_age - t_ms)/t_hg;
00124           luminosity = l_bgb*pow(l_g/l_bgb, ff);
00125           radius = rt*pow(rg/rt, ff);
00126 
00127           evolve_core_mass(dt);
00128        }
00129        else {
00130 
00131          // Stars with M > 20.97184...Msun do not ascend the sub_giant branch
00132          // but become directly a horizontal branch star.
00133          // See Tout et al. 1997, implemented (SPZ+GN:23 Sep 1998)
00134          if (base_giant_branch_time(t_ms)) {
00135           star_transformation_story(Sub_Giant);
00136           new sub_giant(*this);
00137           return;
00138          }
00139          else {
00140           star_transformation_story(Horizontal_Branch);
00141           new horizontal_branch(*this);
00142           return;
00143         }
00144        }
00145 
00146        update();
00147        stellar_wind(dt);
00148 }
00149 
00150 star* hertzsprung_gap::reduce_mass(const real mdot) {
00151 
00152       if (envelope_mass<=mdot) {
00153         envelope_mass = 0;
00154 
00155         // (SPZ+GN: 27 Jul 2000)
00156         // non degenerate core < helium_dwarf_mass_limit always(!) become
00157         // white dwarfs
00158         if (get_total_mass() < cnsts.parameters(helium_dwarf_mass_limit) &&
00159             relative_mass < cnsts.parameters(
00160                             upper_ZAMS_mass_for_degenerate_core)) {
00161           star_transformation_story(Helium_Dwarf);
00162           return dynamic_cast(star*, new white_dwarf(*this));
00163         } 
00164         else {
00165           star_transformation_story(Helium_Star);
00166           return dynamic_cast(star*, new helium_star(*this));
00167         }
00168       }
00169 
00170       envelope_mass -= mdot;
00171       return this;
00172    }
00173 
00174 star* hertzsprung_gap::subtrac_mass_from_donor(const real dt, real& mdot) {
00175 //cerr<<"real hertzsprung_gap::subtrac_mass_from_donor( dt= "<<dt<<")"<<endl;
00176 
00177       mdot = relative_mass*dt/get_binary()->get_donor_timescale();
00178 
00179       mdot = mass_ratio_mdot_limit(mdot);
00180 
00181       if (envelope_mass<=mdot) {
00182 //        cerr << "Transform hertzsprung_gap star into Heliun stars"<<endl;
00183          mdot = envelope_mass;
00184          envelope_mass = 0;
00185 
00186         // (SPZ+GN: 27 Jul 2000)
00187         // non degenerate core < helium_dwarf_mass_limit always(!) become
00188         // white dwarfs
00189         if (get_total_mass() < cnsts.parameters(helium_dwarf_mass_limit) &&
00190             relative_mass < cnsts.parameters(
00191                             upper_ZAMS_mass_for_degenerate_core)) {
00192           star_transformation_story(Helium_Dwarf);
00193           return dynamic_cast(star*, new white_dwarf(*this));
00194         } 
00195         else {
00196           star_transformation_story(Helium_Star);
00197           return dynamic_cast(star*, new helium_star(*this));
00198         }
00199       }
00200 
00201 // (GN+SPZ Apr 29 1999) 
00202       adjust_donor_radius(mdot);
00203 
00204       envelope_mass -= mdot;
00205       return this;
00206    }
00207 
00208 //  relative age adjusted lineairly with accreted mass.
00209 void hertzsprung_gap::adjust_accretor_age(const real mdot, const bool rejuvenate=true) {
00210 //cerr <<"void hertzsprung_gap::adjust_accretor_age("<<mdot<<")"<<endl;
00211 
00212       real m_rel_new;
00213       real m_tot_new = get_total_mass() + mdot;
00214       if (m_tot_new>relative_mass)
00215          m_rel_new = m_tot_new;
00216       else m_rel_new = relative_mass;
00217 
00218       real t_ms_old = main_sequence_time();
00219       real t_hg_old = hertzsprung_gap_time(t_ms_old);
00220 
00221       real t_ms_new = main_sequence_time(m_rel_new);
00222       real t_hg_new = hertzsprung_gap_time(m_rel_new, t_ms_old);
00223 
00224       real dtime = relative_age - t_ms_old;
00225 
00226 // (GN+SPZ May  4 1999) update last_update_age
00227       last_update_age = t_ms_new;
00228 
00229       relative_age = t_ms_new 
00230                    + dtime*(t_hg_new/t_hg_old);
00231       if (rejuvenate)
00232          relative_age *= rejuvenation_fraction(mdot/m_tot_new); 
00233 
00234       relative_age = max(relative_age, 
00235                          last_update_age + cnsts.safety(minimum_timestep)); 
00236       
00237       // next_update_age should not be reset here
00238       // next_update_age = t_ms_new + t_hg_new;
00239    }
00240 
00241 // Adiabatic response function for hertzsprung_gap star.
00242 // Polynomial fit to Hjellming and Webbink 1987 ApJ, 318, 804
00243 real hertzsprung_gap::zeta_adiabatic() {
00244 //cerr<<"real hertzsprung_gap::zeta_adiabatic(): " << endl;
00245 
00246 #if 0
00247       real z;
00248 
00249       real x = core_mass/get_total_mass();
00250       real A = -0.220823;
00251       real B = -2.84699;
00252       real C = 32.0344;
00253       real D = -75.6863;
00254       real E = 57.8109;
00255 
00256       if (get_relative_mass()<=0.4)
00257          z = -cnsts.mathematics(one_third);
00258       else if (low_mass_star())
00259          z = A + x*(B + x*(C + x*(D + x*E)));
00260       else if (medium_mass_star())
00261          z = 2.25;                 // 15 according to Pols & Marinus 1994
00262       else                         // We do it differently.
00263          z = 2.25;                 // lekker puh.
00264 #endif
00265       real z = 4; // this is neede to prevent Thermal in extreme mass
00266                      // ratio systems ... 
00267 // (GN+SPZ Apr 29 1999) Pols & Marinus 1994 were maybe right: not!
00268 
00269       return z;
00270    }
00271 
00272 // Thermal response function for hertzsprung_gap star.
00273 real hertzsprung_gap::zeta_thermal() {
00274 
00275       real z;
00276 
00277       if (get_relative_mass()<=0.4)
00278          z = 0;         // no better estimate present.
00279       else if (low_mass_star())
00280          z = -2;        // -10 according to Pols & Marinus 1994
00281       else              // Changed to current values
00282          z = -2;        // by (SPZ+GN: 1 Oct 1998)
00283 
00284       return z;
00285    }
00286 
00287 void hertzsprung_gap::adjust_next_update_age() {
00288    
00289       real t_ms = main_sequence_time();
00290       if (relative_age<t_ms)
00291          relative_age = t_ms;
00292       next_update_age = t_ms + hertzsprung_gap_time(t_ms);
00293 }
00294 
00295 void hertzsprung_gap::detect_spectral_features() {
00296 
00297 //              Use standard spectral feature detection.
00298       single_star::detect_spectral_features();
00299 
00300       if (accreted_mass>=cnsts.parameters(B_emission_star_mass_limit))
00301         spec_type[Emission]=Emission;
00302    }
00303 
00304 #if 0
00305 real hertzsprung_gap::stellar_radius(const real mass, const real age_max) {
00306 
00307       real alpha, beta, gamma, delta;
00308       real t_ms   = main_sequence_time(mass);
00309       real age = max(t_ms, age_max);            // Safety
00310       real t_hg   = hertzsprung_gap_time(t_ms);
00311 
00312       real log_mass = log10(mass);
00313 
00314       if (mass>1.334) {
00315          alpha = 0.1509 + 0.1709*log_mass;
00316          beta  = 0.06656 - 0.4805*log_mass;
00317          gamma = 0.007395 + 0.5083*log_mass;
00318          delta = (0.7388*pow(mass, 1.679)
00319                - 1.968*pow(mass, 2.887))
00320                / (1.0 - 1.821*pow(mass, 2.337));
00321        }
00322        else {
00323           alpha = 0.08353 + 0.0565*log_mass;
00324           beta  = 0.01291 + 0.2226*log_mass;
00325           gamma = 0.1151 + 0.06267*log_mass;
00326           delta = pow(mass, 1.25)
00327                 * (0.1148 + 0.8604*mass*mass)
00328                 / (0.04651 + mass*mass);
00329        }
00330 
00331        real l_g    = giant_luminosity(mass);
00332 
00333        real rt = delta*pow(10., (alpha + beta + gamma));
00334        real rg = (0.25*pow(l_g, 0.4) + 0.8*pow(l_g, 0.67))
00335                / pow(mass, 0.27);
00336        real ff = (age - t_ms)/t_hg;
00337        real r_hg = rt*pow(rg/rt, ff);
00338 
00339        return r_hg;
00340    }
00341 #endif
00342 
00343 
00344 // Stellar Gyration radii squared for detmination of
00345 // angular momentum.
00346 // Implemented by (SPZ+GN: 1 Oct 1998)
00347 real hertzsprung_gap::gyration_radius_sq() {
00348 
00349   return cnsts.parameters(radiative_star_gyration_radius_sq); 
00350 }
00351 
00352 // Helium core at the terminal-age main-sequence
00353 // (SPZ+GN: 1 Oct 1998)
00354 real hertzsprung_gap::TAMS_helium_core_mass() {
00355 
00356   // (SPZ+GN: 28 Jul 2000)
00357   // old Eggleton 2000 (ToBeBook) fit to core mass.
00358   real mc = (0.11*pow(relative_mass,1.2)
00359           + 7.e-5*pow(relative_mass,4))
00360           / (1+ 2e-4*pow(relative_mass, 3));
00361 
00362   // (SPZ+GN: 28 Jul 2000)
00363   // produces lower mass core betwee 0 and 20 Msun.
00364   // is fine for low mass (<5Msun) stars but too small for 
00365   // high mass (>8Msun) stars.
00366   //  real mc = (0.05 + 0.08*pow(relative_mass,1.2)
00367   //          + 7.e-5*pow(relative_mass,4))
00368   //          / (1+ 2e-4*pow(relative_mass, 3));
00369 
00370   // (SPZ+GN: 31 Jul 2000)
00371   // TAMS core mass must be smaller than get_total_mass to 
00372   // assure that it becomes a helium star decently.
00373   return min(max(mc,core_mass), 
00374              get_total_mass()-cnsts.safety(minimum_mass_step));
00375 
00376 }
00377 
00378 void hertzsprung_gap::evolve_core_mass(const real dt) {
00379 
00380   // (GN Oct 11 1999) correct for hydrogen fraction envelope: X = 0.7
00381   real X = cnsts.parameters(hydrogen_fraction);
00382   real delta_mcore = luminosity*dt
00383                    / (X * cnsts.parameters(energy_to_mass_in_internal_units));
00384 
00385 // (GN+SPZ Apr 29 1999) no type change by core growth
00386   delta_mcore = min(delta_mcore, envelope_mass);
00387   //(SPZ+GN: 31 Jul 2000)
00388   // removed the safety, nothing against type change by core growth.
00389   //  delta_mcore = min(delta_mcore, 
00390   //                envelope_mass-cnsts.safety(minimum_mass_step));
00391 
00392   if (delta_mcore<0) {
00393       PRC(luminosity);PRC(dt);PRL(delta_mcore);
00394       cerr << "Core mass increas is negative in hertzsprung_gap:evolve_core_mass()"<<endl;
00395       delta_mcore = 0;
00396       dump(cerr, false);
00397       exit(-1);
00398       return;
00399   }
00400 
00401   envelope_mass -= delta_mcore; 
00402   core_mass += delta_mcore;
00403 }
00404 
00405 // wind_constant is fraction of envelope lost in nuclear lifetime
00406 // of stars. Should be updated after mass accretion
00407 // (SPZ+GN: 1 Oct 1998)
00408 void hertzsprung_gap::update_wind_constant() {
00409 // (GN+SPZ Apr 28 1999) new fits to Maeder, de Koter and common sense
00410 
00411   if (relative_mass >= cnsts.parameters(super_giant2neutron_star)) {
00412 
00413     real meader_fit_dm = 0.01*pow(relative_mass,2.);
00414     
00415     if (relative_mass < 85)
00416       wind_constant = meader_fit_dm;
00417     else {// constant
00418       real final_mass = 30;
00419       wind_constant = relative_mass - final_mass;
00420     }
00421 
00422   } 
00423   else { // (GN+SPZ Apr 29 1999) 1% loss on hg
00424 
00425     wind_constant = 0.01*relative_mass;
00426   }
00427 
00428   wind_constant = max(wind_constant, 0.0);
00429 }

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