Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

stdfunc.C

Go to the documentation of this file.
00001 //#INCLUDE "constants.h"
00002 //#include "stdinc.h"
00003 
00004 #include "stdfunc.h"
00005 
00006 #ifndef TOOLBOX
00007 
00008 // Standard functions for various implementations.
00009 
00010 // Tidal energy dissipation during close encounter.
00011 // Portegies Zwart, SF & Meinen AT, 1992, AA 280, 174.
00012 // for polytrope n=1.5
00013 real tf2_energy_diss(const real eta, const stellar_type type) {
00014 
00015 //              Polytropic index 1.5 is default
00016       real coeff2[] = {-0.397, 1.678, 1.277, -12.42, 9.446, -5.550};
00017 
00018 /*
00019       switch (type) {
00020          case Brown_Dwarf:              //polytropic index = 3
00021          case Horizontal_Branch:        //fully radiative stars.
00022          case Helium_Star:
00023          case Wolf_Rayet:
00024          case White_Dwarf:
00025          case Neutron_Star:
00026          case Black_Hole:
00027               coeff2[0] =  -1.124;
00028               coeff2[1] =   0.877;
00029               coeff2[2] = -13.37;
00030               coeff2[3] =  21.55;
00031               coeff2[4] = -16.48;
00032               coeff2[5] =   4.124;
00033               break;
00034          case Main_Sequence:            //polytropic index = 2
00035          case Hertzsprung_Gap:          
00036               coeff2[0] =  -0.517;
00037               coeff2[1] =  -0.906;
00038               coeff2[2] =  23.88;
00039               coeff2[3] = -93.49;
00040               coeff2[4] = 112.3;
00041               coeff2[5] = -44.15;
00042               break;
00043          case Sub_Giant:                //polytropic index = 1.5
00044          case Super_Giant:              //fully convective stars.
00045               coeff2[0] =  -0.397;
00046               coeff2[1] =   1.678;
00047               coeff2[2] =   1.277;
00048               coeff2[3] = -12.42;
00049               coeff2[4] =   9.446;
00050               coeff2[5] =  -5.550;
00051               break;
00052          default:               //SAFETY polytropic index = 1.5
00053               coeff2[0] =  -0.397;
00054               coeff2[1] =   1.678;
00055               coeff2[2] =   1.277;
00056               coeff2[3] = -12.42;
00057               coeff2[4] =   9.446;
00058               coeff2[5] =  -5.550;
00059       }
00060 */
00061 
00062       real y = log10(eta);
00063       y = min(1.0, max(y, 0.0));
00064       real logT = ((((coeff2[5]*y + coeff2[4])*y + coeff2[3])*y
00065                    + coeff2[2])*y + coeff2[1])*y + coeff2[0];
00066 //      logT = min(0, max(logT, -10));
00067 
00068       return pow(10., logT);
00069    }
00070 
00071 // Tidal energy dissipation during close encounter.
00072 // Portegies Zwart, SF & Meinen AT, 1992, AA 280, 174.
00073 // for polytrope n=1.5
00074 real tf3_energy_diss(const real eta, const stellar_type type) {
00075 
00076 //              Initialization with polytrope index 1.5
00077       real coeff3[] = {-0.909, 1.574, 12.37, -57.40, 80.10, -46.43};
00078 /*
00079       switch (type) {
00080          case Brown_Dwarf:              //polytropic index = 3
00081          case Helium_Star:              //fully convecitve stars.
00082          case Wolf_Rayet:
00083          case White_Dwarf:
00084          case Neutron_Star:
00085          case Black_Hole:
00086               coeff3[0] =  -1.703;
00087               coeff3[1] =   2.653;
00088               coeff3[2] = -14.34;
00089               coeff3[3] =  12.85;
00090               coeff3[4] =  -0.492;
00091               coeff3[5] =  -3.600;
00092 //              Do nothing just polytrope index 1.5.
00093               break;
00094          case Main_Sequence:            //polytropic index = 2
00095          case Hertzsprung_Gap:         
00096          case Horizontal_Branch:
00097               coeff3[0] =   -1.040;
00098               coeff3[1] =   -1.354;
00099               coeff3[2] =   37.64;
00100               coeff3[3] = -139.9;
00101               coeff3[4] =  168.2;
00102               coeff3[5] =  -66.53;
00103               break;
00104          case Sub_Giant:                //polytropic index = 1.5
00105          case Super_Giant:              //Convective stars.
00106               coeff3[0] =  -0.909;
00107               coeff3[1] =   1.574;
00108               coeff3[2] =  12.37;
00109               coeff3[3] = -57.40;
00110               coeff3[4] =  80.10;
00111               coeff3[5] = -46.43;
00112               break;
00113          default:               //SAFETY polytropic index = 1.5
00114               coeff3[0] =  -0.909;
00115               coeff3[1] =   1.574;
00116               coeff3[2] =  12.37;
00117               coeff3[3] = -57.40;
00118               coeff3[4] =  80.10;
00119               coeff3[5] = -46.43;
00120       }
00121 */
00122 
00123       real y = log10(eta);
00124       y = min(1.0, max(y, 0.0));
00125       real logT = ((((coeff3[5]*y + coeff3[4])*y + coeff3[3])*y
00126                    + coeff3[2])*y + coeff3[1])*y + coeff3[0];
00127 //      logT = min(0, max(logT, -10));
00128 
00129       return pow(10., logT);
00130    }
00131 
00132 //              Standard lineair interpolation routine.
00133 real lineair_interpolation(const real x,
00134                            const real x1, const real x2,
00135                            const real y1, const real y2) {
00136 
00137         real a = (y2-y1)/(x2-x1);
00138         real b = y1 - a*x1;
00139 
00140         real y = a*x + b;
00141         return y;
00142 }
00143 
00144 //              Super nova utilities.
00145 
00146 //              Super nova utilities.
00147 
00148 //      Check!!
00149 real post_sn_cm_velocity(const real a_init,     const real e_init,
00150                          const real separation,
00151                          const real m1_0, const real m2_0,
00152                          const real m1, const real m2,
00153                          const real v_kick,
00154                          const real theta,      const real phi) {
00155 
00156 //      Check!!
00157      real v_orb = sqrt((cnsts.physics(G)*cnsts.parameters(solar_mass)/cnsts.parameters(solar_radius))*(m1_0+ m2_0)*(2/separation - 1/a_init));
00158 //          v_orb /= cnsts.physics(km_per_s);
00159      real vr_k = cnsts.physics(km_per_s)*v_kick/v_orb;
00160 
00161      real mu = m1_0*m2_0/(m1_0+m2_0);
00162           mu *= cnsts.parameters(solar_mass);
00163      real dm = (m1_0+m2_0) - (m1+m2);
00164           dm *= cnsts.parameters(solar_mass);
00165      real v_cm = v_orb/(cnsts.parameters(solar_mass)*(m1 + m2));
00166      v_cm *= sqrt(pow(mu*dm/(cnsts.parameters(solar_mass)*m1_0), 2) - 2*(mu*dm*m1/m1_0)
00167            * vr_k*sin(theta)*cos(phi) + pow(cnsts.parameters(solar_mass)*m1*vr_k, 2));
00168      v_cm /= cnsts.physics(km_per_s);
00169 
00170 //      Check!!
00171      return v_cm;
00172    }
00173 
00174 
00175 real post_sn_semi_major_axis(const real a_init,     const real e_init,
00176                              const real separation,
00177                              const real m1_0, const real m2_0,
00178                              const real m1, const real m2,
00179                              const real v_kick,
00180                              const real theta,      const real phi) {
00181 
00182 //              SPZ's method.
00183      real mu = (m1 + m2)/(m1_0 + m2_0);
00184      real v_orb = sqrt((cnsts.physics(G)*cnsts.parameters(solar_mass)/cnsts.parameters(solar_radius))*(m1_0+ m2_0)*(2/separation - 1/a_init));
00185           v_orb /= cnsts.physics(km_per_s);
00186      real vr_k = v_kick/v_orb;
00187      real vr2 = 1 + vr_k*vr_k + 2*vr_k*sin(theta)*cos(phi);
00188      real a_new = 1/(2/separation - (vr2/mu)*(2/separation - 1/a_init));
00189      real alpha = a_new/a_init;
00190 
00191      real epsilon = (1/(mu*alpha))*(vr2 - vr_k*vr_k*pow(cos(theta), 2));
00192      real e_new = sqrt(1 - (1-e_init*e_init)*epsilon);
00193 
00194 
00195 //     cerr<<"final: "<< alpha*a_init<<" "<<e_new<<endl;
00196 
00197      return a_new;
00198 }
00199 
00200 real post_sn_eccentricity(const real a_init,     const real e_init,
00201                           const real separation,
00202                           const real m1_0, const real m2_0,
00203                           const real m1, const real m2,
00204                           const real v_kick,
00205                           const real theta,      const real phi) {
00206 
00207      real mu = (m1 + m2)/(m1_0 + m2_0);
00208      real v_orb = sqrt((cnsts.physics(G)*cnsts.parameters(solar_mass)/cnsts.parameters(solar_radius))*(m1_0+ m2_0)*(2/separation - 1/a_init));
00209           v_orb /= cnsts.physics(km_per_s);
00210      real vr_k = v_kick/v_orb;
00211      real vr2 = 1 + vr_k*vr_k + 2*vr_k*sin(theta)*cos(phi);
00212      real a_new = 1/(2/separation - (vr2/mu)*(2/separation - 1/a_init));
00213      real alpha = a_new/a_init;
00214 
00215      real epsilon = (1/(mu*alpha))*(vr2 - vr_k*vr_k*pow(cos(theta), 2));
00216      real e_new = sqrt(1 - (1-e_init*e_init)*epsilon);
00217 
00218      return e_new;
00219 }
00220 
00221 real kinetic_energy(const real mass, const real velocity) {
00222              real Mkm_s2 = cnsts.parameters(solar_mass)*cnsts.physics(km_per_s)*cnsts.physics(km_per_s);
00223              real k = 0.5*Mkm_s2*mass*velocity*velocity;
00224              return k;
00225         }
00226 real potential_energy(const real sep, const real m1, const real m2) {
00227 
00228        real GM2_R = cnsts.physics(G)*cnsts.parameters(solar_mass)*cnsts.parameters(solar_mass)/cnsts.parameters(solar_radius);
00229        real u = GM2_R*m1*m2/sep;
00230        return -u;
00231    }
00232 
00233 real velocity_at_infinity(const real vel, 
00234                           const real sep, 
00235                           const real m_prim, 
00236                           const real m_sec) {
00237 
00238       real e_kin = kinetic_energy(m_prim+m_sec, vel);
00239       real e_pot = potential_energy(sep, m_prim, m_sec);
00240       real m_tot = cnsts.parameters(solar_mass)*(m_prim + m_sec);
00241       real velocity = 0;
00242       if (e_kin>abs(e_pot)) 
00243          velocity = sqrt((e_kin + e_pot)/m_tot);
00244 
00245       return velocity/cnsts.physics(km_per_s);
00246    }
00247 
00248 real random_angle(const real min, const real max) {
00249 
00250      extern real randinter(real, real);
00251 
00252      real rnd = randinter(min, max);
00253 
00254 //     cerr << "rdn: " << rnd<< endl;
00255      return rnd;
00256 }
00257 
00258 real random_eccentric_anomaly(const real ecc) {
00259 
00260 //      Solve Kepler equation by iterating: M = E - e sin E
00261 //      Lit.: Sterne, T.E., 1960, An introdiction to Celestial
00262 //            Mechanics, p. 13-14
00263 
00264 /*
00265      real mean_anomaly = random_angle(0, cnsts.math.two_pi);
00266 //cerr<<" mean_anomaly="<<mean_anomaly<<endl;
00267      real ecc_anomaly = mean_anomaly;     // first guess.
00268 
00269 //              Interpolate for better result.
00270          ecc_anomaly = mean_anomaly
00271                            - (ecc_anomaly - ecc*sin(ecc_anomaly)
00272                               - mean_anomaly)
00273                            / (1 - ecc*cos(ecc_anomaly));
00274 
00275 */
00276 
00277       real mean_anomaly = random_angle(0, cnsts.mathematics(two_pi));
00278 //      cerr<<" mean_anomaly="<<mean_anomaly<<endl;
00279 
00280 //              First guess.
00281      real ecc_anomaly = mean_anomaly
00282                             + cnsts.mathematics(two_pi)*(ecc*sin(mean_anomaly)
00283                             + 0.5*ecc*ecc*sin(2*mean_anomaly));
00284 //     cerr<<"ecc_anomaly=" <<ecc_anomaly<<endl;
00285      real m0 = ecc_anomaly - ecc*sin(ecc_anomaly);
00286      real de0 = (mean_anomaly-m0)
00287               / (1 - ecc*cos(ecc_anomaly));
00288 
00289      ecc_anomaly += de0;
00290      real m1, de1;
00291      do {
00292         m1 = ecc_anomaly - ecc*sin(ecc_anomaly);
00293 
00294         de1 = (mean_anomaly-m1)
00295             / (1 - ecc*cos(ecc_anomaly));
00296         
00297         ecc_anomaly += de1;
00298 
00299      }
00300      while(de1>=0.001);
00301 
00302 //cerr<<" => ecc_anomaly="<<ecc_anomaly<<endl;
00303      return ecc_anomaly;
00304 }
00305 
00306 real eccentric_anomaly(const real ecc, const real mean_anomaly) {
00307 
00308 //      Solve Kepler equation by iterating: M = E - e sin E
00309 //      Lit.: Sterne, T.E., 1960, An introdiction to Celestial
00310 //            Mechanics, p. 13-14
00311 
00312 //      cerr<<" mean_anomaly="<<mean_anomaly<<endl;
00313 
00314 //              First guess.
00315      real ecc_anomaly = mean_anomaly
00316                             + cnsts.mathematics(two_pi)*(ecc*sin(mean_anomaly)
00317                             + 0.5*ecc*ecc*sin(2*mean_anomaly));
00318 //     cerr<<"ecc_anomaly=" <<ecc_anomaly<<endl;
00319      real m0 = ecc_anomaly - ecc*sin(ecc_anomaly);
00320      real de0 = (mean_anomaly-m0)
00321               / (1 - ecc*cos(ecc_anomaly));
00322 
00323      ecc_anomaly += de0;
00324      real m1, de1;
00325      do {
00326         m1 = ecc_anomaly - ecc*sin(ecc_anomaly);
00327 
00328         de1 = (mean_anomaly-m1)
00329             / (1 - ecc*cos(ecc_anomaly));
00330 
00331         ecc_anomaly += de1;
00332 
00333      }
00334      while(de1>=0.001);
00335 
00336 //cerr<<" => ecc_anomaly="<<ecc_anomaly<<endl;
00337      return ecc_anomaly;
00338 }
00339 
00340 
00341 real random_separation(const real semi, const real ecc) {
00342 //cerr<<"random_separation(a="<<semi<<", e="<<ecc<<")"<<endl;
00343 
00344      real ecc_anomaly = random_eccentric_anomaly(ecc);
00345 
00346 //cerr<<"ecc_anomaly=" << ecc_anomaly;
00347      real separation = semi*(1-ecc*cos(ecc_anomaly));
00348 //cerr<<" ==> separation="<<separation<<endl;
00349 
00350      return separation;
00351 }
00352 
00353 /*
00354 real maxwellian_distribution() {
00355 
00356         static int iset=0;
00357         static real gset;
00358         real fac,rsq,v1,v2;
00359 
00360         if  (iset == 0) {
00361                 do {
00362                         v1=2.0*randinter(0,1)-1.0;
00363                         v2=2.0*randinter(0,1)-1.0;
00364                         rsq=v1*v1+v2*v2;
00365                 } while (rsq >= 1.0 || rsq == 0.0);
00366                 fac=sqrt(-2.0*log(rsq)/rsq);
00367                 gset=v1*fac;
00368                 iset=1;
00369                 return v2*fac;
00370         } else {
00371                 iset=0;
00372                 return gset;
00373         }
00374    }
00375 */
00376 
00377 real maxwellian(const real velocity, const real v_disp) {
00378 
00379 
00380       real Mxwmax = 4/(sqrt(cnsts.mathematics(pi))*exp(1));
00381       real u2 = pow(velocity/v_disp, 2);
00382       real prob = (4./sqrt(cnsts.mathematics(pi))) * u2 / exp(u2);
00383       prob /= Mxwmax;
00384 
00385       return prob;
00386    }
00387 
00388 real random_maxwellian_velocity(const real v_disp) {
00389 
00390      real rnd_gauss, v[3];
00391      real final_vel=0;
00392      real mean_vel = 0.;
00393      real v1d_disp = v_disp/sqrt(3.);
00394 
00395      for (int i=0; i<3; i++) {
00396          rnd_gauss = gauss();
00397          v[i] = mean_vel + v1d_disp*rnd_gauss;  // km/s
00398          final_vel += v[i]*v[i];
00399      }
00400 
00401      return sqrt(final_vel);
00402   }
00403 
00404 real paczynski_distribution(const real velocity, const real v_disp) {
00405 
00406       real prob = (4./cnsts.mathematics(pi))/pow(1+pow(velocity/v_disp, 2.), 2.);
00407 
00408 //              Normaization to unity for its maximum.
00409       prob /= (4./cnsts.mathematics(pi));
00410 
00411       return prob;
00412    }
00413 
00414 
00415 real random_paczynski_velocity(const real v_disp) {
00416 //      Velocity distribution used by Paczynski, B., 1990, ApJ 348, 485.
00417 //      with a dispersion of 270 km/s.
00418 //      Phinney uses the same distribution with a dispersion of 600 km/s.
00419 //      The distribution:
00420 //      P(u)du = \frac{4}{\pi} \cdot \frac{du}{(1+u^2)^2},
00421 //      u=v/v_d,
00422 //      v_d is the dispersion velocity = 270 or 600 km/s respectively.
00423 
00424 //      The safe and clumsy method
00425         
00426       real prob, velocity, dist_value;
00427       real max_distr = 4./cnsts.mathematics(pi);
00428       real v_max = 4;
00429       do {
00430          prob = max_distr*randinter(0., 1.);
00431          velocity = v_max*randinter(0., 1.);
00432          dist_value = max_distr/pow(1+pow(velocity, 2.), 2.);
00433      }
00434      while(prob>dist_value);
00435 
00436      return velocity*v_disp;
00437    }
00438  
00439 real cross_section(const real m_prim, const real m_sec,
00440                    const real r_min,  const real v_rel) {
00441 
00442       real cgs_const = cnsts.physics(G)*cnsts.parameters(solar_mass)/(cnsts.parameters(solar_radius)*pow(cnsts.physics(km_per_s), 2));
00443       real gr_foc = cgs_const*(m_prim+m_sec)/(r_min*pow(v_rel, 2));
00444       real sigma = cnsts.mathematics(pi)*pow(r_min*cnsts.parameters(solar_radius), 2) * (1 + gr_foc);
00445       sigma /= pow(cnsts.parameters(solar_radius), 2);
00446 
00447       return sigma;     // in R_SUN^2
00448    }
00449 
00450 real eddington_limit(const real radius,
00451                      const real dt,
00452                      const real mu) {
00453   return cnsts.parameters(solar_radius)*radius*dt*mu*1.5e-08;
00454 }
00455 
00456 real gf_velocity_distribution_extremum(const real m_prim, const real m_sec,
00457                                      const real r_min, const real v_disp) {
00458 
00459       real abc_A = 3*cnsts.parameters(solar_radius)*r_min/pow(cnsts.physics(km_per_s)*v_disp, 2); 
00460       real abc_B = 6*cnsts.physics(G)*cnsts.parameters(solar_mass)*(m_prim+m_sec)/pow(cnsts.physics(km_per_s)*v_disp, 2) - 4*cnsts.parameters(solar_radius)*r_min; 
00461       real abc_C = -4*cnsts.physics(G)*cnsts.parameters(solar_mass)*(m_prim+m_sec);
00462       real discriminant = pow(abc_B, 2) - 4*abc_A*abc_C;
00463       real kappa1 = (-abc_B + sqrt(discriminant))/(2*abc_A);
00464       real kappa2 = (-abc_B - sqrt(discriminant))/(2*abc_A);
00465       real extremum1 = sqrt(abs(kappa1))/cnsts.physics(km_per_s);
00466       // real extremum2 = sqrt(abs(kappa2))/cnsts.physics(km_per_s);
00467      
00468 //      cerr << " maxima: "<< extremum1 << " " << extremum2 << endl;
00469 //      return max(v_disp, min(extremum1, extremum2));
00470       return extremum1;
00471    }
00472 
00473 //The relative velocity between the two encountering
00474 //objects must be chosen from the distribution $P(v)$ given by:
00475 //        P(v) dv = \sigma v {\cal F}(v)dv.
00476 //here {\cal F}(v)dv is the Maxwellian.
00477 real gravitational_focussed_velocity(const real m_prim, const real m_sec,
00478                                      const real r_min,  const real vel,
00479                                      const real v_disp) {
00480 
00481       real konst = 4*sqrt(cnsts.mathematics(pi))*pow(3./(2*pow(v_disp*cnsts.physics(km_per_s), 2)), 3./2.);
00482       real GMm = cnsts.physics(G)*cnsts.parameters(solar_mass)*(m_prim+m_sec);
00483       real e_x = 1./exp((3./2.)*pow(vel/v_disp, 2));
00484       real velocity = vel*cnsts.physics(km_per_s);
00485       real s1 = pow(velocity, 3)*pow(cnsts.parameters(solar_radius)*r_min, 2);
00486       real s2 = 2*GMm*velocity*cnsts.parameters(solar_radius)*r_min;
00487 
00488       real pvs = konst*e_x*(s1 + s2);
00489 
00490       return pvs;
00491 
00492    }
00493 
00494 real random_focussed_maxwellian_velocity(const real m_prim, const real m_sec,
00495                                      const real r_min,  const real v_disp,
00496                                      const real v_esc) {
00497 
00498       real v_extremum = gf_velocity_distribution_extremum(m_prim, m_sec,
00499                                                         r_min, v_disp);
00500       real max_prob = gravitational_focussed_velocity(m_prim, m_sec,
00501                                                    r_min,  v_extremum, v_disp);
00502 
00503       real pprob, velocity, prob;
00504       do {
00505          pprob    = randinter(0, 1.25);
00506          velocity = randinter(0, v_esc);
00507          prob     = gravitational_focussed_velocity(m_prim, m_sec,
00508                                                     r_min,  velocity, v_disp)
00509                   / max_prob;
00510       }
00511       while (prob<pprob);
00512 
00513       return velocity;
00514 
00515    }
00516 
00517 /*
00518 real random_focussed_maxwellian_velocity(const real v_disp, const real v_esc) {
00519 
00520       real v_disp2  = pow(v_disp, 2);
00521       real vprob, pprob, prob;
00522       do {
00523          pprob = randinter(0, 1.);
00524          vprob = randinter(0, v_esc);
00525          prob = 1./exp(pow(vprob, 2)/(sqrt(2.)*v_disp2));
00526       }
00527       while (prob>pprob);
00528 
00529       return vprob;
00530    }
00531 */
00532 
00533 real gauss(const real velocity, const real v_disp) {
00534 
00535       real u2 = pow(velocity/v_disp, 2);
00536       real prob = 1./exp(u2);
00537 
00538       return prob;
00539   }
00540 
00541 real gauss() {
00542 
00543     extern real randinter(real, real);
00544 
00545     static int iset = 0;
00546 
00547     /* System generated locals */
00548     real ret_val, r_1, r_2;
00549 
00550     /* Builtin functions */
00551 //    double log(), sqrt();
00552 
00553     /* Local variables */
00554     static real gset, r, v1, v2, fac;
00555 
00556 //    srand(idum);
00557 
00558     if (iset == 0) {
00559         do {
00560             v1 = 2*randinter(0, 1) - 1.;
00561             v2 = 2*randinter(0, 1) - 1.;
00562 /* Computing 2nd power */
00563             r_1 = v1;
00564 /* Computing 2nd power */
00565             r_2 = v2;
00566             r = r_1 * r_1 + r_2 * r_2;
00567         }
00568         while(r >= 1.);
00569         fac = sqrt(-2*log(r)/r);
00570         gset = v1 * fac;
00571         ret_val = v2 * fac;
00572         iset = 1;
00573     } else {
00574         ret_val = gset;
00575         iset = 0;
00576     }
00577 //cerr << "gauss: " << ret_val << endl;
00578     return ret_val;
00579 } 
00580 
00581 real turn_off_mass(const real time) {
00582 
00583      real mass = 0.5*cnsts.parameters(maximum_main_sequence);
00584      real mdot = mass;
00585      real to_time = main_sequence_time(mass);
00586 
00587      while(abs(time-to_time)>1.e-4) {
00588         mdot *= 0.5;
00589         if(to_time>time)
00590            mass += mdot;
00591         else
00592            mass -= mdot;
00593         to_time = main_sequence_time(mass);
00594 
00595         if(mass>=cnsts.parameters(maximum_main_sequence)
00596                 -cnsts.safety(minimum_mass_step) ||
00597            mass<=cnsts.parameters(minimum_main_sequence)
00598                 -cnsts.safety(minimum_mass_step))
00599            to_time = time;
00600      }
00601 
00602      return mass;
00603 }
00604 
00605 real main_sequence_time(const real mass) {
00606 
00607      real t_ms = (2550. + 667.*pow(mass,2.5)
00608                + pow(mass,4.5) )
00609                / (0.0327*pow(mass,1.5)
00610                + 0.346*pow(mass,4.5));
00611 
00612      return t_ms;
00613 }
00614 
00615 real zero_age_main_sequnece_radius(const real mass) {
00616 
00617     real alpha, beta, gamma, delta, kappa, lambda;
00618 
00619     real log_mass = log10(mass);
00620 
00621     if (mass > 1.334) {
00622 
00623         alpha = 0.1509 + 0.1709*log_mass;
00624         beta  = 0.06656 - 0.4805*log_mass;
00625         gamma = 0.007395 + 0.5083*log_mass;
00626         delta = (0.7388*pow(mass, 1.679) - 1.968*pow(mass, 2.887))
00627               / (1.0 - 1.821*pow(mass, 2.337));
00628     } 
00629     else {
00630       
00631         alpha = 0.08353 + 0.0565*log_mass;
00632         beta  = 0.01291 + 0.2226*log_mass;
00633         gamma = 0.1151 + 0.06267*log_mass;
00634         delta = pow(mass, 1.25) * (0.1148 + 0.8604*mass*mass)
00635               / (0.04651 + mass*mass);
00636     }
00637 
00638     real radius = delta;
00639 
00640     return radius;
00641 }
00642 
00643 
00644 real roche_radius(const real a, const real m1, const real m2) {
00645 
00646     real q = m1/m2;
00647     real q1_3 = pow(q, cnsts.mathematics(one_third));
00648     real q2_3 = pow(q1_3, 2);   //pow(mr, TWO_THIRD);
00649   
00650     real Rl =  a*0.49*q2_3/(0.6*q2_3 + log(1 + q1_3));
00651 
00652     return Rl;
00653 }
00654 
00655 /*
00656 #define EPS 1.0e-4
00657 #define JMAX 20
00658 #define JMAXP (JMAX+1)
00659 #define K 5
00660 
00661 real integrate(const real a,
00662                const real b,
00663                real (*func)(const real)) {
00664 
00665         void polint(real xa[], real ya[], int n, real x, real *y, real *dy);
00666         real trapzd(real (*func)(const real), 
00667                     real a, real b, int n);
00668         real ss,dss;
00669         real s[JMAXP+1],h[JMAXP+1];
00670         int j;
00671 
00672         h[1]=1.0;
00673         for (j=1;j<=JMAX;j++) {
00674                 s[j]=trapzd(func,a,b,j);
00675                 if (j >= K) {
00676                         polint(&h[j-K],&s[j-K],K,0.0,&ss,&dss);
00677                         if (abs(dss) < EPS*abs(ss)) return ss;
00678                 }
00679                 s[j+1]=s[j];
00680                 h[j+1]=0.25*h[j];
00681         }
00682         cerr<<"Too many steps in routine integrate";
00683         return 0.0;
00684 }
00685 #undef EPS
00686 #undef JMAX
00687 #undef JMAXP
00688 #undef K
00689 
00690 real trapzd(real (*func)(const real), 
00691             real a, real b, int n)
00692 {
00693         real x,tnm,sum,del;
00694         static real s;
00695         int it,j;
00696 
00697         if (n == 1) {
00698                 return (s=0.5*(b-a)*((*func)(a)+(*func)(b)));
00699         } else {
00700                 for (it=1,j=1;j<n-1;j++) it <<= 1;
00701                 tnm=it;
00702                 del=(b-a)/tnm;
00703                 x=a+0.5*del;
00704                 for (sum=0.0,j=1;j<=it;j++,x+=del) sum += (*func)(x);
00705                 s=0.5*(s+(b-a)*sum/tnm);
00706                 return s;
00707         }
00708 }
00709 
00710 #define NRANSI
00711 
00712 */
00713 void polint(real xa[], real ya[], int n, real x, real *y, real *dy)
00714 {
00715         int i,m,ns=1;
00716         real den,dif,dift,ho,hp,w;
00717         real *c,*d;
00718         void free_vector(real *v, long nl, long nh);
00719         real *vector(long nl, long nh);
00720 
00721         dif=fabs(x-xa[1]);
00722         c=vector(1,n);
00723         d=vector(1,n);
00724         for (i=1;i<=n;i++) {
00725                 if ( (dift=fabs(x-xa[i])) < dif) {
00726                         ns=i;
00727                         dif=dift;
00728                 }
00729                 c[i]=ya[i];
00730                 d[i]=ya[i];
00731         }
00732         *y=ya[ns--];
00733         for (m=1;m<n;m++) {
00734                 for (i=1;i<=n-m;i++) {
00735                         ho=xa[i]-x;
00736                         hp=xa[i+m]-x;
00737                         w=c[i+1]-d[i];
00738                         if ( (den=ho-hp) == 0.0) 
00739                            cerr<<"Error in routine polin t";
00740                         den=w/den;
00741                         d[i]=hp*den;
00742                         c[i]=ho*den;
00743                 }
00744                 *y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--]));
00745         }
00746         free_vector(d,1,n);
00747         free_vector(c,1,n);
00748 }
00749 #undef NRANSI
00750 #define NR_END 1
00751 #define FREE_ARG char*
00752 
00753 void free_vector(real *v, long nl, long nh)
00754 /* free a real vector allocated with vector() */
00755 {
00756         free((FREE_ARG) (v+nl-NR_END));
00757 }
00758 
00759 real *vector(long nl, long nh)
00760 /* allocate a real vector with subscript range v[nl..nh] */
00761 {
00762         real *v;
00763 
00764         v=(real *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(real)));
00765         if (!v) cerr<<"allocation failure in vector()";
00766         return v-nl+NR_END;
00767 }
00768 
00769 void fool(char * message) {
00770 
00771       cerr << "Fool: You canot " << message << "!" << endl;
00772    }
00773 
00774 // stellar evolution timescales timescales.
00775 // should the effective_radius be used??
00776 real kelvin_helmholds_timescale(const real mass,
00777                                 const real radius,
00778                                 const real luminosity) {
00779     return 31.56*pow(mass,2.)/(radius*luminosity);
00780   }
00781 
00782 real nucleair_evolution_timescale(const real mass,
00783                                   const real luminosity) {
00784   // t_nuc = 10^10 [years] Msun/Lsun.
00785   // Assumed that 0.1 Msun is thermalized.
00786 
00787   real fused_mass = 0.1*mass;
00788 
00789   return cnsts.parameters(energy_to_mass_in_internal_units)
00790        * fused_mass/luminosity;
00791   //return cnsts.parameters(nucleair_efficiency)*1.4e+7*mass/luminosity;
00792 }
00793 
00794 real dynamic_timescale(const real mass,
00795                        const real radius) {
00796 
00797     return 5.08e-11*sqrt(pow(radius, 3.)/mass); 
00798 }
00799 
00800 #else
00801 
00802 void main() {
00803 
00804   real v_disp = 8; // km/s
00805 //  real v_disp = 4; // km/s
00806   for(int i=0; i< 1000; i++) {
00807 //    real velocity = i/(4.*v_disp);
00808 //    real velocity = random_maxwellian_velocity(v_disp);
00809 //    cerr << " v= " << velocity << endl;
00810 //         << " p= " << maxwellian(velocity, v_disp) << endl;
00811     real velocity = random_focussed_maxwellian_velocity(39.3, 15.3, 
00812                                      1.,  v_disp, 4*v_disp);
00813     cerr << " v= " << velocity << endl;
00814 
00815   }
00816 
00817 }
00818 
00819 #endif

Generated at Sun Feb 24 09:57:17 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001