Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ElElasticScat.cpp
Go to the documentation of this file.
1#include <fstream>
2#include <iomanip>
3#include <cmath>
4
11#include "wcpplib/matter/AtomDef.h" // to find atomic weights for histogramms
13
16
17/*
182003, I. Smirnov
19*/
20
21namespace Heed {
22
23double ElElasticScatDataStruct::CS(double theta) {
24 if (A[0] == -1.0) return -1.0;
25 double s = 0.0;
26 const double ctheta = cos(theta);
27 for (long n = 0; n < 4; ++n) {
28 s += A[n] / (pow(1.0 - ctheta + 2.0 * B, double(n + 1)));
29 }
30 for (long n = 0; n < 7; ++n) {
31 s += C[n] * polleg(n, ctheta);
32 }
33 return s;
34}
35
36ElElasticScat::ElElasticScat(const String& file_name) : atom(0) {
37 mfunnamep("ElElasticScat::ElElasticScat(const String& filename)");
38#ifdef USE_STLSTRING
39 std::ifstream file(file_name.c_str());
40#else
41 std::ifstream file(file_name);
42#endif
43 if (!file) {
44 funnw.ehdr(mcerr);
45 mcerr << "cannot open file " << file_name << std::endl;
47 }
48 int i = findmark(file, "#");
49 check_econd11a(i, != 1, "cannot find sign #, wrong file format", mcerr);
50 file >> qe;
51 energy_mesh = DynLinArr<double>(qe);
52 gamma_beta2 = DynLinArr<double>(qe);
53 for (long ne = 0; ne < qe; ++ne) {
54 file >> energy_mesh[ne];
55 if (!file.good()) {
56 funnw.ehdr(mcerr);
57 mcerr << "error at reading energy_mesh, ne=" << ne << '\n';
59 }
60 double gamma = 1.0 + 0.001 * energy_mesh[ne] / ELMAS;
61 // energy_mesh[ne] in KeV
62 double beta2 =
63 (2.0 * 0.001 * energy_mesh[ne] / ELMAS +
64 pow(0.001 * energy_mesh[ne] / ELMAS, 2.0)) / pow(gamma, 2.0);
65 gamma_beta2[ne] = gamma * beta2;
66 }
67 while (findmark(file, "$") == 1) {
68 atom.increment();
69 long na = atom.get_qel() - 1;
70 long Z;
71 file >> Z;
72 check_econd21(Z, < 1 ||, > 110, mcerr);
73 atom[na] = ElElasticScatData(Z, qe);
74 for (int nc = 0; nc < 4; ++nc) {
75 for (long ne = 0; ne < qe; ++ne) {
76 file >> atom[na].data[ne].A[nc];
77 if (!file.good()) {
78 funnw.ehdr(mcerr);
79 mcerr << "error at reading A, Z=" << Z << " nc=" << nc << " ne=" << ne
80 << '\n';
82 }
83 }
84 }
85 for (int nc = 0; nc < 7; ++nc) {
86 for (long ne = 0; ne < qe; ++ne) {
87 file >> atom[na].data[ne].C[nc];
88 if (!file.good()) {
89 funnw.ehdr(mcerr);
90 mcerr << "error at reading C, Z=" << Z << " nc=" << nc << " ne=" << ne
91 << '\n';
93 }
94 }
95 }
96 for (long ne = 0; ne < qe; ++ne) {
97 file >> atom[na].data[ne].B;
98 if (!file.good()) {
99 funnw.ehdr(mcerr);
100 mcerr << "error at reading B, Z=" << Z << " ne=" << ne << '\n';
101 spexit(mcerr);
102 }
103 }
104 }
105}
106
107double ElElasticScat::get_CS_for_presented_atom(long na, double energy,
108 double angle) {
109 mfunnamep("double ElElasticScat::get_CS_for_presented_atom(long na, double "
110 "energy, double angle)");
111 long ne;
112 double enKeV = energy * 1000.0;
113 double gamma = 1.0 + energy / ELMAS;
114 double beta2 =
115 (2.0 * energy / ELMAS + pow(energy / ELMAS, 2.0)) / pow(gamma, 2.0);
116 double gamma_beta2_t = gamma * beta2;
117 double coe = atom[na].Z / (FSCON * FSCON) / gamma_beta2_t;
118 if (enKeV < energy_mesh[0]) {
119 double r = -1.;
120 // looking for valid data
121 for (ne = 0; ne < qe; ne++) {
122 r = atom[na].data[ne].CS(angle);
123 if (r >= 0.0) break;
124 }
125 check_econd11(r, < 0.0, mcerr);
126 r = r * coe * coe;
127 return r;
128 } else {
129 if (enKeV >= energy_mesh[qe - 1]) {
130 double r = -1.;
131 // looking for valid data
132 for (ne = qe - 1; ne >= 0; ne--) {
133 r = atom[na].data[ne].CS(angle);
134 if (r >= 0.0) break;
135 }
136 check_econd11(r, < 0.0, mcerr);
137 r = r * coe * coe;
138 return r;
139 //double coe = atom[na].Z / (FSCON * FSCON) / gamma_beta2[0];
140 //return atom[na].data[qe-1].CS(angle) * coe * coe;
141 } else {
142 for (ne = 1; ne < qe; ne++) {
143 if (energy_mesh[ne] > enKeV) {
144 break;
145 }
146 }
147 //Iprintn(mcout, ne);
148 double cs[2] = { -1., -1. };
149 //double coe[2];
150 // starting points
151 long ne_left = ne - 1;
152 long ne_right = ne;
153 // looking for valid data
154 for (ne = ne_left; ne >= 0; ne--) {
155 cs[0] = atom[na].data[ne].CS(angle);
156 if (cs[0] >= 0.0) break;
157 }
158 //cs[0] = atom[na].data[ne-1].CS(angle);
159 //coe[0] = atom[na].Z / (FSCON * FSCON) / gamma_beta2[ne - 1];
160 //cs[0] = cs[0] * coe[0] * coe[0];
161 for (ne = ne_right; ne < qe; ne++) {
162 cs[1] = atom[na].data[ne].CS(angle);
163 if (cs[1] >= 0.0) break;
164 }
165 //cs[1] = atom[na].data[ne].CS(angle);
166 //coe[1] = atom[na].Z / (FSCON * FSCON) / gamma_beta2[ne];
167 //cs[1] = cs[1] * coe[1] * coe[1];
168 //Iprintn(mcout, cs[0]);
169 //Iprintn(mcout, cs[1]);
170 double r = cs[0];
171 if (cs[0] >= 0.0 && cs[1] >= 0.0) {
172 r = cs[0] + (cs[1] - cs[0]) / (energy_mesh[ne] - energy_mesh[ne - 1]) *
173 (enKeV - energy_mesh[ne - 1]);
174 } else {
175 if (cs[0] >= 0.0) {
176 r = cs[0];
177 } else if (cs[1] >= 0.0) {
178 r = cs[1];
179 } else {
180 funnw.ehdr(mcerr);
181 mcerr << "not implemented case\n";
182 spexit(mcerr);
183 }
184 }
185 r = r * coe * coe;
186 //Iprintn(mcout, r);
187 return r;
188 }
189 }
190}
191
192double ElElasticScat::get_CS(long Z, double energy, double angle,
193 int s_interp) {
194 mfunname("double ElElasticScat::get_CS(long Z, double energy, double angle, "
195 "int s_interp)");
196 long qa = atom.get_qel();
197 long na;
198 long na_left = 0;
199 long Z_left = -100;
200 long na_right = qa - 1;
201 long Z_right = 10000;
202 for (na = 0; na < qa; na++) {
203 if (atom[na].Z == Z && s_interp == 0) {
204 //mcout << "ElElasticScat::get_CS: atom[na].Z=" << atom[na].Z
205 // << " energy=" << energy
206 // << " angle=" << angle << '\n';
207 return get_CS_for_presented_atom(na, energy, angle);
208 } else {
209 if (atom[na].Z > Z_left && atom[na].Z < Z) {
210 Z_left = atom[na].Z;
211 na_left = na;
212 } else if (atom[na].Z < Z_right && atom[na].Z > Z) {
213 Z_right = atom[na].Z;
214 na_right = na;
215 }
216 }
217 }
218 check_econd11a(Z_left, == -100, " have not found previous atom", mcerr);
219 check_econd11a(Z_right, == 10000, " have not found next atom", mcerr);
220 double f1 = get_CS_for_presented_atom(na_left, energy, angle);
221 double f2 = get_CS_for_presented_atom(na_right, energy, angle);
222 double z1 = atom[na_left].Z;
223 double z2 = atom[na_right].Z;
224 double c = (f1 * pow(2, 2.0) - f2 * pow(z1, 2.0)) / (f2 * z1 - f1 * z2);
225 double k = f1 / (z1 * (z1 + c));
226 double r = k * Z * (Z + c);
227 if (r < 0.0) r = 0.0;
228 return r;
229}
230
231double ElElasticScat::get_CS_Rutherford(long Z, double energy, double angle) {
232 mfunname("double ElElasticScat::get_CS_Rutherford(long Z, double energy, "
233 "double angle)");
234 double gamma_1 = energy / ELMAS;
235 double beta2 = lorbeta2(gamma_1);
236 double momentum2 = energy * energy + 2.0 * ELMAS * energy;
237 double r = (1 / 4.) * Z * Z * ELRAD * ELRAD * ELMAS * ELMAS /
238 (momentum2 * beta2 * pow(sin(angle / 2.0), 4.0)) /
239 (pow(5.07E10, 2.0)) * 1.0e16;
240 return r;
241}
242
243#ifndef EXCLUDE_FUNCTIONS_WITH_HISTDEF
244
246 mfunname("double ElElasticScat::fill_hist(void)");
247 const long qh = 100;
248 long qa = atom.get_qel();
249 long na;
250 long ne;
251 DynArr<histdef> raw_hist(qa, qe);
252 DynArr<histdef> cor_hist(qa, qe);
253 DynArr<histdef> corpol_hist(qa, qe);
254 DynArr<histdef> corpola_hist(qa, qe);
255 DynLinArr<histdef> path_length_cor_hist(qa);
256 DynArr<histdef> int_hist(qa, qe);
257 DynArr<histdef> rut_hist(qa, qe);
258 DynArr<histdef> rutpol_hist(qa, qe);
259 DynLinArr<histdef> path_length_rut_hist(qa);
260 for (na = 0; na < qa; na++) {
261 String name;
262 name = "path_length_cor_" + long_to_String(atom[na].Z);
263 path_length_cor_hist[na] = histdef(name, qe, 0.0, qe);
264 path_length_cor_hist[na].init();
265 name = "path_length_rut_" + long_to_String(atom[na].Z);
266 path_length_rut_hist[na] = histdef(name, qe, 0.0, qe);
267 path_length_rut_hist[na].init();
268 for (ne = 0; ne < qe; ne++) {
269 double energyKeV = energy_mesh[ne];
270 double energyMeV = 0.001 * energyKeV;
271 name = "raw_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
272 raw_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
273 raw_hist.ac(na, ne).init();
274 name = "cor_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
275 cor_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
276 cor_hist.ac(na, ne).init();
277 name = "corpol_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
278 corpol_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
279 corpol_hist.ac(na, ne).init();
280 name = "corpola_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
281 corpola_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
282 corpola_hist.ac(na, ne).init();
283 name = "int_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
284 int_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
285 int_hist.ac(na, ne).init();
286 name = "rut_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
287 rut_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
288 rut_hist.ac(na, ne).init();
289 name = "rutpol_" + long_to_String(atom[na].Z) + "_" + long_to_String(ne);
290 rutpol_hist.ac(na, ne) = histdef(name, qh, 0.0, 180.0);
291 rutpol_hist.ac(na, ne).init();
292 double s_cor = 0;
293 double s_rut = 0;
294 //double coef = Avogadro / (1.0*gram/mole) * 8.31896e-05*gram/cm3;
295 //Iprintn(mcout, coef/cm3);
296 double coef = Avogadro / (1.0 * g / mole) * 1.0 * g / cm3;
297 // for A = 1 and for unit density
298 // real values are not known in this program
299 double angle_step = M_PI / qh; // in rad
300 long nan;
301 for (nan = 0; nan < qh; nan++) {
302 double angle = raw_hist.ac(na, ne).get_bin_center(0, nan);
303 double anglerad = angle / 180.0 * M_PI;
304 double gamma = 1.0 + energyMeV / ELMAS;
305 double beta2 = (2.0 * energyMeV / ELMAS + pow(energyMeV / ELMAS, 2.0)) /
306 pow(gamma, 2.0);
307 double gamma_beta2_t = gamma * beta2;
308 double coe = atom[na].Z / (FSCON * FSCON) / gamma_beta2_t;
309 double r = atom[na].data[ne].CS(anglerad);
310 raw_hist.ac(na, ne).fill(angle, 0.0, r * coe * coe);
311 double t;
312 cor_hist.ac(na, ne)
313 .fill(angle, 0.0, (t = get_CS(atom[na].Z, energyMeV, anglerad)));
314 corpol_hist.ac(na, ne).fill(angle, 0.0, 2.0 * M_PI * sin(anglerad) * t);
315 corpola_hist.ac(na, ne)
316 .fill(angle, 0.0, 2.0 * M_PI * sin(anglerad) * t /
317 (AtomDef::get_A(atom[na].Z) / (gram / mole)));
318 s_cor += 2.0 * M_PI * sin(anglerad) * t;
319 if (na != 0 && na < qa - 1) // bypass not implemented
320 {
321 int_hist.ac(na, ne).fill(angle, 0.0, get_CS(atom[na].Z, energyMeV,
322 angle / 180.0 * M_PI, 1));
323 }
324 rut_hist.ac(na, ne)
325 .fill(angle, 0.0, (t = get_CS_Rutherford(atom[na].Z, energyMeV,
326 angle / 180.0 * M_PI)));
327 rutpol_hist.ac(na, ne).fill(angle, 0.0, 2.0 * M_PI * sin(anglerad) * t);
328 s_rut += 2.0 * M_PI * sin(anglerad) * t;
329 }
330 //path_length_cor_hist[na].fill
331 // (ne, 0.0,
332 // angle_step * s_cor);
333 path_length_cor_hist[na].fill(
334 ne, 0.0, 1.0 / (coef * angle_step * s_cor * 1.e-20 * meter2) / cm);
335 path_length_rut_hist[na].fill(
336 ne, 0.0, 1.0 / (coef * angle_step * s_rut * 1.e-20 * meter2) / cm);
337 }
338 }
339}
340
342 const String& file_name_dist) {
343 mfunnamep("double ElElasticScat::fill_hist_low_scat(const String& file_name, "
344 "const String& file_name_dist)");
345 int s_write_dist = 0;
346 if (file_name_dist != String("") && file_name_dist != String("none"))
347 s_write_dist = 1;
348 const long qh = 100;
349 long qa = atom.get_qel();
350 //long na;
351 long ne;
352 long nq;
353 const long qquan = 4; // quantity of different quantities and histogramms
354 long quan[qquan] = { 5, 10, 20, 40 }; // used for selection of hist.
355 // mean and rms are computed by all collisions up to quan[qquan-1]
356
357 //long quan[qquan]={5, 10, 20, 40, 100, 200, 400};
358 long zmax = atom[qa - 1].Z;
359 //DynArr< histdef > ang_hist(qa, qe, qquan);
360 DynArr<histdef> ang_hist(zmax, qe, qquan);
361 DynArr<histdef> mean_hist(zmax, qe);
362 DynArr<histdef> sigma_hist(zmax, qe);
363 DynLinArr<histdef> sigma_coef_hist(zmax);
364 // two arrays where mean and sigma is stored. They are used
365 // to write file file_name_dist
366 DynArr<double> mea_ang_hist(zmax, qe, qquan);
367 DynArr<double> sig_ang_hist(zmax, qe, qquan);
368
369 const long q_angular_mesh = 50;
370 DynLinArr<double> angular_mesh_c(q_angular_mesh);
371 // angular mesh, centers
372 long n;
373 /*
374 double amin = 1.0;
375 double amax = 180.0;
376 double rk = pow(amax/amin,(1.0/double(q_angular_mesh)));
377 double ar = amin;
378 angular_mesh_c[0] = ar;
379 for( n=1; n<q_angular_mesh; n++)
380 {
381 angular_mesh_c[n] = angular_mesh_c[n-1] * rk;
382 }
383 */
384 angular_mesh_c[0] = 0.0;
385 double amin = 0.3;
386 double amax = 180.0;
387 double rk = pow(amax / amin, (1.0 / double(q_angular_mesh - 2)));
388 double ar = amin;
389 angular_mesh_c[1] = ar;
390 for (n = 2; n < q_angular_mesh; n++) {
391 angular_mesh_c[n] = angular_mesh_c[n - 1] * rk;
392 }
393 angular_mesh_c[q_angular_mesh - 1] = 180.0;
394
395#ifdef USE_STLSTRING
396 std::ofstream ofile(file_name.c_str());
397#else
398 std::ofstream ofile(file_name);
399#endif
400 if (!ofile) {
401 funnw.ehdr(mcerr);
402 mcerr << "cannot open file " << file_name << endl;
403 spexit(mcerr);
404 }
405 long za;
406 ofile << "this file is created by function void "
407 "ElElasticScat::fill_hist_low_scat(void)\n";
408 ofile << "This is new format, in which the mean of 1 - cos(theta) is "
409 "inserted\n";
410 ofile << " format:\nnumber of atoms maximal number of interactions,\nthen "
411 "loop by atoms:\nZ of atom\n";
412 //ofile<<"number of energies\n"
413 ofile << "ne energy_mesh[ne] (mean of 1 - cos(theta)) (sqrt(mean of "
414 "(1-coef)^2)\n";
415 //ofile<<"number of interactions, mean cos of scattering angle, sigma of cos
416 //of scattering angle(thinking that mean is zero)\n";
417 ofile << "dollar sign means starting of this format\n";
418 ofile << "$\n" << zmax << ' ' << quan[qquan - 1] << '\n';
419 for (za = 1; za <= zmax; za++) {
420 //for(na=0; na<qa; na++)
421 //{
422 //mcout<<"starting calculate na="<<na<<'\n';
423 mcout << "starting calculate za=" << za << endl;
424 ofile << za << '\n';
425 //ofile<<na<<' '<<atom[na].Z<<'\n';
426 String name;
427 //name = "ang_" + long_to_String(atom[na].Z) + '_' +
428 name = "sigma_coef" + long_to_String(za);
429 sigma_coef_hist[za - 1] = histdef(name, qe, 0.0, qe);
430 sigma_coef_hist[za - 1].init();
431 // run events
432 for (ne = 0; ne < qe; ne++) {
433 mcout << "starting calculate ne=" << ne << endl;
434 //ofile<<ne<<' '<<energy_mesh[ne]<<'\n';
435 double energy = energy_mesh[ne] * 0.001;
437 long nan;
438 for (nan = 0; nan < q_angular_mesh; nan++) {
439 double angle = angular_mesh_c[nan] / 180.0 * M_PI;
440 double s = get_CS(za, energy, angle);
441 //double s = get_CS(atom[na].Z,
442 // energy,
443 // angle);
444 s = s * 2.0 * M_PI * sin(angle); // sr -> dtheta
445
446 cs[nan] = s;
447 }
448 PointsRan angular_points_ran(angular_mesh_c, cs, 0.0, low_cut_angle_deg);
449 DynLinArr<double> mean(quan[qquan - 1], 0.0); // for all collisions
450 DynLinArr<double> disp(quan[qquan - 1], 0.0); // for all collisions
451 for (nq = 0; nq < qquan; nq++) {
452 String name;
453 //name = "ang_" + long_to_String(atom[na].Z) + '_' +
454 name = "ang_" + long_to_String(za) + '_' + long_to_String(ne) + '_' +
455 long_to_String(nq);
456 ang_hist.ac(za - 1, ne, nq) = histdef(name, 1000, -1.0, 1.0);
457 ang_hist.ac(za - 1, ne, nq).init();
458 //ang_hist.ac(na,ne,nq) = histdef(name, 100, -1.0, 1.0);
459 //ang_hist.ac(na,ne,nq).init();
460 }
461 String name;
462 //name = "ang_" + long_to_String(atom[na].Z) + '_' +
463 name = "mean_" + long_to_String(za) + '_' + long_to_String(ne);
464 // Comparing with similar statement below this is better
465 // because the linear interpolation (h/pl ... l)
466 // goes precisely through zero at the plot.
467 // It also have correct number of bins and good right border.
468 mean_hist.ac(za - 1, ne) =
469 histdef(name, quan[qquan - 1] + 1, -0.5, quan[qquan - 1] + 0.5);
470 //mean_hist.ac(za-1,ne) = histdef
471 // (name, quan[qquan-1], 0.0, quan[qquan-1]);
472 mean_hist.ac(za - 1, ne).init();
473 name = "sigma_" + long_to_String(za) + '_' + long_to_String(ne);
474 sigma_hist.ac(za - 1, ne) =
475 histdef(name, quan[qquan - 1] + 1, -0.5, quan[qquan - 1] + 0.5);
476 //sigma_hist.ac(za-1,ne) = histdef
477 // (name, quan[qquan-1], 0.0, quan[qquan-1]);
478 sigma_hist.ac(za - 1, ne).init();
479 // run events
480 long qev = 100000;
481 long nev;
482 long ncs;
483 for (nev = 0; nev < qev; nev++) {
484 nq = 0;
485 vec dir(0, 0, 1); // current direction
486 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
487 //mcout<<"nev="<<nev<<" dir="<<dir;
488 basis temp(dir, "temp");
489 //#ifdef USE_SRANLUX
490 double theta_rot = angular_points_ran.ran(SRANLUX());
491 //#else
492 //double theta_rot = angular_points_ran.ran(random_engine.flat());
493 //#endif //Iprintn(mcout, theta_rot);
494 //double phi = 2.0 * M_PI * SRANLUX();
495 vec vturn;
496 vturn.random_round_vec();
497 vturn = vturn * sin(theta_rot / 180.0 * M_PI);
498 vec new_dir(vturn.x, vturn.y, cos(theta_rot / 180.0 * M_PI));
499 new_dir.down(&temp);
500 //Iprint(mcout, new_dir);
501 double theta = asin(sqrt(pow(new_dir.x, 2) + pow(new_dir.y, 2)) /
502 length(new_dir));
503 if (new_dir.z < 0.0) theta = M_PI - theta;
504 //Iprintn(mcout, theta);
505 dir = new_dir;
506 double ctheta = cos(theta);
507 if (ncs == quan[nq] - 1) // ncs is starting from 0
508 {
509 ang_hist.ac(za - 1, ne, nq).fill(ctheta, 0.0, 1.0);
510 //ang_hist.ac(na,ne,nq).fill(ctheta, 0.0, 1.0);
511 nq++;
512 }
513 mean[ncs] += 1.0 - ctheta;
514 disp[ncs] += (ctheta - 1.0) * (ctheta - 1.0);
515 }
516 }
517 nq = 0;
518 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
519 mean[ncs] = mean[ncs] / qev;
520 disp[ncs] = sqrt(disp[ncs] / (qev - 1));
521 //ofile<<setw(5)<<ncs<<' '
522 // <<setw(12)<<mean[ncs]<<' '<<setw(12)<<disp[ncs]<<'\n';
523 mean_hist.ac(za - 1, ne).fill(ncs + 1, 0.0, mean[ncs]);
524 sigma_hist.ac(za - 1, ne).fill(ncs + 1, 0.0, disp[ncs]);
525 if (ncs == quan[nq] - 1) // ncs is starting from 0
526 {
527 mea_ang_hist.ac(za - 1, ne, nq) = mean[ncs];
528 sig_ang_hist.ac(za - 1, ne, nq) = disp[ncs];
529 nq++;
530 }
531 }
532 // computing means for all collisions.
533 double mean_coef = 0.0;
534 long ns = 0;
535 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
536 if (mean[ncs] < 0.4) {
537 mean_coef += mean[ncs] / (ncs + 1.0);
538 ns++;
539 }
540 }
541 mean_coef = mean_coef / ns;
542 double coef = 0.0;
543 ns = 0;
544 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
545 if (disp[ncs] < 0.4) {
546 coef += disp[ncs] / (ncs + 1.0);
547 ns++;
548 }
549 }
550 coef = coef / ns;
551 sigma_coef_hist[za - 1].fill(ne, 0.0, coef);
552 ofile << ne << ' ' << setw(12) << energy_mesh[ne] << ' ' << setw(12)
553 << mean_coef << ' ' << setw(12) << coef << '\n';
554 }
555 }
556 if (s_write_dist == 1) {
557#ifdef USE_STLSTRING
558 std::ofstream ofile(file_name_dist.c_str());
559#else
560 std::ofstream ofile(file_name_dist);
561#endif
562 if (!ofile) {
563 funnw.ehdr(mcerr);
564 mcerr << "cannot open file " << file_name_dist << endl;
565 spexit(mcerr);
566 }
567 ofile << setw(5) << zmax << setw(5) << qe << setw(5) << qquan << '\n';
568 for (za = 1; za <= zmax; za++) {
569 for (ne = 0; ne < qe; ne++) {
570 for (nq = 0; nq < qquan; nq++) {
572 ang_hist.ac(za - 1, ne, nq).unpack(hi);
573 long q = hi.get_qel();
574 ofile << "\n# " << setw(5) << za << ' ' << setw(5) << ne << ' '
575 << setw(5) << nq << ' ' << setw(5) << q << ' ' << setw(15)
576 << mea_ang_hist.ac(za - 1, ne, nq) << ' ' << setw(15)
577 << sig_ang_hist.ac(za - 1, ne, nq) << '\n';
578 long n;
579 for (n = 0; n < q; n++) {
580 //ofile<<setw(5)<<n<<setw(12)<<hi[n]<<'\n';
581 ofile << hi[n] << '\n';
582 }
583 }
584 }
585 }
586
587 }
588
589}
590
591#endif
592
593void ElElasticScat::print(std::ostream& file, int l) const {
594 if (l <= 0) return;
595 Ifile << "ElElasticScat(l=" << l << "): qe=" << qe
596 << " atom.get_gel()=" << atom.get_qel() << std::endl;
597 if (l <= 1) return;
598 indn.n += 2;
599 Ifile << "energy_mesh=";
600 for (long ne = 0; ne < qe; ++ne) {
601 file << std::setw(12) << energy_mesh[ne];
602 }
603 file << std::endl;
604 Ifile << "gamma_beta2=";
605 for (long ne = 0; ne < qe; ++ne) {
606 file << std::setw(12) << gamma_beta2[ne];
607 }
608 file << std::endl;
609 indn.n -= 2;
610 long qa = atom.get_qel();
611 for (long na = 0; na < qa; ++na) {
612 Ifile << "atom[na].Z=" << atom[na].Z << '\n';
613 Ifile << " ";
614 for (long ne = 0; ne < qe; ++ne) {
615 file << std::setw(12) << energy_mesh[ne];
616 }
617 file << std::endl;
618 for (long n = 0; n < 4; ++n) {
619 Ifile << "A[" << n << "]";
620 for (long ne = 0; ne < qe; ++ne) {
621 file << std::setw(12) << atom[na].data[ne].A[n];
622 }
623 file << std::endl;
624 }
625 for (int n = 0; n < 7; ++n) {
626 Ifile << "C[" << n << "]";
627 for (long ne = 0; ne < qe; ++ne) {
628 file << std::setw(12) << atom[na].data[ne].C[n];
629 }
630 file << std::endl;
631 }
632 Ifile << "B ";
633 for (long ne = 0; ne < qe; ++ne) {
634 file << std::setw(12) << atom[na].data[ne].B;
635 }
636 file << std::endl;
637 /*
638 for (int n = 0; n < 2; ++n) {
639 Ifile << "D[" << n << "]";
640 for (long ne = 0; ne < qe; ++ne) {
641 file << std::setw(12) << atom[na].data[ne].D[n];
642 }
643 file << std::endl;
644 }
645 */
646 }
647}
648
650 const String& file_name)
651 : ees(fees) {
652 mfunnamep("ElElasticScatLowSigma::ElElasticScatLowSigma(...)");
653#ifdef USE_STLSTRING
654 std::ifstream file(file_name.c_str());
655#else
656 std::ifstream file(file_name);
657#endif
658 if (!file) {
659 funnw.ehdr(mcerr);
660 mcerr << "cannot open file " << file_name << std::endl;
661 spexit(mcerr);
662 }
663 int i = findmark(file, "$");
664 check_econd11(i, != 1, mcerr);
665 file >> qat >> qscat;
666 check_econd11(qat, <= 0, mcerr);
667 check_econd11(qscat, <= 0, mcerr);
668 mean_coef = DynLinArr<DynLinArr<double> >(qat);
669 coef = DynLinArr<DynLinArr<double> >(qat);
670 for (long nat = 0; nat < qat; ++nat) {
671 mean_coef[nat] = DynLinArr<double>(ees->get_qe());
672 coef[nat] = DynLinArr<double>(ees->get_qe());
673 long z;
674 file >> z;
675 check_econd12(z, !=, nat + 1, mcerr);
676 for (long ne = 0; ne < ees->get_qe(); ++ne) {
677 long fne;
678 double e;
679 mean_coef[nat][ne] = 0.0;
680 coef[nat][ne] = 0.0;
681 file >> fne >> e >> mean_coef[nat][ne] >> coef[nat][ne];
682 // file >> fne >> e >> coef[nat][ne]; // old format
683 check_econd12(fne, !=, ne, mcerr);
684 check_econd12(e, !=, ees->get_energy_mesh(ne), mcerr);
685 check_econd11(mean_coef[nat][ne], <= 0, mcerr);
686 check_econd11(coef[nat][ne], <= 0, mcerr);
687 }
688 }
689}
690
691}
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:431
DoubleAc asin(const DoubleAc &f)
Definition: DoubleAc.cpp:468
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:336
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:313
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:383
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:428
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:395
#define mfunnamep(string)
Definition: FunNameStack.h:77
#define spexit(stream)
Definition: FunNameStack.h:536
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:380
#define mfunname(string)
Definition: FunNameStack.h:67
double polleg(int l, double x)
Definition: PolLeg.cpp:14
String long_to_String(long n)
Definition: String.h:102
std::string String
Definition: String.h:75
T & ac(long i)
Definition: AbsArr.h:2057
long get_qel(void) const
Definition: AbsArr.h:420
static double get_A(int fZ)
Definition: AtomDef.cpp:38
void fill_hist_low_scat(const String &file_name, const String &file_name_dist)
double get_CS(long Z, double energy, double angle, int s_interp=0)
void print(std::ostream &file, int l) const
double get_CS_Rutherford(long Z, double energy, double angle)
double ran(double flat_ran) const
Definition: PointsRan.cpp:114
Definition: vec.h:397
Definition: vec.h:248
vfloat y
Definition: vec.h:250
void down(const basis *fabas)
Definition: vec.cpp:247
void random_round_vec(void)
Definition: vec.cpp:311
vfloat x
Definition: vec.h:250
vfloat z
Definition: vec.h:250
int findmark(std::istream &file, const char *s)
Definition: findmark.cpp:18
Definition: BGMesh.cpp:3
const double low_cut_angle_deg
Definition: HeedGlobals.h:6
const long q_angular_mesh
const double ELMAS
const double FSCON
const double ELRAD
double lorbeta2(const double gamma_1)
Definition: lorgamma.cpp:26
indentation indn
Definition: prstream.cpp:13
#define mcout
Definition: prstream.h:133
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
ffloat SRANLUX(void)
Definition: ranluxint.h:262