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(...)");
110 name = real_pacs->get_name();
111 number = real_pacs->get_number();
112 Z = real_pacs->get_Z();
117 mfunname(
"double AveragePhotoAbsCS::get_CS(double energy) const");
119 if (width == 0.0)
return real_pacs->get_CS(energy);
120 const double w2 = width * 0.5;
121 const double e1 = std::max(energy - w2, 0.);
122 return real_pacs->get_integral_CS(e1, energy + w2) / width;
126 double energy2)
const {
127 mfunname(
"double AveragePhotoAbsCS::get_integral_CS(...) const");
128 if (width == 0.0 || energy1 >= energy2) {
130 return real_pacs->get_integral_CS(energy1, energy2);
132 long q = long((energy2 - energy1) / step);
133 if (q > max_q_step) {
134 return real_pacs->get_integral_CS(energy1, energy2);
137 const double rstep = (energy2 - energy1) / q;
138 double x0 = energy1 + 0.5 * rstep;
140 for (
long n = 0; n < q; n++) s +=
get_CS(x0 + rstep * n);
145 mfunname(
"void AveragePhotoAbsCS::scale(double fact)");
146 real_pacs->scale(fact);
150 mfunname(
"void PhotoAbsCS::print(std::ostream& file, int l) const");
151 Ifile <<
"AveragePhotoAbsCS: width = " << width <<
" step=" << step
152 <<
" max_q_step=" << max_q_step <<
'\n';
154 real_pacs->print(file, l);
161 :
PhotoAbsCS(
"H", 1, 15.43e-6), prefactor(1.) {
166 if (energy <
threshold || energy == DBL_MAX)
return 0.0;
168 return 0.5 * prefactor * 0.0535 * (
pow(100.0e-6 / energy, 3.228));
172 double energy2)
const {
175 if (energy2 == DBL_MAX) {
176 return 0.5 * prefactor * 0.0535 *
pow(100.0e-6, 3.228) / 2.228 *
177 (1.0 /
pow(energy1, 2.228));
179 return 0.5 * prefactor * 0.0535 *
pow(100.0e-6, 3.228) / 2.228 *
180 (1.0 /
pow(energy1, 2.228) - 1.0 /
pow(energy2, 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(...)");
934 mfunname(
"double SimpleAtomPhotoAbsCS::get_threshold(int nshell) const");
936 return acs[nshell]->get_threshold();
940 mfunname(
"double SimpleAtomPhotoAbsCS::get_ACS(double energy) const");
942 for (
int n = 0; n <
qshell; ++n) {
948 double energy2)
const {
949 mfunnamep(
"double SimpleAtomPhotoAbsCS::get_integral_ACS(...) const");
951 for (
int n = 0; n <
qshell; ++n) {
953 const double t =
acs[n]->get_integral_CS(energy1, energy2);
967 mfunname(
"double SimpleAtomPhotoAbsCS::get_ACS(int nshell, double energy)");
974 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ACS(...) const");
980 mfunname(
"double SimpleAtomPhotoAbsCS::get_ICS(double energy) const");
982 for (
int n = 0; n <
qshell; ++n) {
989 double energy2)
const {
990 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ICS(...) const");
992 for (
int n = 0; n <
qshell; ++n) {
999 mfunname(
"double SimpleAtomPhotoAbsCS::get_ICS(int nshell, double energy)");
1006 mfunname(
"double SimpleAtomPhotoAbsCS::get_integral_ICS(...) const");
1013 Ifile <<
"SimpleAtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
1018 for (
int n = 0; n <
qshell; ++n) {
1019 Ifile <<
"nshell=" << n << std::endl;
1020 acs[n].print(file, l);
1029 const std::string& fthreshold_file_name,
1030 const std::string& fsimple_table_file_name,
1031 const std::string& fname,
1032 double fminimal_threshold)
1033 : threshold_file_name(fthreshold_file_name),
1034 simple_table_file_name(fsimple_table_file_name),
1035 BT_file_name(
"none"),
1036 minimal_threshold(fminimal_threshold) {
1037 mfunnamep(
"ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(...) const");
1040 if (!threshold_file) {
1045 std::vector<double> thr;
1046 std::vector<int> Zshell;
1047 std::vector<double> fl;
1048 std::vector<std::string> shell_name;
1049 bool foundZ =
false;
1050 while (
findmark(threshold_file,
"#") == 1) {
1051 threshold_file >>
Z;
1052 if (
Z != fZ)
continue;
1053 threshold_file >>
qshell;
1058 Zshell.resize(
qshell, 0);
1060 shell_name.resize(
qshell);
1063 std::string temp_name;
1064 threshold_file >> temp_name;
1065 name = fname ==
"none" ? temp_name : fname;
1067 for (
int nshell = 0; nshell <
qshell; nshell++) {
1068 threshold_file >> thr[nshell];
1070 thr[nshell] *= 1.0e-6;
1071 threshold_file >> Zshell[nshell];
1073 sZshell += Zshell[nshell];
1074 threshold_file >> fl[nshell];
1076 threshold_file >> shell_name[nshell];
1082 double st = DBL_MAX;
1083 for (
int nshell = 0; nshell <
qshell; nshell++) {
1084 if (thr[nshell] < st) {
1089 for (
int nshell = 0; nshell <
qshell; nshell++) {
1090 if (fl[nshell] <= 0)
continue;
1092 std::vector<double> felectron_energy;
1093 std::vector<double> fphoton_energy;
1094 fphoton_energy.push_back(thr[nshell] - thr[n_min]);
1095 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1102 mcerr <<
"there is no element Z=" << fZ <<
" in file "
1108 const std::vector<double>& ener = stpacs.
get_arr_ener();
1109 const std::vector<double>& CS = stpacs.
get_arr_CS();
1110 std::vector<double> left_CS = CS;
1111 const long qe = ener.size();
1113 std::vector<std::vector<double> > SCS(
qshell, std::vector<double>(qe, 0.));
1115 unsigned long nce = 0;
1118 if (ener[0] < thr[
qshell - 1]) {
1119 for (
long ne = 0; ne < qe && (ener[ne] < thr[
qshell - 1] ||
1120 (ener[ne] >= thr[
qshell - 1] && ne > 1 &&
1121 CS[ne - 1] <= CS[ne - 2]));
1123 if (ne > 0) left_CS[ne - 1] = 0.0;
1136 for (nt = nct; nt >= 0; nt--) {
1138 if (thr[nt] > ener[nce]) {
1143 if (thr[nt] > ener[nce + 1]) {
1152 int nce_next = ener.size();
1160 for (ne = nce; ne < ener.size(); ne++) {
1161 if (thr[nt] <= ener[ne]) {
1174 if (ne > 1 && ne < ener.size() - 1 && ne > nce + 2 &&
1175 thr[nt] <= ener[ne + 1] &&
1176 (thr[nt] - ener[ne]) / (ener[ne + 1] - ener[ne]) < 0.1 &&
1177 CS[ne] > CS[ne - 1]) {
1184 if (ne == ener.size())
1189 int qt = nt1 - nt2 + 1;
1194 for (nt = 0; nt < qt; nt++) {
1195 const int nshell = nct - nt;
1196 s += Zshell[nshell];
1199 std::vector<double> w(qt);
1200 for (nt = 0; nt < qt; nt++) {
1201 const int nshell = nct - nt;
1202 w[nt] = double(Zshell[nshell]) / s;
1204 double save_left_CS = left_CS[nce_next - 1];
1205 for (
long ne = 0; ne < nce_next; ne++) {
1206 for (nt = 0; nt < qt; nt++) {
1207 int nshell = nct - nt;
1208 SCS[nshell][ne] = left_CS[ne] * w[nt];
1212 for (
unsigned long ne = nce_next; ne < ener.size(); ne++) {
1214 save_left_CS *
pow(ener[nce_next - 1], 2.75) /
pow(ener[ne], 2.75);
1215 if (extrap_CS > left_CS[ne]) extrap_CS = left_CS[ne];
1216 for (nt = 0; nt < qt; nt++) {
1217 int nshell = nct - nt;
1218 SCS[nshell][ne] = extrap_CS * w[nt];
1220 left_CS[ne] -= extrap_CS;
1224 }
while (s_more != 0);
1228 for (
int ns = 0; ns < nt2; ns++) {
1232 for (
int ns = nt2; ns <
qshell; ns++) {
1234 shell_name[ns], Zshell[ns], thr[ns], ener, SCS[ns]);
1245 if (pred_integ > integ) {
1247 const double threshold =
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 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;
1341 double st = DBL_MAX;
1342 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1345 if (thresh[nshell] < st) {
1347 st = thresh[nshell];
1351 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1352 if (fl[nshell] > 0) {
1354 std::vector<double> felectron_energy;
1355 std::vector<double> fphoton_energy;
1356 fphoton_energy.push_back(thresh[nshell] - thresh[n_min]);
1357 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1371 if (pred_integ > integ) {
1373 const double thr =
acs[
qshell - 1]->get_threshold();
1388 const double fact = pred_integ / integ;
1389 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1390 acs[nshell]->scale(fact);
1398#define READ_FILE_WITH_PRINCIPAL_NUMBERS
1401 const std::string& fFitBT_file_name,
1403 int s_no_scale,
double fminimal_threshold)
1404 : threshold_file_name(
"none"),
1405 simple_table_file_name(
"none"),
1406 BT_file_name(fFitBT_file_name),
1407 minimal_threshold(fminimal_threshold) {
1409 "ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(int fZ, const std::string& fname, "
1411 "std::string& fFitBT_file_name, int id, int id1, double "
1412 "fminimal_threshold)");
1417 std::ifstream BT_file(fFitBT_file_name.c_str());
1423 std::vector<double> thresh;
1424 std::vector<double> fl;
1426 while ((i =
findmark(BT_file,
"$")) == 1) {
1429 if (iZ !=
Z)
continue;
1439 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1440#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1450 if (BT_file.eof()) {
1454 if (!BT_file.good()) {
1458#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1460 if (!BT_file.good()) {
1466 BT_file >> l >> threshold >> E0 >> sigma >> ya >> P >> yw;
1469 threshold *= 1.0e-6;
1473 "n_princ=" << n_princ <<
" l=" << l <<
'\n',
mcerr);
1477 if (BT_file.eof()) {
1481 if (!BT_file.good()) {
1488 thresh[nshell] = threshold;
1491#ifdef READ_FILE_WITH_PRINCIPAL_NUMBERS
1493 std::string shellname(
long_to_String(n_princ) +
" shell number " +
1500 threshold, l, E0, yw, ya, P, sigma));
1509 mcerr <<
"there is no element Z=" << fZ <<
" in file " << fFitBT_file_name
1516 double st = DBL_MAX;
1517 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1520 if (thresh[nshell] < st) {
1522 st = thresh[nshell];
1526 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1527 if (fl[nshell] > 0) {
1529 std::vector<double> felectron_energy;
1530 std::vector<double> fphoton_energy;
1531 fphoton_energy.push_back(thresh[nshell] - thresh[n_min]);
1532 asp[nshell].add_channel(fl[nshell], felectron_energy, fphoton_energy);
1546 if (pred_integ > integ) {
1548 const double thr =
acs[
qshell - 1]->get_threshold();
1563 const double fact = pred_integ / integ;
1564 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1565 acs[nshell]->scale(fact);
1574 int fZ,
const std::string& fname,
const std::string& fFitBT_file_name,
1575 const std::string& fsimple_table_file_name,
double emax_repl,
1577 double fminimal_threshold) {
1578 mfunname(
"ExAtomPhotoAbsCS::ExAtomPhotoAbsCS(...)");
1583 fminimal_threshold);
1588 double thrmin = DBL_MAX;
1591 for (
long ns = 0; ns <
qshell; ++ns) {
1594 thrmin =
acs[ns]->get_threshold();
1618 if (pred_integ > integ) {
1620 const double thr =
acs[
qshell - 1]->get_threshold();
1635 const double fact = pred_integ / integ;
1636 for (
int nshell = 0; nshell <
qshell; ++nshell) {
1637 acs[nshell]->scale(fact);
1646 mfunname(
"double ExAtomPhotoAbsCS::get_threshold(int nshell) const");
1648 double r =
acs[nshell]->get_threshold();
1656 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(double energy) const");
1658 for (
int n = 0; n <
qshell; ++n) {
1661 const double t =
acs[n]->get_threshold();
1665 s +=
acs[n]->get_CS(energy - shift);
1671 double energy2)
const {
1672 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ICS(double energy) const");
1674 for (
int n = 0; n <
qshell; ++n) {
1677 const double t =
acs[n]->get_threshold();
1681 s +=
acs[n]->get_integral_CS(energy1 - shift, energy2 - shift);
1687 mfunname(
"double ExAtomPhotoAbsCS::get_ICS(int nshell, double energy) const");
1691 const double t =
acs[nshell]->get_threshold();
1695 return acs[nshell]->get_CS(energy - shift);
1699 double energy2)
const {
1700 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ICS(int nshell, ...) const");
1704 const double t =
acs[nshell]->get_threshold();
1708 return acs[nshell]->get_integral_CS(energy1 - shift, energy2 - shift);
1712 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(double energy) const");
1714 for (
int n = 0; n <
qshell; ++n) {
1717 const double t =
acs[n]->get_threshold();
1721 s +=
acs[n]->get_CS(energy - shift);
1728 double energy2)
const {
1729 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ACS(...) const");
1731 for (
int n = 0; n <
qshell; ++n) {
1734 const double t =
acs[n]->get_threshold();
1738 s +=
acs[n]->get_integral_CS(energy1 - shift, energy2 - shift);
1740 double b[2] = {std::max(
exener[0], energy1), std::min(
exener[1], energy2)};
1746 mfunname(
"double ExAtomPhotoAbsCS::get_ACS(int nshell, double energy)");
1750 const double t =
acs[nshell]->get_threshold();
1754 double s =
acs[nshell]->get_CS(energy - shift);
1762 double energy2)
const {
1763 mfunname(
"double ExAtomPhotoAbsCS::get_integral_ACS(int nshell, ...) const");
1767 const double t =
acs[nshell]->get_threshold();
1771 double s =
acs[nshell]->get_integral_CS(energy1 - shift, energy2 - shift);
1772 if (nshell ==
qshell - 1) {
1773 double b[2] = {std::max(
exener[0], energy1), std::min(
exener[1], energy2)};
1781 Ifile <<
"ExAtomPhotoAbsCS(l=" << l <<
"): name=" <<
name <<
" Z = " <<
Z
1782 <<
" qshell = " <<
qshell << std::endl;
1793 <<
" exener=" <<
exener[0] <<
' ' <<
exener[1] <<
'\n';
1795 Ifile <<
"integrals by shells:\n";
1796 Ifile <<
"nshell, int(acs), int(ics)\n";
1797 for (
long n = 0; n <
qshell; n++) {
1800 Ifile << n <<
" " << ainteg <<
" " << iinteg <<
'\n';
1806 for (
long n = 0; n <
qshell; ++n) {
1807 Ifile <<
"nshell=" << n << std::endl;
1808 acs[n].print(file, l);
1818 mfunname(
"void ExAtomPhotoAbsCS::replace_shells_by_average(...)");
1819 for (
long n = 0; n <
qshell; n++) {
1829 double fW,
double fF)
1830 : qatom(fqatom), W(fW), F(fF) {
1831 qatom_ps.push_back(qatom);
1833 if (W == 0.0) W =
coef_I_to_W * atom[0]->get_I_min();
1838 double fW,
double fF)
1839 : qatom(fqatom_ps1 + fqatom_ps2), W(fW), F(fF) {
1840 qatom_ps.push_back(fqatom_ps1);
1841 qatom_ps.push_back(fqatom_ps2);
1842 atom.push_back(fatom1);
1843 atom.push_back(fatom2);
1844 if (W != 0.0)
return;
1845#ifdef CALC_W_USING_CHARGES
1846 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_Z() * atom[0]->get_I_min() +
1847 qatom_ps[1] * atom[1]->get_Z() * atom[1]->get_I_min()) /
1848 (qatom_ps[0] * atom[0]->get_Z() + qatom_ps[1] * atom[1]->get_Z());
1850 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_I_min() +
1851 qatom_ps[1] * atom[1]->get_I_min()) /
1859 double fW,
double fF)
1860 : qatom(fqatom_ps1 + fqatom_ps2 + fqatom_ps3), W(fW), F(fF) {
1861 qatom_ps.push_back(fqatom_ps1);
1862 qatom_ps.push_back(fqatom_ps2);
1863 qatom_ps.push_back(fqatom_ps3);
1864 atom.push_back(fatom1);
1865 atom.push_back(fatom2);
1866 atom.push_back(fatom3);
1867 if (W != 0.0)
return;
1868#ifdef CALC_W_USING_CHARGES
1869 W =
coef_I_to_W * (qatom_ps[0] * atom[0]->get_Z() * atom[0]->get_I_min() +
1870 qatom_ps[1] * atom[1]->get_Z() * atom[1]->get_I_min() +
1871 qatom_ps[2] * atom[2]->get_Z() * atom[2]->get_I_min()) /
1872 (qatom_ps[0] * atom[0]->get_Z() + qatom_ps[1] * atom[1]->get_Z() +
1873 qatom_ps[2] * atom[2]->get_Z());
1876 (qatom_ps[0] * atom[0]->get_I_min() + qatom_ps[1] * atom[1]->get_I_min() +
1877 qatom_ps[2] * atom[2]->get_I_min()) /
1883 mfunname(
"double MolecPhotoAbsCS::get_ACS(double energy) const");
1884 const long q = qatom_ps.size();
1886 for (
long n = 0; n < q; n++) s += qatom_ps[n] * atom[n]->
get_ACS(energy);
1891 mfunname(
"double MolecPhotoAbsCS::get_integral_ACS(double e1, double e2)");
1892 const long q = qatom_ps.size();
1894 for (
long n = 0; n < q; n++) {
1895 s += qatom_ps[n] * atom[n]->get_integral_ACS(en1, en2);
1901 mfunname(
"double MolecPhotoAbsCS::get_ICS(double energy) const");
1902 const long q = qatom_ps.size();
1904 for (
long n = 0; n < q; n++) s += qatom_ps[n] * atom[n]->
get_ICS(energy);
1909 mfunname(
"double MolecPhotoAbsCS::get_integral_ICS(double e1, double e2)");
1910 const long q = qatom_ps.size();
1912 for (
long n = 0; n < q; n++) {
1913 s += qatom_ps[n] * atom[n]->get_integral_ICS(en1, en2);
1919 mfunname(
"int MolecPhotoAbsCS::get_total_Z() const");
1920 const long q = qatom_ps.size();
1922 for (
long n = 0; n < q; n++) {
1923 s += qatom_ps[n] * atom[n]->get_Z();
1929 Ifile <<
"MolecPhotoAbsCS (l=" << l <<
"):\n";
1933 const long q = qatom_ps.size();
1934 Ifile <<
"number of sorts of atoms is " << q <<
'\n';
1936 for (
long n = 0; n < q; n++) {
1937 Ifile <<
"n=" << n <<
" qatom_ps[n]=" << qatom_ps[n] <<
" atom:\n";
1938 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)
Active pointer or automatic container or controlling pointer.
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
virtual 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.
virtual double get_CS(double energy) const
Retrieve cross-section [Mb] at a given energy [MeV].
virtual void print(std::ostream &file, int l) const
virtual double get_integral_CS(double energy1, double energy2) const
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
AveragePhotoAbsCS()
Default constructor.
virtual void scale(double fact)
Multiply by some factor. Can be useful for debugging and other purposes.
double integ_abs_before_corr
void replace_shells_by_average(double fwidth, double fstep, long fmax_q_step)
std::vector< ActivePtr< PhotoAbsCS > > acs
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.
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
virtual void print(std::ostream &file, int l) const
virtual double get_CS(double energy) const
Retrieve cross-section [Mb] at a given energy [MeV].
virtual double get_integral_CS(double energy1, double energy2) const
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
HydrogenPhotoAbsCS()
Constructor.
virtual void scale(double fact)
Multiply by some factor. Can be useful for debugging and other purposes.
virtual 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.
virtual double get_ICS(double energy) const
Photo-ionization cross-section [Mbarn] at a given energy [MeV].
virtual double get_integral_ICS(double energy1, double energy2) const
Integral photo-ionization cross-section.
MolecPhotoAbsCS()
Default constructor.
virtual double get_integral_ACS(double energy1, double energy2) const
Integral photo-absorption cross-section.
virtual void print(std::ostream &file, int l) const
Simple phenomenological CS for any shell (analytic formula).
virtual double get_integral_CS(double energy1, double energy2) const
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
virtual double get_CS(double energy) const
Retrieve cross-section [Mb] at a given energy [MeV].
virtual void print(std::ostream &file, int l) const
PhenoPhotoAbsCS()
Default constructor.
virtual void scale(double fact)
Multiply by some factor. Can be useful for debugging and other purposes.
PhotoAbsCS()
Default constructor.
double get_threshold() const
Return the threshold energy.
virtual void print(std::ostream &file, int l) const
const std::string & get_name() const
Name of this shell or atom.
SimpleAtomPhotoAbsCS()
Default constructor.
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
std::vector< ActivePtr< PhotoAbsCS > > acs
SimpleTablePhotoAbsCS()
Default constructor.
virtual double get_integral_CS(double energy1, double energy2) const
Retrieve integral cross-section [Mb * MeV] in a given interval [MeV].
void remove_leading_tiny(double level)
virtual double get_CS(double energy) const
Retrieve cross-section [Mb] at a given energy [MeV].
virtual void print(std::ostream &file, int l) const
virtual void scale(double fact)
Multiply by some factor. Can be useful for debugging and other purposes.
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)
const double low_boundary_of_excitations
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)
const double Thomas_sum_rule_const_Mb
TRK sum rule [Mb * MeV].
int findmark(std::istream &file, const char *s)
DoubleAc sqrt(const DoubleAc &f)
String long_to_String(const long n)
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)