28bool sign_nonlinear_interpolation(
double e1,
double cs1,
double e2,
double cs2,
30#ifdef ALWAYS_LINEAR_INTERPOLATION
34 if (cs2 >= cs1 || cs2 <= 0 || e1 < 300.0e-6 || e1 < 1.5 * threshold) {
37 const double pw = log(cs1 / cs2) / log(e1 / e2);
41 }
else if (pw < -5.0) {
58double my_integr_fun(
double xp1,
double yp1,
double xp2,
double yp2,
59 double xmin,
double ,
double x1,
double x2) {
60 const bool nonlin = sign_nonlinear_interpolation(xp1, yp1, xp2, yp2, xmin);
61 return nonlin ? Heed::t_integ_power_2point<double>(xp1, yp1, xp2, yp2, x1, x2)
66double my_val_fun(
double xp1,
double yp1,
double xp2,
double yp2,
double xmin,
68 const bool nonlin = sign_nonlinear_interpolation(xp1, yp1, xp2, yp2, xmin);
70 ? Heed::t_value_power_2point<double>(xp1, yp1, xp2, yp2, x)
82 : name(fname), number(-1), Z(fZ), threshold(fthreshold) {
85 std::istringstream ss(
name);
88 if (i >= 1 && i <= 50)
number = i;
93 Ifile <<
"PhotoAbsCS: name=" <<
name <<
" Z = " <<
Z
94 <<
" threshold = " <<
threshold << std::endl;
100 double fstep,
long fmax_q_step)
103 max_q_step(fmax_q_step),
105 mfunname(
"AveragePhotoAbsCS::AveragePhotoAbsCS(...)");
107 real_pacs.reset(apacs);
111 name = real_pacs->get_name();
112 number = real_pacs->get_number();
113 Z = real_pacs->get_Z();
118 mfunname(
"double AveragePhotoAbsCS::get_CS(double energy) const");
120 if (width == 0.0)
return real_pacs->get_CS(energy);
121 const double w2 = width * 0.5;
122 const double e1 = std::max(energy - w2, 0.);
123 return real_pacs->get_integral_CS(e1, energy + w2) / width;
127 double energy2)
const {
128 mfunname(
"double AveragePhotoAbsCS::get_integral_CS(...) const");
129 if (width == 0.0 || energy1 >= energy2) {
131 return real_pacs->get_integral_CS(energy1, energy2);
133 long q = long((energy2 - energy1) / step);
134 if (q > max_q_step) {
135 return real_pacs->get_integral_CS(energy1, energy2);
138 const double rstep = (energy2 - energy1) / q;
139 double x0 = energy1 + 0.5 * rstep;
141 for (
long n = 0; n < q; n++) s +=
get_CS(x0 + rstep * n);
146 mfunname(
"void AveragePhotoAbsCS::scale(double fact)");
147 real_pacs->scale(fact);
151 mfunname(
"void PhotoAbsCS::print(std::ostream& file, int l) const");
152 Ifile <<
"AveragePhotoAbsCS: width = " << width <<
" step=" << step
153 <<
" max_q_step=" << max_q_step <<
'\n';
155 real_pacs->print(file, l);
167 if (energy <
threshold || energy == DBL_MAX)
return 0.0;
169 return 0.5 * prefactor * 0.0535 * (
pow(100.0e-6 / energy, 3.228));
176 const double c1 = 0.5 * 0.0535 *
pow(100.0e-6, 3.228) / 2.228;
178 return prefactor * c1 * (1. /
pow(e1, 2.228));
180 return prefactor * c1 * (1. /
pow(e1, 2.228) - 1. /
pow(e2, 2.228));
188 Ifile <<
"HydrogenPhotoAbsCS: name=" <<
name <<
" Z = " <<
Z
189 <<
" threshold = " <<
threshold << std::endl;
196 const std::string& ffile_name)
197 :
PhotoAbsCS(fname, fZ, fthreshold), file_name(ffile_name) {
198 mfunnamep(
"SimpleTablePhotoAbsCS::SimpleTablePhotoAbsCS(...)");
199 std::ifstream file(file_name.c_str());
202 mcerr <<
"cannot open file " << file_name << std::endl;
211 if (!file.good())
break;
218 if (!file.good())
break;
221 ener.push_back(x * 1.e-6);
228 const std::vector<double>& fener,
229 const std::vector<double>& fcs)
234 mfunname(
"SimpleTablePhotoAbsCS::SimpleTablePhotoAbsCS(...)");
239 double fthreshold,
int l,
240 double E0,
double yw,
double ya,
241 double P,
double sigma)
243 mfunname(
"SimpleTablePhotoAbsCS::SimpleTablePhotoAbsCS(...)");
247 const double emin = 2.e-6;
248 const double emax = 2.e-1;
249 const double rk =
pow(emax / emin, (1.0 /
double(q)));
251 for (
long n = 0; n < q; n++) {
252 const double e1 = e2;
254 ener[n] = (e1 + e2) * 0.5;
257 for (
long n = 0; n < q; n++) {
258 double energy = ener[n];
260 const double Q = 5.5 + l - 0.5 * P;
261 const double y = energy / E0;
262 const double Fpasc = ((y - 1) * (y - 1) + yw * yw) *
pow(y, (-Q)) *
263 pow((1.0 +
sqrt(y / ya)), (-P));
264 cs[n] = Fpasc * sigma;
273 "SimpleTablePhotoAbsCS::SimpleTablePhotoAbsCS(const "
274 "SimpleTablePhotoAbsCS& total,...)");
278 long qe_i = total.ener.size();
280 const std::vector<double>& ener_r = part.
get_arr_ener();
281 const std::vector<double>& cs_r = part.
get_arr_CS();
282 long qe_r = ener_r.size();
283 std::vector<double> new_ener;
284 std::vector<double> new_cs;
286 for (
long ne = 0; ne < qe_r; ne++) {
287 if (ener_r[ne] >= total.
get_threshold() && ener_r[ne] <= emax_repl) {
288 new_ener.push_back(ener_r[ne]);
289 new_cs.push_back(cs_r[ne]);
292 for (
long ne = 0; ne < qe_i; ne++) {
293 if (ener[ne] >= total.
get_threshold() && ener[ne] > emax_repl) {
294 new_ener.push_back(total.ener[ne]);
295 new_cs.push_back(total.cs[ne]);
303 const long q = ener.size();
305 for (ne = 0; ne < q; ne++) {
306 if (cs[ne] > 0.0)
break;
309 const long qn = q - ne;
310 std::vector<double> enern(qn);
311 std::vector<double> csn(qn);
312 for (
long nez = ne; nez < q; nez++) {
313 enern[nez - ne] = ener[nez];
314 csn[nez - ne] = cs[nez];
320 const long q = ener.size();
322 for (ne = 0; ne < q; ne++) {
323 if (cs[ne] > level)
break;
326 const long qn = q - ne;
327 std::vector<double> enern(qn);
328 std::vector<double> csn(qn);
329 for (
long nez = ne; nez < q; nez++) {
330 enern[nez - ne] = ener[nez];
331 csn[nez - ne] = cs[nez];
338 mfunname(
"double SimpleTablePhotoAbsCS::get_CS(double energy) const");
339 long q = ener.size();
340 if (q == 0)
return 0.0;
343 if (energy <= ener[q - 1]) {
346 double, std::vector<double>,
348 pcm, cs, &my_val_fun, energy, 1,
threshold, 0, DBL_MAX);
350 if (energy == DBL_MAX)
353 return cs[q - 1] *
pow(energy, -2.75) /
pow(ener[q - 1], -2.75);
358 double energy2)
const {
359 mfunname(
"double SimpleTablePhotoAbsCS::get_integral_CS(...)");
361 const long q = ener.size();
362 if (q == 0)
return 0.0;
367 double energy21 = ener[q - 1];
368 if (energy1 < energy21) {
369 if (energy21 > energy2) energy21 = energy2;
373 double, std::vector<double>,
375 pcm, cs, &my_integr_fun, energy1, energy21, 1,
threshold, 0, DBL_MAX);
384 if (energy2 > ener[q - 1]) {
386 if (energy2 == DBL_MAX) {
387 if (energy1 < ener[q - 1]) energy1 = ener[q - 1];
389 cs[q - 1] / (1.75 *
pow(ener[q - 1], -2.75)) *
pow(energy1, -1.75);
393 if (energy1 < ener[q - 1]) energy1 = ener[q - 1];
394 double c = cs[q - 1] / (1.75 *
pow(ener[q - 1], -2.75)) *
395 (
pow(energy1, -1.75) -
pow(energy2, -1.75));
404 mfunnamep(
"void SimpleTablePhotoAbsCS::scale(double fact)");
405 const long q = ener.size();
406 for (
long n = 0; n < q; ++n) cs[n] *= fact;
411 Ifile <<
"SimpleTablePhotoAbsCS: name=" <<
name <<
" Z = " <<
Z <<
"\n";
412 Ifile <<
" threshold = " <<
threshold <<
" file_name=" << file_name <<
"\n";
415 const long q = ener.size();
416 for (
long n = 0; n < q; ++n) {
417 Ifile <<
"n=" << n <<
" ener=" << ener[n] <<
" cs=" << cs[n] <<
"\n";
428 double fthreshold,
double fpower)
429 :
PhotoAbsCS(fname, fZ, fthreshold), power(fpower) {
430 mfunname(
"PhenoPhotoAbsCS::PhenoPhotoAbsCS(...)");
431 check_econd11a(power, <= 2,
" value not allowed, integral would be infinite",
433 const double a = power - 1.;
438 if (energy <
threshold || energy == DBL_MAX)
return 0.0;
439 return factor *
pow(energy, -power);
445 const double a = power - 1.;
447 if (energy2 == DBL_MAX) {
448 s = factor / a * (1. /
pow(energy1, a));
450 s = factor / a * (1. /
pow(energy1, a) - 1. /
pow(energy2, a));
456 mfunnamep(
"void PhenoPhotoAbsCS::scale(double fact)");
462 Ifile <<
"PhenoPhotoAbsCS: name=" <<
name <<
" Z = " <<
Z << std::endl;
464 <<
" factor=" << factor << std::endl;
470 double fchannel_prob_dens,
const std::vector<double>& felectron_energy,
471 const std::vector<double>& fphoton_energy,
int s_all_rest) {
472 mfunnamep(
"void AtomicSecondaryProducts::add_channel(...)");
475 long q_new = q_old + 1;
479 if (s_all_rest == 1) {
481 for (
long n = 0; n < q_old; ++n) {
485 fchannel_prob_dens = 1.0 - s;
491 for (
long n = 0; n < q_new; ++n) {
496 mcerr <<
"s > 1.0, s=" << s <<
'\n';
498 for (
long n = 0; n < q_new; ++n) {
507 std::vector<double>& fphoton_energy)
509 mfunname(
"int AtomicSecondaryProducts::get_channel(...)");
510#ifdef DEBUG_PRINT_get_escape_particles
511 mcout <<
"AtomicSecondaryProducts::get_channel is started\n";
516 double rn = SRANLUX();
517#ifdef DEBUG_PRINT_get_escape_particles
529 for (
long n = 0; n < q; ++n) {
535#ifdef DEBUG_PRINT_get_escape_particles
542#ifdef DEBUG_PRINT_get_escape_particles
543 mcout <<
"AtomicSecondaryProducts::get_channel is finishing\n";
551 Ifile <<
"AtomicSecondaryProducts(l=" << l <<
"):\n";
553 Ifile <<
"number of channels=" << q <<
'\n';
555 for (
long n = 0; n < q; ++n) {
560 Ifile <<
"number of electrons=" << qel <<
'\n';
562 for (
long nel = 0; nel < qel; ++nel) {
568 Ifile <<
"number of photons=" << qph <<
'\n';
570 for (
long nph = 0; nph < qph; ++nph) {
583 double factual_minimal_threshold)
const {
584 mfunname(
"double AtomPhotoAbsCS::get_TICS(...) const");
585 if (factual_minimal_threshold <= energy) {
594 double energy1,
double energy2,
double factual_minimal_threshold)
const {
595 mfunname(
"double AtomPhotoAbsCS::get_integral_TICS(...) const");
596 if (factual_minimal_threshold > energy2)
return 0.;
597 energy1 = std::max(energy1, factual_minimal_threshold);
602 double factual_minimal_threshold)
const {
603 mfunname(
"double AtomPhotoAbsCS::get_TICS(...) const");
605 if (factual_minimal_threshold <= energy) {
612 int nshell,
double energy1,
double energy2,
613 double factual_minimal_threshold)
const {
614 mfunname(
"double AtomPhotoAbsCS::get_integral_TICS(...) const");
616 if (factual_minimal_threshold <= energy1) {
619 if (factual_minimal_threshold >= energy2)
return 0.0;
624 mfunname(
"void AtomPhotoAbsCS::remove_shell(int nshell)");
630 mfunname(
"void AtomPhotoAbsCS::restore_shell(int nshell)");
636 mfunnamep(
"void AtomPhotoAbsCS::print(std::ostream& file, int l) const");
638 Ifile <<
"AtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
639 <<
" qshell = " <<
qshell << std::endl;
645 for (
long n = 0; n < q; ++n) {
653 for (
long n = 0; n < q; ++n) {
668 mfunname(
"double AtomPhotoAbsCS::get_I_min() const");
676 const int nshell,
double energy, std::vector<double>& el_energy,
677 std::vector<double>& ph_energy)
const {
678 mfunname(
"void AtomPhotoAbsCS::get_escape_particles(...)");
679#ifdef DEBUG_PRINT_get_escape_particles
680 mcout <<
"AtomPhotoAbsCS::get_escape_particles is started\n";
697 double thrMin = DBL_MAX;
698 for (
int n = 0; n <
qshell; ++n) {
704#ifdef DEBUG_PRINT_get_escape_particles
707 if (nshell == n_min) {
709 const double en = std::max(energy - thrMin, 0.);
710 el_energy.push_back(en);
714 double en = energy - thrShell;
727 std::vector<double> felectron_energy;
728 std::vector<double> fphoton_energy;
729#ifdef DEBUG_PRINT_get_escape_particles
732#ifndef DEBUG_ignore_non_standard_channels
735 is =
asp[nshell].get_channel(felectron_energy, fphoton_energy);
742#ifdef DEBUG_PRINT_get_escape_particles
752 el_energy.resize(1 + felectron_energy.size());
754 long q = felectron_energy.size();
755 for (
long n = 0; n < q; ++n) {
757 el_energy[1 + n] = felectron_energy[n] - hdist;
758 if (el_energy[1 + n] < 0) {
759 hdist = -el_energy[1 + n];
760 el_energy[1 + n] = 0.0;
765 ph_energy.resize(fphoton_energy.size());
766 q = fphoton_energy.size();
767 for (
long n = 0; n < q; ++n) {
769 ph_energy[n] = fphoton_energy[n] - hdist;
770 if (ph_energy[n] < 0) {
771 hdist = -ph_energy[n];
783 const double en1 = thrShell - hdist - 2 * thrMin;
784 el_energy.push_back(en);
785 if (en1 >= 0.0) el_energy.push_back(en1);
789 int main_n_largest = 0;
790 for (
int n = 0; n <
qshell; ++n) {
793#ifdef DEBUG_PRINT_get_escape_particles
796 if (main_n_largest - main_n < 2) {
798 double en1 = thrShell - hdist - 2 * thrMin;
799 el_energy.push_back(en);
800 if (en1 >= 0.0) el_energy.push_back(en1);
807 double thr = DBL_MAX;
809 for (
int n = 0; n <
qshell; ++n) {
813 if (main_n_t > 0 && main_n_t == main_n + 1) {
820#ifdef DEBUG_PRINT_get_escape_particles
827 el_energy.push_back(en);
829 el_energy.push_back(en1);
834 el_energy.push_back(en2);
835 el_energy.push_back(en2);
843 el_energy.push_back(en);
844 el_energy.push_back(en1);
849 if (en2 > 0.) el_energy.push_back(en2);
854 mfunnamep(
"AtomicSecondaryProducts* AtomPhotoAbsCS::get_asp(int nshell)");
856 return &(
asp[nshell]);
862 const std::string& ffile_name)
863 : file_name(ffile_name) {
864 mfunnamep(
"SimpleAtomPhotoAbsCS::SimpleAtomPhotoAbsCS(...)");
874 if (
Z != fZ)
continue;
881 std::vector<double> fl(
qshell);
883 for (
int nshell = 0; nshell <
qshell; ++nshell) {
886 std::string shell_name;
901 for (
int nshell = 0; nshell <
qshell; ++nshell) {
906 for (
int nshell = 0; nshell <
qshell; ++nshell) {
907 if (fl[nshell] <= 0)
continue;
909 std::vector<double> felectron_energy;
910 std::vector<double> fphoton_energy;
912 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
917 mcerr <<
"there is no element Z=" << fZ <<
" in file " <<
file_name <<
'\n';
922 mfunname(
"SimpleAtomPhotoAbsCS::SimpleAtomPhotoAbsCS(...)");
929 name = facs->get_name();
931 m_acs[0] = std::move(facs);
935 mfunname(
"double SimpleAtomPhotoAbsCS::get_threshold(int nshell) const");
937 return m_acs[nshell]->get_threshold();
941 mfunname(
"double SimpleAtomPhotoAbsCS::get_ACS(double energy) const");
943 for (
int n = 0; n <
qshell; ++n) {
949 double energy2)
const {
950 mfunnamep(
"double SimpleAtomPhotoAbsCS::get_integral_ACS(...) const");
952 for (
int n = 0; n <
qshell; ++n) {
954 const double t =
m_acs[n]->get_integral_CS(energy1, energy2);
968 mfunname(
"double SimpleAtomPhotoAbsCS::get_ACS(int nshell, double energy)");
975 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ACS(...) const");
981 mfunname(
"double SimpleAtomPhotoAbsCS::get_ICS(double energy) const");
983 for (
int n = 0; n <
qshell; ++n) {
990 double energy2)
const {
991 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ICS(...) const");
993 for (
int n = 0; n <
qshell; ++n) {
1000 mfunname(
"double SimpleAtomPhotoAbsCS::get_ICS(int nshell, double energy)");
1007 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ICS(...) const");
1014 Ifile <<
"SimpleAtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
1019 for (
int n = 0; n <
qshell; ++n) {
1020 Ifile <<
"nshell=" << n << std::endl;
1021 m_acs[n]->print(file, l);
1030 const std::string& fthreshold_file_name,
1031 const std::string& fsimple_table_file_name,
1032 const std::string& fname,
1033 double fminimal_threshold)
1034 : threshold_file_name(fthreshold_file_name),
1035 simple_table_file_name(fsimple_table_file_name),
1036 BT_file_name(
"none"),
1037 minimal_threshold(fminimal_threshold) {
1038 mfunnamep(
"ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(...) const");
1041 if (!threshold_file) {
1046 std::vector<double> thr;
1047 std::vector<int> Zshell;
1048 std::vector<double> fl;
1049 std::vector<std::string> shell_name;
1050 bool foundZ =
false;
1051 while (
findmark(threshold_file,
"#") == 1) {
1052 threshold_file >>
Z;
1053 if (
Z != fZ)
continue;
1054 threshold_file >>
qshell;
1059 Zshell.resize(
qshell, 0);
1061 shell_name.resize(
qshell);
1064 std::string temp_name;
1065 threshold_file >> temp_name;
1066 name = fname ==
"none" ? temp_name : fname;
1068 for (
int nshell = 0; nshell <
qshell; nshell++) {
1069 threshold_file >> thr[nshell];
1071 thr[nshell] *= 1.0e-6;
1072 threshold_file >> Zshell[nshell];
1074 sZshell += Zshell[nshell];
1075 threshold_file >> fl[nshell];
1077 threshold_file >> shell_name[nshell];
1083 double st = DBL_MAX;
1084 for (
int nshell = 0; nshell <
qshell; nshell++) {
1085 if (thr[nshell] < st) {
1090 for (
int nshell = 0; nshell <
qshell; nshell++) {
1091 if (fl[nshell] <= 0)
continue;
1093 std::vector<double> felectron_energy;
1094 std::vector<double> fphoton_energy;
1095 fphoton_energy.push_back(thr[nshell] - thr[n_min]);
1096 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1103 mcerr <<
"there is no element Z=" << fZ <<
" in file "
1109 const std::vector<double>& ener = stpacs.
get_arr_ener();
1110 const std::vector<double>& CS = stpacs.
get_arr_CS();
1111 std::vector<double> left_CS = CS;
1112 const long qe = ener.size();
1114 std::vector<std::vector<double> > SCS(
qshell, std::vector<double>(qe, 0.));
1116 unsigned long nce = 0;
1119 if (ener[0] < thr[
qshell - 1]) {
1120 for (
long ne = 0; ne < qe && (ener[ne] < thr[
qshell - 1] ||
1121 (ener[ne] >= thr[
qshell - 1] && ne > 1 &&
1122 CS[ne - 1] <= CS[ne - 2]));
1124 if (ne > 0) left_CS[ne - 1] = 0.0;
1137 for (nt = nct; nt >= 0; nt--) {
1139 if (thr[nt] > ener[nce]) {
1144 if (thr[nt] > ener[nce + 1]) {
1153 int nce_next = ener.size();
1161 for (ne = nce; ne < ener.size(); ne++) {
1162 if (thr[nt] <= ener[ne]) {
1175 if (ne > 1 && ne < ener.size() - 1 && ne > nce + 2 &&
1176 thr[nt] <= ener[ne + 1] &&
1177 (thr[nt] - ener[ne]) / (ener[ne + 1] - ener[ne]) < 0.1 &&
1178 CS[ne] > CS[ne - 1]) {
1185 if (ne == ener.size())
1190 int qt = nt1 - nt2 + 1;
1195 for (nt = 0; nt < qt; nt++) {
1196 const int nshell = nct - nt;
1197 s += Zshell[nshell];
1200 std::vector<double> w(qt);
1201 for (nt = 0; nt < qt; nt++) {
1202 const int nshell = nct - nt;
1203 w[nt] = double(Zshell[nshell]) / s;
1205 double save_left_CS = left_CS[nce_next - 1];
1206 for (
long ne = 0; ne < nce_next; ne++) {
1207 for (nt = 0; nt < qt; nt++) {
1208 int nshell = nct - nt;
1209 SCS[nshell][ne] = left_CS[ne] * w[nt];
1213 for (
unsigned long ne = nce_next; ne < ener.size(); ne++) {
1215 save_left_CS *
pow(ener[nce_next - 1], 2.75) /
pow(ener[ne], 2.75);
1216 if (extrap_CS > left_CS[ne]) extrap_CS = left_CS[ne];
1217 for (nt = 0; nt < qt; nt++) {
1218 int nshell = nct - nt;
1219 SCS[nshell][ne] = extrap_CS * w[nt];
1221 left_CS[ne] -= extrap_CS;
1225 }
while (s_more != 0);
1229 for (
int ns = 0; ns < nt2; ns++) {
1233 for (
int ns = nt2; ns <
qshell; ns++) {
1235 adr->remove_leading_zeros();
1236 m_acs[ns].reset(adr);
1245 if (pred_integ > integ) {
1247 const double threshold =
m_acs[
qshell - 1]->get_threshold();
1260 }
else if (pred_integ < integ) {
1262 const double fact = pred_integ / integ;
1263 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1264 m_acs[nshell]->scale(fact);
1273 const std::string& fBT_file_name,
int id,
1274 double fminimal_threshold)
1275 : threshold_file_name(
"none"),
1276 simple_table_file_name(
"none"),
1277 BT_file_name(fBT_file_name),
1278 minimal_threshold(fminimal_threshold) {
1280 "ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(int fZ, const std::string& fname, "
1281 "const std::string& fBT_file_name, int id, double fminimal_threshold)");
1292 std::vector<double> thresh;
1293 std::vector<double> fl;
1295 int i =
findmark(BT_file,
"NUCLEAR CHARGE =");
1298 BT_file >> Z_from_file;
1301 while ((i =
findmark(BT_file,
"Z =")) == 1) {
1304 std::string shellname;
1305 BT_file >> shellname;
1312 std::vector<double> fener(qen, 0.0);
1313 std::vector<double> fcs(qen, 0.0);
1319 thresh.push_back(thr);
1320 fl.resize(fl.size() + 1);
1326 for (nen = 0; nen < qen; nen++) {
1327 BT_file >> fener[nen] >> fcs[nen];
1330 fener[nen] *= 1.0e-3;
1339 double st = DBL_MAX;
1340 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1343 if (thresh[nshell] < st) {
1345 st = thresh[nshell];
1349 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1350 if (fl[nshell] > 0) {
1352 std::vector<double> felectron_energy;
1353 std::vector<double> fphoton_energy;
1354 fphoton_energy.push_back(thresh[nshell] - thresh[n_min]);
1355 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1369 if (pred_integ > integ) {
1371 const double thr =
m_acs[
qshell - 1]->get_threshold();
1386 const double fact = pred_integ / integ;
1387 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1388 m_acs[nshell]->scale(fact);
1396#define READ_FILE_WITH_PRINCIPAL_NUMBERS
1399 const std::string& fFitBT_file_name,
1401 int s_no_scale,
double fminimal_threshold)
1402 : threshold_file_name(
"none"),
1403 simple_table_file_name(
"none"),
1404 BT_file_name(fFitBT_file_name),
1405 minimal_threshold(fminimal_threshold) {
1407 "ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(int fZ, const std::string& fname, "
1409 "std::string& fFitBT_file_name, int id, int id1, double "
1410 "fminimal_threshold)");
1415 std::ifstream BT_file(fFitBT_file_name.c_str());
1421 std::vector<double> thresh;
1422 std::vector<double> fl;
1424 while ((i =
findmark(BT_file,
"$")) == 1) {
1427 if (iZ !=
Z)
continue;
1437 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1438#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1448 if (BT_file.eof()) {
1452 if (!BT_file.good()) {
1456#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1458 if (!BT_file.good()) {
1464 BT_file >> l >> threshold >> E0 >> sigma >> ya >> P >> yw;
1467 threshold *= 1.0e-6;
1471 "n_princ=" << n_princ <<
" l=" << l <<
'\n',
mcerr);
1475 if (BT_file.eof()) {
1479 if (!BT_file.good()) {
1486 thresh[nshell] = threshold;
1489#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1491 std::string shellname(std::to_string(n_princ) +
" shell number " +
1492 std::to_string(nshell));
1494 std::string shellname(
"shell number " + std::to_string(nshell));
1497 l, E0, yw, ya, P, sigma));
1506 mcerr <<
"there is no element Z=" << fZ <<
" in file " << fFitBT_file_name
1513 double st = DBL_MAX;
1514 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1517 if (thresh[nshell] < st) {
1519 st = thresh[nshell];
1523 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1524 if (fl[nshell] > 0) {
1526 std::vector<double> felectron_energy;
1527 std::vector<double> fphoton_energy;
1528 fphoton_energy.push_back(thresh[nshell] - thresh[n_min]);
1529 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1543 if (pred_integ > integ) {
1545 const double thr =
m_acs[
qshell - 1]->get_threshold();
1560 const double fact = pred_integ / integ;
1561 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1562 m_acs[nshell]->scale(fact);
1571 int fZ,
const std::string& fname,
const std::string& fFitBT_file_name,
1572 const std::string& fsimple_table_file_name,
double emax_repl,
1574 double fminimal_threshold) {
1575 mfunname(
"ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(...)");
1580 fminimal_threshold);
1585 double thrmin = DBL_MAX;
1588 for (
long ns = 0; ns <
qshell; ++ns) {
1591 thrmin =
m_acs[ns]->get_threshold();
1606 m_acs[nsmin].reset(merged);
1614 if (pred_integ > integ) {
1616 const double thr =
m_acs[
qshell - 1]->get_threshold();
1631 const double fact = pred_integ / integ;
1632 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1633 m_acs[nshell]->scale(fact);
1642 mfunname(
"double ExAtomPhotoAbsCS::get_threshold(int nshell) const");
1644 double r =
m_acs[nshell]->get_threshold();
1652 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(double energy) const");
1654 for (
int n = 0; n <
qshell; ++n) {
1657 const double t =
m_acs[n]->get_threshold();
1661 s +=
m_acs[n]->get_CS(energy - shift);
1667 double energy2)
const {
1668 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ICS(double energy) const");
1670 for (
int n = 0; n <
qshell; ++n) {
1673 const double t =
m_acs[n]->get_threshold();
1677 s +=
m_acs[n]->get_integral_CS(energy1 - shift, energy2 - shift);
1683 mfunname(
"double ExAtomPhotoAbsCS::get_ICS(int nshell, double energy) const");
1687 const double t =
m_acs[nshell]->get_threshold();
1691 return m_acs[nshell]->get_CS(energy - shift);
1695 double energy2)
const {
1696 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ICS(int nshell, ...) const");
1700 const double t =
m_acs[nshell]->get_threshold();
1704 return m_acs[nshell]->get_integral_CS(energy1 - shift, energy2 - shift);
1708 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(double energy) const");
1710 for (
int n = 0; n <
qshell; ++n) {
1713 const double t =
m_acs[n]->get_threshold();
1717 s +=
m_acs[n]->get_CS(energy - shift);
1724 double energy2)
const {
1725 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ACS(...) const");
1727 for (
int n = 0; n <
qshell; ++n) {
1730 const double t =
m_acs[n]->get_threshold();
1734 s +=
m_acs[n]->get_integral_CS(energy1 - shift, energy2 - shift);
1736 double b[2] = {std::max(
exener[0], energy1), std::min(
exener[1], energy2)};
1742 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(int nshell, double energy)");
1746 const double t =
m_acs[nshell]->get_threshold();
1750 double s =
m_acs[nshell]->get_CS(energy - shift);
1758 double energy2)
const {
1759 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ACS(int nshell, ...) const");
1763 const double t =
m_acs[nshell]->get_threshold();
1767 double s =
m_acs[nshell]->get_integral_CS(energy1 - shift, energy2 - shift);
1768 if (nshell ==
qshell - 1) {
1769 double b[2] = {std::max(
exener[0], energy1), std::min(
exener[1], energy2)};
1777 Ifile <<
"ExAtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
1778 <<
" qshell = " <<
qshell << std::endl;
1789 <<
" exener=" <<
exener[0] <<
' ' <<
exener[1] <<
'\n';
1791 Ifile <<
"integrals by shells:\n";
1792 Ifile <<
"nshell, int(acs), int(ics)\n";
1793 for (
long n = 0; n <
qshell; n++) {
1796 Ifile << n <<
" " << ainteg <<
" " << iinteg <<
'\n';
1802 for (
long n = 0; n <
qshell; ++n) {
1803 Ifile <<
"nshell=" << n << std::endl;
1804 m_acs[n]->print(file, l);
1814 mfunname(
"void ExAtomPhotoAbsCS::replace_shells_by_average(...)");
1815 for (
long n = 0; n <
qshell; n++) {
1816 if (!
m_acs[n])
continue;
1826 double fW,
double fF)
1827 : qatom(fqatom), W(fW), F(fF) {
1828 qatom_ps.push_back(qatom);
1829 atom.push_back(fatom);
1830 if (W == 0.0) W =
coef_I_to_W * atom[0]->get_I_min();
1835 double fW,
double fF)
1836 : qatom(fqatom_ps1 + fqatom_ps2), W(fW), F(fF) {
1837 qatom_ps.push_back(fqatom_ps1);
1838 qatom_ps.push_back(fqatom_ps2);
1839 atom.push_back(fatom1);
1840 atom.push_back(fatom2);
1841 if (W != 0.0)
return;
1842#ifdef CALC_W_USING_CHARGES
1843 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_Z() * atom[0]->get_I_min() +
1844 qatom_ps[1] * atom[1]->get_Z() * atom[1]->get_I_min()) /
1845 (qatom_ps[0] * atom[0]->get_Z() + qatom_ps[1] * atom[1]->get_Z());
1847 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_I_min() +
1848 qatom_ps[1] * atom[1]->get_I_min()) /
1856 double fW,
double fF)
1857 : qatom(fqatom_ps1 + fqatom_ps2 + fqatom_ps3), W(fW), F(fF) {
1858 qatom_ps.push_back(fqatom_ps1);
1859 qatom_ps.push_back(fqatom_ps2);
1860 qatom_ps.push_back(fqatom_ps3);
1861 atom.push_back(fatom1);
1862 atom.push_back(fatom2);
1863 atom.push_back(fatom3);
1864 if (W != 0.0)
return;
1865#ifdef CALC_W_USING_CHARGES
1866 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_Z() * atom[0]->get_I_min() +
1867 qatom_ps[1] * atom[1]->get_Z() * atom[1]->get_I_min() +
1868 qatom_ps[2] * atom[2]->get_Z() * atom[2]->get_I_min()) /
1869 (qatom_ps[0] * atom[0]->get_Z() + qatom_ps[1] * atom[1]->get_Z() +
1870 qatom_ps[2] * atom[2]->get_Z());
1873 (qatom_ps[0] * atom[0]->get_I_min() + qatom_ps[1] * atom[1]->get_I_min() +
1874 qatom_ps[2] * atom[2]->get_I_min()) /
1880 mfunname(
"double MolecPhotoAbsCS::get_ACS(double energy) const");
1881 const long q = qatom_ps.size();
1883 for (
long n = 0; n < q; n++) s += qatom_ps[n] * atom[n]->
get_ACS(energy);
1888 mfunname(
"double MolecPhotoAbsCS::get_integral_ACS(double e1, double e2)");
1889 const long q = qatom_ps.size();
1891 for (
long n = 0; n < q; n++) {
1892 s += qatom_ps[n] * atom[n]->get_integral_ACS(en1, en2);
1898 mfunname(
"double MolecPhotoAbsCS::get_ICS(double energy) const");
1899 const long q = qatom_ps.size();
1901 for (
long n = 0; n < q; n++) s += qatom_ps[n] * atom[n]->
get_ICS(energy);
1906 mfunname(
"double MolecPhotoAbsCS::get_integral_ICS(double e1, double e2)");
1907 const long q = qatom_ps.size();
1909 for (
long n = 0; n < q; n++) {
1910 s += qatom_ps[n] * atom[n]->get_integral_ICS(en1, en2);
1916 mfunname(
"int MolecPhotoAbsCS::get_total_Z() const");
1917 const long q = qatom_ps.size();
1919 for (
long n = 0; n < q; n++) {
1920 s += qatom_ps[n] * atom[n]->get_Z();
1926 Ifile <<
"MolecPhotoAbsCS (l=" << l <<
"):\n";
1930 const long q = qatom_ps.size();
1931 Ifile <<
"number of sorts of atoms is " << q <<
'\n';
1933 for (
long n = 0; n < q; n++) {
1934 Ifile <<
"n=" << n <<
" qatom_ps[n]=" << qatom_ps[n] <<
" atom:\n";
1935 atom[n]->print(file, l);
#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)
Atomic photoabsorption cross-section abstract base class.
AtomPhotoAbsCS()
Default constructor.
std::vector< bool > s_ignore_shell
virtual void remove_shell(int nshell)
Deactivate a sub-shell. Set s_ignore_shell flag to true.
std::string name
Name of the atom.
virtual double get_I_min() const
Get the lowest ionization threshold among all shells.
virtual double get_ACS(double energy) const =0
virtual int get_main_shell_number(int nshell) const =0
virtual void print(std::ostream &file, int l) const
virtual double get_TICS(double energy, double factual_minimal_threshold) const
virtual double get_threshold(int nshell) const =0
Get the ionization threshold for a given shell.
virtual double get_integral_TICS(double energy1, double energy2, double factual_minimal_threshold) const
Integral photo-ionization cross-section with redefined threshold.
virtual void restore_shell(int nshell)
Activate a sub-shell. Set s_ignore_shell flag to false.
int qshell
Number of shells.
unsigned int get_qshell() const
Get the number of shells.
virtual void get_escape_particles(const int nshell, double energy, std::vector< double > &el_energy, std::vector< double > &ph_energy) const
std::vector< AtomicSecondaryProducts > asp
Sampling of relaxation products for each shell.
AtomicSecondaryProducts * get_asp(int nshell)
virtual double get_integral_ACS(double energy1, double energy2) const =0
Integrated photo-absorption cross-section overa given interval.
int get_channel(std::vector< double > &felectron_energy, std::vector< double > &fphoton_energy) const
void print(std::ostream &file, int l) const
std::vector< std::vector< double > > electron_energy
std::vector< std::vector< double > > photon_energy
void add_channel(double fchannel_prob_dens, const std::vector< double > &felectron_energy, const std::vector< double > &fphoton_energy, int s_all_rest=0)
std::vector< double > channel_prob_dens
Smoothed/smeared photoabsorption cross-section.
void scale(double fact) override
Multiply by some factor. Can be useful for debugging and other purposes.
double get_CS(double energy) const override
Retrieve cross-section [Mb] at a given energy [MeV].
AveragePhotoAbsCS()
Default constructor.
void print(std::ostream &file, int l) const override
double get_integral_CS(double energy1, double energy2) const override
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
double integ_abs_before_corr
void replace_shells_by_average(double fwidth, double fstep, long fmax_q_step)
double height_of_excitation
Excitation cross-section (assumed in the lowest shell).
virtual double get_threshold(int nshell) const
Get the ionization threshold for a given shell.
static const int s_add_excitations_to_normalize
double exener[2]
Boundaries of excitation.
std::vector< std::shared_ptr< PhotoAbsCS > > m_acs
double integ_ioniz_after_corr
virtual double get_integral_ACS(double energy1, double energy2) const
Integrated photo-absorption cross-section overa given interval.
virtual double get_ACS(double energy) const
static const int s_scale_to_normalize_if_more
std::string threshold_file_name
ExAtomPhotoAbsCS()
Default constructor.
std::string simple_table_file_name
virtual void print(std::ostream &file, int l) const
virtual double get_ICS(double energy) const
virtual double get_integral_ICS(double energy1, double energy2) const
Integrated photo-ionization cross-section over a given interval.
double integ_abs_after_corr
void scale(double fact) override
Multiply by some factor. Can be useful for debugging and other purposes.
HydrogenPhotoAbsCS()
Constructor.
double get_integral_CS(double energy1, double energy2) const override
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
double get_CS(double energy) const override
Retrieve cross-section [Mb] at a given energy [MeV].
void print(std::ostream &file, int l) const override
double get_ACS(double energy) const
Photo-absorption cross-section [Mbarn] at a given energy [MeV].
int get_total_Z() const
Sum up the atomic numbers of all atoms in the molecule.
double get_ICS(double energy) const
Photo-ionization cross-section [Mbarn] at a given energy [MeV].
double get_integral_ICS(double energy1, double energy2) const
Integral photo-ionization cross-section.
MolecPhotoAbsCS()=default
Default constructor.
double get_integral_ACS(double energy1, double energy2) const
Integral photo-absorption cross-section.
void print(std::ostream &file, int l) const
Simple phenomenological CS for any shell (analytic formula).
void print(std::ostream &file, int l) const override
void scale(double fact) override
Multiply by some factor. Can be useful for debugging and other purposes.
double get_integral_CS(double energy1, double energy2) const override
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
double get_CS(double energy) const override
Retrieve cross-section [Mb] at a given energy [MeV].
PhenoPhotoAbsCS()
Default constructor.
PhotoAbsCS()
Default constructor.
double get_threshold() const
Return the threshold energy.
virtual void print(std::ostream &file, int l) const
SimpleAtomPhotoAbsCS()
Default constructor.
std::vector< std::shared_ptr< PhotoAbsCS > > m_acs
virtual double get_ACS(double energy) const
virtual void print(std::ostream &file, int l) const
std::string file_name
Filename (saved for printing).
virtual double get_integral_ACS(double energy1, double energy2) const
Integrated photo-absorption cross-section overa given interval.
virtual double get_integral_ICS(double energy1, double energy2) const
Integrated photo-ionization cross-section over a given interval.
virtual double get_threshold(int nshell) const
Get the ionization threshold for a given shell.
virtual double get_ICS(double energy) const
void remove_leading_tiny(double level)
void print(std::ostream &file, int l) const override
double get_integral_CS(double energy1, double energy2) const override
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
SimpleTablePhotoAbsCS()=default
Default constructor.
void scale(double fact) override
Multiply by some factor. Can be useful for debugging and other purposes.
double get_CS(double energy) const override
Retrieve cross-section [Mb] at a given energy [MeV].
const std::vector< double > & get_arr_CS() const
const std::vector< double > & get_arr_ener() const
void remove_leading_zeros()
Remove points with zero cross-section from the table.
T t_value_straight_2point(T x1, T y1, T x2, T y2, T x, int s_ban_neg)
constexpr double Thomas_sum_rule_const_Mb
TRK sum rule [Mb * MeV].
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
DoubleAc pow(const DoubleAc &f, double p)
T t_integ_straight_2point(T x1, T y1, T x2, T y2, T xl, T xr, int xpower, int s_ban_neg)
T t_integ_generic_point_ar(const M &mesh, const D &y, T(*fun)(T xp1, T yp1, T xp2, T yp2, T xmin, T xmax, T x1, T x2), T x1, T x2, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond)
constexpr double coef_I_to_W
int findmark(std::istream &file, const char *s)
constexpr double low_boundary_of_excitations
DoubleAc sqrt(const DoubleAc &f)
T t_value_generic_point_ar(const M &mesh, const D &y, T(*funval)(T xp1, T yp1, T xp2, T yp2, T xmin, T xmax, T x), T x, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond)
#define Iprint(file, name)
#define Iprintn(file, name)
#define Iprint2n(file, name1, name2)