00001
00002
00003
00004
00005 #include "sub_giant.h"
00006 #include "hertzsprung_gap.h"
00007
00008
00009
00010
00011 sub_giant::sub_giant(hertzsprung_gap & 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 instantaneous_element();
00021 update();
00022
00023 post_constructor();
00024 }
00025
00026
00027 #if 0
00028 void sub_giant::adjust_initial_star() {
00029
00030 if(relative_age<=0) {
00031 real t_ms = main_sequence_time();
00032 relative_age = max(t_ms + hertzsprung_gap_time(t_ms), relative_age);
00033 }
00034 }
00035 #endif
00036
00037 void sub_giant::instantaneous_element() {
00038
00039
00040 real l_g = giant_luminosity();
00041 real t_ms = main_sequence_time();
00042 real tend_hg = t_ms + hertzsprung_gap_time(t_ms);
00043 real t_gs = 0.15*main_sequence_time();
00044
00045 real tau = t_gs / (tend_hg + t_gs - relative_age);
00046
00047
00048
00049
00050 luminosity = l_g*pow(tau, 1.17);
00051 luminosity = min(luminosity, maximum_luminosity());
00052
00053
00054
00055
00056
00057 radius = (0.25*pow(luminosity, 0.4) + 0.8*pow(luminosity, 0.67))
00058 / pow(relative_mass, 0.27);
00059 }
00060
00061
00062
00063 void sub_giant::evolve_element(const real end_time) {
00064
00065 real dt = end_time - current_time;
00066 current_time = end_time;
00067 relative_age += dt;
00068
00069 if (relative_age<=next_update_age) {
00070 real l_g = giant_luminosity();
00071 real t_ms = main_sequence_time();
00072 real tend_hg = t_ms + hertzsprung_gap_time(t_ms);
00073 real t_gs = 0.15*main_sequence_time();
00074
00075 real tau = t_gs / (tend_hg + t_gs - relative_age);
00076 real tau_prev = t_gs
00077 / (tend_hg + t_gs - (relative_age-dt));
00078
00079 luminosity = l_g*pow(tau, 1.17);
00080 luminosity = min(luminosity, maximum_luminosity());
00081
00082 radius = (0.25*pow(luminosity, 0.4) + 0.8*pow(luminosity, 0.67))
00083 / pow(relative_mass, 0.27);
00084
00085
00086
00087 real m_tot = get_total_mass();
00088 real new_mcore;
00089 if (relative_mass <
00090 cnsts.parameters(upper_ZAMS_mass_for_degenerate_core)) {
00091 new_mcore = max(core_mass, 0.146*pow(luminosity, 0.143));
00092 }
00093 else {
00094
00095 real X = cnsts.parameters(hydrogen_fraction);
00096
00097 new_mcore = core_mass
00098 + l_g*6*t_gs*(pow(tau,1./6)-pow(tau_prev,1./6.))
00099 / (X*cnsts.parameters(energy_to_mass_in_internal_units));
00100 }
00101
00102
00103
00104
00105
00106 core_mass = min(m_tot, new_mcore);
00107 envelope_mass = m_tot - core_mass;
00108
00109
00110 }
00111 else {
00112
00113
00114 star_transformation_story(Horizontal_Branch);
00115 new horizontal_branch(*this);
00116 return;
00117 }
00118
00119 update();
00120 stellar_wind(dt);
00121 }
00122
00123 star* sub_giant::reduce_mass(const real mdot) {
00124
00125 if (envelope_mass<=mdot) {
00126 envelope_mass = 0;
00127
00128
00129
00130
00131 if (get_total_mass() < cnsts.parameters(helium_dwarf_mass_limit) &&
00132 relative_mass < cnsts.parameters(
00133 upper_ZAMS_mass_for_degenerate_core)) {
00134 star_transformation_story(Helium_Dwarf);
00135 return dynamic_cast(star*, new white_dwarf(*this));
00136 }
00137 else {
00138 star_transformation_story(Helium_Star);
00139 return dynamic_cast(star*, new helium_star(*this));
00140 }
00141 }
00142
00143 envelope_mass -= mdot;
00144 return this;
00145 }
00146
00147 star* sub_giant::subtrac_mass_from_donor(const real dt, real& mdot) {
00148
00149 mdot = relative_mass*dt/get_binary()->get_donor_timescale();
00150 mdot = mass_ratio_mdot_limit(mdot);
00151
00152 if (envelope_mass<=mdot) {
00153 mdot = envelope_mass;
00154 envelope_mass = 0;
00155
00156
00157
00158
00159 if (get_total_mass() < cnsts.parameters(helium_dwarf_mass_limit) &&
00160 relative_mass < cnsts.parameters(
00161 upper_ZAMS_mass_for_degenerate_core)) {
00162 star_transformation_story(Helium_Dwarf);
00163 return dynamic_cast(star*, new white_dwarf(*this));
00164 }
00165 else {
00166 star_transformation_story(Helium_Star);
00167 return dynamic_cast(star*, new helium_star(*this));
00168 }
00169 }
00170
00171
00172 adjust_donor_radius(mdot);
00173
00174 envelope_mass -= mdot;
00175 return this;
00176 }
00177
00178 void sub_giant::adjust_accretor_age(const real mdot,
00179 const bool rejuvenate=true) {
00180
00181 real t_ms = main_sequence_time();
00182 real tend_hg_old = hertzsprung_gap_time(t_ms) + t_ms;
00183 real t_bgb_old = base_giant_branch_time(t_ms);
00184
00185 real m_tot_new = get_total_mass() + mdot;
00186 real m_rel_new = max(m_tot_new, relative_mass);
00187
00188 t_ms = main_sequence_time(m_rel_new);
00189 real tend_hg_new = t_ms + hertzsprung_gap_time(m_rel_new, t_ms);
00190 real t_bgb_new = base_giant_branch_time(m_rel_new, t_ms);
00191
00192 real dtime = relative_age - tend_hg_old;
00193
00194
00195
00196
00197 if (t_bgb_new>0) {
00198
00199
00200 last_update_age = tend_hg_new;
00201 relative_age = tend_hg_new
00202 + dtime*(t_bgb_new/t_bgb_old);
00203 if (rejuvenate) {
00204
00205
00206
00207 relative_age *= rejuvenation_fraction(mdot/m_tot_new);
00208
00209 }
00210
00211 relative_age = max(relative_age,
00212 last_update_age + cnsts.safety(minimum_timestep));
00213 }
00214 else {
00215
00216
00217
00218 relative_age = tend_hg_new;
00219 }
00220
00221
00222
00223
00224 }
00225
00226 void sub_giant::adjust_next_update_age() {
00227
00228 real t_ms = main_sequence_time();
00229 real t_giant = t_ms + hertzsprung_gap_time(t_ms)
00230 + base_giant_branch_time(t_ms);
00231
00232 next_update_age = t_giant;
00233 }
00234
00235 void sub_giant::detect_spectral_features() {
00236
00237 single_star::detect_spectral_features();
00238
00239
00240 if (accreted_mass>=cnsts.parameters(B_emission_star_mass_limit))
00241 spec_type[Emission]=Emission;
00242
00243 }
00244
00245 #if 0
00246 real sub_giant::stellar_radius(const real mass, const real new_age) {
00247
00248 real t_ms = main_sequence_time(mass);
00249 real t_giant = t_ms + hertzsprung_gap_time(mass, t_ms)
00250 + base_giant_branch_time(mass, t_ms);
00251
00252 real age = new_age;
00253 if(new_age<t_giant)
00254 age = new_age;
00255
00256 real l_g = giant_luminosity(mass);
00257 real tend_hg = t_ms + hertzsprung_gap_time(mass, t_ms);
00258 real t_gs = 0.15*t_ms;
00259
00260 real l_sg = l_g*pow(t_gs/(tend_hg + t_gs - age), 1.17);
00261 l_sg = min(l_sg, maximum_luminosity(mass));
00262
00263 real r_sg = (0.25*pow(l_sg, 0.4) + 0.8*pow(l_sg, 0.67))
00264 / pow(mass, 0.27);
00265
00266 return r_sg;
00267 }
00268 #endif
00269
00270 real sub_giant::gyration_radius_sq() {
00271
00272 return cnsts.parameters(convective_star_gyration_radius_sq);
00273 }
00274
00275
00276 real sub_giant::zeta_adiabatic() {
00277
00278
00279
00280
00281 real r_dconv = 2.4*pow(relative_mass,1.56);
00282 if (relative_mass > 10 )
00283 r_dconv = 5.24*pow(relative_mass,1.32);
00284 else if (relative_mass > 5)
00285 r_dconv = 1.33*pow(relative_mass,1.93);
00286
00287 if (radius < r_dconv) {
00288
00289 return 4;
00290 }
00291 else {
00292
00293 real x = core_mass/get_total_mass();
00294 real A = -0.220823;
00295 real B = -2.84699;
00296 real C = 32.0344;
00297 real D = -75.6863;
00298 real E = 57.8109;
00299
00300 return A + x*(B + x*(C + x*(D + x*E)));
00301
00302 }
00303 }
00304
00305
00306 real sub_giant::zeta_thermal() {
00307
00308
00309 real z;
00310 if (low_mass_star())
00311 z = 0;
00312 else
00313 z = 0;
00314
00315 return z;
00316 }
00317
00318
00319
00320
00321 void sub_giant::update_wind_constant() {
00322
00323
00324
00325 if (relative_mass >= cnsts.parameters(super_giant2neutron_star)) {
00326
00327 real meader_fit_dm = 0.01*pow(relative_mass,2.);
00328
00329 if (relative_mass < 85)
00330 wind_constant = meader_fit_dm;
00331 else {
00332 real final_mass = 30;
00333 wind_constant = relative_mass - final_mass;
00334 }
00335
00336 }
00337 else {
00338
00339
00340
00341
00342
00343
00344 wind_constant = max(0., (2.5 - relative_mass)/7.5);
00345
00346
00347
00348
00349
00350
00351 }
00352
00353 wind_constant = max(wind_constant, 0.0);
00354
00355 }
00356
00357