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
750 el_energy.resize(1 + felectron_energy.size());
752 long q = felectron_energy.size();
753 for (
long n = 0; n < q; ++n) {
755 el_energy[1 + n] = felectron_energy[n] - hdist;
756 if (el_energy[1 + n] < 0) {
757 hdist = -el_energy[1 + n];
758 el_energy[1 + n] = 0.0;
763 ph_energy.resize(fphoton_energy.size());
764 q = fphoton_energy.size();
765 for (
long n = 0; n < q; ++n) {
767 ph_energy[n] = fphoton_energy[n] - hdist;
768 if (ph_energy[n] < 0) {
769 hdist = -ph_energy[n];
781 const double en1 = thrShell - hdist - 2 * thrMin;
782 el_energy.push_back(en);
783 if (en1 >= 0.0) el_energy.push_back(en1);
787 int main_n_largest = 0;
788 for (
int n = 0; n <
qshell; ++n) {
791#ifdef DEBUG_PRINT_get_escape_particles
794 if (main_n_largest - main_n < 2) {
796 double en1 = thrShell - hdist - 2 * thrMin;
797 el_energy.push_back(en);
798 if (en1 >= 0.0) el_energy.push_back(en1);
805 double thr = DBL_MAX;
807 for (
int n = 0; n <
qshell; ++n) {
811 if (main_n_t > 0 && main_n_t == main_n + 1) {
818#ifdef DEBUG_PRINT_get_escape_particles
825 el_energy.push_back(en);
827 el_energy.push_back(en1);
832 el_energy.push_back(en2);
833 el_energy.push_back(en2);
841 el_energy.push_back(en);
842 el_energy.push_back(en1);
847 if (en2 > 0.) el_energy.push_back(en2);
852 mfunnamep(
"AtomicSecondaryProducts* AtomPhotoAbsCS::get_asp(int nshell)");
854 return &(
asp[nshell]);
860 const std::string& ffile_name)
861 : file_name(ffile_name) {
862 mfunnamep(
"SimpleAtomPhotoAbsCS::SimpleAtomPhotoAbsCS(...)");
872 if (
Z != fZ)
continue;
879 std::vector<double> fl(
qshell);
881 for (
int nshell = 0; nshell <
qshell; ++nshell) {
884 std::string shell_name;
899 for (
int nshell = 0; nshell <
qshell; ++nshell) {
904 for (
int nshell = 0; nshell <
qshell; ++nshell) {
905 if (fl[nshell] <= 0)
continue;
907 std::vector<double> felectron_energy;
908 std::vector<double> fphoton_energy;
910 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
915 mcerr <<
"there is no element Z=" << fZ <<
" in file " <<
file_name <<
'\n';
920 mfunname(
"SimpleAtomPhotoAbsCS::SimpleAtomPhotoAbsCS(...)");
927 name = facs->get_name();
929 m_acs[0] = std::move(facs);
933 mfunname(
"double SimpleAtomPhotoAbsCS::get_threshold(int nshell) const");
935 return m_acs[nshell]->get_threshold();
939 mfunname(
"double SimpleAtomPhotoAbsCS::get_ACS(double energy) const");
941 for (
int n = 0; n <
qshell; ++n) {
947 double energy2)
const {
948 mfunnamep(
"double SimpleAtomPhotoAbsCS::get_integral_ACS(...) const");
950 for (
int n = 0; n <
qshell; ++n) {
952 const double t =
m_acs[n]->get_integral_CS(energy1, energy2);
966 mfunname(
"double SimpleAtomPhotoAbsCS::get_ACS(int nshell, double energy)");
973 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ACS(...) const");
979 mfunname(
"double SimpleAtomPhotoAbsCS::get_ICS(double energy) const");
981 for (
int n = 0; n <
qshell; ++n) {
988 double energy2)
const {
989 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ICS(...) const");
991 for (
int n = 0; n <
qshell; ++n) {
998 mfunname(
"double SimpleAtomPhotoAbsCS::get_ICS(int nshell, double energy)");
1005 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ICS(...) const");
1012 Ifile <<
"SimpleAtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
1017 for (
int n = 0; n <
qshell; ++n) {
1018 Ifile <<
"nshell=" << n << std::endl;
1019 m_acs[n]->print(file, l);
1028 const std::string& fthreshold_file_name,
1029 const std::string& fsimple_table_file_name,
1030 const std::string& fname,
1031 double fminimal_threshold)
1032 : threshold_file_name(fthreshold_file_name),
1033 simple_table_file_name(fsimple_table_file_name),
1034 BT_file_name(
"none"),
1035 minimal_threshold(fminimal_threshold) {
1036 mfunnamep(
"ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(...) const");
1039 if (!threshold_file) {
1044 std::vector<double> thr;
1045 std::vector<int> Zshell;
1046 std::vector<double> fl;
1047 std::vector<std::string> shell_name;
1048 bool foundZ =
false;
1049 while (
findmark(threshold_file,
"#") == 1) {
1050 threshold_file >>
Z;
1051 if (
Z != fZ)
continue;
1052 threshold_file >>
qshell;
1057 Zshell.resize(
qshell, 0);
1059 shell_name.resize(
qshell);
1062 std::string temp_name;
1063 threshold_file >> temp_name;
1064 name = fname ==
"none" ? temp_name : fname;
1066 for (
int nshell = 0; nshell <
qshell; nshell++) {
1067 threshold_file >> thr[nshell];
1069 thr[nshell] *= 1.0e-6;
1070 threshold_file >> Zshell[nshell];
1072 sZshell += Zshell[nshell];
1073 threshold_file >> fl[nshell];
1075 threshold_file >> shell_name[nshell];
1081 double st = DBL_MAX;
1082 for (
int nshell = 0; nshell <
qshell; nshell++) {
1083 if (thr[nshell] < st) {
1088 for (
int nshell = 0; nshell <
qshell; nshell++) {
1089 if (fl[nshell] <= 0)
continue;
1091 std::vector<double> felectron_energy;
1092 std::vector<double> fphoton_energy;
1093 fphoton_energy.push_back(thr[nshell] - thr[n_min]);
1094 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1101 mcerr <<
"there is no element Z=" << fZ <<
" in file "
1107 const std::vector<double>& ener = stpacs.
get_arr_ener();
1108 const std::vector<double>& CS = stpacs.
get_arr_CS();
1109 std::vector<double> left_CS = CS;
1110 const long qe = ener.size();
1112 std::vector<std::vector<double> > SCS(
qshell, std::vector<double>(qe, 0.));
1114 unsigned long nce = 0;
1117 if (ener[0] < thr[
qshell - 1]) {
1118 for (
long ne = 0; ne < qe && (ener[ne] < thr[
qshell - 1] ||
1119 (ne > 1 && CS[ne - 1] <= CS[ne - 2]));
1121 if (ne > 0) left_CS[ne - 1] = 0.0;
1134 for (nt = nct; nt >= 0; nt--) {
1136 if (thr[nt] > ener[nce]) {
1141 if (thr[nt] > ener[nce + 1]) {
1150 int nce_next = ener.size();
1158 for (ne = nce; ne < ener.size(); ne++) {
1159 if (thr[nt] <= ener[ne]) {
1172 if (ne > 1 && ne < ener.size() - 1 && ne > nce + 2 &&
1173 thr[nt] <= ener[ne + 1] &&
1174 (thr[nt] - ener[ne]) / (ener[ne + 1] - ener[ne]) < 0.1 &&
1175 CS[ne] > CS[ne - 1]) {
1182 if (ne == ener.size())
1187 int qt = nt1 - nt2 + 1;
1192 for (nt = 0; nt < qt; nt++) {
1193 const int nshell = nct - nt;
1194 s += Zshell[nshell];
1197 std::vector<double> w(qt);
1198 for (nt = 0; nt < qt; nt++) {
1199 const int nshell = nct - nt;
1200 w[nt] = double(Zshell[nshell]) / s;
1202 double save_left_CS = left_CS[nce_next - 1];
1203 for (
long ne = 0; ne < nce_next; ne++) {
1204 for (nt = 0; nt < qt; nt++) {
1205 int nshell = nct - nt;
1206 SCS[nshell][ne] = left_CS[ne] * w[nt];
1210 for (
unsigned long ne = nce_next; ne < ener.size(); ne++) {
1212 save_left_CS *
pow(ener[nce_next - 1], 2.75) /
pow(ener[ne], 2.75);
1213 if (extrap_CS > left_CS[ne]) extrap_CS = left_CS[ne];
1214 for (nt = 0; nt < qt; nt++) {
1215 int nshell = nct - nt;
1216 SCS[nshell][ne] = extrap_CS * w[nt];
1218 left_CS[ne] -= extrap_CS;
1222 }
while (s_more != 0);
1226 for (
int ns = 0; ns < nt2; ns++) {
1230 for (
int ns = nt2; ns <
qshell; ns++) {
1232 adr->remove_leading_zeros();
1233 m_acs[ns].reset(adr);
1242 if (pred_integ > integ) {
1244 const double threshold =
m_acs[
qshell - 1]->get_threshold();
1257 }
else if (pred_integ < integ) {
1259 const double fact = pred_integ / integ;
1260 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1261 m_acs[nshell]->scale(fact);
1270 const std::string& fBT_file_name,
int id,
1271 double fminimal_threshold)
1272 : threshold_file_name(
"none"),
1273 simple_table_file_name(
"none"),
1274 BT_file_name(fBT_file_name),
1275 minimal_threshold(fminimal_threshold) {
1277 "ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(int fZ, const std::string& fname, "
1278 "const std::string& fBT_file_name, int id, double fminimal_threshold)");
1289 std::vector<double> thresh;
1290 std::vector<double> fl;
1292 int i =
findmark(BT_file,
"NUCLEAR CHARGE =");
1295 BT_file >> Z_from_file;
1298 while ((i =
findmark(BT_file,
"Z =")) == 1) {
1301 std::string shellname;
1302 BT_file >> shellname;
1309 std::vector<double> fener(qen, 0.0);
1310 std::vector<double> fcs(qen, 0.0);
1316 thresh.push_back(thr);
1317 fl.resize(fl.size() + 1);
1323 for (nen = 0; nen < qen; nen++) {
1324 BT_file >> fener[nen] >> fcs[nen];
1327 fener[nen] *= 1.0e-3;
1336 double st = DBL_MAX;
1337 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1340 if (thresh[nshell] < st) {
1342 st = thresh[nshell];
1346 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1347 if (fl[nshell] > 0) {
1349 std::vector<double> felectron_energy;
1350 std::vector<double> fphoton_energy;
1351 fphoton_energy.push_back(thresh[nshell] - thresh[n_min]);
1352 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1366 if (pred_integ > integ) {
1368 const double thr =
m_acs[
qshell - 1]->get_threshold();
1383 const double fact = pred_integ / integ;
1384 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1385 m_acs[nshell]->scale(fact);
1393#define READ_FILE_WITH_PRINCIPAL_NUMBERS
1396 const std::string& fFitBT_file_name,
1398 int s_no_scale,
double fminimal_threshold)
1399 : threshold_file_name(
"none"),
1400 simple_table_file_name(
"none"),
1401 BT_file_name(fFitBT_file_name),
1402 minimal_threshold(fminimal_threshold) {
1404 "ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(int fZ, const std::string& fname, "
1406 "std::string& fFitBT_file_name, int id, int id1, double "
1407 "fminimal_threshold)");
1412 std::ifstream BT_file(fFitBT_file_name.c_str());
1418 std::vector<double> thresh;
1419 std::vector<double> fl;
1421 while ((i =
findmark(BT_file,
"$")) == 1) {
1424 if (iZ !=
Z)
continue;
1434 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1435#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1445 if (BT_file.eof()) {
1449 if (!BT_file.good()) {
1453#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1455 if (!BT_file.good()) {
1461 BT_file >> l >> threshold >> E0 >> sigma >> ya >> P >> yw;
1464 threshold *= 1.0e-6;
1468 "n_princ=" << n_princ <<
" l=" << l <<
'\n',
mcerr);
1472 if (BT_file.eof()) {
1476 if (!BT_file.good()) {
1483 thresh[nshell] = threshold;
1486#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1488 std::string shellname(std::to_string(n_princ) +
" shell number " +
1489 std::to_string(nshell));
1491 std::string shellname(
"shell number " + std::to_string(nshell));
1494 l, E0, yw, ya, P, sigma));
1503 mcerr <<
"there is no element Z=" << fZ <<
" in file " << fFitBT_file_name
1510 double st = DBL_MAX;
1511 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1514 if (thresh[nshell] < st) {
1516 st = thresh[nshell];
1520 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1521 if (fl[nshell] > 0) {
1523 std::vector<double> felectron_energy;
1524 std::vector<double> fphoton_energy;
1525 fphoton_energy.push_back(thresh[nshell] - thresh[n_min]);
1526 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1540 if (pred_integ > integ) {
1542 const double thr =
m_acs[
qshell - 1]->get_threshold();
1557 const double fact = pred_integ / integ;
1558 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1559 m_acs[nshell]->scale(fact);
1568 int fZ,
const std::string& fname,
const std::string& fFitBT_file_name,
1569 const std::string& fsimple_table_file_name,
double emax_repl,
1571 double fminimal_threshold) {
1572 mfunname(
"ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(...)");
1577 fminimal_threshold);
1582 double thrmin = DBL_MAX;
1585 for (
long ns = 0; ns <
qshell; ++ns) {
1588 thrmin =
m_acs[ns]->get_threshold();
1603 m_acs[nsmin].reset(merged);
1611 if (pred_integ > integ) {
1613 const double thr =
m_acs[
qshell - 1]->get_threshold();
1628 const double fact = pred_integ / integ;
1629 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1630 m_acs[nshell]->scale(fact);
1639 mfunname(
"double ExAtomPhotoAbsCS::get_threshold(int nshell) const");
1641 double r =
m_acs[nshell]->get_threshold();
1649 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(double energy) const");
1651 for (
int n = 0; n <
qshell; ++n) {
1654 const double t =
m_acs[n]->get_threshold();
1658 s +=
m_acs[n]->get_CS(energy - shift);
1664 double energy2)
const {
1665 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ICS(double energy) const");
1667 for (
int n = 0; n <
qshell; ++n) {
1670 const double t =
m_acs[n]->get_threshold();
1674 s +=
m_acs[n]->get_integral_CS(energy1 - shift, energy2 - shift);
1680 mfunname(
"double ExAtomPhotoAbsCS::get_ICS(int nshell, double energy) const");
1684 const double t =
m_acs[nshell]->get_threshold();
1688 return m_acs[nshell]->get_CS(energy - shift);
1692 double energy2)
const {
1693 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ICS(int nshell, ...) const");
1697 const double t =
m_acs[nshell]->get_threshold();
1701 return m_acs[nshell]->get_integral_CS(energy1 - shift, energy2 - shift);
1705 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(double energy) const");
1707 for (
int n = 0; n <
qshell; ++n) {
1710 const double t =
m_acs[n]->get_threshold();
1714 s +=
m_acs[n]->get_CS(energy - shift);
1721 double energy2)
const {
1722 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ACS(...) const");
1724 for (
int n = 0; n <
qshell; ++n) {
1727 const double t =
m_acs[n]->get_threshold();
1731 s +=
m_acs[n]->get_integral_CS(energy1 - shift, energy2 - shift);
1733 double b[2] = {std::max(
exener[0], energy1), std::min(
exener[1], energy2)};
1739 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(int nshell, double energy)");
1743 const double t =
m_acs[nshell]->get_threshold();
1747 double s =
m_acs[nshell]->get_CS(energy - shift);
1755 double energy2)
const {
1756 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ACS(int nshell, ...) const");
1760 const double t =
m_acs[nshell]->get_threshold();
1764 double s =
m_acs[nshell]->get_integral_CS(energy1 - shift, energy2 - shift);
1765 if (nshell ==
qshell - 1) {
1766 double b[2] = {std::max(
exener[0], energy1), std::min(
exener[1], energy2)};
1774 Ifile <<
"ExAtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
1775 <<
" qshell = " <<
qshell << std::endl;
1786 <<
" exener=" <<
exener[0] <<
' ' <<
exener[1] <<
'\n';
1788 Ifile <<
"integrals by shells:\n";
1789 Ifile <<
"nshell, int(acs), int(ics)\n";
1790 for (
long n = 0; n <
qshell; n++) {
1793 Ifile << n <<
" " << ainteg <<
" " << iinteg <<
'\n';
1799 for (
long n = 0; n <
qshell; ++n) {
1800 Ifile <<
"nshell=" << n << std::endl;
1801 m_acs[n]->print(file, l);
1811 mfunname(
"void ExAtomPhotoAbsCS::replace_shells_by_average(...)");
1812 for (
long n = 0; n <
qshell; n++) {
1813 if (!
m_acs[n])
continue;
1823 double fW,
double fF)
1824 : qatom(fqatom), W(fW), F(fF) {
1825 qatom_ps.push_back(qatom);
1826 atom.push_back(fatom);
1827 if (W == 0.0) W =
coef_I_to_W * atom[0]->get_I_min();
1832 double fW,
double fF)
1833 : qatom(fqatom_ps1 + fqatom_ps2), W(fW), F(fF) {
1834 qatom_ps.push_back(fqatom_ps1);
1835 qatom_ps.push_back(fqatom_ps2);
1836 atom.push_back(fatom1);
1837 atom.push_back(fatom2);
1838 if (W != 0.0)
return;
1839#ifdef CALC_W_USING_CHARGES
1840 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_Z() * atom[0]->get_I_min() +
1841 qatom_ps[1] * atom[1]->get_Z() * atom[1]->get_I_min()) /
1842 (qatom_ps[0] * atom[0]->get_Z() + qatom_ps[1] * atom[1]->get_Z());
1844 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_I_min() +
1845 qatom_ps[1] * atom[1]->get_I_min()) /
1853 double fW,
double fF)
1854 : qatom(fqatom_ps1 + fqatom_ps2 + fqatom_ps3), W(fW), F(fF) {
1855 qatom_ps.push_back(fqatom_ps1);
1856 qatom_ps.push_back(fqatom_ps2);
1857 qatom_ps.push_back(fqatom_ps3);
1858 atom.push_back(fatom1);
1859 atom.push_back(fatom2);
1860 atom.push_back(fatom3);
1861 if (W != 0.0)
return;
1862#ifdef CALC_W_USING_CHARGES
1863 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_Z() * atom[0]->get_I_min() +
1864 qatom_ps[1] * atom[1]->get_Z() * atom[1]->get_I_min() +
1865 qatom_ps[2] * atom[2]->get_Z() * atom[2]->get_I_min()) /
1866 (qatom_ps[0] * atom[0]->get_Z() + qatom_ps[1] * atom[1]->get_Z() +
1867 qatom_ps[2] * atom[2]->get_Z());
1870 (qatom_ps[0] * atom[0]->get_I_min() + qatom_ps[1] * atom[1]->get_I_min() +
1871 qatom_ps[2] * atom[2]->get_I_min()) /
1877 mfunname(
"double MolecPhotoAbsCS::get_ACS(double energy) const");
1878 const long q = qatom_ps.size();
1880 for (
long n = 0; n < q; n++) s += qatom_ps[n] * atom[n]->
get_ACS(energy);
1885 mfunname(
"double MolecPhotoAbsCS::get_integral_ACS(double e1, double e2)");
1886 const long q = qatom_ps.size();
1888 for (
long n = 0; n < q; n++) {
1889 s += qatom_ps[n] * atom[n]->get_integral_ACS(en1, en2);
1895 mfunname(
"double MolecPhotoAbsCS::get_ICS(double energy) const");
1896 const long q = qatom_ps.size();
1898 for (
long n = 0; n < q; n++) s += qatom_ps[n] * atom[n]->
get_ICS(energy);
1903 mfunname(
"double MolecPhotoAbsCS::get_integral_ICS(double e1, double e2)");
1904 const long q = qatom_ps.size();
1906 for (
long n = 0; n < q; n++) {
1907 s += qatom_ps[n] * atom[n]->get_integral_ICS(en1, en2);
1913 mfunname(
"size_t MolecPhotoAbsCS::get_total_Z() const");
1914 const size_t q = qatom_ps.size();
1916 for (
size_t n = 0; n < q; n++) {
1917 s += qatom_ps[n] * atom[n]->get_Z();
1923 Ifile <<
"MolecPhotoAbsCS (l=" << l <<
"):\n";
1927 const long q = qatom_ps.size();
1928 Ifile <<
"number of sorts of atoms is " << q <<
'\n';
1930 for (
long n = 0; n < q; n++) {
1931 Ifile <<
"n=" << n <<
" qatom_ps[n]=" << qatom_ps[n] <<
" atom:\n";
1932 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
size_t get_total_Z() const
Sum up the atomic numbers of all atoms in the molecule.
double get_ACS(double energy) const
Photo-absorption cross-section [Mbarn] at a given energy [MeV].
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 Iprintn(file, name)
#define Iprint2n(file, name1, name2)