Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
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