Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

horizontal_branch.C

Go to the documentation of this file.
00001 //
00002 // horizontal_branch.C
00003 //
00004 
00005 #include "horizontal_branch.h"
00006 #include "sub_giant.h"
00007 #include "hertzsprung_gap.h"
00008 
00009 // ANSI C++ first creates the base class before the dreived classes are
00010 // created.
00011 //
00012 
00013 horizontal_branch::horizontal_branch(sub_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     adjust_next_update_age();
00021 
00022     instantaneous_element();
00023     update();
00024 
00025     post_constructor();
00026 }
00027 
00028 horizontal_branch::horizontal_branch(hertzsprung_gap & h) : single_star(h) {
00029 
00030     delete &h;
00031 
00032 // (GN+SPZ May  4 1999) last update age is time of previous type change
00033   last_update_age = next_update_age;
00034 
00035     adjust_next_update_age();
00036 
00037     instantaneous_element();
00038     update();
00039 
00040     post_constructor();
00041       
00042 }
00043 
00044 #if 0
00045 void horizontal_branch::adjust_initial_star() {
00046 
00047   if(relative_age<=0) {
00048     real t_ms = main_sequence_time();
00049     real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00050                  + base_giant_branch_time(t_ms);
00051     relative_age = max(t_giant, relative_age);
00052   }
00053 }
00054 #endif
00055 
00056 
00057 void horizontal_branch::instantaneous_element() {
00058 
00059     luminosity = min(helium_giant_luminosity(), 
00060                      maximum_luminosity());
00061 
00062     radius = (0.25*pow(luminosity, 0.4)
00063            + 0.8*pow(luminosity, 0.67))/pow(relative_mass, 0.27);
00064 
00065     real t_ms = main_sequence_time();
00066     real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00067                  + base_giant_branch_time(t_ms);
00068     real t_he = helium_giant_time(t_ms);
00069   
00070     real ff = (relative_age - t_giant)/t_he;
00071     if (radius<=25)
00072       radius *= 1.0 - 0.1*ff;
00073     else
00074       radius *= pow(25.0/radius, ff); // Giant
00075 
00076     // (SPZ+GN:  1 Aug 2000)
00077     // coming from previous type the effective readius should 
00078     // remain the same.
00079     //    effective_radius = radius;
00080 }
00081 
00082 // evolve a horizontal_branch star upto time argument according to
00083 // the model discribed by Eggleton et al. 1989.
00084 void horizontal_branch::evolve_element(const real end_time) {
00085 
00086       real dt = end_time - current_time;
00087       current_time = end_time;
00088       relative_age += dt;
00089 
00090       if (relative_age<=next_update_age) {
00091          luminosity = min(helium_giant_luminosity(), 
00092                           maximum_luminosity());
00093 
00094          evolve_core_mass(dt);
00095          
00096          radius = (0.25*pow(luminosity, 0.4)
00097                 + 0.8*pow(luminosity, 0.67))/pow(relative_mass, 0.27);
00098 
00099          real t_ms = main_sequence_time();
00100          real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00101                              + base_giant_branch_time(t_ms);
00102          real t_he = helium_giant_time(t_ms);
00103 
00104          real ff = (relative_age - t_giant)/t_he;
00105          if (radius<=25)
00106             radius *= 1.0 - 0.1*ff;
00107          else
00108             radius *= pow(25.0/radius, ff); // Giant
00109       }
00110       else {
00111         // Core mass remains unchanged: second dredge-up 
00112         // accounted for in Super_Giant (SPZ+GN: 27 Jul 2000)
00113         star_transformation_story(Super_Giant);
00114         new super_giant(*this);
00115          return;
00116       }
00117 
00118       update();
00119       stellar_wind(dt);
00120    }
00121 
00122 // Post-evolution stellar update.
00123 // Makes sure age and radius are updated.
00124 void horizontal_branch::update() {
00125 
00126   // New core mass determination occurs in ::evolve_element.
00127   // (SPZ+GN:09/1998)
00128   // real m_tot = get_total_mass();
00129   // core_mass = helium_core_mass();
00130   // envelope_mass = m_tot - core_mass;
00131 
00132   core_radius = helium_core_radius();
00133 
00134 // (GN+SPZ Apr 28 1999)
00135 // effective_radius can not be larger than radius for horizontal branch stars
00136   effective_radius = radius;
00137 
00138   detect_spectral_features();
00139 
00140 }
00141 
00142 star* horizontal_branch::reduce_mass(const real mdot) {
00143 
00144       if (envelope_mass<=mdot) {
00145          envelope_mass = 0;
00146          star_transformation_story(Helium_Star);
00147          return dynamic_cast(star*, new helium_star(*this));
00148       }
00149 
00150       envelope_mass -= mdot;
00151       return this;
00152    }
00153 
00154 star* horizontal_branch::subtrac_mass_from_donor(const real dt,
00155                                                  real& mdot) {
00156 
00157       real mdot_temp = relative_mass*dt/get_binary()->get_donor_timescale();
00158       mdot = mass_ratio_mdot_limit(mdot_temp);
00159 
00160       if (envelope_mass<=mdot) {
00161          mdot = envelope_mass;
00162          envelope_mass = 0;
00163          star_transformation_story(Helium_Star);
00164          return dynamic_cast(star*, new helium_star(*this));
00165       }
00166 
00167       envelope_mass -= mdot;
00168       return this;
00169    }
00170 
00171 void horizontal_branch::adjust_accretor_age(const real mdot, const bool rejuvenate=true) {
00172 
00173       real m_rel_new;
00174       real m_tot_new = get_total_mass() + mdot;
00175       if (m_tot_new>relative_mass)
00176          m_rel_new = m_tot_new;
00177       else m_rel_new = relative_mass;
00178 
00179       real t_ms = main_sequence_time();
00180       real t_giant_old = t_ms + hertzsprung_gap_time(t_ms) 
00181                               + base_giant_branch_time(t_ms);
00182       real t_he_old = helium_giant_time(t_ms);
00183 
00184       t_ms = main_sequence_time(m_rel_new);
00185       real t_giant_new = t_ms + hertzsprung_gap_time(m_rel_new, t_ms) 
00186                               + base_giant_branch_time(m_rel_new, t_ms);
00187       real t_he_new = helium_giant_time(m_rel_new, t_ms); 
00188 
00189       real dtime = relative_age - t_giant_old;
00190 
00191 // (GN+SPZ May  4 1999) update last_update_age
00192       last_update_age = t_giant_new;
00193       relative_age = t_giant_new
00194                    + dtime*(t_he_new/t_he_old);
00195       if (rejuvenate)
00196          relative_age *= rejuvenation_fraction(mdot/m_tot_new);
00197 
00198       relative_age = max(relative_age, 
00199                          last_update_age + cnsts.safety(minimum_timestep));
00200 
00201       // next_update_age should not be reset here
00202       // next_update_age = t_giant_new + t_he_new;
00203 
00204    }
00205 
00206 real horizontal_branch::zeta_adiabatic() {
00207       return 15;        
00208    }
00209 
00210 real horizontal_branch::zeta_thermal() {
00211       return 15;
00212    }
00213 
00214 void horizontal_branch::adjust_next_update_age() {
00215      
00216       real t_ms = main_sequence_time();
00217       real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00218                           + base_giant_branch_time(t_ms);
00219       real t_he = helium_giant_time(t_ms);
00220       next_update_age = t_giant + t_he;
00221    }
00222 
00223 real horizontal_branch::gyration_radius_sq() {
00224 
00225   return cnsts.parameters(radiative_star_gyration_radius_sq); 
00226 }
00227 
00228 void horizontal_branch::evolve_core_mass(const real dt) {
00229 
00230   real X = cnsts.parameters(hydrogen_fraction);
00231   // (SPZ+GN: 27 Jul 2000) Factor 0.5 introduced to model
00232   // that the luminosity is partially generated by core burning.
00233   // see Nelemans YPZV 2000
00234   real delta_mcore = 0.5 * luminosity*dt 
00235                    / (X * cnsts.parameters(energy_to_mass_in_internal_units));
00236 
00237   //(SPZ+GN: 31 Jul 2000)
00238   // removed the safety, nothing against type change by core growth.
00239   //  delta_mcore = min(delta_mcore, 
00240   //                envelope_mass-cnsts.safety(minimum_mass_step));
00241   delta_mcore = min(delta_mcore, envelope_mass);
00242 
00243   if (delta_mcore<0) {
00244       PRC(luminosity);PRC(dt);PRL(delta_mcore);
00245       cerr << "Core mass increas is negative in horizontal_branch::evolve_core_mass()"<<endl;
00246       delta_mcore = 0;
00247       exit(-1);
00248 //      return;
00249   }
00250 
00251   envelope_mass -= delta_mcore; 
00252   core_mass += delta_mcore;
00253       
00254 }
00255 
00256 // wind_constant is fraction of envelope lost in nuclear lifetime
00257 // of stars. Should be updated after mass accretion
00258 // (SPZ+GN: 1 Oct 1998)
00259 void horizontal_branch::update_wind_constant() {
00260   
00261 // (GN+SPZ Apr 28 1999) new fits to Maeder, de Koter and common sense
00262 
00263   if (relative_mass >= cnsts.parameters(super_giant2neutron_star)) {
00264 
00265     real meader_fit_dm = 0.01*pow(relative_mass,2.);
00266     
00267     if (relative_mass < 85)
00268       wind_constant = meader_fit_dm;
00269     else {// constant
00270       real final_mass = 30;
00271       wind_constant = relative_mass - final_mass;
00272     }
00273 
00274   } 
00275   else { // 5% of initial envelope
00276 
00277     wind_constant = 0.05*(relative_mass - final_core_mass());
00278   }
00279   
00280   wind_constant = max(wind_constant, 0.0);
00281 
00282 }

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