00001 #include "hertzsprung_gap.h"
00002 #include "main_sequence.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00026
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
00065
00066
00067
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
00081
00082 void hertzsprung_gap::evolve_element(const real end_time) {
00083
00084
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;
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
00132
00133
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
00156
00157
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
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
00183 mdot = envelope_mass;
00184 envelope_mass = 0;
00185
00186
00187
00188
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
00202 adjust_donor_radius(mdot);
00203
00204 envelope_mass -= mdot;
00205 return this;
00206 }
00207
00208
00209 void hertzsprung_gap::adjust_accretor_age(const real mdot, const bool rejuvenate=true) {
00210
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
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
00238
00239 }
00240
00241
00242
00243 real hertzsprung_gap::zeta_adiabatic() {
00244
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;
00262 else
00263 z = 2.25;
00264 #endif
00265 real z = 4;
00266
00267
00268
00269 return z;
00270 }
00271
00272
00273 real hertzsprung_gap::zeta_thermal() {
00274
00275 real z;
00276
00277 if (get_relative_mass()<=0.4)
00278 z = 0;
00279 else if (low_mass_star())
00280 z = -2;
00281 else
00282 z = -2;
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
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);
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
00345
00346
00347 real hertzsprung_gap::gyration_radius_sq() {
00348
00349 return cnsts.parameters(radiative_star_gyration_radius_sq);
00350 }
00351
00352
00353
00354 real hertzsprung_gap::TAMS_helium_core_mass() {
00355
00356
00357
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
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
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
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
00386 delta_mcore = min(delta_mcore, envelope_mass);
00387
00388
00389
00390
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
00406
00407
00408 void hertzsprung_gap::update_wind_constant() {
00409
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 {
00418 real final_mass = 30;
00419 wind_constant = relative_mass - final_mass;
00420 }
00421
00422 }
00423 else {
00424
00425 wind_constant = 0.01*relative_mass;
00426 }
00427
00428 wind_constant = max(wind_constant, 0.0);
00429 }