00001
00002
00003
00004
00005
00006
00007 #include "sigma3.h"
00008
00009 #define DEBUG 0
00010
00011 #define MIN_OSC 5 // Defines a "strong" resonance
00012
00013
00014
00015 #define NBIN 5 // defined bins: 0: direct exchange
00016
00017
00018
00019
00020
00021 #define NR N_RHO_ZONE_MAX // for brevity (N_RHO_ZONE_MAX defined in sigma3.h)
00022
00023
00024
00025 static int n_total[NBIN][NR];
00026 static real da_total[NBIN][NR];
00027
00028
00029
00030 #define NMAX 25000 // should be adequate...
00031
00032 static int nscat[NBIN][NR];
00033 static real dascat[NBIN][NR][NMAX];
00034
00035 local void initialize_stats()
00036 {
00037 for (int ibin = 0; ibin < NBIN; ibin++)
00038 for (int kr = 0; kr < NR; kr++) {
00039 n_total[ibin][kr] = 0;
00040 da_total[ibin][kr] = 0;
00041 nscat[ibin][kr] = 0;
00042 }
00043 }
00044
00045
00046
00047
00048
00049
00050
00051 local void accumulate_stats(scatter_profile& prof,
00052 initial_state3& init,
00053 intermediate_state3& inter,
00054 final_state3& final,
00055 int rho_zone,
00056 sigma_out& out)
00057 {
00058 if (inter.n_stars == 3 &&
00059 (inter.descriptor == hierarchical_resonance
00060 || inter.descriptor == democratic_resonance
00061 || final.descriptor == exchange_1
00062 || final.descriptor == exchange_2)) {
00063
00064 real da = final.sma/init.sma - 1;
00065
00066 if (DEBUG) {
00067 int p = cerr.precision(STD_PRECISION);
00068 cerr << "accumulate_stats: " << state_string(inter.descriptor)
00069 << " " << state_string(final.descriptor)
00070 << ", n_osc = " << inter.n_osc << endl;
00071 cerr << " rho_zone = " << rho_zone;
00072 cerr << " escaper = " << final.escaper;
00073 cerr << " mass = " << final.system[final.escaper-1].mass;
00074 cerr << " da/a = " << da << endl;
00075 cerr.precision(p);
00076 }
00077
00078 int ibin = 0;
00079 if (inter.descriptor == hierarchical_resonance)
00080 ibin = 1;
00081 else if (inter.descriptor == democratic_resonance) {
00082 if (inter.n_osc >= MIN_OSC)
00083 ibin = 2;
00084 else {
00085 if (final.descriptor == preservation)
00086 ibin = 3;
00087 else
00088 ibin = 4;
00089 }
00090 }
00091
00092
00093
00094 n_total[ibin][rho_zone]++;
00095 da_total[ibin][rho_zone] += da;
00096 dascat[ibin][rho_zone][nscat[ibin][rho_zone]++] = da;
00097 }
00098 }
00099
00100 local int realcomp(const void * a, const void * b)
00101 {
00102 if (*((real *) a) > *((real *) b))
00103 return 1;
00104 else if (*((real *) a) < *((real *) b))
00105 return -1;
00106 else
00107 return 0;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 local void print_stats(scatter_profile& prof, sigma_out& out)
00117 {
00118 char* s[NBIN] = {"non-resonant exchange ",
00119 "hierarchical resonance ",
00120 "strong democratic resonance ",
00121 "weak democratic preservation",
00122 "weak democratic exchange "};
00123
00124 for (int ibin = 0; ibin < NBIN; ibin++) {
00125
00126 real sigma = 0;
00127 real da = 0;
00128 int nt = 0;
00129
00130 cerr << endl << s[ibin] << endl;
00131
00132 real w_min = VERY_LARGE_NUMBER, w_max = 0;
00133
00134 for (int kr = 0; kr < out.i_max; kr++) {
00135
00136 real w = zone_weight(out, kr);
00137
00138 w_min = min(w_min, w);
00139 w_max = max(w_max, w);
00140
00141
00142
00143 sigma += w * n_total[ibin][kr];
00144 da += w * da_total[ibin][kr];
00145
00146 nt +=nscat[ibin][kr] ;
00147
00148 cerr << " radial zone " << kr << " (weight = " << w
00149 << "): n_total = " << n_total[ibin][kr]
00150 << ", <da/a> = " << da_total[ibin][kr]
00151 / max(1, n_total[ibin][kr])
00152 << endl;
00153
00154 if (nscat[ibin][kr] > 3) {
00155
00156 cerr << " da/a quartiles:";
00157
00158 qsort((void*)&dascat[ibin][kr][0], (size_t)nscat[ibin][kr],
00159 sizeof(real), realcomp);
00160 real factor = 0.25*nscat[ibin][kr];
00161 for (int i = 1; i <= 3; i++)
00162 cerr << " " << dascat[ibin][kr][(int)(factor*i)];
00163
00164 cerr << endl;
00165
00166 if (DEBUG)
00167 for (int i = 0; i < nscat[ibin][kr]; i++)
00168 cerr << " " << dascat[ibin][kr][i] << endl;
00169
00170 }
00171 }
00172
00173 if (sigma > 0) da /= sigma;
00174
00175 cerr << "<da/a> for " << s[ibin] << " = " << da
00176 << ", v^2 sigma = " << prof.v_inf * prof.v_inf * sigma << endl;
00177
00178 if (nt > 3) {
00179
00180
00181
00182 cerr << "da/a quartiles:";
00183
00184 real* tempda = new real[out.i_max*nt*(int)(w_max/w_min + 0.1)];
00185 nt = 0;
00186
00187
00188
00189 for (int kr = 0; kr <= out.i_max; kr++)
00190 for (int i = 0; i < nscat[ibin][kr]; i++)
00191 for (int ww = 0;
00192 ww < (int)(zone_weight(out, kr)/w_min + 0.1); ww++)
00193 tempda[nt++] = dascat[ibin][kr][i];
00194
00195 qsort((void*)tempda, (size_t)nt, sizeof(real), realcomp);
00196 real factor = 0.25*nt;
00197 for (int i = 1; i <= 3; i++)
00198 cerr << " " << tempda[(int)(factor*i)];
00199
00200 cerr << endl;
00201
00202 if (DEBUG)
00203 for (int i = 0; i < nt; i++)
00204 cerr << " " << tempda[i] << endl;
00205
00206 }
00207 }
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 main(int argc, char **argv)
00219 {
00220 int debug = 0;
00221 int seed = 0;
00222 int n_rand = 0;
00223 real max_trial_density = 1.0;
00224
00225 real cpu_time_check = 3600;
00226 real dt_snap = VERY_LARGE_NUMBER;
00227 real snap_cube_size = 10;
00228 int scatter_summary_level = 0;
00229
00230 bool print_counts = FALSE;
00231
00232
00233
00234 bool pvm = false;
00235 if (strstr(argv[0], ".pvm")) {
00236
00237 #ifndef HAS_PVM // Compile-time check.
00238 err_exit("PVM not available");
00239 #endif
00240 if (getenv("PVM_ROOT") == NULL)
00241 err_exit("PVM not available");
00242
00243 pvm = true;
00244 }
00245
00246 scatter_profile prof;
00247 make_standard_profile(prof);
00248
00249 extern char *poptarg;
00250 int c;
00251 char* param_string = "A:c:C:D:d:e:m:M:N:pqQs:V:v:x:y:z:";
00252
00253 while ((c = pgetopt(argc, argv, param_string)) != -1)
00254 switch(c) {
00255
00256 case 'A': prof.eta = atof(poptarg);
00257 break;
00258 case 'c': cpu_time_check = 3600*atof(poptarg);
00259 break;
00260 case 'C': if (!pvm)
00261 snap_cube_size = atof(poptarg);
00262 else
00263 cerr << "\"-C\" option disallowed in PVM mode\n";
00264 break;
00265 case 'd': max_trial_density = atof(poptarg);
00266 break;
00267 case 'D': if (!pvm) {
00268 dt_snap = atof(poptarg);
00269 scatter_summary_level = 2;
00270 } else
00271 cerr << "\"-D\" option disallowed in PVM mode\n";
00272 break;
00273 case 'e': prof.ecc = atof(poptarg);
00274 prof.ecc_flag = 1;
00275 break;
00276 case 'm': prof.m2 = atof(poptarg);
00277 break;
00278 case 'M': prof.m3 = atof(poptarg);
00279 break;
00280 case 'N': n_rand = atoi(poptarg);
00281 break;
00282 case 'p': print_counts = 1 - print_counts;
00283 break;
00284 case 'q': if (scatter_summary_level > 0)
00285 scatter_summary_level = 0;
00286 else
00287 scatter_summary_level = 1;
00288 break;
00289 case 'Q': if (scatter_summary_level > 0)
00290 scatter_summary_level = 0;
00291 else
00292 scatter_summary_level = 2;
00293 break;
00294 case 's': seed = atoi(poptarg);
00295 break;
00296 case 'v': prof.v_inf = atof(poptarg);
00297 break;
00298 case 'V': debug = atoi(poptarg);
00299 break;
00300 case 'x': prof.r1 = atof(poptarg);
00301 break;
00302 case 'y': prof.r2 = atof(poptarg);
00303 break;
00304 case 'z': prof.r3 = atof(poptarg);
00305 break;
00306 case '?': params_to_usage(cerr, argv[0], param_string);
00307 exit(1);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317 cpu_init();
00318
00319 sigma_out out;
00320 int first_seed = srandinter(seed, n_rand);
00321
00322 cerr << "random seed = " << first_seed << endl;
00323 print_profile(cerr, prof);
00324
00325 initialize_stats();
00326
00327
00328
00329
00330 get_sigma3(max_trial_density, prof, out,
00331 debug, cpu_time_check,
00332 dt_snap, snap_cube_size,
00333 scatter_summary_level,
00334 accumulate_stats);
00335
00336
00337
00338
00339
00340
00341
00342 print_sigma3(out, prof.v_inf * prof.v_inf);
00343 if (print_counts) print_all_sigma3_counts(out, cerr);
00344
00345
00346
00347 for (int i = 0; i < 72; i++) cerr << "-";
00348 cerr << endl;
00349
00350 print_stats(prof, out);
00351 }