00001
00002
00003
00004 #include "sstar_to_dyn.h"
00005 #include "dyn.h"
00006 #include "single_star.h"
00007
00008 #ifndef TOOLBOX
00009
00010 #define OUTPUT_MASS_LIMIT 10 // Msun
00011 #define OUTPUT_NUMBER_LIMIT 10
00012 #define MINIMUM_LUMINOSITY 1.0e-4 // planets' luminosity
00013
00014 #define MAX_PREDEF_RADII 9
00015 enum bin_option {lineair, predefined};
00016
00017 typedef struct {
00018
00019 real sort_param;
00020
00021 stellar_type_summary type;
00022 real Lu;
00023 real Lb;
00024 real Lv;
00025 real Lr;
00026 real Li;
00027 } star_table, *star_ubvri_ptr;
00028
00029 struct pop {
00030 int stypes[no_of_stellar_type];
00031
00032 pop() {
00033 for (int i=0; i<no_of_stellar_type; i++)
00034 stypes[i] = 0;
00035 }
00036 };
00037
00038 struct nm_bin {
00039 int no_of_stars;
00040 real mass_limit;
00041 real total_mass;
00042 nm_bin() {
00043 no_of_stars = 0;
00044 mass_limit=total_mass = 0;
00045 }
00046 };
00047
00048 local int which_zone(dyn* bi, vector& center, int n_lagr, real* r_lagr)
00049 {
00050 vector pos = something_relative_to_root(bi, &dyn::get_pos);
00051 vector dr = pos - center;
00052 real dr2 = dr*dr;
00053
00054 for (int j = 0; j < n_lagr; j++)
00055 if (r_lagr[j] > dr2) return j;
00056
00057 return n_lagr;
00058 }
00059
00060 local void print_stellar_content(dyn* b) {
00061
00062 int n_lagr = 0;
00063 real *r_lagr = NULL;
00064 vector lagr_pos = 0;
00065
00066
00067
00068
00069 if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00070
00071
00072
00073 n_lagr = getiq(b->get_dyn_story(), "n_lagr");
00074 r_lagr = new real[n_lagr];
00075 getra(b->get_dyn_story(), "r_lagr", r_lagr, n_lagr);
00076
00077 lagr_pos = getvq(b->get_dyn_story(), "lagr_pos");
00078
00079 }
00080 else
00081 r_lagr = new real[n_lagr];
00082
00083 pop *content = new pop[n_lagr+1];
00084
00085
00086
00087
00088
00089 for (int i = 0; i <= n_lagr; i++)
00090 if (i < n_lagr) r_lagr[i] *= r_lagr[i];
00091
00092 int N_total = 0;
00093 stellar_type stype = NAS;
00094
00095 for_all_daughters(dyn, b, bi) {
00096
00097
00098
00099 if (bi->get_oldest_daughter() != NULL)
00100
00101 stype = Double;
00102
00103 else {
00104
00105 if (b->get_use_sstar())
00106 stype = bi->get_starbase()->get_element_type();
00107 else if (find_qmatch(bi->get_star_story(), "Type"))
00108 stype = extract_stellar_type_string(
00109 getsq(bi->get_star_story(), "Type"));
00110 else {
00111 cerr << " No stellar information found for: ";
00112 bi->pretty_print_node(cerr);
00113 return;
00114 }
00115 }
00116
00117
00118
00119 int i = which_zone(bi, lagr_pos, n_lagr, r_lagr);
00120
00121
00122
00123 N_total++;
00124 content[i].stypes[(int)stype]++;
00125 }
00126
00127 if (N_total > 0) {
00128
00129 int j, k;
00130 char* ts;
00131 cerr << " (";
00132 for (j = 0; j <= dynamic_cast(int, Super_Giant); j++)
00133 cerr << " " << type_short_string(dynamic_cast(stellar_type, j));
00134
00135 cerr << " ";
00136 for (j = dynamic_cast(int, Carbon_Star);
00137 j < dynamic_cast(int, no_of_stellar_type); j++)
00138 cerr << " " << type_short_string(dynamic_cast(stellar_type, j));
00139
00140 cerr << ")" << endl;
00141
00142 for (k = 0; k <= n_lagr; k += 5) {
00143 if (k > 0) cerr << endl;
00144 for (int i = k; i < k+5 && i <= n_lagr; i++) {
00145 cerr << " zone " << i << " ";
00146 for (j=0; j<=Super_Giant; j++)
00147 cerr << " " << content[i].stypes[j];
00148 cerr << " ";
00149 for (j=Carbon_Star; j<no_of_stellar_type; j++)
00150 cerr << " " << content[i].stypes[j];
00151 cerr << endl;
00152 }
00153 }
00154
00155 } else
00156 cerr << " (none)\n";
00157
00158 delete [] content;
00159 delete [] r_lagr;
00160
00161
00162
00163
00164
00165 }
00166
00167 local int print_special_stars(dyn* b) {
00168
00169 if (!b->get_use_sstar())
00170 return -1;
00171
00172
00173
00174
00175 real current_time = b->get_starbase()
00176 ->conv_t_dyn_to_star(b->get_system_time());
00177 int N_special = 0;
00178 real f_Bs, t_Bs;
00179 for_all_leaves(dyn, b, bi) {
00180
00181
00182
00183 stellar_type stype = NAS;
00184 star* ss = NULL;
00185
00186 if (has_sstar(bi)) {
00187 star* ss = dynamic_cast(star*, bi->get_starbase());
00188
00189 if (ss!=NULL) {
00190 star_state sts(ss);
00191
00192 if (sts.special()) {
00193
00194 N_special++;
00195
00196 cerr << " " << bi->format_label()
00197 << " is ";
00198 put_short_state(sts, cerr);
00199 cerr << " (" << type_dominant_state(sts)
00200 << ")";
00201
00202 if (sts.class_spec[Blue_Straggler]) {
00203
00204
00205 t_Bs = current_time - ss->get_relative_age();
00206 cerr << " [t_Bs = " << t_Bs << " Myr]";
00207 }
00208
00209 if (ss->is_binary_component()) {
00210 cerr << " binary companion is "
00211 << bi->get_binary_sister()->format_label() << " ";
00212 print_star(dynamic_cast(starbase*,
00213 ss->get_companion()));
00214 }
00215 cerr << endl;
00216 }
00217 else if (ss->get_element_type() == Disintegrated) {
00218
00219 N_special++;
00220
00221 cerr << " " << bi->format_label()
00222 << " is disintegrated star" << endl;
00223 }
00224 }
00225 }
00226 }
00227
00228 if (N_special == 0)
00229 cerr << " ---No special stars---" <<endl;
00230 }
00231
00232 local void print_compact_stars(dyn* b) {
00233
00234
00235 if (!b->get_use_sstar())
00236 return;
00237
00238 int N_compact = 0;
00239
00240 for_all_leaves(dyn, b, bi) {
00241
00242
00243
00244 stellar_type stype = NAS;
00245 star* ss = NULL;
00246
00247
00248 if (has_sstar(bi)) {
00249
00250 ss = dynamic_cast(star*, bi->get_starbase());
00251
00252 bool accreting = false;
00253 if (ss!=NULL)
00254 if(ss->remnant()) {
00255 N_compact++;
00256
00257 stype = ss->get_element_type();
00258 accreting = ((ss->get_spec_type(Accreting))?true:false);
00259
00260 if (stype == Xray_Pulsar || stype == Radio_Pulsar) {
00261
00262 cerr << " " << bi->format_label()
00263 << " is " << type_string(stype)
00264 << " (Ps = " << ss->get_rotation_period()
00265 << ", log B = " << ss->get_magnetic_field()
00266 << ") ";
00267 if (ss->is_binary_component()) {
00268 cerr << " binary companion is "
00269 << bi->get_binary_sister()->format_label()
00270 << " ";
00271 print_star(dynamic_cast(starbase*,
00272 ss->get_companion()));
00273 }
00274 cerr << endl;
00275 }
00276 else if (stype == Helium_Giant) {
00277
00278 cerr << " " << bi->format_label()
00279 << " is " << type_string(stype)
00280 << " (M =" << ss->get_relative_mass()
00281 << ", Reff = " << ss->get_effective_radius()
00282 << ", L = " << ss->get_luminosity()
00283 << ") ";
00284 if (ss->is_binary_component()) {
00285 cerr << "binary companion is "
00286 << bi->get_binary_sister()->format_label()
00287 << " ";
00288 print_star(dynamic_cast(starbase*,
00289 ss->get_companion()));
00290 }
00291 cerr << endl;
00292 }
00293 else if (accreting) {
00294
00295 cerr << " " << bi->format_label()
00296 << " is accreting " << type_string(stype);
00297 if (ss->is_binary_component()) {
00298 cerr << " binary companion is "
00299 << bi->get_binary_sister()->format_label()
00300 << " ";
00301 print_star(dynamic_cast(starbase*,
00302 ss->get_companion()));
00303 }
00304 cerr << endl;
00305 }
00306 }
00307 else if (stype == Thorn_Zytkow) {
00308
00309 cerr << " " << bi->format_label()
00310 << " is " << type_string(stype)
00311 << " (M =" << ss->get_relative_mass()
00312 << ", Reff = " << ss->get_effective_radius()
00313 << ", L = " << ss->get_luminosity()
00314 << ") ";
00315 if (ss->is_binary_component()) {
00316 cerr << "binary companion is "
00317 << bi->get_binary_sister()->format_label()
00318 << " ";
00319 print_star(dynamic_cast(starbase*,
00320 ss->get_companion()));
00321 }
00322 cerr << endl;
00323 }
00324 }
00325 }
00326
00327 if (N_compact == 0)
00328 cerr << " ---No compact stars---" <<endl;
00329 else
00330 cerr << " Number of compact stars = " << N_compact << endl;
00331 }
00332
00333
00334 local int compare_parameters(const void * pi, const void * pj) {
00335
00336 if (((star_ubvri_ptr) pi)->sort_param > ((star_ubvri_ptr) pj)->sort_param)
00337 return(1);
00338 else if (((star_ubvri_ptr)pi)->sort_param < ((star_ubvri_ptr)pj)->sort_param)
00339 return(-1);
00340 else
00341 return(0);
00342 }
00343
00344 local void sort_stellar_ubvri(dyn * b, int nzones, int n,
00345 star_ubvri_ptr table, real *Ltot) {
00346
00347
00348 vector dc_pos = 0;
00349 vector dc_vel = 0;
00350 real rcore = 0;
00351 if (find_qmatch(b->get_dyn_story(), "density_center_pos"))
00352 dc_pos = getvq(b->get_dyn_story(), "density_center_pos");
00353
00354
00355
00356 int i=0;
00357
00358
00359
00360 stellar_type stype;
00361 real Lu, Lb, Lv, Lr, Li;
00362
00363 Ltot[0] = Ltot[1] = Ltot[2] = Ltot[3] = Ltot[4] = 0;
00364
00365 vector rstar;
00366 for_all_leaves(dyn, b, bi) {
00367
00368 rstar = (bi->get_top_level_node()->get_pos() - dc_pos);
00369 table[i].sort_param = abs(rstar[0]);
00370
00371 stype = NAS;
00372
00373 Lu=Lb=Lv=Lr=Li=0;
00374 get_Lubvri_star(bi, stype, Lu, Lb, Lv, Lr, Li);
00375
00376
00377 if (summarize_stellar_type(stype)==Inert_Remnant)
00378 Lu=Lb=Lv=Lr=Li=0;
00379
00380 table[i].type = summarize_stellar_type(stype);
00381 table[i].Lu = Lu;
00382 table[i].Lb = Lb;
00383 table[i].Lv = Lv;
00384 table[i].Lr = Lr;
00385 table[i].Li = Li;
00386
00387
00388
00389
00390
00391
00392
00393 i++;
00394 }
00395
00396 qsort((void *)table, (size_t)n, sizeof(star_table), compare_parameters);
00397
00398 for(i=1; i<n; i++) {
00399 table[i].Lu += table[i-1].Lu;
00400 table[i].Lb += table[i-1].Lb;
00401 table[i].Lv += table[i-1].Lv;
00402 table[i].Lr += table[i-1].Lr;
00403 table[i].Li += table[i-1].Li;
00404 }
00405 for(i=0; i<n; i++) {
00406 table[i].Lu = log(table[i].Lu);
00407 table[i].Lb = log(table[i].Lb);
00408 table[i].Lv = log(table[i].Lv);
00409 table[i].Lr = log(table[i].Lr);
00410 table[i].Li = log(table[i].Li);
00411 }
00412 Ltot[0] = table[n-1].Lu;
00413 Ltot[1] = table[n-1].Lb;
00414 Ltot[2] = table[n-1].Lv;
00415 Ltot[3] = table[n-1].Lr;
00416 Ltot[4] = table[n-1].Li;
00417
00418 PRC(Ltot[0]);PRC(Ltot[1]);PRC(Ltot[2]);PRC(Ltot[3]);PRC(Ltot[4]);
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 }
00431
00432
00433 local real predifinced_lagrangian_fraction(int i) {
00434
00435 real bin_radius;
00436 switch(i) {
00437 case 0: bin_radius = 0.005;
00438 break;
00439 case 1: bin_radius = 0.01;
00440 break;
00441 case 2: bin_radius = 0.02;
00442 break;
00443 case 3: bin_radius = 0.05;
00444 break;
00445 case 4: bin_radius = 0.01;
00446 break;
00447 case 5: bin_radius = 0.25;
00448 break;
00449 case 6: bin_radius = 0.50;
00450 break;
00451 case 7: bin_radius = 0.75;
00452 break;
00453 default: bin_radius = 0.90;
00454 }
00455
00456 return bin_radius;
00457 }
00458
00459 local real lagrangian_radius(int i, int nzones,
00460 bin_option binning) {
00461
00462 real bin;
00463 if (binning == predefined && nzones==MAX_PREDEF_RADII)
00464
00465 bin = predifinced_lagrangian_fraction(i);
00466 else
00467 bin = ((i + 1) / (real)nzones);
00468
00469 return bin;
00470 }
00471
00472 local void get_lagrangian_ubvri_radii(dyn *b, int nzones, bin_option binning,
00473 real *rLu, real *rLb, real *rLv,
00474 real *rLr, real *rLi) {
00475
00476
00477 if (nzones < 2)
00478 return;
00479
00480 int n = b->n_leaves();
00481
00482 star_ubvri_ptr table = new star_table[n];
00483 if (table == NULL) {
00484 cerr << "sort_stellar_ubvri: "
00485 << "not enough memory left for table\n";
00486 exit(0);
00487 }
00488
00489 real Ltot[] = {0, 0, 0, 0, 0};
00490 sort_stellar_ubvri(b, nzones, n, table, Ltot);
00491
00492
00493
00494 if (nzones > 100) {
00495 cerr << "get_lagrangian_ubvri_radii: too many zones!" << endl;
00496 return;
00497 }
00498
00499 real L_percent[5][100];
00500
00501
00502 for (int k=0; k<nzones; k++) {
00503 for (int l=0; l<5; l++) {
00504 L_percent[l][k] = lagrangian_radius(k, nzones, binning)*Ltot[l];
00505 }
00506 }
00507
00508 real Lcum[] = {0, 0, 0, 0, 0};
00509 int ipercent[] = {0, 0, 0, 0, 0};
00510
00511 for (int k=0; k<nzones; k++) {
00512 for (int l=0; l<5; l++) {
00513
00514 while (Lcum[l] < L_percent[l][k]) {
00515 switch(l) {
00516 case 0: Lcum[l] = table[ipercent[l]].Lu;
00517 break;
00518 case 1: Lcum[l] = table[ipercent[l]].Lb;
00519 break;
00520 case 2: Lcum[l] = table[ipercent[l]].Lv;
00521 break;
00522 case 3: Lcum[l] = table[ipercent[l]].Lr;
00523 break;
00524 case 4: Lcum[l] = table[ipercent[l]].Li;
00525 break;
00526 };
00527
00528 ipercent[l]++;
00529 }
00530 }
00531
00532 rLu[k] = table[ipercent[0]-1].sort_param;
00533 rLb[k] = table[ipercent[1]-1].sort_param;
00534 rLv[k] = table[ipercent[2]-1].sort_param;
00535 rLr[k] = table[ipercent[3]-1].sort_param;
00536 rLi[k] = table[ipercent[4]-1].sort_param;
00537 }
00538
00539 int p = cerr.precision(4);
00540 cerr << " Total luminosities: " << exp(table[n-1].Lu) << " "
00541 << exp(table[n-1].Lb) << " "
00542 << exp(table[n-1].Lv) << " "
00543 << exp(table[n-1].Lr) << " "
00544 << exp(table[n-1].Li)
00545 << " [Lsun]\n" << endl;
00546 cerr.precision(p);
00547
00548 delete []table;
00549
00550 }
00551
00552 local void print_lagrangian_ubvri_radii(dyn *b, int nzones,
00553 bin_option binning) {
00554
00555 cerr << " (currently NON) Projected ubvri Lagrangian radii" << endl;
00556 cerr << " [%] u b< v r i"
00557 << endl;
00558 cerr << " Temporarily removed"<<endl;
00559
00560 #if 0
00561 real *rLu = new real[nzones];
00562 real *rLb = new real[nzones];
00563 real *rLv = new real[nzones];
00564 real *rLr = new real[nzones];
00565 real *rLi = new real[nzones];
00566
00567 get_lagrangian_ubvri_radii(b, nzones, binning, rLu, rLb, rLv, rLr, rLi);
00568
00569 cerr << " (currently NON) Projected ubvri Lagrangian radii" << endl;
00570 cerr << " [%] u b v r i"
00571 << endl;
00572
00573 int p = cerr.precision(4);
00574 int ncount, nstar = 0;
00575 for (int k=0; k<nzones; k++)
00576 cerr << " " << lagrangian_radius(k, nzones, binning) << " "
00577 << rLu[k] << " "<< rLb[k] << " " << rLv[k]
00578 << " " << rLr[k] << " "<< rLi[k] << endl;
00579 cerr.precision(p);
00580
00581 delete []rLu;
00582 delete []rLb;
00583 delete []rLv;
00584 delete []rLr;
00585 delete []rLi;
00586 #endif
00587 }
00588
00589 local void print_mass_over_light(dyn* b) {
00590
00591 if (!b->get_use_sstar())
00592 return;
00593
00594
00595
00596 if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00597
00598
00599
00600 int n_lagr = getiq(b->get_dyn_story(), "n_lagr");
00601 real *r_lagr = new real[n_lagr];
00602 getra(b->get_dyn_story(), "r_lagr", r_lagr, n_lagr);
00603
00604 vector lagr_pos = 0;
00605
00606 if (find_qmatch(b->get_dyn_story(), "lagr_pos"))
00607 lagr_pos = getvq(b->get_dyn_story(), "lagr_pos");
00608 else
00609 warning("print_mass_over_light: lagr_pos not found");
00610
00611 int *total_star = new int[n_lagr+1];
00612 real *total_mass = new real[n_lagr+1];
00613 real *total_lumi = new real[n_lagr+1];
00614 real *total_Ngt1Msun = new real[n_lagr+1];
00615 real *total_Ngt10Msun = new real[n_lagr+1];
00616
00617 int i;
00618 for (i = 0; i <= n_lagr; i++) {
00619 total_star[i] = 0;
00620 total_Ngt1Msun[i] = total_Ngt10Msun[i]
00621 = total_mass[i] = total_lumi[i] = 0;
00622 }
00623
00624
00625
00626
00627
00628 for (i = 0; i <= n_lagr; i++)
00629 if (i < n_lagr) r_lagr[i] *= r_lagr[i];
00630
00631 int N_total = 0, N_Mgt1Msun = 0, N_Mgt10Msun = 0;
00632 real L_star = 0, M_star = 0;
00633 bool Mgt1Msun, Mgt10Msun;
00634
00635 for_all_leaves(dyn, b, bi) {
00636
00637
00638
00639 Mgt1Msun = Mgt10Msun = false;
00640
00641 if (bi->get_oldest_daughter() == NULL)
00642 if (has_sstar(bi)) {
00643
00644 L_star = ((single_star*)bi->get_starbase())
00645 ->get_luminosity();
00646 M_star = bi->get_starbase()->get_total_mass();
00647 if ( ((single_star*)bi->get_starbase())->remnant() )
00648 L_star = 0;
00649 if(M_star>1) {
00650 Mgt1Msun = true;
00651 if(M_star>10)
00652 Mgt10Msun = true;
00653 }
00654 }
00655 else if (bi->get_star_story()!=NULL) {
00656
00657 L_star = getrq(bi->get_star_story(), "L_eff");
00658 M_star = getrq(bi->get_star_story(), "M_env")
00659 + getrq(bi->get_star_story(), "M_core");
00660 if(M_star>1) {
00661 Mgt1Msun = true;
00662 if(M_star>10)
00663 Mgt10Msun = true;
00664 }
00665 }
00666
00667
00668
00669 i = which_zone(bi, lagr_pos, n_lagr, r_lagr);
00670
00671
00672
00673 N_total++;
00674
00675 total_mass[i] += M_star;
00676 total_lumi[i] += L_star;
00677 total_star[i]++;
00678
00679 if(Mgt1Msun) {
00680 total_Ngt1Msun[i]++;
00681 N_Mgt1Msun++;
00682 }
00683 if(Mgt10Msun) {
00684 total_Ngt10Msun[i]++;
00685 N_Mgt10Msun++;
00686 }
00687 }
00688
00689 cerr << " Name M(tot) L(tot) "
00690 << "\tN(all)\t N(M>1)\t N(M>10Msun)\n";
00691
00692 if (N_total > 0) {
00693
00694 for (i=0; i<=n_lagr; i++)
00695 if (total_lumi[i]>0 && total_star[i]>0)
00696 cerr << " zone " << i << " "
00697 << total_mass[i] <<" \t"
00698 << total_lumi[i] <<" \t"
00699 << total_star[i] <<" \t"
00700 << total_Ngt1Msun[i] <<" \t"
00701 << total_Ngt10Msun[i] << endl;
00702 else
00703 cerr << " zone " << i << " "
00704 << " no mass "
00705 << " no luminosity \tno stars"
00706 << endl;
00707
00708 } else
00709 cerr << " (none)\n";
00710
00711 delete []r_lagr;
00712 delete []total_mass;
00713 delete []total_lumi;
00714 delete []total_star;
00715 delete []total_Ngt1Msun;
00716 delete []total_Ngt10Msun;
00717 }
00718 }
00719
00720 local void print_mass_spectrum(dyn* b, int nzones, bool verbose) {
00721
00722 if (!b->get_use_sstar() || nzones < 2)
00723 return;
00724
00725 nm_bin *mass_bins = new nm_bin[nzones+1];
00726 if (mass_bins == NULL) {
00727 cerr << "not enough memory left for print_mass_spectrum\n";
00728 return;
00729 }
00730
00731 real m_min = b->get_starbase()->conv_m_star_to_dyn(0.1);
00732 real m_max = b->get_starbase()->conv_m_star_to_dyn(100);
00733
00734 real log_m_min = log10(m_min);
00735 mass_bins[1].mass_limit = log_m_min;
00736 real mass_int = (log10(m_max)-mass_bins[1].mass_limit)/(nzones-2);
00737
00738 int i;
00739 for (i=0; i<nzones; i++) {
00740 mass_bins[i].mass_limit = pow(10, log_m_min + (i-1)*mass_int);
00741 mass_bins[i].no_of_stars = 0;
00742 mass_bins[i].total_mass = 0;
00743 }
00744 mass_bins[0].mass_limit = mass_bins[nzones].mass_limit = 0;
00745
00746 int N_total = 0;
00747 real mi, m_total=0;
00748 for_all_leaves(dyn, b, bi) {
00749 mi = bi->get_mass();
00750 m_total += mi;
00751 N_total++;
00752 if (mi > m_min && mi <= m_max) {
00753
00754 for (i=2; i<nzones-1; i++)
00755
00756 if (mi > mass_bins[i-1].mass_limit &&
00757 mi <= mass_bins[i].mass_limit) {
00758
00759 mass_bins[i-1].no_of_stars++;
00760 mass_bins[i-1].total_mass += mi;
00761 }
00762 }
00763 else if (mi<=m_min) {
00764
00765 mass_bins[0].no_of_stars++;
00766 mass_bins[0].total_mass += mi;
00767 }
00768 else {
00769
00770 mass_bins[nzones].no_of_stars++;
00771 mass_bins[nzones].total_mass += mi;
00772 }
00773 }
00774
00775 real scaling = 1;
00776 if (b->get_use_sstar()) {
00777 scaling = b->get_starbase()->conv_m_star_to_dyn(1);
00778 m_min = b->get_starbase()->conv_m_dyn_to_star(m_min);
00779 m_max = b->get_starbase()->conv_m_dyn_to_star(m_max);
00780 }
00781 int p = cerr.precision(LOW_PRECISION);
00782
00783 if (N_total > 0) {
00784
00785 cerr << endl;
00786 if (verbose)
00787 cerr << " Mass function (dlog_m = " << mass_int
00788 << " min = " << m_min
00789 << " max = " << m_max << " [Msun]): "
00790 << endl;
00791
00792 cerr << " " << mass_bins[0].no_of_stars
00793 << " <";
00794 for (i=1; i<=nzones-2; i++)
00795 cerr << " " << mass_bins[i].no_of_stars;
00796
00797 cerr << " > " << mass_bins[nzones-1].no_of_stars
00798 << endl;
00799 }
00800 else
00801 cerr << " (none)\n";
00802
00803 cerr.precision(p);
00804 delete []mass_bins;
00805 }
00806
00807
00808 local void print_luminosity_function(dyn* b, int nzones, bool verbose) {
00809
00810 if (!b->get_use_sstar() || nzones < 2)
00811 return;
00812
00813 nm_bin *lstar_bins = new nm_bin[nzones+1];
00814 if (lstar_bins == NULL) {
00815 cerr << "not enough memory left for print_luminosity_function\n";
00816 return;
00817 }
00818
00819 real l_min = 0.01;
00820 real l_max = 1.e+6;
00821 real log_l_min = log10(l_min);
00822 real log_l_max = log10(l_max);
00823
00824 lstar_bins[1].mass_limit = log_l_min;
00825 real lstar_int = (log_l_max-log_l_min)/(nzones-2);
00826
00827 int i;
00828 for (i=0; i<nzones; i++) {
00829 lstar_bins[i].mass_limit = pow(10, log_l_min + (i-1)*lstar_int);
00830 lstar_bins[i].no_of_stars = 0;
00831 lstar_bins[i].total_mass = 0;
00832 }
00833 lstar_bins[0].mass_limit = lstar_bins[nzones].mass_limit = 0;
00834
00835 int N_total = 0;
00836 real li, l_total=0;
00837 for_all_leaves(dyn, b, bi) {
00838
00839 li = ((star*)bi->get_starbase())->get_luminosity();
00840 l_total += li;
00841 N_total++;
00842 if (li > l_min && li <= l_max) {
00843
00844 for (i=2; i<nzones-1; i++)
00845
00846 if (li > lstar_bins[i-1].mass_limit &&
00847 li <= lstar_bins[i].mass_limit) {
00848 lstar_bins[i-1].no_of_stars++;
00849 lstar_bins[i-1].total_mass += li;
00850 }
00851 }
00852 else if (li <= l_min) {
00853
00854 lstar_bins[0].no_of_stars++;
00855 lstar_bins[0].total_mass += li;
00856 }
00857 else {
00858
00859 lstar_bins[nzones].no_of_stars++;
00860 lstar_bins[nzones].total_mass += li;
00861 }
00862 }
00863
00864 if (N_total > 0) {
00865
00866 cerr << endl;
00867 if (verbose)
00868 cerr << " Luminosity function (dlog_L = " << lstar_int
00869 << " min = 10^" << log_l_min
00870 << " max = 10^" << log_l_max << " [Lsun]): "
00871 << endl;
00872
00873 cerr << " " << lstar_bins[0].no_of_stars
00874 << " <";
00875 for (i=1; i<=nzones-2; i++)
00876 cerr << " " << lstar_bins[i].no_of_stars;
00877
00878 cerr << " > " << lstar_bins[nzones].no_of_stars
00879 << endl;
00880
00881 }
00882 else
00883 cerr << " (none)\n";
00884
00885 delete [] lstar_bins;
00886 }
00887
00888 local void print_massive_star(dyn *bi, vector center_pos,
00889 vector center_vel, bool verbose) {
00890
00891 real mass = bi->get_starbase()->get_total_mass();
00892 real r_com = abs(bi->get_pos() - center_pos);
00893 real v_com = abs(bi->get_vel() - center_vel);
00894
00895 cerr << " star# " << bi->format_label()
00896 << " " << mass << " ("; put_state(make_star_state(bi), cerr);
00897 cerr << ") \t " << r_com << " " << v_com << endl;
00898 }
00899
00900 local int print_massive_binary(dyn *bi,
00901 vector center_pos, vector center_vel,
00902 real mass_limit, real number_limit,
00903 bool verbose) {
00904
00905
00906 real m_tot = bi->get_starbase()->conv_m_dyn_to_star(bi->get_mass());
00907 real mass1 = bi->get_oldest_daughter()
00908 ->get_starbase()->get_total_mass();
00909 int index1 = bi->get_oldest_daughter()->get_index();
00910 real mass2 = bi->get_oldest_daughter()->get_younger_sister()
00911 ->get_starbase()->get_total_mass();
00912 int index2 = bi->get_oldest_daughter()->get_younger_sister()->get_index();
00913
00914 if ((bi->get_index() > 0 && bi->get_index() <= number_limit) ||
00915 (mass1 >= mass_limit || (index1 >0 && index1 <= number_limit)) ||
00916 (mass2 >= mass_limit || (index2 >0 && index2 <= number_limit))) {
00917
00918 real r_com = abs(bi->get_pos() - center_pos);
00919 real v_com = abs(bi->get_vel() - center_vel);
00920
00921 cerr << " " << bi->format_label()
00922 << " " << m_tot
00923 << " (Multiple) \t " << r_com << " " << v_com << endl;
00924
00925 cerr << " " << mass1 << " (";
00926 put_state(make_star_state(bi->get_oldest_daughter()), cerr);
00927 cerr << ") " << endl;
00928 cerr << " " << mass2 << " (";
00929 put_state(make_star_state(bi->get_younger_sister()), cerr);
00930 cerr << ") " << endl;
00931 }
00932
00933 return 1;
00934 }
00935
00936 local bool contains_massive_star(dyn *b,
00937 real mass_limit,
00938 real number_limit) {
00939
00940 for_all_leaves(dyn, b, bi)
00941 if ((bi->get_index()>0 && bi->get_index() <= number_limit) ||
00942 bi->get_starbase()->get_total_mass() >= mass_limit)
00943 return true;
00944
00945 return false;
00946 }
00947
00948 local int print_massive_binary_recursive(dyn *b,
00949 vector center_pos, vector center_vel,
00950 real mass_limit, real number_limit,
00951 bool verbose) {
00952
00953 int nb = 0;
00954 if (b->get_oldest_daughter() &&
00955 contains_massive_star(b, mass_limit, number_limit)) {
00956
00957 real r_com = abs(b->get_pos() - center_pos);
00958 real v_com = abs(b->get_vel() - center_vel);
00959
00960 real m_tot = b->get_starbase()->conv_m_dyn_to_star(b->get_mass());
00961 cerr << " " << b->format_label()
00962 << " " << m_tot
00963 << " (Multiple) \t " << r_com << " " << v_com << endl;
00964
00965 for_all_daughters(dyn, b, bb)
00966 if (bb->n_leaves() >= 2)
00967 nb += print_massive_binary_recursive(bb,
00968 center_pos, center_vel,
00969 mass_limit, number_limit,
00970 verbose);
00971 else
00972 print_massive_star(bb, center_pos, center_vel, verbose);
00973
00974
00975
00976 }
00977 return nb;
00978 }
00979
00980 local void print_massive_star_header(bool cod) {
00981
00982 cerr << endl;
00983 cerr << " Massive stars:" << endl;
00984 if (cod)
00985 cerr << " Name M(sun) (type) \t r_cod v_cod"
00986 << endl;
00987 else
00988 cerr << " Name M(sun) (type) \t r_com v_com"
00989 << endl;
00990 }
00991
00992 typedef struct
00993 {
00994 real mass;
00995 dyn *b;
00996 } md_pair, *md_pair_ptr;
00997
00998 local int compare_mass(const void * pi, const void * pj)
00999 {
01000 if (((md_pair_ptr) pi)->mass > ((md_pair_ptr) pj)->mass)
01001 return -1;
01002 else if (((md_pair_ptr)pi)->mass < ((md_pair_ptr)pj)->mass)
01003 return +1;
01004 else
01005 return 0;
01006 }
01007
01008
01009 local void print_most_massive_stars(dyn *b,
01010 real mass_limit,
01011 real number_limit,
01012 vector center_pos,
01013 bool verbose) {
01014
01015 bool cod = false;
01016 vector center_vel = 0;
01017
01018 if (abs(center_pos) == 0)
01019 cod = (get_std_center(b, center_pos, center_vel) == 1);
01020
01021
01022
01023
01024 int nl = 0;
01025 for_all_daughters(dyn, b, bi)
01026 if (bi->is_leaf()) nl++;
01027
01028 md_pair_ptr md_list = new md_pair[nl];
01029
01030 nl = 0;
01031 for_all_daughters(dyn, b, bi)
01032 if (bi->is_leaf()) {
01033 md_list[nl].mass = bi->get_starbase()->get_total_mass();
01034 md_list[nl].b = bi;
01035 nl++;
01036 }
01037
01038
01039
01040 qsort((void *)md_list, (size_t)nl, sizeof(md_pair), compare_mass);
01041
01042 int ns = 0;
01043 if (nl < rint(number_limit)) nl = (int)rint(number_limit);
01044
01045 for (ns = 0; ns < nl; ns++)
01046 if (md_list[ns].mass < mass_limit) break;
01047
01048 if (ns > 0) print_massive_star_header(cod);
01049
01050
01051
01052 for (int i = 0; i < ns; i++)
01053 print_massive_star(md_list[i].b, center_pos, center_vel, verbose);
01054
01055 delete [] md_list;
01056
01057
01058
01059 int nb = 0;
01060 for_all_daughters(dyn, b, bi) {
01061 if (!bi->is_leaf())
01062 nb += print_massive_binary_recursive(bi, center_pos, center_vel,
01063 mass_limit, number_limit,
01064 verbose);
01065 }
01066
01067 if (verbose && ns+nb==0)
01068 cerr << " (none)\n";
01069 }
01070
01071
01072
01073 void print_sstar_time_scales(dyn *b) {
01074
01075 real time = b->get_system_time();
01076 cerr << " = " << b->get_starbase()->conv_t_dyn_to_star(time)
01077 << " Myr (Turn_off_mass = "
01078 << turn_off_mass(b->get_starbase()->conv_t_dyn_to_star(time))
01079 << ")" << endl;
01080
01081 b->get_starbase()->print_stellar_evolution_scaling(cerr);
01082 }
01083
01084 void sstar_stats(dyn* b, bool mass_spectrum, vector center,
01085 bool verbose) {
01086
01087 if (b->get_use_sstar()) {
01088
01089 int axis = 0;
01090 if (verbose) cerr << "\n Projected luminosity profile: ";
01091 real r1_r9 = compute_projected_luminosity_radii(b, axis, true, 10);
01092
01093 if (verbose) cerr << "\n Projected King profile:";
01094 print_fitted_king_model(r1_r9, proj_r10_r90_light);
01095
01096 if (mass_spectrum) {
01097
01098 print_luminosity_function(b, 12, verbose);
01099 print_mass_spectrum(b, 12, verbose);
01100 print_most_massive_stars(b, OUTPUT_MASS_LIMIT, OUTPUT_NUMBER_LIMIT,
01101 center, verbose);
01102 }
01103
01104 if (verbose)
01105 cerr << endl
01106 << " M, L and massive stars by Lagrangian zone (all stars):"
01107 << endl;
01108
01109 print_mass_over_light(b);
01110
01111 if (verbose)
01112 cerr << endl
01113 << " stellar ubvr and i Lagrangian zones (all stars):"
01114 << endl;
01115
01116 print_lagrangian_ubvri_radii(b, MAX_PREDEF_RADII, predefined);
01117
01118 if (verbose)
01119 cerr << "\n Stellar content:\n";
01120 print_stellar_content(b);
01121
01122 if (verbose)
01123 cerr << "\n Special star content:\n";
01124 print_special_stars(b);
01125
01126 if (verbose)
01127 cerr << "\n Compact stars:\n";
01128 print_compact_stars(b);
01129
01130 }
01131 else
01132 cerr << "\n No stellar evolution\n";
01133 }
01134
01135 #else
01136
01137 main(int argc, char **argv)
01138 {
01139 bool binaries = true, verbose = true, out = false,
01140 n_sq = true, calc_e = true;
01141 int which_lagr = 0;
01142 real T_start = 0;
01143
01144 extern char *poptarg;
01145 int c;
01146 char* param_string = "bneost";
01147
01148
01149 while ((c = pgetopt(argc, argv, param_string)) != -1)
01150 switch(c) {
01151
01152 case 'b': binaries = !binaries;
01153 break;
01154 case 'e': calc_e = !calc_e;
01155 break;
01156 case 'n': n_sq = !n_sq;
01157 break;
01158 case 'o': out = !out;
01159 break;
01160 case 's': which_lagr = 2;
01161 break;
01162 case 't': which_lagr = 1;
01163 break;
01164 case 'v': verbose = !verbose;
01165 break;
01166 case '?': params_to_usage(cerr, argv[0], param_string);
01167 exit(1);
01168 }
01169
01170
01171
01172 dyn *b;
01173 int i = 0;
01174 vector zero = 0;
01175 bool mass_spectrum = true;
01176 while (b = get_dyn(cin)) {
01177
01178
01179
01180 if(find_qmatch(b->get_oldest_daughter()
01181 ->get_starbase()->get_star_story(), "Type")) {
01182
01183 addstar(b,
01184 b->get_system_time(),
01185 Main_Sequence,
01186 true);
01187 b->set_use_sstar(true);
01188
01189 if (i++ > 0) cerr << endl;
01190 sstar_stats(b, mass_spectrum, zero, verbose);
01191
01192 }
01193
01194 if (out) put_node(cout, *b);
01195 rmtree(b);
01196 }
01197 }
01198
01199 #endif