Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

proj_lagr.C

Go to the documentation of this file.
00001 
00016 
00017 //-----------------------------------------------------------------------------
00018 //   version 1:  Jul 1998   Simon Portegies Zwart
00019 //.............................................................................
00020 //   non-local functions: 
00021 //      compute_gereral_luminosity_radii
00022 //      compute_luminosity_radii_quartiles
00023 //      compute_luminosity_radii_percentiles
00024 //-----------------------------------------------------------------------------
00025 
00026 //#include "dyn.h"
00027 #include "sstar_to_dyn.h"
00028 #include "star.h"
00029 
00030 #ifndef TOOLBOX
00031 
00032 typedef  struct
00033 {
00034     real  radius;
00035     real  mass;
00036 } rm_pair, *rm_pair_ptr;
00037 
00038 //-----------------------------------------------------------------------------
00039 //  compare_radii  --  compare the radii of two particles
00040 //-----------------------------------------------------------------------------
00041 
00042 local int compare_radii(const void * pi, const void * pj)
00043 {
00044     if (((rm_pair_ptr) pi)->radius > ((rm_pair_ptr) pj)->radius)
00045         return(1);
00046     else if (((rm_pair_ptr)pi)->radius < ((rm_pair_ptr)pj)->radius)
00047         return(-1);
00048     else
00049         return(0);
00050 }
00051 
00052 //-----------------------------------------------------------------------------
00053 //  compute_general_luminosity_radii  --  Get the massradii for all particles.
00054 //-----------------------------------------------------------------------------
00055 
00056 static real nonlin_masses[9] = {0.005, 0.01, 0.02, 0.05, 0.1,
00057                                 0.25, 0.5, 0.75, 0.9};
00058 
00059 real compute_projected_luminosity_radii(dyn * b, int axis, bool Llagr,
00060                                         int nzones,
00061                                         bool nonlin,
00062                                         boolfn bf) {
00063 
00064   real r1_r9 = 0;
00065     if (nzones < 2) return nzones;
00066     if (nonlin && nzones != 10) return nzones;          // Special case
00067 
00068     // Note: nzones specifies the number of radial zones to consider.
00069     //       However, we only store radii corresponding to the nzones-1 
00070     //       interior zone boundaries.
00071 
00072     real* mass_percent = new real[nzones-1];
00073     if (mass_percent == NULL) {
00074         cerr << "compute_general_luminosity_radii: "
00075              << "not enough memory left for mass_percent\n";
00076         return r1_r9;
00077     }
00078 
00079     int n = 0;
00080     if (bf == NULL)
00081         n = b->n_leaves();
00082     else {
00083         for_all_leaves(dyn, b, bb)
00084             if ((*bf)(bb)) n++;
00085     }
00086 
00087     rm_pair_ptr rm_table = new rm_pair[n];
00088 
00089     if (rm_table == NULL) {
00090         cerr << "compute_general_luminosity_radii: "
00091              << "not enough memory left for rm_table\n";
00092         return r1_r9;
00093     }
00094 
00095     // Use the density center if known and up to date.
00096     // Otherwise, use center of mass if known and up to date.
00097     // Otherwise, use the geometric center.
00098 
00099     vector dc_pos = 0;
00100     bool try_com = false;
00101 
00102     if (find_qmatch(b->get_dyn_story(), "density_center_pos")) {
00103 
00104         if (getrq(b->get_dyn_story(), "density_center_time")
00105                 != b->get_system_time()) {
00106             warning("lagrad: neglecting out-of-date density center");
00107             try_com = true;
00108         } else
00109             dc_pos = getvq(b->get_dyn_story(), "density_center_pos");
00110 
00111     }
00112 
00113     if (try_com && find_qmatch(b->get_dyn_story(), "com_pos")) {
00114 
00115         if (getrq(b->get_dyn_story(), "com_time")
00116                 != b->get_system_time()) {
00117             warning("lagrad: neglecting out-of-date center of mass");
00118         } else
00119             dc_pos = getvq(b->get_dyn_story(), "com_pos");
00120 
00121     }
00122     if(axis>=0)
00123       dc_pos[axis] = 0;
00124 
00125     // Set up an array of (radius, mass) pairs.  Also find the total
00126     // mass of all nodes under consideration.
00127 
00128     real total_mass = 0;
00129 
00130     int i = 0;
00131     real lstar = 0;
00132     vector pos = 0;
00133     for_all_leaves(dyn, b, bi) {
00134         if (bf == NULL || (*bf)(bi)) {
00135           if(Llagr) {
00136             if (find_qmatch(bi->get_starbase()->get_star_story(), "L_eff")) {
00137               lstar = getrq(bi->get_starbase()->get_star_story(), "L_eff");
00138             }
00139             else if (b->get_use_sstar()){
00140               lstar = ((star*)bi->get_starbase())->get_luminosity();
00141             }
00142           }
00143           else
00144             lstar = bi->get_mass(); 
00145 
00146             total_mass += lstar;
00147             pos = bi->get_pos();
00148             if(axis>=0)
00149               pos[axis] = 0;
00150             rm_table[i].radius = abs(pos - dc_pos);
00151             rm_table[i].mass = lstar;
00152             i++;
00153         }
00154     }
00155 
00156     // Sort the array by radius.
00157 
00158     qsort((void *)rm_table, (size_t)n, sizeof(rm_pair), compare_radii);
00159 
00160     // Determine Lagrangian radii.
00161 
00162     // cerr << "Determining Lagrangian radii 1" << endl << flush;
00163 
00164     int k;
00165     for (k = 0; k < nzones-1; k++) {
00166         if (!nonlin) 
00167             mass_percent[k] = ((k + 1) / (real)nzones) * total_mass;
00168         else
00169             mass_percent[k] = nonlin_masses[k] * total_mass;
00170     }
00171 
00172     real *rlagr = new real[nzones-1];
00173     real cumulative_mass = 0.0;
00174     i = 0;
00175 
00176     switch(axis) {
00177     case 0:
00178       cerr <<"     (projected along x-axis)\n";
00179       break;
00180     case 1:
00181       cerr <<"     (projected along y-axis)\n";
00182       break;
00183     case 2:
00184       cerr <<"     (projected along x-axis)\n";
00185       break;
00186     default:
00187       cerr <<"     (unprojected)\n";
00188     }
00189     
00190     cerr << "    r_lagr =";
00191 
00192     for (k = 0; k < nzones-1; k++) {
00193 
00194         while (cumulative_mass < mass_percent[k])
00195             cumulative_mass += rm_table[i++].mass;
00196 
00197         rlagr[k] = rm_table[i-1].radius;
00198         
00199         cerr << "  " << rlagr[k];
00200     }
00201     cerr << endl;
00202 
00203     
00204     if (nzones==10 && rlagr[8]>0)
00205       r1_r9 = rlagr[0]/rlagr[8];
00206 
00207     delete [] mass_percent;
00208     delete [] rm_table;
00209     delete [] rlagr;
00210 
00211     return r1_r9;
00212 }
00213 
00214 #else
00215 
00216 //-----------------------------------------------------------------------------
00217 //  main  --  driver to use  compute_luminosity_radii() as a tool
00218 //-----------------------------------------------------------------------------
00219 
00220 main(int argc, char ** argv)
00221 {
00222     char  *comment;
00223     int n = 0;
00224     int axis = -1;
00225     bool  c_flag = false;      // if TRUE: a comment given on command line
00226     bool  t_flag = false;      // if TRUE: percentiles rather than quartiles
00227     bool  nonlin = false;
00228     bool  Llagr  = true;
00229 
00230     check_help();
00231 
00232     void compute_luminosity_radii(dyn *, int, bool, bool);
00233 
00234   extern char *poptarg;
00235     int c;
00236     char* param_string = "a:c:mn:xyzst";
00237 
00238     while ((c = pgetopt(argc, argv, param_string)) != -1)
00239         switch(c)
00240             {
00241             case 'a': axis = atoi(poptarg);
00242                       break;
00243             case 'c': c_flag = true;
00244                       comment = poptarg;
00245                       break;
00246             case 'x': axis = 0;
00247                       break;
00248             case 'y': axis = 1;
00249                       break;
00250             case 'z': axis = 2;
00251                       break;
00252             case 'n': n = atoi(poptarg);
00253                       break;
00254             case 'm': Llagr = false;
00255                       break;
00256             case 's': n = 10;
00257               nonlin = true;  // fall through
00258             case 't': t_flag = true;
00259                       break;
00260             case '?': params_to_usage(cerr, argv[0], param_string);
00261                       get_help();
00262                       exit(1);
00263             }            
00264 
00265     dyn *b;
00266 
00267     while (b = get_dyn(cin)) {
00268 
00269       //        addstar(b);
00270         
00271         if (c_flag == TRUE)
00272             b->log_comment(comment);
00273 
00274         b->log_history(argc, argv);
00275 
00276         if (Llagr) 
00277           cerr << "Lagrangian mass radii"<<endl;
00278         else
00279           cerr << "Lagrangian luminosity radii"<<endl;
00280         
00281         if (axis>=0) {
00282           cerr << "\nprojected along the ";
00283           switch(axis) {
00284             case 0: cerr << "x";
00285                     break;
00286             case 1: cerr << "y";
00287                     break;
00288             case 2: cerr << "z";
00289                     break;
00290           }
00291           cerr << "-axis\n";
00292         }
00293 
00294         real r1_r9 = 0;
00295         if (t_flag)
00296           real r1_r9 = compute_projected_luminosity_radii(b, axis, Llagr, 10);
00297         else {
00298           if (n <= 1)
00299             compute_projected_luminosity_radii(b, axis, Llagr, 4);
00300           else
00301             compute_projected_luminosity_radii(b, axis, Llagr, n, nonlin);
00302         }
00303 
00304         // Print out radii in case of quartiles only.
00305 
00306         if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00307 
00308             int n_lagr = getiq(b->get_dyn_story(), "n_lagr");
00309             real *r_lagr = new real[n_lagr];
00310             getra(b->get_dyn_story(), "r_lagr", r_lagr, n_lagr);
00311             cerr << "r_lagr =";
00312             for (int i = 0; i < n_lagr; i++) cerr << " " << r_lagr[i];
00313             cerr << endl;
00314 
00315         }
00316 
00317         //put_dyn(cout, *b);    
00318         delete b;
00319     }
00320 }
00321 
00322 #endif
00323 

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