24 if (
A[0] == -1.0)
return -1.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)));
30 for (
long n = 0; n < 7; ++n) {
37 mfunnamep(
"ElElasticScat::ElElasticScat(const String& filename)");
39 std::ifstream file(file_name.c_str());
41 std::ifstream file(file_name);
45 mcerr <<
"cannot open file " << file_name << std::endl;
53 for (
long ne = 0; ne < qe; ++ne) {
54 file >> energy_mesh[ne];
57 mcerr <<
"error at reading energy_mesh, ne=" << ne <<
'\n';
60 double gamma = 1.0 + 0.001 * energy_mesh[ne] /
ELMAS;
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;
69 long na = atom.get_qel() - 1;
74 for (
int nc = 0; nc < 4; ++nc) {
75 for (
long ne = 0; ne < qe; ++ne) {
76 file >> atom[na].data[ne].A[nc];
79 mcerr <<
"error at reading A, Z=" << Z <<
" nc=" << nc <<
" ne=" << ne
85 for (
int nc = 0; nc < 7; ++nc) {
86 for (
long ne = 0; ne < qe; ++ne) {
87 file >> atom[na].data[ne].C[nc];
90 mcerr <<
"error at reading C, Z=" << Z <<
" nc=" << nc <<
" ne=" << ne
96 for (
long ne = 0; ne < qe; ++ne) {
97 file >> atom[na].data[ne].B;
100 mcerr <<
"error at reading B, Z=" << Z <<
" ne=" << ne <<
'\n';
107double ElElasticScat::get_CS_for_presented_atom(
long na,
double energy,
109 mfunnamep(
"double ElElasticScat::get_CS_for_presented_atom(long na, double "
110 "energy, double angle)");
112 double enKeV = energy * 1000.0;
113 double gamma = 1.0 + energy /
ELMAS;
116 double gamma_beta2_t = gamma * beta2;
117 double coe = atom[na].Z / (
FSCON *
FSCON) / gamma_beta2_t;
118 if (enKeV < energy_mesh[0]) {
121 for (ne = 0; ne < qe; ne++) {
122 r = atom[na].data[ne].CS(angle);
129 if (enKeV >= energy_mesh[qe - 1]) {
132 for (ne = qe - 1; ne >= 0; ne--) {
133 r = atom[na].data[ne].CS(angle);
142 for (ne = 1; ne < qe; ne++) {
143 if (energy_mesh[ne] > enKeV) {
148 double cs[2] = { -1., -1. };
151 long ne_left = ne - 1;
154 for (ne = ne_left; ne >= 0; ne--) {
155 cs[0] = atom[na].data[ne].CS(angle);
156 if (cs[0] >= 0.0)
break;
161 for (ne = ne_right; ne < qe; ne++) {
162 cs[1] = atom[na].data[ne].CS(angle);
163 if (cs[1] >= 0.0)
break;
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]);
177 }
else if (cs[1] >= 0.0) {
181 mcerr <<
"not implemented case\n";
194 mfunname(
"double ElElasticScat::get_CS(long Z, double energy, double angle, "
196 long qa = atom.get_qel();
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) {
207 return get_CS_for_presented_atom(na, energy, angle);
209 if (atom[na].Z > Z_left && atom[na].Z < Z) {
212 }
else if (atom[na].Z < Z_right && atom[na].Z > Z) {
213 Z_right = atom[na].Z;
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;
232 mfunname(
"double ElElasticScat::get_CS_Rutherford(long Z, double energy, "
234 double gamma_1 = energy /
ELMAS;
236 double momentum2 = energy * energy + 2.0 *
ELMAS * energy;
238 (momentum2 * beta2 *
pow(
sin(angle / 2.0), 4.0)) /
239 (
pow(5.07E10, 2.0)) * 1.0e16;
243#ifndef EXCLUDE_FUNCTIONS_WITH_HISTDEF
246 mfunname(
"double ElElasticScat::fill_hist(void)");
248 long qa = atom.get_qel();
260 for (na = 0; na < qa; na++) {
263 path_length_cor_hist[na] = histdef(name, qe, 0.0, qe);
264 path_length_cor_hist[na].init();
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;
272 raw_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
273 raw_hist.
ac(na, ne).init();
275 cor_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
276 cor_hist.
ac(na, ne).init();
278 corpol_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
279 corpol_hist.
ac(na, ne).init();
281 corpola_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
282 corpola_hist.
ac(na, ne).init();
284 int_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
285 int_hist.
ac(na, ne).init();
287 rut_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
288 rut_hist.
ac(na, ne).init();
290 rutpol_hist.
ac(na, ne) = histdef(name, qh, 0.0, 180.0);
291 rutpol_hist.
ac(na, ne).init();
296 double coef = Avogadro / (1.0 * g / mole) * 1.0 * g / cm3;
299 double angle_step = M_PI / qh;
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)) /
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);
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 /
318 s_cor += 2.0 * M_PI *
sin(anglerad) * t;
319 if (na != 0 && na < qa - 1)
321 int_hist.
ac(na, ne).fill(angle, 0.0,
get_CS(atom[na].Z, energyMeV,
322 angle / 180.0 * M_PI, 1));
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;
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);
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"))
349 long qa = atom.get_qel();
353 const long qquan = 4;
354 long quan[qquan] = { 5, 10, 20, 40 };
358 long zmax = atom[qa - 1].Z;
384 angular_mesh_c[0] = 0.0;
389 angular_mesh_c[1] = ar;
391 angular_mesh_c[n] = angular_mesh_c[n - 1] * rk;
396 std::ofstream ofile(file_name.c_str());
398 std::ofstream ofile(file_name);
402 mcerr <<
"cannot open file " << file_name << endl;
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 "
410 ofile <<
" format:\nnumber of atoms maximal number of interactions,\nthen "
411 "loop by atoms:\nZ of atom\n";
413 ofile <<
"ne energy_mesh[ne] (mean of 1 - cos(theta)) (sqrt(mean of "
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++) {
423 mcout <<
"starting calculate za=" << za << endl;
429 sigma_coef_hist[za - 1] = histdef(name, qe, 0.0, qe);
430 sigma_coef_hist[za - 1].init();
432 for (ne = 0; ne < qe; ne++) {
433 mcout <<
"starting calculate ne=" << ne << endl;
435 double energy = energy_mesh[ne] * 0.001;
439 double angle = angular_mesh_c[nan] / 180.0 * M_PI;
440 double s =
get_CS(za, energy, angle);
444 s = s * 2.0 * M_PI *
sin(angle);
451 for (nq = 0; nq < qquan; 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();
468 mean_hist.
ac(za - 1, ne) =
469 histdef(name, quan[qquan - 1] + 1, -0.5, quan[qquan - 1] + 0.5);
472 mean_hist.
ac(za - 1, ne).init();
474 sigma_hist.
ac(za - 1, ne) =
475 histdef(name, quan[qquan - 1] + 1, -0.5, quan[qquan - 1] + 0.5);
478 sigma_hist.
ac(za - 1, ne).init();
483 for (nev = 0; nev < qev; nev++) {
486 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
488 basis temp(dir,
"temp");
490 double theta_rot = angular_points_ran.
ran(
SRANLUX());
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));
503 if (new_dir.
z < 0.0) theta = M_PI - theta;
506 double ctheta =
cos(theta);
507 if (ncs == quan[nq] - 1)
509 ang_hist.
ac(za - 1, ne, nq).fill(ctheta, 0.0, 1.0);
513 mean[ncs] += 1.0 - ctheta;
514 disp[ncs] += (ctheta - 1.0) * (ctheta - 1.0);
518 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
519 mean[ncs] = mean[ncs] / qev;
520 disp[ncs] =
sqrt(disp[ncs] / (qev - 1));
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)
527 mea_ang_hist.
ac(za - 1, ne, nq) = mean[ncs];
528 sig_ang_hist.
ac(za - 1, ne, nq) = disp[ncs];
533 double mean_coef = 0.0;
535 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
536 if (mean[ncs] < 0.4) {
537 mean_coef += mean[ncs] / (ncs + 1.0);
541 mean_coef = mean_coef / ns;
544 for (ncs = 0; ncs < quan[qquan - 1]; ncs++) {
545 if (disp[ncs] < 0.4) {
546 coef += disp[ncs] / (ncs + 1.0);
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';
556 if (s_write_dist == 1) {
558 std::ofstream ofile(file_name_dist.c_str());
560 std::ofstream ofile(file_name_dist);
564 mcerr <<
"cannot open file " << file_name_dist << endl;
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);
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';
579 for (n = 0; n < q; n++) {
581 ofile << hi[n] <<
'\n';
595 Ifile <<
"ElElasticScat(l=" << l <<
"): qe=" << qe
596 <<
" atom.get_gel()=" << atom.get_qel() << std::endl;
599 Ifile <<
"energy_mesh=";
600 for (
long ne = 0; ne < qe; ++ne) {
601 file << std::setw(12) << energy_mesh[ne];
604 Ifile <<
"gamma_beta2=";
605 for (
long ne = 0; ne < qe; ++ne) {
606 file << std::setw(12) << gamma_beta2[ne];
610 long qa = atom.get_qel();
611 for (
long na = 0; na < qa; ++na) {
612 Ifile <<
"atom[na].Z=" << atom[na].Z <<
'\n';
614 for (
long ne = 0; ne < qe; ++ne) {
615 file << std::setw(12) << energy_mesh[ne];
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];
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];
633 for (
long ne = 0; ne < qe; ++ne) {
634 file << std::setw(12) << atom[na].data[ne].B;
652 mfunnamep(
"ElElasticScatLowSigma::ElElasticScatLowSigma(...)");
654 std::ifstream file(file_name.c_str());
656 std::ifstream file(file_name);
660 mcerr <<
"cannot open file " << file_name << std::endl;
665 file >> qat >> qscat;
670 for (
long nat = 0; nat < qat; ++nat) {
676 for (
long ne = 0; ne < ees->get_qe(); ++ne) {
679 mean_coef[nat][ne] = 0.0;
681 file >> fne >> e >> mean_coef[nat][ne] >> coef[nat][ne];
DoubleAc cos(const DoubleAc &f)
DoubleAc asin(const DoubleAc &f)
DoubleAc pow(const DoubleAc &f, double p)
DoubleAc sqrt(const DoubleAc &f)
DoubleAc sin(const DoubleAc &f)
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
#define check_econd11(a, signb, stream)
#define check_econd11a(a, signb, add, stream)
#define mfunnamep(string)
#define check_econd12(a, sign, b, stream)
double polleg(int l, double x)
String long_to_String(long n)
static double get_A(int fZ)
ElElasticScatLowSigma(void)
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
void down(const basis *fabas)
void random_round_vec(void)
int findmark(std::istream &file, const char *s)
const double low_cut_angle_deg
const long q_angular_mesh
double lorbeta2(const double gamma_1)