00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifdef TOOLBOX
00010 #include "sigma3.h"
00011
00012 #define USAGE "usage: rate_stats \
00013 [-A #] [-d #] [-e #] [-m #] [-M #] [-n #] [-r[123] # ] [-s #] [-v #] \n"
00014
00015
00016
00017
00018
00019 #define NA 10
00020 #define NE 10
00021 #define N1 50
00022
00023 static int n_hit = 0;
00024 static int counter[NA][NE][N_RHO_ZONE_MAX];
00025 static int ecounter[N1][N_RHO_ZONE_MAX];
00026 static int vcounter[N1][N_RHO_ZONE_MAX];
00027
00028 static real sigma[NA][NE];
00029 static real sigma_err_sq[NA][NE];
00030 static real esigma[N1];
00031 static real vsigma[N1];
00032 static real v_scale = 1;
00033
00034 local void initialize_local_stats()
00035 {
00036 for (int ia = 0; ia < NA; ia++)
00037 for (int je = 0; je < NE; je++)
00038 sigma[ia][je] = sigma_err_sq[ia][je] = 0;
00039
00040 for (int i1 = 0; i1 < N1; i1++)
00041 esigma[i1] = vsigma[i1] = 0;
00042 }
00043
00044 local void initialize_local_counters()
00045 {
00046 int kr;
00047
00048 for (int ia = 0; ia < NA; ia++)
00049 for (int je = 0; je < NE; je++)
00050 for (kr = 0; kr < N_RHO_ZONE_MAX; kr++)
00051 counter[ia][je][kr] = 0;
00052
00053 for (int i1 = 0; i1 < N1; i1++)
00054 for (kr = 0; kr < N_RHO_ZONE_MAX; kr++)
00055 ecounter[i1][kr] = vcounter[i1][kr] = 0;
00056 }
00057
00058 local real v_recoil(initial_state3& init, final_state3& final)
00059 {
00060
00061
00062 real m_total = 1 + init.m3;
00063 real m2i = init.m2;
00064 real m1i = 1 - m2i;
00065 real m3i = init.m3;
00066
00067
00068
00069 int i1f = 0, i2f = 1;
00070 if (final.system[0].index == final.escaper) {
00071 i1f = 2;
00072 } else if (final.system[1].index == final.escaper) {
00073 i2f = 2;
00074 }
00075
00076 real m1f = final.system[i1f].mass;
00077 real m2f = final.system[i2f].mass;
00078 real m3f = m_total - m1f - m2f;
00079
00080 real de = m1f*m2f/final.sma - m1i*m2i/init.sma;
00081 real vinff = sqrt(max( (2*m_total*de + (m1i+m2i)*m3i*init.v_inf*init.v_inf)
00082 / ((m1f+m2f)*m3f), 0.0));
00083
00084 return m3f*vinff/m_total;
00085 }
00086
00087
00088
00089
00090 local void accumulate_local_stats(scatter_profile& prof,
00091 initial_state3& init,
00092 intermediate_state3& inter,
00093 final_state3& final,
00094 int rho_bin,
00095 sigma_out& out)
00096 {
00097 if (final.descriptor == exchange_1 || final.descriptor == exchange_2) {
00098
00099 if (prof.r3 > 0) {
00100
00101 real ratio = final.sma / prof.r3;
00102
00103 int ia = (int) (log(ratio) / log(2.0));
00104 if (ia >= NA) ia = NA - 1;
00105
00106 int je = (int) (NE * final.ecc);
00107 if (je >= NE) je = NE - 1;
00108
00109 counter[ia][je][rho_bin]++;
00110 n_hit++;
00111
00112
00113
00114 int i1 = (int) (N1 * final.ecc);
00115 if (i1 >= N1) i1 = N1 - 1;
00116 ecounter[i1][rho_bin]++;
00117
00118
00119
00120 i1 = (int) (N1 * v_recoil(init, final) / v_scale);
00121 if (i1 >= N1) i1 = N1 - 1;
00122 vcounter[i1][rho_bin]++;
00123 }
00124 }
00125 }
00126
00127 local void integrate_local_stats(sigma_out& out, real weight)
00128 {
00129 for (int ia = 0; ia < NA; ia++)
00130 for (int je = 0; je < NE; je++) {
00131
00132
00133
00134 real dsigma = 0;
00135 real dsigma_err_sq = 0;
00136
00137
00138
00139 real rho_sq_min, rho_sq_max;
00140 int kr;
00141 for (kr = 0, rho_sq_min = 0, rho_sq_max = out.rho_sq_init;
00142 kr <= out.i_max;
00143 kr++, rho_sq_min = rho_sq_max, rho_sq_max *= RHO_SQ_FACTOR) {
00144
00145 real factor = (rho_sq_max - rho_sq_min) / out.trials_per_zone;
00146 dsigma += factor * counter[ia][je][kr];
00147 dsigma_err_sq += factor * factor * counter[ia][je][kr];
00148 }
00149
00150
00151
00152
00153 sigma[ia][je] += dsigma * weight;
00154 sigma_err_sq[ia][je] += dsigma_err_sq * weight * weight;
00155 }
00156
00157 for (int i1 = 0; i1 < N1; i1++) {
00158
00159
00160
00161 real desigma = 0;
00162 real dvsigma = 0;
00163
00164 real rho_sq_min, rho_sq_max;
00165 int kr;
00166 for (kr = 0, rho_sq_min = 0, rho_sq_max = out.rho_sq_init;
00167 kr <= out.i_max;
00168 kr++, rho_sq_min = rho_sq_max, rho_sq_max *= RHO_SQ_FACTOR) {
00169
00170 real factor = (rho_sq_max - rho_sq_min) / out.trials_per_zone;
00171 desigma += factor * ecounter[i1][kr];
00172 dvsigma += factor * vcounter[i1][kr];
00173 }
00174
00175
00176
00177 esigma[i1] += desigma * weight;
00178 vsigma[i1] += dvsigma * weight;
00179 }
00180 }
00181
00182 local void print_local_stats()
00183 {
00184 int ia, je, i1;
00185
00186 cerr << "\nDifferential cross sections:\n";
00187
00188 cerr << "\n<v sigma> / (pi a^2 v_rel_th)\n\n";
00189 for (ia = 0; ia < NA; ia++) {
00190 for (je = 0; je < NE; je++)
00191 fprintf(stderr, " %7.3f", sigma[ia][je]);
00192 cerr << endl;
00193 }
00194
00195 cerr << "\n(<v sigma> error) / (pi a^2 v_rel_th)\n\n";
00196 for (ia = 0; ia < NA; ia++) {
00197 for (je = 0; je < NE; je++)
00198 fprintf(stderr, " %7.3f", sqrt(sigma_err_sq[ia][je]));
00199 cerr << endl;
00200 }
00201
00202 cerr << "\n<v sigmae> / (pi a^2 v_rel_th)\n\n";
00203 for (i1 = 0; i1 < N1; i1++) fprintf(stderr, " %7.3f", esigma[i1]);
00204 cerr << endl;
00205
00206 cerr << "\n<v sigmav> / (pi a^2 v_rel_th)\n\n";
00207 for (i1 = 0; i1 < N1; i1++) fprintf(stderr, " %7.3f", vsigma[i1]);
00208 cerr << endl;
00209 }
00210
00211
00212
00213 local real stat_weight(real v, real v_th_3d)
00214 {
00215
00216
00217 real x = v/v_th_3d;
00218 return 3 * sqrt(6/PI) * x * x * x * exp(-1.5*x*x);
00219
00220
00221
00222 }
00223
00224 local int get_rate3(scatter_profile& prof, real v_rel_th,
00225 int nv, real max_dens,
00226 real total_sigma[][N_FINAL], real total_err_sq[][N_FINAL])
00227 {
00228 real v_max = 2 * v_rel_th;
00229 real dv = v_max / nv;
00230
00231 int ii, jj;
00232
00233
00234
00235 int total_trials = 0;
00236
00237 for (ii = 0; ii < N_INTER; ii++)
00238 for (jj = 0; jj < N_FINAL; jj++) {
00239 total_sigma[ii][jj] = 0;
00240 total_err_sq[ii][jj] = 0;
00241 }
00242
00243
00244
00245 initialize_local_stats();
00246
00247
00248
00249
00250 for (int i = 1; i < nv; i++) {
00251
00252 prof.v_inf = i * dv;
00253
00254 initialize_local_counters();
00255
00256 sigma_out out;
00257 get_sigma3(max_dens, prof, out,
00258 0,
00259 VERY_LARGE_NUMBER,
00260 VERY_LARGE_NUMBER,
00261 VERY_LARGE_NUMBER,
00262 0,
00263 accumulate_local_stats);
00264
00265 total_trials += out.total_trials;
00266
00267
00268
00269 real weight = stat_weight(prof.v_inf, v_rel_th) * dv / v_rel_th;
00270
00271 for (ii = 0; ii < N_INTER; ii++)
00272 for (jj = 0; jj < N_FINAL; jj++) {
00273
00274 total_sigma[ii][jj] += out.sigma[ii][jj] * weight;
00275
00276
00277
00278 total_err_sq[ii][jj] += out.sigma_err_sq[ii][jj]
00279 * weight * weight;
00280 }
00281
00282
00283
00284 integrate_local_stats(out, weight);
00285
00286
00287 }
00288
00289 return total_trials;
00290 }
00291
00292 local real total_coll(real total_sigma[][N_FINAL])
00293 {
00294 real sigma_coll = 0;
00295
00296 for (int i_int = 0; i_int < N_INTER; i_int++)
00297 sigma_coll += total_sigma[i_int][merger_binary_1]
00298 + total_sigma[i_int][merger_binary_2]
00299 + total_sigma[i_int][merger_binary_3]
00300 + total_sigma[i_int][merger_escape_1]
00301 + total_sigma[i_int][merger_escape_2]
00302 + total_sigma[i_int][merger_escape_3]
00303 + total_sigma[i_int][triple_merger];
00304 return sigma_coll;
00305 }
00306
00307 main(int argc, char **argv) {
00308
00309 scatter_profile prof;
00310 make_standard_profile(prof);
00311
00312
00313
00314 int seed = 0;
00315 prof.m2 = prof.m3 = 0.5;
00316 prof.r1 = prof.r2 = prof.r3 = 0;
00317 real v_rel_th = 1;
00318
00319 real max_dens = 64;
00320 int nv = 6;
00321
00322
00323
00324 int i = 0;
00325 while (++i < argc) if (argv[i][0] == '-')
00326 switch (argv[i][1]) {
00327 case 'A': prof.eta = atof(argv[++i]);
00328 break;
00329 case 'd': max_dens = atoi(argv[++i]);
00330 break;
00331 case 'e': prof.ecc = atof(argv[++i]);
00332 prof.ecc_flag = 1;
00333 break;
00334 case 'm': prof.m2 = atof(argv[++i]);
00335 break;
00336 break;
00337 case 'M': prof.m3 = atof(argv[++i]);
00338 break;
00339 case 'n': nv = atoi(argv[++i]);
00340 break;
00341 case 'r': switch(argv[i][2]) {
00342 case '1': prof.r1 = atof(argv[++i]);
00343 break;
00344 case '2': prof.r2 = atof(argv[++i]);
00345 break;
00346 case '3': prof.r3 = atof(argv[++i]);
00347 break;
00348 }
00349 if (prof.r3 < 0)
00350 err_exit("r3 < 0");
00351
00352 break;
00353 case 's': seed = atoi(argv[++i]);
00354 break;
00355 case 'v': v_rel_th = atof(argv[++i]);
00356 break;
00357 default: cerr << USAGE;
00358 exit(1);
00359 }
00360
00361 if (prof.r3 <= 0) err_exit("rate_stats: must specify r3 > 0.");
00362
00363 int first_seed = srandinter(seed);
00364 cerr << "Thermally averaged reaction rates, random seed = "
00365 << first_seed << endl;
00366
00367
00368
00369 prof.v_inf = -1;
00370 print_profile(cerr, prof);
00371
00372 cerr << "binary eccentricity = ";
00373 if (prof.ecc_flag)
00374 cerr << prof.ecc;
00375 else
00376 cerr << "thermal [f(e) = 2e]";
00377
00378 cerr << " v_rel_th = " << v_rel_th << endl;
00379
00380 real total_sigma[N_INTER][N_FINAL];
00381 real total_err_sq[N_INTER][N_FINAL];
00382
00383
00384
00385 v_scale = 4 * v_rel_th;
00386 int total_trials = get_rate3(prof, v_rel_th, nv, max_dens,
00387 total_sigma, total_err_sq);
00388
00389
00390
00391 cerr << "\nmax_dens = " << max_dens
00392 << " nv = " << nv
00393 << " total_trials = " << total_trials
00394 << " (" << n_hit << " hits)\n\n";
00395
00396 cerr << "<v sigma> (unit = pi a^2 v_rel_th):\n\n";
00397 print_sigma3_array(total_sigma, 1);
00398
00399 cerr << "<v sigma_err> (unit = pi a^2 v_rel_th):\n\n";
00400 print_sigma3_err_array(total_err_sq, 1);
00401
00402
00403
00404 cerr << "<v sigma> and <v sigma_err> (details):\n\n";
00405 print_sigma3_nonmergers(total_sigma, total_err_sq, 1);
00406
00407 if (total_coll(total_sigma) > 0)
00408 print_sigma3_mergers(total_sigma, total_err_sq, 1);
00409
00410
00411
00412 print_local_stats();
00413 }
00414 #endif