00001
00002
00003
00004
00005 #include "horizontal_branch.h"
00006 #include "sub_giant.h"
00007 #include "hertzsprung_gap.h"
00008
00009
00010
00011
00012
00013 horizontal_branch::horizontal_branch(sub_giant & g) : single_star(g) {
00014
00015 delete &g;
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 horizontal_branch::horizontal_branch(hertzsprung_gap & h) : single_star(h) {
00029
00030 delete &h;
00031
00032
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);
00075
00076
00077
00078
00079
00080 }
00081
00082
00083
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);
00109 }
00110 else {
00111
00112
00113 star_transformation_story(Super_Giant);
00114 new super_giant(*this);
00115 return;
00116 }
00117
00118 update();
00119 stellar_wind(dt);
00120 }
00121
00122
00123
00124 void horizontal_branch::update() {
00125
00126
00127
00128
00129
00130
00131
00132 core_radius = helium_core_radius();
00133
00134
00135
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
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
00202
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
00232
00233
00234 real delta_mcore = 0.5 * luminosity*dt
00235 / (X * cnsts.parameters(energy_to_mass_in_internal_units));
00236
00237
00238
00239
00240
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
00249 }
00250
00251 envelope_mass -= delta_mcore;
00252 core_mass += delta_mcore;
00253
00254 }
00255
00256
00257
00258
00259 void horizontal_branch::update_wind_constant() {
00260
00261
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 {
00270 real final_mass = 30;
00271 wind_constant = relative_mass - final_mass;
00272 }
00273
00274 }
00275 else {
00276
00277 wind_constant = 0.05*(relative_mass - final_core_mass());
00278 }
00279
00280 wind_constant = max(wind_constant, 0.0);
00281
00282 }