00001
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "dyn.h"
00030
00031 #ifndef TOOLBOX
00032
00033 typedef struct
00034 {
00035 real radius;
00036 real mass;
00037 } rm_pair, *rm_pair_ptr;
00038
00039
00040
00041
00042
00043 local int compare_radii(const void * pi, const void * pj)
00044 {
00045 if (((rm_pair_ptr) pi)->radius > ((rm_pair_ptr) pj)->radius)
00046 return +1;
00047 else if (((rm_pair_ptr)pi)->radius < ((rm_pair_ptr)pj)->radius)
00048 return -1;
00049 else
00050 return 0;
00051 }
00052
00053
00054
00055
00056
00057 static real nonlin_masses[9] = {0.005, 0.01, 0.02, 0.05, 0.1,
00058 0.25, 0.5, 0.75, 0.9};
00059
00060 void compute_general_mass_radii(dyn * b, int nzones,
00061 bool nonlin,
00062 boolfn bf)
00063 {
00064 if (nzones < 2) return;
00065 if (nonlin && nzones != 10) return;
00066
00067
00068
00069
00070
00071 char lagr_string[64] = "geometric center";
00072
00073 int n = 0;
00074 if (bf == NULL)
00075 n = b->n_daughters();
00076 else {
00077 for_all_daughters(dyn, b, bb)
00078 if ((*bf)(bb)) n++;
00079 }
00080
00081
00082
00083
00084 vector lagr_pos, lagr_vel;
00085 int which = get_std_center(b, lagr_pos, lagr_vel);
00086 if (which == 1)
00087 strcpy(lagr_string, "density center");
00088 else
00089 strcpy(lagr_string, "modified center of mass");
00090
00091 rm_pair_ptr rm_table = new rm_pair[n];
00092
00093 if (rm_table == NULL) {
00094 cerr << "compute_general_mass_radii: "
00095 << "not enough memory left for rm_table\n";
00096 return;
00097 }
00098
00099
00100
00101
00102 real total_mass = 0;
00103 int i = 0;
00104
00105 for_all_daughters(dyn, b, bi) {
00106 if (bf == NULL || (*bf)(bi)) {
00107 total_mass += bi->get_mass();
00108 rm_table[i].radius = abs(bi->get_pos() - lagr_pos);
00109 rm_table[i].mass = bi->get_mass();
00110 i++;
00111 }
00112 }
00113
00114
00115
00116
00117 qsort((void *)rm_table, (size_t)i, sizeof(rm_pair), compare_radii);
00118
00119
00120
00121
00122
00123 real* mass_percent = new real[nzones-1];
00124 if (mass_percent == NULL) {
00125 cerr << "compute_general_mass_radii: "
00126 << "not enough memory left for mass_percent\n";
00127 return;
00128 }
00129
00130 int k;
00131 for (k = 0; k < nzones-1; k++) {
00132 if (!nonlin)
00133 mass_percent[k] = ((k + 1) / (real)nzones) * total_mass;
00134 else
00135 mass_percent[k] = nonlin_masses[k] * total_mass;
00136 }
00137
00138 real *rlagr = new real[nzones-1];
00139 real cumulative_mass = 0.0;
00140 i = 0;
00141
00142
00143
00144 for (k = 0; k < nzones-1; k++) {
00145
00146 while (cumulative_mass < mass_percent[k])
00147 cumulative_mass += rm_table[i++].mass;
00148
00149 rlagr[k] = rm_table[i-1].radius;
00150 }
00151
00152
00153
00154
00155
00156 if (bf == NULL)
00157 putiq(b->get_dyn_story(), "boolfn", 0);
00158 else
00159 putiq(b->get_dyn_story(), "boolfn", 1);
00160
00161 putiq(b->get_dyn_story(), "n_nodes", n);
00162 putrq(b->get_dyn_story(), "lagr_time", b->get_system_time());
00163 putvq(b->get_dyn_story(), "lagr_pos", lagr_pos);
00164 putvq(b->get_dyn_story(), "lagr_vel", lagr_vel);
00165 putsq(b->get_dyn_story(), "pos_type", lagr_string);
00166 putiq(b->get_dyn_story(), "n_lagr", nzones-1);
00167 putra(b->get_dyn_story(), "r_lagr", rlagr, nzones-1);
00168
00169 delete [] mass_percent;
00170 delete [] rm_table;
00171 delete [] rlagr;
00172 }
00173
00174
00175
00176 void compute_mass_radii_quartiles(dyn * b)
00177 {
00178 compute_general_mass_radii(b, 4);
00179 }
00180
00181 void compute_mass_radii_percentiles(dyn * b)
00182 {
00183 compute_general_mass_radii(b, 10);
00184 }
00185
00186 #else
00187
00188
00189
00190
00191
00192 main(int argc, char ** argv)
00193 {
00194 char *comment;
00195 int n = 0;
00196 bool c_flag = false;
00197 bool t_flag = false;
00198 bool nonlin = false;
00199
00200 check_help();
00201
00202 extern char *poptarg;
00203 int c;
00204 char* param_string = "c:n:st";
00205
00206 while ((c = pgetopt(argc, argv, param_string)) != -1)
00207 switch(c)
00208 {
00209 case 'c': c_flag = true;
00210 comment = poptarg;
00211 break;
00212 case 'n': n = atoi(poptarg);
00213 break;
00214 case 's': n = 10;
00215 nonlin = true;
00216 case 't': t_flag = true;
00217 break;
00218 case '?': params_to_usage(cerr, argv[0], param_string);
00219 get_help();
00220 exit(1);
00221 }
00222
00223 dyn *b;
00224
00225 while (b = get_dyn(cin)) {
00226
00227 if (c_flag == TRUE)
00228 b->log_comment(comment);
00229
00230 b->log_history(argc, argv);
00231
00232 if (t_flag)
00233 compute_mass_radii_percentiles(b);
00234 else {
00235 if (n <= 1)
00236 compute_mass_radii_quartiles(b);
00237 else
00238 compute_general_mass_radii(b, n, nonlin);
00239 }
00240
00241
00242
00243 if (find_qmatch(b->get_dyn_story(), "n_lagr")) {
00244
00245 int n_lagr = getiq(b->get_dyn_story(), "n_lagr");
00246 real *r_lagr = new real[n_lagr];
00247 getra(b->get_dyn_story(), "r_lagr", r_lagr, n_lagr);
00248 cerr << "r_lagr =";
00249 for (int i = 0; i < n_lagr; i++) cerr << " " << r_lagr[i];
00250 cerr << endl;
00251
00252 }
00253
00254 put_dyn(cout, *b);
00255 delete b;
00256 }
00257 }
00258
00259 #endif
00260
00261