21using CLHEP::electron_mass_c2;
22using CLHEP::fine_structure_const;
25 if (
A[0] == -1.0)
return -1.0;
27 const double ctheta =
cos(theta);
28 for (
long n = 0; n < 4; ++n) {
29 s +=
A[n] / (
pow(1.0 - ctheta + 2.0 *
B, n + 1));
31 for (
long n = 0; n < 7; ++n) {
38 mfunnamep(
"ElElasticScat::ElElasticScat(const string& filename)");
39 std::ifstream file(file_name.c_str());
42 mcerr <<
"cannot open file " << file_name << std::endl;
48 energy_mesh.resize(qe);
49 gamma_beta2.resize(qe);
50 for (
long ne = 0; ne < qe; ++ne) {
51 file >> energy_mesh[ne];
54 mcerr <<
"error at reading energy_mesh, ne=" << ne <<
'\n';
58 const double rm = 0.001 * energy_mesh[ne] / electron_mass_c2;
59 const double gamma = 1. + rm;
60 const double beta2 = (2 * rm + rm * rm) / (gamma * gamma);
61 gamma_beta2[ne] = gamma * beta2;
68 for (
int nc = 0; nc < 4; ++nc) {
69 for (
long ne = 0; ne < qe; ++ne) {
70 file >> atom.back().data[ne].A[nc];
73 mcerr <<
"error at reading A, Z=" << Z <<
" nc=" << nc <<
" ne=" << ne
79 for (
int nc = 0; nc < 7; ++nc) {
80 for (
long ne = 0; ne < qe; ++ne) {
81 file >> atom.back().data[ne].C[nc];
84 mcerr <<
"error at reading C, Z=" << Z <<
" nc=" << nc <<
" ne=" << ne
90 for (
long ne = 0; ne < qe; ++ne) {
91 file >> atom.back().data[ne].B;
94 mcerr <<
"error at reading B, Z=" << Z <<
" ne=" << ne <<
'\n';
101double ElElasticScat::get_CS_for_presented_atom(
long na,
double energy,
104 "double ElElasticScat::get_CS_for_presented_atom(long na, double "
105 "energy, double angle)");
106 const double enKeV = energy * 1000.0;
107 const double rm = energy / electron_mass_c2;
108 const double gamma = 1. + rm;
109 const double beta2 = (2. * rm + rm * rm) / (gamma * gamma);
110 const double gamma_beta2_t = gamma * beta2;
112 fine_structure_const * fine_structure_const * atom[na].Z / gamma_beta2_t;
113 if (enKeV < energy_mesh[0]) {
116 for (
long ne = 0; ne < qe; ne++) {
117 r = atom[na].data[ne].CS(angle);
121 return r * coe * coe;
123 if (enKeV >= energy_mesh[qe - 1]) {
126 for (
long ne = qe - 1; ne >= 0; ne--) {
127 r = atom[na].data[ne].CS(angle);
131 return r * coe * coe;
134 for (ne = 1; ne < qe; ne++) {
135 if (energy_mesh[ne] > enKeV)
break;
137 double cs[2] = {-1., -1.};
139 long ne_left = ne - 1;
142 for (ne = ne_left; ne >= 0; ne--) {
143 cs[0] = atom[na].data[ne].CS(angle);
144 if (cs[0] >= 0.0)
break;
146 for (ne = ne_right; ne < qe; ne++) {
147 cs[1] = atom[na].data[ne].CS(angle);
148 if (cs[1] >= 0.0)
break;
151 if (cs[0] >= 0.0 && cs[1] >= 0.0) {
152 r = cs[0] + (cs[1] - cs[0]) / (energy_mesh[ne] - energy_mesh[ne - 1]) *
153 (enKeV - energy_mesh[ne - 1]);
157 }
else if (cs[1] >= 0.0) {
161 mcerr <<
"not implemented case\n";
165 return r * coe * coe;
171 "double ElElasticScat::get_CS(long Z, double energy, double angle, "
173 const long qa = atom.size();
176 long na_right = qa - 1;
177 long Z_right = 10000;
178 for (
long na = 0; na < qa; na++) {
179 if (atom[na].Z == Z && s_interp == 0) {
180 return get_CS_for_presented_atom(na, energy, angle);
182 if (atom[na].Z > Z_left && atom[na].Z < Z) {
185 }
else if (atom[na].Z < Z_right && atom[na].Z > Z) {
186 Z_right = atom[na].Z;
192 const double f1 = get_CS_for_presented_atom(na_left, energy, angle);
193 const double f2 = get_CS_for_presented_atom(na_right, energy, angle);
194 const double z1 = atom[na_left].Z;
195 const double z2 = atom[na_right].Z;
196 const double c = (f1 * 4 - f2 * z1 * z1) / (f2 * z1 - f1 * z2);
197 const double k = f1 / (z1 * (z1 + c));
198 double r = k * Z * (Z + c);
199 if (r < 0.0) r = 0.0;
205 "double ElElasticScat::get_CS_Rutherford(long Z, double energy, "
207 const double gamma_1 = energy / electron_mass_c2;
208 const double beta2 =
lorbeta2(gamma_1);
209 const double momentum2 = energy * energy + 2.0 * electron_mass_c2 * energy;
211 double r = 0.25 * Z * Z * fine_structure_const * fine_structure_const /
212 (momentum2 * beta2 *
pow(
sin(0.5 * angle), 4)) /
213 (
pow(5.07E10, 2)) * 1.0e16;
219 Ifile <<
"ElElasticScat(l=" << l <<
"): qe=" << qe
220 <<
" atom.size()=" << atom.size() << std::endl;
223 Ifile <<
"energy_mesh=";
224 for (
long ne = 0; ne < qe; ++ne) {
225 file << std::setw(12) << energy_mesh[ne];
228 Ifile <<
"gamma_beta2=";
229 for (
long ne = 0; ne < qe; ++ne) {
230 file << std::setw(12) << gamma_beta2[ne];
234 const long qa = atom.size();
235 for (
long na = 0; na < qa; ++na) {
236 Ifile <<
"atom[na].Z=" << atom[na].Z <<
'\n';
238 for (
long ne = 0; ne < qe; ++ne) {
239 file << std::setw(12) << energy_mesh[ne];
242 for (
long n = 0; n < 4; ++n) {
243 Ifile <<
"A[" << n <<
"]";
244 for (
long ne = 0; ne < qe; ++ne) {
245 file << std::setw(12) << atom[na].data[ne].A[n];
249 for (
int n = 0; n < 7; ++n) {
250 Ifile <<
"C[" << n <<
"]";
251 for (
long ne = 0; ne < qe; ++ne) {
252 file << std::setw(12) << atom[na].data[ne].C[n];
257 for (
long ne = 0; ne < qe; ++ne) {
258 file << std::setw(12) << atom[na].data[ne].B;
265 const std::string& file_name)
267 mfunnamep(
"ElElasticScatLowSigma::ElElasticScatLowSigma(...)");
268 std::ifstream file(file_name.c_str());
271 mcerr <<
"cannot open file " << file_name << std::endl;
276 file >> qat >> qscat;
279 mean_coef.resize(qat);
281 for (
long nat = 0; nat < qat; ++nat) {
282 mean_coef[nat].resize(ees->
get_qe());
283 coef[nat].resize(ees->
get_qe());
287 for (
long ne = 0; ne < ees->
get_qe(); ++ne) {
290 mean_coef[nat][ne] = 0.0;
292 file >> fne >> e >> mean_coef[nat][ne] >> coef[nat][ne];
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
#define check_econd11(a, signb, stream)
#define check_econd11a(a, signb, add, stream)
#define mfunnamep(string)
#define check_econd12(a, sign, b, stream)
double CS(const double theta) const
Return -1 if not valid.
double A[4]
If -1.0 then the combination is not valid.
Array of ElElasticScatDataStruct objects for a set of energies.
ElElasticScatLowSigma()=default
Default constructor.
double get_CS(long Z, double energy, double angle, int s_interp=0)
double get_energy_mesh(long ne) const
ElElasticScat()=default
Default constructor.
void print(std::ostream &file, int l) const
double get_CS_Rutherford(long Z, double energy, double angle)
DoubleAc cos(const DoubleAc &f)
DoubleAc pow(const DoubleAc &f, double p)
int findmark(std::istream &file, const char *s)
double polleg(const int l, const double x)
DoubleAc sin(const DoubleAc &f)
double lorbeta2(const double gamma_1)
as function of .