Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

sstar_stats.C

Go to the documentation of this file.
00001 
00002 //  sstar_stats.C: Print out various diagnostic statistics on a system.
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     // As in lagrad, use the geometric center if 
00067     // density center is unknown.
00068 
00069     if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00070 
00071         // Make a list of previously computed lagrangian radii.
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     // Note that r_lagr omits the 0% and 100% radii.
00086     
00087     // Initialization:
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         // Count single stars and binaries separately.
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         // Find which zone we are in.
00118 
00119         int i = which_zone(bi, lagr_pos, n_lagr, r_lagr);
00120 
00121         // Update statistics.
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 //  else 
00163 //      cerr << "     ---No Lagrangian radii specified--- " << endl;
00164   
00165 }
00166 
00167 local int print_special_stars(dyn* b) {
00168 
00169     if (!b->get_use_sstar())
00170         return -1;
00171 
00172 //    real M_to = turn_off_mass(b->get_starbase()
00173 //                             ->conv_t_dyn_to_star(b->get_system_time()));
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         // Count all single stars 
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                         //f_Bs = sts.mass/M_to;
00204                         //cerr << " [f_Bs = " << f_Bs << "]";
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     //  for_all_daughters(dyn, b, bi) {
00235     if (!b->get_use_sstar())
00236         return;
00237 
00238     int N_compact = 0;
00239 
00240     for_all_leaves(dyn, b, bi) {
00241 
00242         // Count all single stars 
00243 
00244         stellar_type stype = NAS;
00245         star* ss = NULL;
00246 
00247         // if (bi->get_oldest_daughter() != NULL)
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   // Use the geometric center if the density center is unknown.
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 //  else
00354 //    print_core_parameters(b, dc_pos, dc_vel, rcore);
00355 
00356   int i=0;
00357 
00358   // fill table with usefull information.
00359   // note that this part might needs a flattening of the tree.
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 //      Ltot[0] += table[i].Lu;
00388 //      Ltot[1] += table[i].Lb;
00389 //      Ltot[2] += table[i].Lv;
00390 //      Ltot[3] += table[i].Lr;
00391 //      Ltot[4] += table[i].Li;
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 //  for(i=0; i<n; i++) {
00421 //      Ltot[0] += table[i].Lu;
00422 //      Ltot[1] += table[i].Lb;
00423 //      Ltot[2] += table[i].Lv;
00424 //      Ltot[3] += table[i].Lr;
00425 //      Ltot[4] += table[i].Li;
00426 //  }
00427 
00428     // now the array table is sorted in radius.
00429     // we can do all kind of beautiful things with it.
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   // return if unresonable input is given.
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   // real L_percent[5][nzones]; // g++ extension!
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];       // ANSI
00500 
00501     // determine the lagrangian radii.
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     // Use lagr_pos as center; do nothing if unavailable.
00595 
00596     if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00597 
00598         // Make a list of previously computed lagrangian radii.
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         // Note that r_lagr omits the 0% and 100% radii.
00625     
00626         // Initialization:
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             // Count single stars and binaries separately.
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             // Find which zone we are in.
00668 
00669             i = which_zone(bi, lagr_pos, n_lagr, r_lagr);
00670 
00671             // Update statistics.
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);   // Msun
00732     real m_max = b->get_starbase()->conv_m_star_to_dyn(100);   // Msun
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         // nb += print_massive_binary(b, center_pos, center_vel,
00975         //                            mass_limit, number_limit,  verbose);
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)  // decreasing mass
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     // Want to print out stars more massive than mass_limit, but no more
01022     // than number_limit.  New code from Steve (8/01).
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     // Sort the list, in order of decreasing mass.
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     // Stars:
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     // Binaries:
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 // Print stellar timescale and turn-off mass.
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;   // x-axis
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";      // Note: "v" removed because only the
01147                                         // "verbose" option currently works.
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     // Loop over input until no more data remain.
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         // NOTE:  get_xxx() reads NaN in as legal garbage...
01179 
01180       if(find_qmatch(b->get_oldest_daughter()
01181                  ->get_starbase()->get_star_story(), "Type")) {
01182         
01183         addstar(b,                            // Note that T_start and
01184                 b->get_system_time(),          // Main_Sequence are
01185                 Main_Sequence,                 // defaults. They are
01186                 true);                         // ignored if a star
01187         b->set_use_sstar(true);                // is there.
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

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