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