00001
00002
00003
00004
00005 #include "hyper_giant.h"
00006 #include "helium_star.h"
00007 #include "main_sequence.h"
00008
00009 hyper_giant::hyper_giant(main_sequence & m) : single_star(m) {
00010
00011 delete &m;
00012
00013 real m_tot = get_total_mass();
00014 core_mass = hyper_giant_core_mass();
00015 envelope_mass = m_tot - core_mass;
00016
00017
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 void hyper_giant::instantaneous_element() {
00029
00030 luminosity = 10e+5;
00031
00032
00033
00034
00035
00036
00037 if(radius<=0)
00038 effective_radius = radius = 5;
00039 core_radius = 5;
00040
00041
00042 if (envelope_mass <= 0)
00043 radius = core_radius;
00044
00045 }
00046
00047 void hyper_giant::evolve_element(const real end_time) {
00048
00049 real dt = end_time - current_time;
00050 current_time = end_time;
00051 relative_age += dt;
00052
00053 if (relative_age>next_update_age) {
00054 create_remnant();
00055 return;
00056 }
00057
00058
00059
00060
00061 if (get_total_mass() <= cnsts.parameters(minimum_helium_star) ||
00062 envelope_mass < cnsts.safety(minimum_mass_step)) {
00063 star_transformation_story(Helium_Star);
00064 new helium_star(*this);
00065 return;
00066 }
00067
00068
00069
00070
00071
00072
00073 real relative_time = relative_age - last_update_age;
00074 real t_end = next_update_age - last_update_age;
00075 radius =
00076 effective_radius =
00077 max(radius, 1000*relative_time/t_end);
00078
00079
00080
00081 update();
00082 stellar_wind(dt);
00083 }
00084
00085 real hyper_giant::hyper_giant_core_mass() {
00086
00087
00088
00089
00090
00091
00092
00093 real m_core_TY = 0.066*pow(relative_mass, 1.54);
00094 real m_core_max = 20 + 0.27*relative_mass;
00095
00096 real m_core = min(m_core_TY, m_core_max);
00097 if (relative_mass >= cnsts.parameters(maximum_main_sequence))
00098 m_core = get_total_mass();
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 if (m_core>get_total_mass()) m_core = get_total_mass();
00111
00112 return m_core;
00113 }
00114
00115 void hyper_giant::create_remnant() {
00116
00117 if (core_mass>=cnsts.parameters(COcore2black_hole)) {
00118 star_transformation_story(Black_Hole);
00119 new black_hole(*this);
00120 return;
00121 }
00122 else {
00123 star_transformation_story(Neutron_Star);
00124 new neutron_star(*this);
00125 return;
00126 }
00127 }
00128
00129 #if 0
00130 real hyper_giant::add_mass_to_accretor(const real mdot) {
00131
00132 if (mdot<0) {
00133 cerr << "hyper_giant::add_mass_to_accretor(mdot="
00134 << mdot << ")"<<endl;
00135 cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00136
00137 return 0;
00138 }
00139
00140 adjust_accretor_age(mdot);
00141 if (relative_mass<get_total_mass() + mdot)
00142 relative_mass = get_total_mass() + mdot;
00143 envelope_mass += mdot;
00144
00145
00146 if (relative_mass >= cnsts.parameters(massive_star_mass_limit)) {
00147
00148 cerr << type_string(get_element_type())
00149 << " wind treatment for stars with M >="
00150 << cnsts.parameters(massive_star_mass_limit)
00151 << " for " << identity << endl
00152 << " M = " << get_total_mass() << " [Msun] "
00153 << " Mdot = " << wind_constant
00154 << " [Msun/Myr] "
00155 << endl;
00156
00157 }
00158
00159 set_spec_type(Accreting);
00160
00161 return mdot;
00162
00163 }
00164
00165 real hyper_giant::add_mass_to_accretor(real mdot, const real dt) {
00166
00167 real m_tot = get_total_mass();
00168
00169 if (mdot<0) {
00170
00171
00172
00173
00174
00175
00176 }
00177
00178 mdot = accretion_limit(mdot, dt);
00179 adjust_accretor_age(mdot);
00180 if (relative_mass<get_total_mass() + mdot)
00181 relative_mass = get_total_mass() + mdot;
00182 envelope_mass += mdot;
00183
00184
00185 if (relative_mass >= cnsts.parameters(massive_star_mass_limit)) {
00186
00187
00188 wind_constant = envelope_mass/(next_update_age-relative_age);
00189 wind_constant = max(wind_constant, 0.);
00190
00191 cerr << type_string(get_element_type())
00192 << " wind treatment for stars with M >="
00193 << cnsts.parameters(massive_star_mass_limit)
00194 << " for " << identity << endl
00195 << " M = " << get_total_mass() << " [Msun] "
00196 << " Mdot = " << wind_constant
00197 << " [Msun/Myr] "
00198 << endl;
00199
00200 }
00201
00202 set_spec_type(Accreting);
00203
00204 return mdot;
00205
00206 }
00207 #endif
00208
00209 real hyper_giant::accretion_limit(const real mdot, const real dt) {
00210
00211 real eddington = 1.5e-08*cnsts.parameters(solar_radius)*radius*dt;
00212
00213 if(mdot>=eddington) return eddington;
00214
00215 return mdot;
00216 }
00217
00218 #if 0
00219
00220 void hyper_giant::stellar_wind(const real dt) {
00221
00222 if (relative_mass<cnsts.parameters(massive_star_mass_limit))
00223 return;
00224
00225 real wind_mass = wind_constant * dt;
00226
00227 if (wind_mass>=envelope_mass) {
00228 wind_mass = envelope_mass;
00229 radius = core_radius;
00230 }
00231
00232 if (is_binary_component())
00233 get_binary()->adjust_binary_after_wind_loss(this, wind_mass, dt);
00234 else
00235 reduce_donor_mass(wind_mass);
00236 return;
00237 }
00238
00239 #endif
00240
00241
00242 star* hyper_giant::subtrac_mass_from_donor(const real dt, real& mdot) {
00243
00244 mdot = relative_mass*dt/get_binary()->get_donor_timescale();
00245 mdot = mass_ratio_mdot_limit(mdot);
00246
00247 if (mdot<=envelope_mass)
00248 envelope_mass -= mdot;
00249 else {
00250
00251 mdot = envelope_mass;
00252 envelope_mass = 0;
00253 }
00254
00255 return this;
00256 }
00257
00258
00259
00260
00261 void hyper_giant::adjust_accretor_age(const real mdot,
00262 const bool rejuvenate=true) {
00263
00264 real m_rel_new;
00265 real m_tot_new = get_total_mass() + mdot;
00266 if (m_tot_new>relative_mass)
00267 m_rel_new = m_tot_new;
00268 else m_rel_new = relative_mass;
00269
00270 real t_ms_old = main_sequence_time();
00271 real t_nuc_old = nucleair_evolution_time();
00272 real dt_wr_old = t_nuc_old - t_ms_old;
00273
00274 real t_ms_new = main_sequence_time(m_rel_new);
00275 real t_nuc_new = nucleair_evolution_time(m_rel_new);
00276 real dt_wr_new = t_nuc_new - t_ms_new;
00277
00278 real dtime = relative_age - t_ms_old;
00279
00280 real new_relative_age = t_ms_new
00281 + dtime*(dt_wr_new/dt_wr_old);
00282 if (rejuvenate)
00283 new_relative_age *= rejuvenation_fraction(mdot/m_tot_new);
00284
00285 relative_age = max(relative_age, new_relative_age);
00286
00287
00288 }
00289
00290
00291 real hyper_giant::zeta_adiabatic() {
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 real z = -cnsts.mathematics(one_third);
00305
00306 return z;
00307
00308 }
00309
00310
00311
00312 real hyper_giant::zeta_thermal() {
00313 return 0;
00314 }
00315
00316 star* hyper_giant::reduce_mass(const real mdot) {
00317
00318
00319
00320 if(envelope_mass<=mdot) {
00321 real mdot_rest = mdot - envelope_mass;
00322 envelope_mass = 0;
00323
00324
00325 if (mdot_rest>=core_mass-cnsts.parameters(minimum_helium_star))
00326 core_mass = cnsts.parameters(minimum_helium_star);
00327 else
00328 core_mass -= mdot_rest;
00329 }
00330 else envelope_mass -= mdot;
00331
00332 return this;
00333 }
00334
00335 void hyper_giant::adjust_next_update_age() {
00336
00337 real t_ms = relative_age;
00338 if (relative_age<t_ms)
00339 relative_age = t_ms;
00340
00341
00342
00343 real end_time = nucleair_evolution_time();
00344 real alpha = cnsts.parameters(massive_star_mass_loss_law);
00345 real t_wind_stripped = end_time
00346 * pow((envelope_mass/wind_constant +
00347 pow((relative_age/end_time),alpha))
00348 , 1/alpha);
00349
00350
00351 t_wind_stripped += 0.001;
00352
00353
00354 next_update_age = min(end_time, t_wind_stripped);
00355 }
00356
00357 real hyper_giant::gyration_radius_sq() {
00358
00359 return cnsts.parameters(convective_star_gyration_radius_sq);
00360
00361 }
00362