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