00001
00002
00003 #include "dyn.h"
00004
00005
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
00017
00018
00019
00020
00021
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
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
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;
00068
00069
00070
00071
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
00102
00103
00104
00105
00106
00107
00108
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
00121 }
00122 }
00123 }
00124
00125
00126
00127 qsort((void *)rm_table, (size_t)n, sizeof(rm_pair), compare_radii);
00128
00129
00130
00131
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
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
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
00191
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
00231
00232
00233 if (which == 0) compute_general_mass_radii(b, nl, dc_pos, m_cutoff, M_cutoff, nonlin);
00234
00235
00236
00237 if (which == 2) compute_general_mass_radii(b, nl, dc_pos, m_cutoff, M_cutoff, nonlin, single_fn);
00238
00239
00240
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
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 local void compute_density(dyn * b,
00278 int k,
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)
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
00296 for_all_daughters(dyn, b, d)
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
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;
00329 story * s = d->get_dyn_story();
00330
00331
00332 }
00333
00334 delete neighbor_dist_sq;
00335 }
00336
00337
00338
00339
00340
00341
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;
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;
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
00447
00448
00449
00450
00451
00452
00453
00454
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
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
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
00596
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
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";
00630
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
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
00670
00671
00672
00673
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
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
00735
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
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
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
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
00823
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
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
00866
00867 r_tot = r_mean[im] + r_mean[jm];
00868 m_tot = m_mean[im] + m_mean[jm];
00869
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
00901
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 }