00001
00002
00003
00004
00005 #include "super_giant.h"
00006 #include "helium_star.h"
00007 #include "helium_giant.h"
00008
00009
00010
00011
00012
00013 helium_giant::helium_giant(super_giant & g) : single_star(g) {
00014
00015 delete &g;
00016
00017
00018 last_update_age = next_update_age;
00019
00020 real second_dredge_up_time = next_update_age
00021 * min(1., relative_mass
00022 / cnsts.parameters(super_giant2neutron_star));
00023
00024 real remaining_time = second_dredge_up_time - relative_age;
00025 next_update_age = helium_time();
00026 relative_age = next_update_age - remaining_time;
00027 last_update_age = relative_age;
00028
00029
00030
00031
00032 instantaneous_element();
00033 update();
00034
00035 post_constructor();
00036 }
00037
00038 helium_giant::helium_giant(helium_star & h) : single_star(h) {
00039
00040 delete &h;
00041
00042
00043 last_update_age = next_update_age;
00044
00045 adjust_next_update_age();
00046
00047 update_wind_constant();
00048
00049 instantaneous_element();
00050 update();
00051
00052 post_constructor();
00053
00054 }
00055
00056 void helium_giant::instantaneous_element() {
00057
00058 real m_tot = get_total_mass();
00059
00060 real temp = log10(m_tot)
00061 * (0.4509 - 0.1085*log10(m_tot)) + 4.7143;
00062 luminosity = 8.33*temp - 36.8;
00063 temp = 1.e-3*pow(10., temp);
00064 luminosity = pow(10., luminosity);
00065 effective_radius = radius = 33.45*sqrt(luminosity)/(temp*temp);
00066 core_radius = 0.2*radius;
00067
00068 if (envelope_mass > 0) {
00069 if (m_tot>=2.7)
00070 radius = 12./get_total_mass();
00071 else if (m_tot>=2.0)
00072 radius *= 250;
00073 else if (m_tot>=1.0)
00074 radius *= 150;
00075 else radius *= 6;
00076 }
00077 else {
00078 effective_radius = radius = core_radius;
00079 }
00080 }
00081
00082 void helium_giant::evolve_element(const real end_time) {
00083
00084 real dt = end_time - current_time;
00085 current_time = end_time;
00086 relative_age += dt;
00087
00088 real m_tot = get_total_mass();
00089
00090 if (relative_age<=next_update_age) {
00091 real tmp = log10(m_tot)
00092 * (0.4509 - 0.1085*log10(m_tot)) + 4.7143;
00093 luminosity = pow(10., 8.33*tmp - 36.8);
00094 tmp = pow(1.e-3*pow(10., tmp), 2);
00095 radius = 33.45*sqrt(luminosity)/tmp;
00096 core_radius = 0.2*radius;
00097
00098
00099
00100 if (envelope_mass > cnsts.safety(minimum_mass_step)) {
00101 if (m_tot>=2.7)
00102 radius = 12./get_total_mass();
00103 else if (m_tot>=2.0)
00104 radius *= 250;
00105 else if (m_tot>=1.0)
00106 radius *= 150;
00107 else radius *= 6;
00108 }
00109 else {
00110 radius = core_radius;
00111 }
00112 }
00113 else {
00114 stellar_wind(dt);
00115 create_remnant();
00116 return;
00117 }
00118
00119 update();
00120 stellar_wind(dt);
00121
00122 }
00123
00124 void helium_giant::update() {
00125
00126 real m_tot = get_total_mass();
00127 core_mass = COcore_mass = CO_core_mass();
00128 envelope_mass = m_tot - core_mass;
00129
00130
00131
00132
00133 detect_spectral_features();
00134
00135
00136 effective_radius = radius;
00137 }
00138
00139
00140
00141 void helium_giant::adjust_next_update_age() {
00142
00143 next_update_age /= cnsts.parameters(helium_star_lifetime_fraction);
00144
00145 }
00146
00147
00148 void helium_giant::create_remnant() {
00149
00150 if (is_binary_component())
00151 get_binary()->dump("binev.data", false);
00152 else
00153 dump("binev.data", false);
00154
00155 stellar_type type = NAS;
00156
00157
00158
00159 if (relative_mass >= cnsts.parameters(maximum_main_sequence) &&
00160 relative_mass < 300)
00161 type = Disintegrated;
00162 else if (core_mass >= cnsts.parameters(COcore2black_hole))
00163 type = Black_Hole;
00164 else if(core_mass >= cnsts.parameters(Chandrasekar_mass))
00165 type = Neutron_Star;
00166 else
00167 type = Carbon_Dwarf;
00168
00169 #if 0 //(SPZ+GN: 27 Jul 2000)
00170
00171 else if(core_mass >= cnsts.
00172 parameters(Chandrasekar_mass) ||
00173 get_total_mass() >= cnsts.parameters(helium2neutron_star))
00174 type = Neutron_Star;
00175
00176
00177
00178
00179
00180 else
00181 type = Carbon_Dwarf;
00182 #endif // (SPZ+GN: 27 Jul 2000)
00183
00184 switch (type) {
00185 case Black_Hole : star_transformation_story(Black_Hole);
00186 new black_hole(*this);
00187 break;
00188 case Neutron_Star : star_transformation_story(Neutron_Star);
00189 new neutron_star(*this);
00190 break;
00191 case Disintegrated : star_transformation_story(Disintegrated);
00192 new disintegrated(*this);
00193 break;
00194 case Carbon_Dwarf : star_transformation_story(Carbon_Dwarf);
00195 new white_dwarf(*this);
00196 break;
00197 default : cerr << "helium_star::create_remnant()" <<endl;
00198 cerr << "star_type not recognized." << endl;
00199 }
00200
00201 }
00202
00203
00204 star* helium_giant::subtrac_mass_from_donor(const real dt, real& mdot) {
00205
00206 mdot = relative_mass*dt/get_binary()->get_donor_timescale();
00207
00208 mdot = mass_ratio_mdot_limit(mdot);
00209
00210 if (mdot<envelope_mass)
00211 envelope_mass -= mdot;
00212 else {
00213 mdot = envelope_mass;
00214 envelope_mass = 0;
00215
00216 if (core_mass <= cnsts.parameters(minimum_helium_star)) {
00217 star_transformation_story(Carbon_Dwarf);
00218 return dynamic_cast(star*, new white_dwarf(*this));
00219 }
00220 }
00221
00222 return this;
00223 }
00224
00225 star* helium_giant::reduce_mass(const real mdot) {
00226
00227 if (mdot < envelope_mass)
00228 envelope_mass -= mdot;
00229 else {
00230 real rest_mdot = mdot;
00231 rest_mdot -= envelope_mass;
00232 envelope_mass = 0;
00233
00234 if (core_mass>rest_mdot) {
00235 if (core_mass-rest_mdot<=
00236 cnsts.parameters(minimum_helium_star)) {
00237 core_mass -= rest_mdot;
00238 COcore_mass = core_mass;
00239 }
00240 else {
00241 core_mass -= rest_mdot;
00242 COcore_mass = core_mass;
00243 }
00244 }
00245 else {
00246 cerr << "ERROR!:"<<endl;
00247 cerr << "void helium_giant::reduce_mass(mdot="
00248 << rest_mdot<<")"<<endl;
00249 cerr << "mdot exceeds helium core mass ("<<core_mass
00250 << ")"<<endl;
00251 cerr << "Decision: Disintegrate helium star!"<<endl;
00252
00253 star_transformation_story(Disintegrated);
00254 return dynamic_cast(star*, new disintegrated(*this));
00255 }
00256 }
00257
00258 return this;
00259 }
00260
00261
00262 real helium_giant::add_mass_to_accretor(const real mdot) {
00263
00264 if (mdot<0) {
00265
00266 cerr << "helium_star::add_mass_to_accretor(mdot="
00267 << mdot << ")"<<endl;
00268 cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00269
00270 return 0;
00271
00272 }
00273
00274 adjust_accretor_age(mdot);
00275 envelope_mass += mdot;
00276 relative_mass = max(relative_mass, get_total_mass());
00277
00278
00279
00280
00281
00282
00283 wind_constant += mdot;
00284
00285 set_spec_type(Accreting);
00286
00287 return mdot;
00288
00289 }
00290
00291 real helium_giant::add_mass_to_accretor(real mdot, const real dt) {
00292
00293 if (mdot<0) {
00294
00295 cerr << "helium_star::add_mass_to_accretor(mdot="
00296 << mdot << ")" <<endl;
00297 cerr << "mdot (" << mdot << ") smaller than zero!" << endl;
00298 }
00299
00300 mdot = accretion_limit(mdot, dt);
00301 adjust_accretor_age(mdot);
00302 envelope_mass += mdot;
00303
00304
00305
00306 wind_constant += mdot;
00307 relative_mass = max(relative_mass, get_total_mass());
00308
00309 set_spec_type(Accreting);
00310
00311 return mdot;
00312
00313 }
00314
00315 real helium_giant::accretion_limit(const real mdot, const real dt) {
00316
00317 real mdot_limit = mdot;
00318
00319 real eddington = 1.5e-08*cnsts.parameters(solar_radius)*radius*dt;
00320 if (mdot>=eddington)
00321 mdot_limit = eddington;
00322
00323 if (envelope_mass<=0)
00324 mdot_limit = 0;
00325
00326 return mdot_limit;
00327
00328 }
00329
00330 void helium_giant::adjust_accretor_age(const real mdot,
00331 const bool rejuvenate) {
00332
00333 real frac = (1-pow(mdot/(get_total_mass()+mdot),
00334 cnsts.parameters(rejuvenation_exponent)));
00335 last_update_age *= frac;
00336 relative_age *= frac;
00337
00338 }
00339
00340
00341 real helium_giant::zeta_adiabatic() {
00342
00343 real z = 0;
00344
00345 real x = core_mass/get_total_mass();
00346 real A = -0.220823;
00347 real B = -2.84699;
00348 real C = 32.0344;
00349 real D = -75.6863;
00350 real E = 57.8109;
00351
00352 if (get_total_mass()<=0.4)
00353 z = -cnsts.mathematics(one_third);
00354 else
00355 z = A + x*(B + x*(C + x*(D + x*E)));
00356
00357 return z;
00358
00359 }
00360
00361 real helium_giant::zeta_thermal() {
00362
00363 real z = -2;
00364
00365 if (get_core_mass()<=0.4)
00366 z = -cnsts.mathematics(one_third);
00367
00368 return z;
00369
00370 }
00371
00372 real helium_giant::CO_core_mass() {
00373
00374
00375
00376
00377
00378
00379
00380
00381 return min(core_mass, get_total_mass());
00382 }
00383
00384 void helium_giant::stellar_wind(const real dt) {
00385
00386
00387
00388
00389
00390
00391
00392 real end_time = next_update_age - last_update_age;
00393 real prev_rel_time = max(0.,previous.relative_age - last_update_age);
00394 real relative_time = min(relative_age - last_update_age, end_time);
00395
00396
00397
00398
00399
00400
00401 real wind_mass = wind_constant
00402 * (pow(relative_time/end_time,
00403 cnsts.parameters(massive_star_mass_loss_law))
00404 - pow((relative_time-dt)/end_time,
00405 cnsts.parameters(massive_star_mass_loss_law)));
00406
00407
00408
00409
00410
00411
00412
00413 if (wind_mass>=envelope_mass) {
00414 wind_mass = envelope_mass;
00415 effective_radius = radius = core_radius;
00416 }
00417
00418 if (is_binary_component())
00419 get_binary()->adjust_binary_after_wind_loss(this, wind_mass, dt);
00420 else
00421 reduce_mass(wind_mass);
00422 return;
00423 }
00424
00425 real helium_giant::gyration_radius_sq() {
00426
00427 return cnsts.parameters(radiative_star_gyration_radius_sq);
00428 }
00429
00430
00431 void helium_giant::update_wind_constant() {
00432
00433
00434
00435
00436
00437
00438 wind_constant = 0.3*envelope_mass;
00439
00440 }
00441
00442 stellar_type helium_giant::get_element_type() {
00443
00444 stellar_type type = Helium_Giant;
00445 if (envelope_mass <= 0)
00446 type = Carbon_Star;
00447
00448 return type;
00449 }
00450
00451 real helium_giant::temperature() {
00452
00453 real T_eff = cnsts.parameters(Tsun)
00454 * sqrt(sqrt(luminosity)/effective_radius);
00455
00456 return T_eff;
00457
00458
00459 }
00460
00461
00462 bool helium_giant::giant_star() {
00463
00464 if (envelope_mass > cnsts.safety(minimum_mass_step))
00465 return TRUE;
00466 else
00467 return FALSE;
00468
00469 }
00470
00471 bool helium_giant::remnant() {
00472
00473 if (envelope_mass > cnsts.safety(minimum_mass_step))
00474 return FALSE;
00475 else
00476 return TRUE;
00477
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487