00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dyn.h"
00026
00027 #ifndef TOOLBOX
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 void compute_density(dyn * b,
00046 int k,
00047 dyn ** list,
00048 int n_list)
00049
00050
00051
00052 {
00053 int q, r;
00054 real *neighbor_dist_sq;
00055 real *neighbor_mass;
00056 real delr_sq;
00057
00058 if (k <= 1) {
00059 cerr << "compute_density: k = " << k << " <= 1" << endl;
00060 return;
00061 }
00062
00063 if (list == NULL)
00064 n_list = 0;
00065 else if (n_list <= 0) {
00066 cerr << "compute_density: n_list = " << n_list << endl;
00067 return;
00068 }
00069
00070 int nsys = b->n_leaves() - 1;
00071 if (n_list > 0)
00072 nsys = n_list;
00073
00074 if (k > nsys) {
00075 cerr << "compute_density: k = " << k << " >= nsys = " << nsys << endl;
00076 return;
00077 }
00078
00079 neighbor_dist_sq = new real[k+1];
00080 neighbor_mass = new real[k+1];
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 dyn* d;
00094
00095 if (list)
00096 d = b;
00097 else
00098 d = b->get_oldest_daughter();
00099
00100 while (d) {
00101
00102 neighbor_dist_sq[0] = 0.0;
00103 neighbor_mass[0] = d->get_mass();
00104 for (q = 1; q <= k; q++) {
00105 neighbor_dist_sq[q] = VERY_LARGE_NUMBER;
00106 neighbor_mass[q] = 0;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 dyn* dd;
00117
00118 if (list)
00119 dd = list[n_list-1];
00120 else
00121 dd = b->get_oldest_daughter();
00122
00123 while (dd) {
00124
00125 if (d != dd) {
00126
00127 delr_sq = square(something_relative_to_root(d, &dyn::get_pos)
00128 - something_relative_to_root(dd, &dyn::get_pos));
00129
00130 if (delr_sq < neighbor_dist_sq[k]) {
00131
00132
00133
00134 for (q = k-1; q >= 0; q--) {
00135 if (delr_sq > neighbor_dist_sq[q]) {
00136 for (r = k; r > q+1; r--) {
00137 neighbor_dist_sq[r] = neighbor_dist_sq[r-1];
00138 neighbor_mass[r] = neighbor_mass[r-1];
00139 }
00140 neighbor_dist_sq[q+1] = delr_sq;
00141 neighbor_mass[q+1] = dd->get_mass();
00142
00143 break;
00144 }
00145 }
00146 }
00147 }
00148
00149
00150
00151 if (list) {
00152 if (--n_list < 0)
00153 dd = NULL;
00154 else
00155 dd = list[n_list];
00156 } else
00157 dd = dd->get_younger_sister();
00158 }
00159
00160 real density = 0;
00161
00162 if (neighbor_dist_sq[k] > 0) {
00163 while (k > 0 && neighbor_dist_sq[k] >= VERY_LARGE_NUMBER)
00164 k--;
00165 if (k > 1 && neighbor_dist_sq[k] > 0
00166 && neighbor_dist_sq[k] < VERY_LARGE_NUMBER) {
00167 real volume = (4.0/3.0) * PI * pow(neighbor_dist_sq[k], 1.5);
00168 if (volume > 0) {
00169
00170
00171 real mass = 0;
00172 for(int m=1; m<k; m++)
00173 mass += neighbor_mass[k];
00174 density = mass/volume;
00175 }
00176 }
00177 }
00178
00179
00180
00181 putrq(d->get_dyn_story(), "density_time", b->get_system_time());
00182 putiq(d->get_dyn_story(), "density_k_level", k);
00183 putrq(d->get_dyn_story(), "density", density);
00184
00185
00186
00187 if (list)
00188 d = NULL;
00189 else
00190 d = d->get_younger_sister();
00191 }
00192
00193
00194
00195 if (!list) {
00196 dyn* root = b->get_root();
00197 putrq(root->get_dyn_story(), "density_time", root->get_system_time());
00198 }
00199
00200
00201
00202 delete neighbor_dist_sq;
00203 delete neighbor_mass;
00204 }
00205
00206 #else
00207
00208 main(int argc, char ** argv)
00209 {
00210 int k = 12;
00211
00212 char *comment;
00213 bool c_flag = false;
00214 bool verbose = false;
00215
00216 check_help();
00217
00218 extern char *poptarg;
00219 int c;
00220 char* param_string = "c:k:v";
00221
00222 while ((c = pgetopt(argc, argv, param_string)) != -1)
00223 switch(c) {
00224 case 'c': c_flag = true;
00225 comment = poptarg;
00226 break;
00227 case 'k': k = atoi(poptarg);
00228 break;
00229 case 'v': verbose = !verbose;
00230 break;
00231 case '?': params_to_usage(cerr, argv[0], param_string);
00232 get_help();
00233 exit(1);
00234 }
00235
00236
00237
00238 dyn *b;
00239 int i = 0;
00240 while (b = get_dyn(cin)) {
00241
00242 if (verbose) cerr << "snap #" << ++i
00243 << ", time = " << b->get_system_time() << endl;
00244
00245 if (c_flag) b->log_comment(comment);
00246 b->log_history(argc, argv);
00247
00248 compute_density(b, k);
00249
00250 put_dyn(cout, *b);
00251 rmtree(b);
00252 }
00253 }
00254
00255 #endif
00256
00257