Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
HeedDeltaElectronCS.cpp
Go to the documentation of this file.
1#include <iomanip>
7/*
82003, I. Smirnov
9*/
10
11namespace Heed {
12
14 ElElasticScat* fees,
16 PairProd* fpairprod, int fsruth,
17 double fmlambda, double fmthetac)
18 : hmd(fhmd),
19 ees(fees),
20 eesls(feesls),
21 pairprod(fpairprod),
22 mlambda(fmlambda),
23 sruth(fsruth),
24 mthetac(fmthetac) {
25 mfunname("HeedDeltaElectronCS::HeedDeltaElectronCS(...)");
26 //mcout<<"starting to inite HeedDeltaElectronCS\n";
27 long qe = hmd->energy_mesh->get_q();
28 long ne;
34 double smax = 0.0;
35 for (ne = 0; ne < qe; ne++) {
36 double ec = hmd->energy_mesh->get_ec(ne);
37 double gamma_1 = ec * MeV / electron_mass_c2;
38 beta[ne] = lorbeta(gamma_1);
39 beta2[ne] = beta[ne] * beta[ne];
40 momentum2[ne] = (pow(electron_mass_c2 + ec * MeV, 2.0) -
41 electron_mass_c2 * electron_mass_c2) / (MeV * MeV);
42 momentum[ne] = sqrt(momentum2[ne]);
43 double ZA = hmd->matter->Z_mean() / hmd->matter->A_mean();
44 double I_eff = 15.8 * eV * hmd->matter->Z_mean();
45 double dedx =
46 e_cont_enloss(ZA, I_eff, hmd->matter->density(), ec * MeV, DBL_MAX, -1);
47 if (smax < dedx) smax = dedx;
48 eLoss[ne] = dedx / (MeV / cm);
49 }
50 //smax = smax / (MeV/cm) / 2.0; // otherwise the ranges are too long
51 smax = smax / (MeV / cm);
52 double deriv_min = 0.0; // looking for minimal(maximal by value but negative)
53 // derivative
54 long n_deriv_min = 0;
55 for (ne = 1; ne < qe; ne++) {
56 double d =
57 (eLoss[ne] * beta[ne] - eLoss[ne - 1] * beta[ne - 1]) /
58 (hmd->energy_mesh->get_ec(ne) - hmd->energy_mesh->get_ec(ne - 1));
59 if (deriv_min > d) {
60 deriv_min = d;
61 n_deriv_min = ne - 1;
62 }
63 }
64 //Iprintn(mcout, n_deriv_min);
65 for (ne = 0; ne < n_deriv_min - 1; ne++) {
66 eLoss[ne] =
67 (eLoss[n_deriv_min - 1] * beta[n_deriv_min - 1] +
68 deriv_min * (hmd->energy_mesh->get_ec(ne) -
69 hmd->energy_mesh->get_ec(n_deriv_min - 1))) / beta[ne];
70 }
71
72 /*
73 for(ne=0; ne<qe; ne++)
74 {
75 if(eLoss[ne] < smax) eLoss[ne] = smax;
76 else break;
77 }
78 */
80 //low_lambda = DynLinArr< double >(qe);
85 sisfera = DynLinArr<int>(qe, 0);
87 if (sruth == 2) {
89 long n;
90 angular_mesh_c[0] = 0.0;
91 double amin = 0.3;
92 double amax = 180.0;
93 double rk = pow(amax / amin, (1.0 / double(q_angular_mesh - 2)));
94 double ar = amin;
95 angular_mesh_c[1] = ar;
96 for (n = 2; n < q_angular_mesh; n++) {
97 angular_mesh_c[n] = angular_mesh_c[n - 1] * rk;
98 }
99 angular_mesh_c[q_angular_mesh - 1] = 180.0;
100
101 //print_DynLinArr_double(mcout, angular_mesh_c);
103 //ismat = DynLinArr< DynLinArr< double > >(qe);
104 //mean_free_path = DynLinArr< double >(qe);
108#ifdef USE_MEAN_COEF
109 mean_coef_low_sigma = DynLinArr<double>(eesls->get_ees()->get_qe());
110#else
111 coef_low_sigma = DynLinArr<double>(eesls->get_ees()->get_qe());
112#endif
113 // long qat = hmd->matter->qatom();
114 // long nat;
115 for (ne = 0; ne < eesls->get_ees()->get_qe(); ne++) {
116 //double energy = eesls->ees->get_energy_mesh(ne) * 0.001;
117 long qat = hmd->matter->qatom();
118 long nat;
119 double s = 0.0;
120
121 for (nat = 0; nat < qat; nat++) {
122//s += pow( eesls->get_coef(hmd->matter->atom(nat)->Z(), ne), 2.0) *
123//hmd->matter->weight_quan(nat);
124#ifdef USE_MEAN_COEF
125 s += eesls->get_mean_coef(hmd->matter->atom(nat)->Z(), ne) *
126 hmd->matter->weight_quan(nat);
127#else
128 s += eesls->get_coef(hmd->matter->atom(nat)->Z(), ne) *
129 hmd->matter->weight_quan(nat);
130#endif
131 }
132//s = sqrt(s);
133#ifdef USE_MEAN_COEF
134 mean_coef_low_sigma[ne] = s;
135#else
136 coef_low_sigma[ne] = s;
137#endif
138 }
139 }
140 for (ne = 0; ne < qe; ne++) {
141 double rr;
142 double ek = hmd->energy_mesh->get_ec(ne) * 1000.0;
143 if (ek <= 10.0) {
144 rr = 1.0e-3 * hmd->matter->A_mean() / (g / mole) / hmd->matter->Z_mean() *
145 3.872e-3 * pow(ek, 1.492);
146 rr = rr / (hmd->matter->density() / (gram / cm3));
147 } else {
148 rr = 1.0e-3 * 6.97e-3 * pow(ek, 1.6);
149 rr = rr / (hmd->matter->density() / (gram / cm3));
150 }
151 rr = rr * 0.1;
152 //Iprintn(mcout, rr);
153 double cor = 1.0;
154 {
155 // b-k*(x-a)**2 = 0 => x= a +- sqrt(b/k)
156 // k = b / (x - a)**2
157 double a = 2.5;
158 double b = 4;
159 //k=1.0/4.0
160 double x = 0.0;
161 double k = b / ((x - a) * (x - a));
162 x = ek * 1000.0;
163 double r = b - k * (x - a) * (x - a);
164 if (r < 0.0)
165 r = 1;
166 else
167 r = r + 1;
168 cor = r;
169 }
170 if (sruth == 1) {
171 lambda[ne] = mlambda / (hmd->matter->density() / (gram / cm3));
172 if (lambda[ne] < rr) lambda[ne] = rr;
173 lambda[ne] = lambda[ne] * cor;
174 // Calculate the minimum angle for restriction of field by
175 // atomic shell
176 double mT =
177 2.0 *
178 asin(1.0 / (2.0 * momentum[ne] * hmd->matter->Z_mean() * 5.07e2));
179 rthetac[ne] = mT;
180 if (mT < mthetac) mT = mthetac; // Throw out too slow interaction. They
181 // do not influent to anything
182
183 // Calculate the cut angle due to mean free part
184 double A = hmd->Rutherford_const / cor / (momentum2[ne] * beta2[ne]) /
185 pow(5.07e10, 2.0);
186 double B = lambda[ne] * A;
187 B = sqrt(B / (B + 1.0));
188 thetac[ne] = 2.0 * asin(B);
189
190 // If it too little, reset it. It will lead to increasing
191 // of lambda and decriasing of calculation time.
192 if (thetac[ne] < mT) {
193 thetac[ne] = mT;
194 B = mT; // B is double precision
195 double r = sin(B / 2.0);
196 lambda[ne] = 1 / A * 2.0 * r * r / (1 + cos(B));
197 //r=cos(TetacBdel(nen,nm))
198 //lamBdel=A*(1.0+r)/(1.0-r)
199 //lamBdel=1.0/lamBdel
200 //lamBdel=(p2*bet2*sin(TetacBdel/2.0)**2) / A
201 }
202 B = thetac[ne];
203 CosThetac12[ne] = cos(B / 2.0);
204 SinThetac12[ne] = sin(B / 2.0);
205 if (thetac[ne] > 1.5)
206 sisfera[ne] = 1;
207 else
208 sisfera[ne] = 0;
209
210 //c debug mode:
211 //c lamaBdel(nen,nm)=2.0*lamaBdel(nen,nm)
212 } else if (sruth == 0) { // gaus formula
213
214 // calculate path length from mTetacBdel
215 double msig_loc = mthetac;
216 double x = msig_loc / (sqrt(2.0) * 13.6 / (beta[ne] * momentum[ne]));
217 x = x * x;
218
219 //x=x/DensMatDS(nMatVol(nVolBdel))
220 x = x * hmd->radiation_length * cor;
221 lambda[ne] = mlambda / (hmd->matter->density() / (gram / cm3));
222 if (lambda[ne] < rr) lambda[ne] = rr;
223 lambda[ne] = lambda[ne] * cor;
224 //c write(oo,*)' x=',x,' rleng=',rleng
225 //c reset if it is too large
226 if (lambda[ne] < x) lambda[ne] = x;
227 msig[ne] = sqrt(2.0) * 13.6 / (beta[ne] * momentum[ne]);
228
229 //c debug mode:
230 //c lamaBdel(nen,nm)=2.0*lamaBdel(nen,nm)
231 //c msigBdel(nen)=0.5*msigBdel(nen)
232 } else if (sruth == 2) {
234 //ismat[ne] = DynLinArr< double >(q_angular_mesh);
235 double energy = hmd->energy_mesh->get_ec(ne);
236 long qat = hmd->matter->qatom();
237 long nat;
238 long nan;
239 for (nan = 0; nan < q_angular_mesh; nan++) {
240 double angle = angular_mesh_c[nan] / 180.0 * M_PI;
241 double s = 0.0;
242 for (nat = 0; nat < qat; nat++) {
243 s += ees->get_CS(hmd->matter->atom(nat)->Z(), energy, angle) *
244 hmd->matter->weight_quan(nat);
245 }
246 s = s * 1.0E-16;
247 //s = s * 1.0E-16 * C1_MEV_CM * C1_MEV_CM;
248 // Angstrem**2 -> cm**2
249 // cm**2 -> MeV**-2
250 s = s * 2.0 * M_PI * sin(angle); // sr -> dtheta
251
252 smat[ne][nan] = s;
253 }
258 //lambda[ne] = angular_points_ran[ne].get_integ()/180.0 * M_PI;
259 //Iprintn(mcout, hmd->matter->density()/(gram/cm3));
260 //Iprintn(mcout, hmd->matter->A_mean()/(gram/mole));
261 lambda[ne] = 1.0 / (angular_points_ran[ne].get_integ_active() / 180.0 *
262 M_PI * AVOGADRO *
263 //(AVOGADRO/(C1_MEV_CM * C1_MEV_CM)) *
264 hmd->matter->density() / (gram / cm3) /
265 (hmd->matter->A_mean() / (gram / mole)));
266 //PointsRan low_angular_points_ran(angular_mesh_c, smat[ne],
267 // 0.0, low_cut_angle_deg);
268 low_lambda[ne] =
269 1.0 / (low_angular_points_ran[ne].get_integ_active() / 180.0 * M_PI *
270 AVOGADRO *
271 // //(AVOGADRO/(C1_MEV_CM * C1_MEV_CM)) *
272 hmd->matter->density() / (gram / cm3) /
273 (hmd->matter->A_mean() / (gram / mole)));
274 }
275
276 }
277
278 //mcout<<"finishing HeedDeltaElectronCS\n";
279
280}
281
282double HeedDeltaElectronCS::get_sigma(double energy, double nscat) const {
283 mfunname("double HeedDeltaElectronCS::get_sigma(...)");
284 check_econd11(nscat, < 0, mcerr);
285 //check_econd21(nscat , < 0 || , > eesls->get_qscat() , mcerr);
286 // ^ not compartible with Poisson
287 double energyKeV = energy * 1000.0;
288 if (energyKeV < ees->get_energy_mesh(0)) energyKeV = ees->get_energy_mesh(0);
289 if (energyKeV > ees->get_energy_mesh(ees->get_qe() - 1))
290 energyKeV = ees->get_energy_mesh(ees->get_qe() - 1);
291 long n1 = 0;
292 long n2 = ees->get_qe() - 1;
293 long n3;
294 while (n2 - n1 > 1) {
295 n3 = n1 + (n2 - n1) / 2;
296 if (energyKeV < ees->get_energy_mesh(n3))
297 n2 = n3;
298 else
299 n1 = n3;
300 }
301//Iprintn(mcout, n1);
302//Iprintn(mcout, n2);
303#ifdef USE_MEAN_COEF
304 double v1 = nscat * mean_coef_low_sigma[n1];
305 double v2 = nscat * mean_coef_low_sigma[n2];
306#else
307 double v1 = nscat * coef_low_sigma[n1];
308 double v2 = nscat * coef_low_sigma[n2];
309#endif
310 //Iprintn(mcout, v1);
311 //Iprintn(mcout, v2);
312 double r =
313 v1 + (v2 - v1) / (ees->get_energy_mesh(n2) - ees->get_energy_mesh(n1)) *
314 (energyKeV - ees->get_energy_mesh(n1));
315 return r;
316}
317
318void HeedDeltaElectronCS::print(std::ostream& file, int l) const {
319 if (l <= 0) return;
320 Ifile << "HeedDeltaElectronCS(l=" << l << "):";
321 long qe = hmd->energy_mesh->get_q();
322 //Iprintn(mcout, qe);
323 //mcout<<std::endl;
324 Iprintn(file, mlambda);
325 Iprintn(file, mthetac);
326 Iprintn(file, sruth);
327 long ne;
328 Ifile << " get_ec, beta, momentum, eLoss, lambda, "
329 " low_lambda:" << std::endl;
330 indn.n += 2;
331 for (ne = 0; ne < qe; ne++) {
332 Ifile << std::setw(3) << ne << ' ' << std::setw(12)
333 << hmd->energy_mesh->get_ec(ne) << ' ' << std::setw(12) << beta[ne]
334 << ' ' << std::setw(12) << momentum[ne] << ' ' << std::setw(12)
335 << eLoss[ne] << ' ' << std::setw(12) << lambda[ne] << ' '
336 << std::setw(12) << low_lambda[ne] << '\n';
337 }
338 indn.n -= 2;
339 Ifile << " get_ec, rthetac, thetac, sisfera, msig:"
340 << std::endl;
341 indn.n += 2;
342 for (ne = 0; ne < qe; ne++) {
343 Ifile << std::setw(3) << ne << ' ' << std::setw(12)
344 << hmd->energy_mesh->get_ec(ne) << ' ' << std::setw(12) << rthetac[ne]
345 << ' ' << std::setw(12) << thetac[ne] << ' ' << std::setw(12)
346 << sisfera[ne] << ' ' << std::setw(12) << msig[ne] << '\n';
347 }
348 indn.n -= 2;
349 Ifile << "na, angular_mesh_c:" << std::endl;
350 indn.n += 2;
351 long na;
352 for (na = 0; na < q_angular_mesh; na++) {
353 Ifile << na << ' ' << std::setw(12) << angular_mesh_c[na] << '\n';
354 }
355 indn.n -= 2;
356 Iprintn(file, eesls->get_ees()->get_qe());
357 indn.n += 2;
358#ifdef USE_MEAN_COEF
359 Ifile << "ne, energy_mesh(ne), mean_coef_low_sigma:" << std::endl;
360 for (ne = 0; ne < eesls->get_ees()->get_qe(); ne++) {
361 Ifile << std::setw(3) << ne << ' ' << std::setw(12)
362 << eesls->get_ees()->get_energy_mesh(ne) << " KeV " << std::setw(12)
363 << mean_coef_low_sigma[ne] << '\n';
364 }
365#else
366 Ifile << "ne, energy_mesh(ne), coef_low_sigma:" << std::endl;
367 for (ne = 0; ne < eesls->get_ees()->get_qe(); ne++) {
368 Ifile << std::setw(3) << ne << ' ' << std::setw(12)
369 << eesls->get_ees()->get_energy_mesh(ne) << " KeV " << std::setw(12)
370 << coef_low_sigma[ne] << '\n';
371 }
372#endif
373 indn.n -= 2;
374}
375
376std::ostream& operator<<(std::ostream& file, const HeedDeltaElectronCSType& f) {
377 mfunname("std::ostream& operator << (std::ostream& file, const "
378 "HeedDeltaElectronCSType& f)");
379 if (f.hdecs.get() == NULL) {
380 Ifile << "HeedDeltaElectronCSType: type is not initialized\n";
381 } else {
382 Ifile << "HeedDeltaElectronCSType: =";
383 f.hdecs->print(file, 1);
384 }
385 return file;
386}
387
388}
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:431
DoubleAc asin(const DoubleAc &f)
Definition: DoubleAc.cpp:468
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:336
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:313
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:383
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
#define mfunname(string)
Definition: FunNameStack.h:67
PassivePtr< HeedDeltaElectronCS > hdecs
DynLinArr< DynLinArr< double > > smat
PassivePtr< ElElasticScat > ees
DynLinArr< double > momentum
virtual void print(std::ostream &file, int l) const
DynLinArr< double > angular_mesh_c
DynLinArr< double > rthetac
double get_sigma(double energy, double nscat) const
PassivePtr< HeedMatterDef > hmd
DynLinArr< double > momentum2
DynLinArr< double > SinThetac12
DynLinArr< double > thetac
DynLinArr< double > lambda
DynLinArr< double > mean_coef_low_sigma
DynLinArr< PointsRan > angular_points_ran
DynLinArr< double > CosThetac12
PassivePtr< ElElasticScatLowSigma > eesls
DynLinArr< PointsRan > low_angular_points_ran
DynLinArr< double > low_lambda
Definition: BGMesh.cpp:3
const double low_cut_angle_deg
Definition: HeedGlobals.h:6
const long q_angular_mesh
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:22
double lorbeta(const double gamma_1)
Definition: lorgamma.cpp:22
const double AVOGADRO
double e_cont_enloss(double ratio_Z_to_A, double I_eff, double density, double Ekin, double Ecut, double z)
indentation indn
Definition: prstream.cpp:13
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
#define Iprintn(file, name)
Definition: prstream.h:216