Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

rcore2_bk.C

Go to the documentation of this file.
00001 //  sys_stats.C: Print out various diagnostic statistics on a system.
00002 
00003 #include "dyn.h"
00004 
00005 // cerr << "    [R]: " << Rsun_pc / r_conv_star_to_dyn << " pc\n";
00006 #define Rsun_pc 2.255e-8                 // R_sun/parsec = 6.960e+10/3.086e+18
00007 
00008 #define ALL_i ni = n->get_oldest_daughter(); ni != NULL; \
00009                                              ni = ni->get_younger_sister()
00010 #define j_ABOVE_i nj = ni->get_younger_sister(); nj != NULL; \
00011                                              nj = nj->get_younger_sister()
00012 
00013 
00014 local real conv_v_dyn_to_star(real v, real rf, real tf) {
00015 
00016 //              Internal velocity is km/s
00017 //              Internal size is solar raii
00018 //              Internal time is Myr.
00019 //              km/s to Rsun/Myr
00020 //      real to_Rsun_Myr = cnsts.physics(km_per_s) * cnsts.physics(Myear)
00021 //                     / cnsts.parameters(solar_radius);
00022 
00023       real myear = 3.15e+13;
00024       real km_s = 1.0e+5;
00025       real R_sun = 6.960e+10;
00026       real to_Rsun_Myr = km_s * myear / R_sun;
00027       real to_dyn      = rf/tf;
00028       
00029       return v/(to_Rsun_Myr * to_dyn);
00030    }
00031 
00032 
00033 typedef  struct
00034 {
00035     real  radius;
00036     real  mass;
00037 } rm_pair, *rm_pair_ptr;
00038 
00039 //-----------------------------------------------------------------------------
00040 //  compare_radii  --  compare the radii of two particles
00041 //-----------------------------------------------------------------------------
00042 
00043 local int compare_radii(const void * pi, const void * pj)
00044 {
00045     if (((rm_pair_ptr) pi)->radius > ((rm_pair_ptr) pj)->radius)
00046         return(1);
00047     else if (((rm_pair_ptr)pi)->radius < ((rm_pair_ptr)pj)->radius)
00048         return(-1);
00049     else
00050         return(0);
00051 }
00052 
00053 //-----------------------------------------------------------------------------
00054 //  compute_general_mass_radii  --  Get the massradii for all particles.
00055 //-----------------------------------------------------------------------------
00056 
00057 static real nonlin_masses[9] = {0.005, 0.01, 0.02, 0.05, 0.1,
00058                                 0.25, 0.5, 0.75, 0.9};
00059 
00060 local void compute_general_mass_radii(dyn * b, int nzones,
00061                                       vector dc_pos, 
00062                                       real m_cutoff, real M_cutoff,
00063                                       bool nonlin = false, 
00064                                       boolfn bf=NULL)
00065 {
00066     if (nzones < 2) return;
00067     if (nonlin && nzones != 10) return;         // Special case
00068 
00069     // Note: nzones specifies the number of radial zones to consider.
00070     //       However, we only store radii corresponding to the nzones-1 
00071     //       interior zone boundaries.
00072 
00073     real* mass_percent = new real[nzones-1];
00074     if (mass_percent == NULL) {
00075         cerr << "compute_general_mass_radii: "
00076              << "not enough memory left for mass_percent\n";
00077         return;
00078     }
00079 
00080     int n = 0;
00081     if (bf == NULL) {
00082       for_all_daughters(dyn, b, bb)
00083         if (bb->get_mass()>=m_cutoff && bb->get_mass()<=M_cutoff)
00084           n++;
00085     }
00086     else {
00087         for_all_daughters(dyn, b, bb)
00088           if (bb->get_mass()>=m_cutoff && bb->get_mass()<=M_cutoff)
00089             if ((*bf)(bb))
00090               n++;
00091     }
00092     
00093     rm_pair_ptr rm_table = new rm_pair[n];
00094 
00095     if (rm_table == NULL) {
00096         cerr << "compute_general_mass_radii: "
00097              << "not enough memory left for rm_table\n";
00098         return;
00099     }
00100 
00101     // Use the geometric center if the density center is unknown.
00102 
00103     //    vector dc_pos = 0;
00104     //    if (find_qmatch(b->get_dyn_story(), "density_center_pos")) 
00105     //  dc_pos = getvq(b->get_dyn_story(), "density_center_pos");
00106 
00107     // Set up an array of (radius, mass) pairs.  Also find the total
00108     // mass of all nodes under consideration.
00109 
00110     real total_mass = 0;
00111 
00112     int i = 0;
00113     for_all_daughters(dyn, b, bi) {
00114         if (bf == NULL || (*bf)(bi)) {
00115           if (bi->get_mass()>=m_cutoff && bi->get_mass()<=M_cutoff) {
00116             total_mass += bi->get_mass();
00117             rm_table[i].radius = abs(bi->get_pos() - dc_pos);
00118             rm_table[i].mass = bi->get_mass();
00119             i++;
00120 //          PRL(i);
00121           }
00122         }
00123     }   
00124 
00125     // Sort the array by radius.
00126 
00127     qsort((void *)rm_table, (size_t)n, sizeof(rm_pair), compare_radii);
00128 
00129     // Determine Lagrangian radii.
00130 
00131     //    cerr << "Determine Lagrangian radii" << endl;
00132     int k;
00133     for (k = 0; k < nzones-1; k++) {
00134         if (!nonlin) 
00135             mass_percent[k] = ((k + 1) / (real)nzones) * total_mass;
00136         else
00137             mass_percent[k] = nonlin_masses[k] * total_mass;
00138     }
00139 
00140     real *rlagr = new real[nzones-1];
00141     real cumulative_mass = 0.0;
00142     i = 0;
00143 
00144 
00145     for (k = 0; k < nzones-1; k++) {
00146 
00147         while (cumulative_mass < mass_percent[k]) {
00148             cumulative_mass += rm_table[i++].mass;
00149         }
00150 
00151         rlagr[k] = rm_table[i-1].radius;
00152 
00153     }
00154 
00155 
00156     // Place the data in the root dyn story.
00157 
00158     if (bf == NULL)
00159         putiq(b->get_dyn_story(), "boolfn", 0);
00160     else
00161         putiq(b->get_dyn_story(), "boolfn", 1);
00162 
00163     putiq(b->get_dyn_story(), "n_nodes", n);
00164 
00165     putiq(b->get_dyn_story(), "n_lagr", nzones-1);
00166     putra(b->get_dyn_story(), "r_lagr", rlagr, nzones-1);
00167 
00168     delete mass_percent;
00169     delete rm_table;
00170     delete rlagr;
00171 }
00172 
00173 // Convenient synonyms:
00174 
00175 local void  compute_mass_radii_quartiles(dyn * b, dc_pos, 
00176                                          real m_cutoff, real M_cutoff)
00177 {
00178     compute_general_mass_radii(b, 4, dc_pos, m_cutoff, M_cutoff);
00179 }
00180 
00181 local void  compute_mass_radii_percentiles(dyn * b, dc_pos,
00182                                            real m_cutoff, real M_cutoff)
00183 {
00184     compute_general_mass_radii(b, 10, dc_pos, m_cutoff, M_cutoff);
00185 }
00186 
00187 local bool single_fn(dyn * b)
00188 {
00189 
00190   //  int test = getiq(b->get_log_story(), "mass_doubled");
00191   //  PRL(test);
00192   if (getiq(b->get_log_story(), "mass_doubled") == 0 )
00193     return true;
00194   else
00195     return false;
00196 }
00197 
00198 local bool double_fn(dyn * b)
00199 {
00200   if (getiq(b->get_log_story(), "mass_doubled") == 1 )
00201     return true;
00202   else
00203     return false;
00204 }  
00205 
00206 local void print_lagrangian_radii(dyn* b, int which_lagr,
00207                                   vector dc_pos,
00208                                   real m_cutoff, real M_cutoff,
00209                                   int which = 0)
00210 {
00211     char tmp[3];
00212     bool nonlin = false;
00213 
00214     int nl, indent;
00215     if (which_lagr == 0) {
00216         nl = 4;
00217         indent = 15;
00218         PRI(4); cerr << "quartiles: ";
00219     } else if (which_lagr == 1) {
00220         nl = 10;
00221         indent = 20;
00222         PRI(4); cerr << "10-percentiles: ";
00223     } else {
00224         nl = 10;
00225         indent = 26;
00226         PRI(4); cerr << "selected percentiles: ";
00227         nonlin = true;
00228     }
00229 
00230     //    cerr << "before testnode call" << endl;
00231     //    if (which != 2 || 3) compute_general_mass_radii(b, nl, nonlin, testnode);
00232 
00233     if (which == 0) compute_general_mass_radii(b, nl, dc_pos, m_cutoff, M_cutoff, nonlin);
00234 
00235     //    cerr << "before single_fn call" << endl;
00236     //    PRL(which);
00237     if (which == 2) compute_general_mass_radii(b, nl, dc_pos, m_cutoff, M_cutoff, nonlin, single_fn);
00238 
00239     //     cerr << "before double_fn call" << endl;
00240     //    PRL(which);
00241     if (which == 3) compute_general_mass_radii(b, nl, dc_pos, m_cutoff, M_cutoff, nonlin, double_fn);
00242 
00243 
00244     if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00245         int n_lagr = getiq(b->get_dyn_story(), "n_lagr");
00246         real *r_lagr = new real[n_lagr];
00247         getra(b->get_dyn_story(), "r_lagr", r_lagr, n_lagr);
00248 
00249         for (int k = 0; k < n_lagr; k += 5) {
00250           if (k > 0) {
00251             cerr << endl;
00252             for (int kk = 0; kk < indent; kk++) cerr << " ";
00253           }
00254           for (int i = k; i < k+5 && i < n_lagr; i++)
00255             cerr << " " << r_lagr[i];
00256         }
00257         cerr << endl;
00258         delete r_lagr;
00259     }
00260 }
00261 
00262 /*-----------------------------------------------------------------------------
00263  *  compute_density  --  Get the density for all particles.
00264  *               note:
00265  *                    the neighbor_dist_sq[q] array will contain the distances
00266  *                    to the q-th nearest neighbor (in the form of the squares 
00267  *                    thereof); therefore  neighbor_dist_sq[0] = 0.0  since
00268  *                    this indicates the distance of a particle to itself.
00269  *                    Including this trivial case simplifies the algorithm
00270  *                    below by making it more homogeneous.
00271  *-----------------------------------------------------------------------------
00272  *              Litt.:
00273  *                    Stefano Casertano and Piet Hut: Astroph.J. 298,80 (1985).
00274  *                    To use their recipe, k >= 2 is required.
00275  *-----------------------------------------------------------------------------
00276  */
00277 local void  compute_density(dyn * b,            /* pointer to an Nbody system */
00278                       int k,            /* use kth nearest neighbor */
00279                       int n,
00280                       real m_cutoff,
00281                       real M_cutoff)
00282 {
00283     int  q, r;
00284     real *neighbor_dist_sq;
00285     real  volume;
00286     real  delr_sq;
00287     
00288     if (k >= n)                           /* no k-th nearest neighbor exists */
00289         cerr << "compute_density: k = " << k << " >= n = " << n << endl;
00290     if (k <= 1)
00291         cerr << "compute_density: k = " << k << " <= 1" << endl;
00292 
00293     neighbor_dist_sq = new real[k+1];
00294 
00295     //  for_all_leaves(dyn, b, d)               // The density is now defined
00296     for_all_daughters(dyn, b, d)        // ONLY for top-level nodes.
00297       if (d->get_mass()>=m_cutoff && d->get_mass()<=M_cutoff)
00298         {
00299         neighbor_dist_sq[0] = 0.0;
00300         for (q = 1; q <= k; q++)
00301             neighbor_dist_sq[q] = VERY_LARGE_NUMBER;
00302 
00303         //      for_all_leaves(dyn, b, dd)
00304         for_all_daughters(dyn, b, dd)
00305           if (dd->get_mass()>=m_cutoff && dd->get_mass()<=M_cutoff)
00306             {
00307             if (d == dd)
00308                 continue;
00309 
00310             delr_sq = square(something_relative_to_root(d, &dyn::get_pos)
00311                              - something_relative_to_root(dd, &dyn::get_pos));
00312 
00313             if (delr_sq < neighbor_dist_sq[k])
00314                 for (q = k-1; q >= 0; q--)
00315                     {
00316                     if (delr_sq > neighbor_dist_sq[q])
00317                         {
00318                         for (r = k; r > q+1; r--)
00319                             neighbor_dist_sq[r] = neighbor_dist_sq[r-1];
00320                         neighbor_dist_sq[q+1] = delr_sq;
00321                         break;
00322                         }
00323                     }
00324             }
00325             
00326         volume = (4.0/3.0) * PI * pow(neighbor_dist_sq[k], 1.5);
00327 
00328         real density =  (k - 1) / volume;           /* Ap. J. 298, 80 (1985) */
00329         story * s = d->get_dyn_story();
00330         //        putiq(s, "density_k_level", k);
00331         //        putrq(s, "density", density);
00332         }
00333 
00334     delete neighbor_dist_sq;
00335 }
00336 
00337 
00338 
00339 /*-----------------------------------------------------------------------------
00340  *  compute_mean_cod -- Returns the position and velocity of the density
00341  *                      center of an N-body system.
00342  *-----------------------------------------------------------------------------
00343  */
00344 local void compute_mean_cod(dyn *b, vector& pos, vector& vel, real m_cutoff,
00345                             real M_cutoff)
00346 {
00347     real total_weight = 0;
00348     pos = 0;
00349     vel = 0;
00350     
00351     for_all_daughters(dyn, b, d) 
00352       if (d->get_mass()>=m_cutoff && d->get_mass()<=M_cutoff) {
00353             
00354         real density = getrq(d->get_dyn_story(), "density");
00355         real dens2 = density * density;                        // weight factor
00356 
00357         total_weight += dens2;
00358         pos += dens2 * d->get_pos();
00359         vel += dens2 * d->get_vel();
00360     }   
00361 
00362     pos /= total_weight;
00363     vel /= total_weight;
00364 }
00365 
00366 /*===========================================================================*/
00367 
00368 local void compute_core_parameters(dyn* b, int k, vector& center,
00369                              real& rcore, int& ncore, real& mcore,
00370                              real & vcore, int n, 
00371                              real m_cutoff, real M_cutoff)
00372 {
00373     vector vel;
00374 
00375     real rcore2 = 0;
00376     if (rcore<=0) {
00377       compute_density(b, k, n, m_cutoff, M_cutoff);
00378       compute_mean_cod(b, center, vel, m_cutoff, M_cutoff);
00379 
00380       real total_weight = 0;
00381       real sum = 0;
00382       for_all_daughters(dyn, b, bi) 
00383         if (bi->get_mass()>=m_cutoff && bi->get_mass()<=M_cutoff) {
00384           real density = getrq(bi->get_dyn_story(), "density");
00385           real dens2 = density * density;              // weight factor
00386 
00387           total_weight += dens2;
00388           sum += dens2 * square(bi->get_pos() - center);
00389         }
00390 
00391       rcore2 = sum/total_weight;
00392       rcore = sqrt(rcore2);
00393     }
00394     else
00395       rcore2 = square(rcore);
00396     
00397     ncore = 0;
00398     mcore = 0;
00399     vcore = 0;
00400 
00401     for_all_daughters(dyn, b, bj)
00402       if (bj->get_mass()>=m_cutoff && bj->get_mass()<=M_cutoff) 
00403         if (square(bj->get_pos() - center) <= rcore2) {
00404             ncore++;
00405             mcore += bj->get_mass();
00406             vcore += bj->get_vel()*bj->get_vel();
00407         }
00408     mcore = mcore/(1.0*ncore);
00409     vcore = sqrt(vcore)/(1.0*ncore);
00410 }
00411 
00412 local void print_core_parameters(dyn* b, vector& density_center, real& rcore,
00413                                  int & ncore, real & vcore,
00414                                  int n, real m_cutoff, real M_cutoff,
00415                                  bool verbose)
00416   {
00417     real mcore;
00418 
00419     compute_core_parameters(b, 6, density_center, rcore, ncore, mcore,
00420                             vcore, n, m_cutoff, M_cutoff);
00421 
00422     real r_density_center = sqrt(density_center*density_center);
00423 
00424     vcore = conv_v_dyn_to_star(vcore,
00425                                b->get_starbase()->conv_r_star_to_dyn(1),
00426                                b->get_starbase()->conv_t_star_to_dyn(1));
00427     if (verbose) {
00428 
00429       real M_lower = b->get_starbase()->conv_m_dyn_to_star(m_cutoff);
00430       real M_upper = b->get_starbase()->conv_m_dyn_to_star(M_cutoff);
00431 
00432       cerr << "n = " << n << ", M (lower/upper) = ( "
00433                           << M_lower << ",  " << M_upper << " ) [Msun]\n";
00434       cerr << "     Core: (N, R, m, v) = ( " << ncore << ", "
00435            << Rsun_pc * b->get_starbase()->conv_r_dyn_to_star(rcore)
00436            << ", "  
00437            << b->get_starbase()->conv_m_dyn_to_star(mcore) <<", "
00438            << vcore
00439            << " ) [solar/km/s]\n";
00440       cerr << "     R_to_density_center = "
00441            << Rsun_pc *
00442               b->get_starbase()->conv_r_dyn_to_star(r_density_center)
00443            << " [pc]\n";
00444       
00445       
00446       //place the data in the root dyn-story.
00447       /*
00448       putiq(b->get_dyn_story(), "n_cutoff", n);
00449       putrq(b->get_dyn_story(), "m_cutoff", m_cutoff);
00450       putrq(b->get_dyn_story(), "M_cutoff", M_cutoff);
00451       putvq(b->get_dyn_story(), "density_center_pos", density_center);
00452       putrq(b->get_dyn_story(), "core_radius", rcore);
00453       putiq(b->get_dyn_story(), "n_core", ncore);
00454       putrq(b->get_dyn_story(), "m_core", mcore);
00455       */
00456     }
00457     else {
00458               PRC(n); PRC(m_cutoff); PRL(M_cutoff);
00459       PRI(4); PRC(rcore); PRC(ncore); PRL(mcore);
00460       PRI(4); PRL(r_density_center);
00461     }
00462         
00463 }
00464 
00465 local real system_energy(dyn* b, real m_cutoff, real M_cutoff)
00466 {
00467     real kin = 0;
00468     for_all_leaves(dyn, b, bj)
00469       if (bj->get_mass()>=m_cutoff && bj->get_mass()<=M_cutoff)
00470         kin += bj->get_mass()
00471              * square(something_relative_to_root(bj, &dyn::get_vel));
00472     kin *= 0.5;
00473 
00474     real pot = 0.0;
00475     for_all_leaves(dyn, b, bi) 
00476       if (bi->get_mass()>=m_cutoff && bi->get_mass()<=M_cutoff) {
00477         real dpot = 0.0;
00478         for_all_leaves(dyn, b, bj) 
00479           if (bj->get_mass()>=m_cutoff && bj->get_mass()<=M_cutoff) {
00480             if (bj == bi) break;
00481             vector dx = something_relative_to_root(bi, &dyn::get_pos)
00482                           - something_relative_to_root(bj, &dyn::get_pos);
00483             dpot += bj->get_mass() / abs(dx);
00484         }
00485         pot -= bi->get_mass() * dpot;
00486     }
00487 
00488     return kin + pot;
00489 }
00490 
00491 local void get_energies(dyn * n, real eps2, 
00492                   real& kinetic_energy, real& potential_energy,
00493                   real m_cutoff, real M_cutoff)
00494 {
00495     dyn  * ni, *nj;
00496 
00497     kinetic_energy = 0;
00498     for (ALL_i) 
00499       if (ni->get_mass()>=m_cutoff && ni->get_mass()<=M_cutoff) {
00500       
00501         vector v = ni->get_vel();
00502         kinetic_energy += ni->get_mass() * v * v;
00503     }
00504     kinetic_energy *= 0.5;
00505 
00506     potential_energy = 0;
00507     for (ALL_i) 
00508       if (ni->get_mass()>=m_cutoff && ni->get_mass()<=M_cutoff) {
00509         real dphi = 0;
00510         vector xi = ni->get_pos();
00511         for (j_ABOVE_i) 
00512           if (nj->get_mass()>=m_cutoff && nj->get_mass()<=M_cutoff) {
00513             vector xij = nj->get_pos() - xi;
00514             dphi += nj->get_mass()/sqrt(xij*xij + eps2);
00515         }
00516         potential_energy -= ni->get_mass() * dphi;
00517     }
00518 }
00519 
00520 
00521 local void print_energies(dyn* b, real& kT,
00522                           real m_cutoff, real M_cutoff, bool verbose) 
00523 {
00524     // Energies (top-level nodes):
00525 
00526     real kinetic_energy, potential_energy;
00527     get_energies(b, 0.0, kinetic_energy, potential_energy, m_cutoff, M_cutoff);
00528 
00529     real total_energy = kinetic_energy + potential_energy;
00530     real virial_ratio = -kinetic_energy / potential_energy;
00531     kT = -total_energy / (1.5*b->n_daughters());
00532 
00533     if (verbose) {
00534       PRI(4); cerr << "top-level nodes:\n";
00535       PRI(8); PRC(kinetic_energy); PRL(potential_energy);
00536       PRI(8); PRC(total_energy); PRC(kT); PRL(virial_ratio);
00537 
00538       PRI(4); cerr << "total energy (full system) = "
00539                    << system_energy(b, m_cutoff, M_cutoff) << endl;
00540     }
00541     else
00542       cerr <<"\t"<< kinetic_energy <<" "<< potential_energy
00543            <<" "<< total_energy <<" "<< kT
00544            <<" "<< virial_ratio <<" "<< system_energy(b, m_cutoff, M_cutoff) << endl;
00545 }
00546 
00547 local void print_relaxation_time(dyn* b, real m_cutoff, real M_cutoff, bool verbose)
00548 {
00549     // Print the relaxation time
00550 
00551     real potential_energy, kinetic_energy;
00552     real r_virial, t_relax;
00553     real total_mass = 0;
00554 
00555     int n=0;
00556     for_all_leaves(dyn, b, bj) 
00557       if (bj->get_mass()>=m_cutoff && bj->get_mass()<=M_cutoff) {
00558         n++;
00559         total_mass += bj->get_mass();
00560     }
00561 
00562     get_energies(b, 0.0, kinetic_energy, potential_energy, m_cutoff, M_cutoff);
00563 
00564     r_virial = -0.5 * total_mass * total_mass / potential_energy;
00565 
00566     t_relax = 9.62e-2 * sqrt(r_virial * r_virial * r_virial / total_mass)
00567               * n / log10(0.4 * n);
00568 
00569     if (verbose) {
00570       PRI(4); cerr << "r_virial = "
00571                    << Rsun_pc *
00572                       b->get_starbase()->conv_r_dyn_to_star(r_virial) << endl;
00573       PRI(4); cerr << "t_relax = "
00574                    <<  b->get_starbase()->conv_t_dyn_to_star(t_relax)  << endl;
00575     }
00576     else
00577       cerr <<"\t"<< r_virial <<" "<< t_relax << endl;
00578 }
00579 
00580 local void get_composition(dyn* b,
00581                            real m_cutoff, real M_cutoff,
00582                            int& n, real& mmean,
00583                            real& rmean,
00584                            real& vdisp) {
00585   
00586   n=0;
00587   real T_eff, L_eff, R_eff;
00588   real m_total=0, v2_disp=0, r_total=0;
00589   
00590   for_all_daughters(dyn, b, bi)
00591     if (bi->get_mass()>=m_cutoff && bi->get_mass()<=M_cutoff) {
00592       n++;
00593       m_total += bi->get_mass();
00594       v2_disp += bi->get_vel()*bi->get_vel();
00595       //R_eff = getrq(bi->get_star_story(), "R_eff");
00596       //if (R_eff<=0) {
00597 
00598       T_eff = getrq(bi->get_star_story(), "T_eff");
00599       L_eff = getrq(bi->get_star_story(), "L_eff");
00600       R_eff = sqrt(max(0.1, (1130.*L_eff)/pow(T_eff, 4)));
00601             
00602       r_total += R_eff;
00603     }
00604 
00605   if (n>0) {
00606     mmean = b->get_starbase()->conv_m_dyn_to_star(m_total)/(1.0*n);
00607     rmean = r_total/(1.0*n);
00608 
00609     vdisp = sqrt(v2_disp)/(1.0*n);
00610     vdisp = conv_v_dyn_to_star(vdisp,
00611                                b->get_starbase()->conv_r_star_to_dyn(1),
00612                                b->get_starbase()->conv_t_star_to_dyn(1));
00613   }
00614   
00615 }
00616 //#else
00617 
00618 main(int argc, char **argv)
00619 {
00620     bool binaries = true, verbose = true, out = false,
00621          calc_e = true, Mcut=true, mcut=true;
00622     int nzones = 10;
00623     bool auto_detect = false;
00624     real m_min = 0.1;
00625     real m_max = 100;
00626 
00627     extern char *poptarg;
00628     int c;
00629     char* param_string = "n:Mmeov";     // Note: "v" removed because only the
00630                                         // "verbose" option currently works.
00631 
00632     while ((c = pgetopt(argc, argv, param_string)) != -1)
00633         switch(c) {
00634 
00635             case 'e': calc_e = !calc_e;
00636                       break;
00637             case 'n': nzones = atoi(poptarg);
00638                       break;
00639             case 'M': Mcut = !Mcut;
00640                       break;
00641             case 'm': mcut = !mcut;
00642                       break;
00643             case 'a': auto_detect = !auto_detect;
00644                       break;
00645             case 'o': out = !out;
00646                       break;
00647             case 'v': verbose = !verbose;
00648                       break;
00649             case '?': params_to_usage(cerr, argv[0], param_string);
00650                       exit(1);
00651         }
00652 
00653     // Loop over input until no more data remain.
00654 
00655     dyn *b;
00656 
00657     real to_volume = 4*PI/3.;
00658     real n_rho1, n_rhoi, n_rhoj;
00659     real r_tot, m_tot, v_rel;      
00660     int n, ncore;
00661     real mass_int;
00662     vector density_center;
00663     real rcore=0, vcore=0;
00664     real kT;
00665     real M_cutoff, m_cutoff;
00666     real m_total;
00667 
00668     real mmean, rmean, vdisp;
00669     //     real *core_radius = (real *) calloc(nzones+1, 8);
00670     //     int  *nstars = (int *) calloc(nzones+1, 4);
00671     //     real *m_mean = (real *) calloc(nzones+1, 8);
00672     //     real *v_disp = (real *) calloc(nzones+1, 8);
00673     //     real *r_mean = (real *) calloc(nzones+1, 8);
00674     
00675     real *core_radius = new real[nzones+1];
00676     int  *ncstars = new int[nzones+1];
00677     int  *nstars = new int[nzones+1];
00678     real *m_mean = new real[nzones+1];
00679     real *v_disp = new real[nzones+1];
00680     real *vc_disp = new real[nzones+1];
00681     real *r_mean = new real[nzones+1];
00682         
00683     real geometric, grav_foc, encounter_rate, total_rate;
00684     total_rate = 0;
00685     
00686     while (b = get_dyn(cin)) {
00687       
00688       for (int i=0; i<=nzones; i++) {
00689         core_radius[i] = m_mean[i] = v_disp[i] = vc_disp[i] = r_mean[i] = 0;
00690         ncstars[i] = nstars[i] = 0;
00691       }
00692 
00693       b->get_starbase()->print_stellar_evolution_scaling(cerr);
00694       cerr << "Time = " << b->get_system_time() << endl;
00695       
00696       // Count stars and find mass extremes.
00697       n=0;
00698       if (auto_detect) {
00699         m_min = VERY_LARGE_NUMBER;
00700         m_max = -m_min;
00701         for_all_daughters(dyn, b, bi) {
00702           n++;
00703           m_min = min(m_min, bi->get_mass());
00704           m_max = max(m_max, bi->get_mass());
00705         }
00706       }
00707       else {
00708         for_all_daughters(dyn, b, bi) 
00709           n++;
00710         m_min = b->get_starbase()->conv_m_star_to_dyn(m_min);
00711         m_max = b->get_starbase()->conv_m_star_to_dyn(m_max);
00712       }
00713       mass_int = (log10(m_max)-log10(m_min))/(1.0*nzones-1);
00714 
00715       rcore = getrq(b->get_dyn_story(), "core_radius");
00716       density_center = getrq(b->get_dyn_story(), "density_center_pos");
00717 
00718       print_core_parameters(b, density_center, rcore, ncore, vcore,
00719                             n, m_min, m_max, verbose);
00720       print_energies(b, kT, m_min, m_max, verbose);
00721       print_relaxation_time(b, m_min, m_max, verbose);
00722       print_lagrangian_radii(b, 0, density_center, m_min, m_max, 0);
00723       
00724       core_radius[0] = Rsun_pc * b->get_starbase()->conv_r_dyn_to_star(rcore);
00725       nstars[0] = n;
00726       ncstars[0] = ncore;
00727       vc_disp[0] = vcore;
00728 
00729       get_composition(b, m_min, m_max, n, mmean, rmean, vdisp);
00730       m_mean[0] = mmean;
00731       v_disp[0] = vdisp;
00732       r_mean[0] = rmean;
00733       
00734       //PRC(nstars[0]);PRC(m_min);PRC(m_max);PRL(mass_int);
00735       //PRC(rcore);PRC(m_mean[0]);PRC(r_mean[0]);PRC(v_disp[0]);
00736 
00737       for (int i=0; i<nzones; i++) {
00738 
00739         m_cutoff = pow(10., log10(m_min)+i*mass_int);
00740         M_cutoff = pow(10., log10(m_min)+(i+1)*mass_int);
00741 
00742         if (!Mcut) M_cutoff = m_max;
00743         if (!mcut) m_cutoff = m_min;
00744 
00745         mmean = vdisp = rmean = 0;
00746         get_composition(b, m_cutoff, M_cutoff, n, mmean, rmean, vdisp); 
00747         nstars[i+1] = n;
00748         m_mean[i+1] = mmean;
00749         v_disp[i+1] = vdisp;
00750         r_mean[i+1] = rmean;
00751         
00752         if (n > 6 &&
00753             !(n==nstars[i] && (!Mcut || !mcut))) {
00754 
00755           rcore = 0;
00756           print_core_parameters(b, density_center, rcore, ncore, vcore,
00757                                 n, m_cutoff, M_cutoff, verbose);
00758           core_radius[i+1] = Rsun_pc * b->get_starbase()
00759                                         ->conv_r_dyn_to_star(rcore);
00760           ncstars[i+1] = ncore;
00761           vc_disp[i+1] = vcore;
00762 
00763           print_energies(b, kT, m_cutoff, M_cutoff, verbose);
00764           print_relaxation_time(b, m_cutoff, M_cutoff, verbose);
00765           print_lagrangian_radii(b, 0, density_center, m_cutoff, M_cutoff, 0);
00766 
00767           //PRC(n);PRC(core_radius[0]);PRL(core_radius[i+1]);
00768 
00769           n_rho1 = 1./(to_volume * pow(core_radius[0], 3));
00770           n_rhoi = ncstars[i+1]/(to_volume * pow(core_radius[i+1], 3));
00771           r_tot  = r_mean[0] + r_mean[i+1];
00772           m_tot  = m_mean[0] + m_mean[i+1];
00773           v_rel  = sqrt(pow(vc_disp[0], 2) + pow(vc_disp[i+1], 2));
00774 
00775           //PRC(vc_disp[0]);PRC(vc_disp[i+1]);PRL(v_rel);
00776           
00777           geometric = 6.31e-9 * v_rel * pow(r_tot, 2);
00778           grav_foc = 3.61e-3 * m_tot * r_tot / v_rel;
00779           encounter_rate = (n_rho1/1000.) * (n_rhoi/1000)
00780                          * pow(core_radius[0], 3)
00781                          * (grav_foc + geometric);
00782 
00783           if (verbose) {
00784             cerr << "     Stars: (N, r, m, v) = ( "
00785                  << nstars[i+1] <<", "
00786                  << r_mean[i+1] <<", "
00787                  << m_mean[i+1] <<", "
00788                  << v_disp[i+1] <<" ) [solar/km/s]\n";
00789             cerr << "     encounter_rate = "
00790                  << encounter_rate << " [per Myr]\n"
00791                  << "          (geo, gf) = ( "
00792                  << 100 * geometric/(geometric+grav_foc)
00793                  << ", " << 100 * grav_foc/(geometric+grav_foc)
00794                  << " ) [\%]\n\n";
00795           }
00796           else {
00797             PRI(4); PRC(m_mean[i+1]);PRC(v_disp[i+1]);PRL(r_mean[i+1]);
00798             PRI(4);PRC(geometric); PRL(grav_foc);
00799             PRI(4);PRL(encounter_rate);
00800             cerr << endl;
00801 
00802           }
00803 
00804         }
00805       }
00806       
00807       // Now print the encounter probability in a mass-mass plane.
00808       cerr << log10(b->get_starbase()
00809                      ->conv_m_dyn_to_star(m_min)) <<" "
00810            << log10(b->get_starbase()
00811                      ->conv_m_dyn_to_star(m_max)) << " "
00812            << nzones << endl;
00813       cerr << log10(b->get_starbase()
00814                      ->conv_m_dyn_to_star(m_min)) <<" "
00815            << log10(b->get_starbase()
00816                      ->conv_m_dyn_to_star(m_max)) << " "
00817            << nzones << endl;
00818       
00819       for (int im=1; im<nzones+1; im++) {
00820         for (int jm=im; jm<nzones+1; jm++) {
00821 
00822           //PRC(im);PRC(jm);PRC(nstars[im]);PRL(nstars[jm]);
00823           //PRC(core_radius[0]);PRC(core_radius[im]);PRL(core_radius[jm]);
00824             
00825           if (core_radius[im]>0 && core_radius[jm]>0) {
00826 
00827 
00828             n_rhoi = 1./(to_volume * pow(core_radius[im], 3));
00829             n_rhoj = 1./(to_volume * pow(core_radius[jm], 3));
00830             r_tot  = r_mean[im] + r_mean[jm];
00831             m_tot  = m_mean[im] + m_mean[jm];
00832             v_rel  = sqrt(pow(vc_disp[im], 2) + pow(vc_disp[jm], 2));
00833 
00834             rcore = min(core_radius[im], core_radius[jm]);
00835 
00836             //PRC(vc_disp[im]);PRC(vc_disp[jm]);PRL(v_rel);
00837 
00838             geometric = 6.31e-15 * v_rel * pow(r_tot, 2);
00839             grav_foc = 3.61e-9 * m_tot * r_tot / v_rel;
00840 
00841             if (im==jm) 
00842               encounter_rate = 0.5 * ((ncstars[im]-1) * n_rhoi)
00843                                    *  (ncstars[jm] * n_rhoj)
00844                              * pow(rcore, 3)
00845                              * (grav_foc + geometric);
00846             else
00847               encounter_rate = (ncstars[im] * n_rhoi)
00848                              * (ncstars[jm] * n_rhoj)
00849                              * pow(rcore, 3)
00850                              * (grav_foc + geometric);
00851 
00852             cerr << jm <<" "<< im <<" "
00853                  << m_mean[jm] <<" "<< m_mean[im] <<" "
00854                  << ncstars[jm] <<" "<< ncstars[im] <<" "
00855                  << encounter_rate << endl;
00856           }
00857           else if (core_radius[im]>0 || core_radius[jm]>0) {
00858 
00859             real ncore_i = ncstars[im];
00860             real ncore_j = ncstars[jm];
00861             
00862             if (ncstars[im]==0) ncore_i = core_radius[0] * nstars[im];
00863             if (ncstars[jm]==0) ncore_j = core_radius[0] * nstars[jm];
00864             
00865             //n_rhoi = 1./(to_volume * pow(core_radius[0], 3));
00866             //n_rhoj = 1./(to_volume * pow(core_radius[0], 3));
00867             r_tot  = r_mean[im] + r_mean[jm];
00868             m_tot  = m_mean[im] + m_mean[jm];
00869             //v_rel  = sqrt(pow(vc_disp[0], 2) + pow(vc_disp[0], 2));
00870 
00871             if (core_radius[im]>0) {
00872               n_rhoi = 1./(to_volume * pow(core_radius[im], 3));
00873               
00874               if (core_radius[jm]>0) {
00875                 n_rhoj = 1./(to_volume * pow(core_radius[jm], 3));
00876                 rcore = min(core_radius[im], core_radius[jm]);
00877                 v_rel  = sqrt(pow(vc_disp[im], 2) + pow(vc_disp[jm], 2));
00878               }
00879               else {
00880                 n_rhoj = 1./(to_volume * pow(core_radius[0], 3));
00881                 rcore = min(core_radius[im], core_radius[0]);
00882                 v_rel  = sqrt(pow(vc_disp[im], 2) + pow(v_disp[jm], 2));
00883               }
00884             }
00885             else {
00886               n_rhoi = 1./(to_volume * pow(core_radius[0], 3));
00887               
00888               if (core_radius[jm]>0) {
00889                 n_rhoj = 1./(to_volume * pow(core_radius[jm], 3));
00890                 rcore = min(core_radius[0], core_radius[jm]);
00891                 v_rel  = sqrt(pow(v_disp[jm], 2) + pow(vc_disp[jm], 2));
00892               }
00893               else {
00894                 rcore = core_radius[0];
00895                 n_rhoj = 1./(to_volume * pow(rcore, 3));
00896                 v_rel  = sqrt(pow(v_disp[im], 2) + pow(v_disp[jm], 2));
00897               }
00898             }
00899 
00900             //PRC(v_rel);PRC(n_rhoi);PRC(n_rhoj);PRL(rcore);
00901             //PRC(ncore_i);PRL(ncore_j);
00902             
00903             geometric = 6.31e-15 * v_rel * pow(r_tot, 2);
00904             grav_foc = 3.61e-9 * m_tot * r_tot / v_rel;
00905             if (im==jm) {
00906               if (ncore_i>1) 
00907                 encounter_rate = 0.5 * ((ncore_i-1) * n_rhoi)
00908                                      *  (ncore_j * n_rhoj)
00909                                * pow(rcore, 3)
00910                                * (grav_foc + geometric);
00911               else
00912                 encounter_rate = 0;
00913             }
00914             else
00915               encounter_rate = (ncore_i * n_rhoi)
00916                              * (ncore_j * n_rhoj)
00917                              * pow(rcore, 3)
00918                              * (grav_foc + geometric);
00919             
00920             
00921             cerr << jm <<" "<< im <<" "
00922                  << m_mean[jm] <<" "<< m_mean[im] <<" "
00923                  << ncore_j <<" "<< ncore_i <<" "
00924                  << encounter_rate << endl;
00925 
00926           } 
00927 
00928           total_rate += encounter_rate;
00929           cerr << flush;
00930         }
00931       }
00932       cerr << "     Total encounter rate = "
00933            << total_rate << " [per Myr]" << endl;
00934       
00935       cerr << 0 << " " << 0 << " "
00936            << 0 << " " << 0 << " "
00937            << 0 << " " << 0 << " "
00938            << 0 << endl;
00939 
00940       rmtree(b);
00941     }
00942 
00943 
00944 }

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