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