16void PrintNotImplemented(
const std::string& cls,
const std::string& fcn) {
17 std::cerr << cls <<
"::" << fcn <<
": Function is not implemented.\n";
20void PrintOutOfRange(
const std::string& cls,
const std::string& fcn,
21 const size_t i,
const size_t j,
const size_t k) {
22 std::cerr << cls <<
"::" << fcn <<
": Index (" << i <<
", " << j <<
", " << k
23 <<
") out of range.\n";
26void PrintDataNotAvailable(
const std::string& cls,
const std::string& fcn) {
27 std::cerr << cls <<
"::" << fcn <<
": Data not available.\n";
30bool CheckFields(
const std::vector<double>& fields,
const std::string& hdr,
31 const std::string& lbl) {
33 std::cerr << hdr <<
": Number of " << lbl <<
" must be > 0.\n";
38 if (fields.front() < 0.) {
39 std::cerr << hdr <<
": " << lbl <<
" must be >= 0.\n";
43 const size_t nEntries = fields.size();
46 for (
size_t i = 1; i < nEntries; ++i) {
47 if (fields[i] <= fields[i - 1]) {
48 std::cerr << hdr <<
": " << lbl <<
" are not in ascending order.\n";
67 SetFieldGrid(100., 100000., 20,
true, 0., 0., 1, HalfPi, HalfPi, 1);
75 <<
" Temperature [K] must be greater than zero.\n";
85 <<
" Pressure [Torr] must be greater than zero.\n";
94 std::cerr <<
m_className <<
"::SetDielectricConstant:\n"
95 <<
" Dielectric constant must be >= 1.\n";
108 std::cerr <<
m_className <<
"::GetComponent: Index out of range.\n";
118 <<
" Atomic number must be >= 1.\n";
128 <<
" Atomic weight must be greater than zero.\n";
137 std::cerr <<
m_className <<
"::SetNumberDensity:\n"
138 <<
" Density [cm-3] must be greater than zero.\n";
148 <<
" Density [g/cm3] must be greater than zero.\n";
154 <<
" Atomic weight is not defined.\n";
197 const double bx,
const double by,
const double bz,
198 const std::vector<std::vector<std::vector<double> > >& velE,
199 const std::vector<std::vector<std::vector<double> > >& velB,
200 const std::vector<std::vector<std::vector<double> > >& velX,
201 const double q,
double& vx,
double& vy,
double& vz)
const {
205 if (velE.empty())
return false;
208 const double e = sqrt(ex * ex + ey * ey + ez * ez);
210 if (e < Small || e0 < Small)
return false;
213 const double b = sqrt(bx * bx + by * by + bz * bz);
215 const double ebang =
GetAngle(ex, ey, ez, bx, by, bz, e, b);
220 std::cerr <<
m_className <<
"::Velocity: Interpolation along E failed.\n";
225 const double mu = q * ve / e;
230 }
else if (velX.empty() || velB.empty() ||
233 Langevin(ex, ey, ez, bx, by, bz, q * ve / e, vx, vy, vz);
239 double ue[3] = {ex / e, ey / e, ez / e};
240 double uexb[3] = {ey * bz - ez * by, ez * bx - ex * bz, ex * by - ey * bx};
242 sqrt(uexb[0] * uexb[0] + uexb[1] * uexb[1] + uexb[2] * uexb[2]);
253 double ubt[3] = {uexb[1] * ez - uexb[2] * ey,
254 uexb[2] * ex - uexb[0] * ez,
255 uexb[0] * ey - uexb[1] * ex};
256 const double bt = sqrt(ubt[0] * ubt[0] + ubt[1] * ubt[1] + ubt[2] * ubt[2]);
269 std::printf(
" unit vector along E: (%15.5f, %15.5f, %15.5f)\n",
270 ue[0], ue[1], ue[2]);
271 std::printf(
" unit vector along E x B: (%15.5f, %15.5f, %15.5f)\n",
272 uexb[0], uexb[1], uexb[2]);
273 std::printf(
" unit vector along Bt: (%15.5f, %15.5f, %15.5f)\n",
274 ubt[0], ubt[1], ubt[2]);
280 std::cerr <<
m_className <<
"::Velocity: Interpolation along ExB failed.\n";
286 std::cerr <<
m_className <<
"::Velocity: Interpolation along Bt failed.\n";
289 if (ex * bx + ey * by + ez * bz > 0.) {
295 vx = q * (ve * ue[0] + vbt * ubt[0] + vexb * uexb[0]);
296 vy = q * (ve * ue[1] + vbt * ubt[1] + vexb * uexb[1]);
297 vz = q * (ve * ue[2] + vbt * ubt[2] + vexb * uexb[2]);
302 double bx,
double by,
double bz,
const double mu,
303 double& vx,
double& vy,
double& vz) {
305 bx *= Tesla2Internal;
306 by *= Tesla2Internal;
307 bz *= Tesla2Internal;
308 const double b2 = bx * bx + by * by + bz * bz;
309 const double mu2 = mu * mu;
310 const double eb = bx * ex + by * ey + bz * ez;
311 const double f = mu / (1. + mu2 * b2);
312 vx = f * (ex + mu * (ey * bz - ez * by) + mu2 * bx * eb);
313 vy = f * (ey + mu * (ez * bx - ex * bz) + mu2 * by * eb);
314 vz = f * (ez + mu * (ex * by - ey * bx) + mu2 * bz * eb);
318 double bx,
double by,
double bz,
319 const double mu,
const double muH,
320 double& vx,
double& vy,
double& vz) {
322 bx *= Tesla2Internal;
323 by *= Tesla2Internal;
324 bz *= Tesla2Internal;
325 const double b2 = bx * bx + by * by + bz * bz;
326 const double mu2 = muH * muH;
327 const double f = mu / (1. + mu2 * b2);
328 const double eb = bx * ex + by * ey + bz * ez;
329 vx = f * (ex + muH * (ey * bz - ez * by) + mu2 * bx * eb);
330 vy = f * (ey + muH * (ez * bx - ex * bz) + mu2 * by * eb);
331 vz = f * (ez + muH * (ex * by - ey * bx) + mu2 * bz * eb);
335 const double bx,
const double by,
const double bz,
336 const std::vector<std::vector<std::vector<double> > >& difL,
337 const std::vector<std::vector<std::vector<double> > >& difT,
338 double& dl,
double& dt)
const {
342 const double e = sqrt(ex * ex + ey * ey + ez * ez);
344 if (e < Small || e0 < Small)
return true;
347 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
349 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
361 if (difL.empty() || difT.empty()) {
362 const double d = sqrt(2. * BoltzmannConstant *
m_temperature / e);
363 if (difL.empty()) dl = d;
364 if (difT.empty()) dt = d;
373 const double bx,
const double by,
const double bz,
374 const std::vector<std::vector<std::vector<std::vector<double> > > >& diff,
375 double cov[3][3])
const {
378 cov[0][0] = cov[0][1] = cov[0][2] = 0.;
379 cov[1][0] = cov[1][1] = cov[1][2] = 0.;
380 cov[2][0] = cov[2][1] = cov[2][2] = 0.;
382 if (diff.empty())
return false;
385 const double e = sqrt(ex * ex + ey * ey + ez * ez);
387 if (e < Small || e0 < Small)
return true;
390 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
392 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
394 for (
int j = 0; j < 6; ++j) {
403 cov[0][1] = cov[1][0] = y;
405 cov[0][2] = cov[2][0] = y;
407 cov[1][2] = cov[2][1] = y;
414 const double bx,
const double by,
const double bz,
415 const std::vector<std::vector<std::vector<double> > >& tab,
416 unsigned int intp,
const unsigned int thr,
417 const std::pair<unsigned int, unsigned int>& extr,
418 double& alpha)
const {
421 if (tab.empty())
return false;
424 const double e = sqrt(ex * ex + ey * ey + ez * ez);
426 if (e < Small || e0 < Small)
return true;
429 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
431 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
435 if (!
Interpolate(e0, b, ebang, tab, alpha, intp, extr)) alpha = -30.;
445 const double bx,
const double by,
const double bz,
446 double& vx,
double& vy,
double& vz) {
448 return Velocity(ex, ey, ez, bx, by, bz,
m_eVelE,
m_eVelB,
m_eVelX, -1.,
453 const double ez,
const double bx,
454 const double by,
const double bz,
double& dl,
461 const double ez,
const double bx,
462 const double by,
const double bz,
469 const double bx,
const double by,
const double bz,
472 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_eAlp,
m_intpAlp,
m_eThrAlp,
m_extrAlp,
482 const double ez,
const double bx,
483 const double by,
const double bz,
double& eta) {
485 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_eAtt,
m_intpAtt,
m_eThrAtt,
m_extrAtt,
495 const double ez,
const double bx,
496 const double by,
const double bz,
499 if (
m_eLor.empty())
return false;
502 const double e = sqrt(ex * ex + ey * ey + ez * ez);
504 if (e < Small || e0 < Small)
return true;
507 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
509 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
519 if (
m_eVelE.empty())
return -1.;
524 const double pz,
double& vx,
double& vy,
525 double& vz,
const int band) {
527 std::cerr <<
m_className <<
"::GetElectronEnergy:\n";
528 std::cerr <<
" Unknown band index.\n";
531 vx = SpeedOfLight * px / ElectronMass;
532 vy = SpeedOfLight * py / ElectronMass;
533 vz = SpeedOfLight * pz / ElectronMass;
535 return 0.5 * (px * px + py * py + pz * pz) / ElectronMass;
539 double& pz,
int& band) {
540 const double p = sqrt(2. * ElectronMass * e) / SpeedOfLight;
557 double& e1,
double& dx,
double& dy,
double& dz,
558 std::vector<std::pair<Particle, double> >& ,
559 int& ndxc,
int& band) {
570 double& s,
int& type,
571 double& energy)
const {
579 const double bx,
const double by,
const double bz,
580 double& vx,
double& vy,
double& vz) {
582 return Velocity(ex, ey, ez, bx, by, bz,
m_hVelE,
m_hVelB,
m_hVelX, +1.,
587 const double bx,
const double by,
const double bz,
588 double& dl,
double& dt) {
593 const double bx,
const double by,
const double bz,
600 const double bx,
const double by,
const double bz,
603 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_hAlp,
m_intpAlp,
m_hThrAlp,
m_extrAlp,
613 const double bx,
const double by,
const double bz,
616 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_hAtt,
m_intpAtt,
m_hThrAtt,
m_extrAtt,
626 if (
m_hVelE.empty())
return -1.;
631 const double bx,
const double by,
const double bz,
632 double& vx,
double& vy,
double& vz) {
634 if (
m_iMob.empty())
return false;
636 const double e = sqrt(ex * ex + ey * ey + ez * ez);
638 if (e < Small || e0 < Small)
return true;
640 const double b = sqrt(bx * bx + by * by + bz * bz);
643 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
647 constexpr double q = 1.;
654 Langevin(ex, ey, ez, bx, by, bz, mu, vx, vy, vz);
661 const double bx,
const double by,
const double bz,
662 double& dl,
double& dt) {
668 const double bx,
const double by,
const double bz,
671 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_iDis,
m_intpDis,
m_iThrDis,
m_extrDis,
685 const double ex,
const double ey,
const double ez,
686 const double bx,
const double by,
const double bz,
687 double& vx,
double& vy,
double& vz) {
692 const double e = sqrt(ex * ex + ey * ey + ez * ez);
694 if (e < Small || e0 < Small)
return true;
696 const double b = sqrt(bx * bx + by * by + bz * bz);
699 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
706 constexpr double q = -1.;
713 Langevin(ex, ey, ez, bx, by, bz, mu, vx, vy, vz);
723 const unsigned int i) {
725 std::cerr <<
m_className <<
"::GetOpticalDataRange: Index out of range.\n";
735 const unsigned int i) {
737 std::cerr <<
m_className <<
"::GetDielectricFunction: Index out of range.\n";
742 std::cerr <<
m_className <<
"::GetDielectricFunction: Energy must be > 0.\n";
753 const unsigned int i) {
755 std::cerr <<
m_className <<
"::GetPhotoAbsorptionCrossSection:\n";
756 std::cerr <<
" Component " << i <<
" does not exist.\n";
761 std::cerr <<
m_className <<
"::GetPhotoAbsorptionCrossSection:\n";
762 std::cerr <<
" Energy must be > 0.\n";
767 PrintNotImplemented(
m_className,
"GetPhotoAbsorptionCrossSection");
781 double& e1,
double& ctheta,
int& nsec,
792 double bmin,
double bmax,
const size_t nb,
793 double amin,
double amax,
const size_t na) {
797 <<
" Number of E-fields must be > 0.\n";
801 if (emin < 0. || emax < 0.) {
803 <<
" Electric fields must be positive.\n";
808 std::cerr <<
m_className <<
"::SetFieldGrid: Swapping min./max. E-field.\n";
809 std::swap(emin, emax);
817 <<
" Min. E-field must be non-zero for log. scale.\n";
822 <<
" Number of E-fields must be > 1 for log. scale.\n";
825 estep = pow(emax / emin, 1. / (ne - 1.));
828 if (ne > 1) estep = (emax - emin) / (ne - 1.);
834 <<
" Number of B-fields must be > 0.\n";
837 if (bmax < 0. || bmin < 0.) {
839 <<
" Magnetic fields must be positive.\n";
843 std::cerr <<
m_className <<
"::SetFieldGrid: Swapping min./max. B-field.\n";
844 std::swap(bmin, bmax);
847 const double bstep = nb > 1 ? (bmax - bmin) / (nb - 1.) : 0.;
852 <<
" Number of angles must be > 0.\n";
855 if (amax < 0. || amin < 0.) {
857 <<
" Angles must be positive.\n";
861 std::cerr <<
m_className <<
"::SetFieldGrid: Swapping min./max. angle.\n";
862 std::swap(amin, amax);
864 const double astep = na > 1 ? (amax - amin) / (na - 1.) : 0;
867 std::vector<double> eFields(ne);
868 std::vector<double> bFields(nb);
869 std::vector<double> bAngles(na);
870 for (
size_t i = 0; i < ne; ++i) {
871 eFields[i] = logE ? emin * pow(estep, i) : emin + i * estep;
873 for (
size_t i = 0; i < nb; ++i) {
874 bFields[i] = bmin + i * bstep;
876 for (
size_t i = 0; i < na; ++i) {
877 bAngles[i] = amin + i * astep;
883 const std::vector<double>& bfields,
884 const std::vector<double>& angles) {
885 const std::string hdr =
m_className +
"::SetFieldGrid";
886 if (!CheckFields(efields, hdr,
"E-fields"))
return;
887 if (!CheckFields(bfields, hdr,
"B-fields"))
return;
888 if (!CheckFields(angles, hdr,
"angles"))
return;
891 std::cout <<
m_className <<
"::SetFieldGrid:\n E-fields:\n";
892 for (
const auto efield : efields) std::cout <<
" " << efield <<
"\n";
893 std::cout <<
" B-fields:\n";
894 for (
const auto bfield : bfields) std::cout <<
" " << bfield <<
"\n";
895 std::cout <<
" Angles:\n";
896 for (
const auto angle : angles) std::cout <<
" " << angle <<
"\n";
902 "electron velocity along E");
904 "electron velocity along Bt");
906 "electron velocity along ExB");
908 "electron longitudinal diffusion");
910 "electron transverse diffusion");
912 "electron Townsend coefficient");
914 "electron attachment coefficient");
916 "electron Lorentz angle");
919 "electron diffusion tensor");
924 "hole velocity along E");
926 "hole velocity along Bt");
928 "hole velocity along ExB");
930 "hole longitudinal diffusion");
932 "hole transverse diffusion");
934 "hole Townsend coefficient");
936 "hole attachment coefficient");
939 "hole diffusion tensor");
946 "ion longitudinal diffusion");
948 "ion transverse diffusion");
952 if (bfields.size() > 1 || angles.size() > 1)
m_tab2d =
true;
959 std::vector<double>& bfields,
960 std::vector<double>& angles) {
967 const std::string& fcn,
968 std::vector<std::vector<std::vector<double> > >& tab,
972 PrintOutOfRange(
m_className,
"Set" + fcn, i, j, k);
983 const std::string& fcn,
984 const std::vector<std::vector<std::vector<double> > >& tab,
988 PrintOutOfRange(
m_className,
"Get" + fcn, i, j, k);
1019 const std::vector<double>& efields,
1020 const std::vector<double>& bfields,
1021 const std::vector<double>& angles,
1022 const unsigned int intp,
1023 const std::pair<unsigned int, unsigned int>& extr,
1024 const double init,
const std::string& lbl) {
1026 std::cout <<
m_className <<
"::Clone: Copying " << lbl <<
" to new grid.\n";
1034 const auto nE = efields.size();
1035 const auto nB = bfields.size();
1036 const auto nA = angles.size();
1039 std::vector<std::vector<std::vector<double> > > tabClone;
1040 Init(nE, nB, nA, tabClone, init);
1043 for (
size_t i = 0; i < nE; ++i) {
1044 const double e = efields[i];
1045 for (
size_t j = 0; j < nB; ++j) {
1046 const double b = bfields[j];
1047 for (
size_t k = 0; k < nA; ++k) {
1048 const double a = angles[k];
1050 if (!
Interpolate(e, b, a, tab, val, intp, extr)) {
1052 <<
" Interpolation of " << lbl <<
" failed.\n"
1053 <<
" Cannot copy value to new grid at E = " << e
1054 <<
", B = " << b <<
", angle: " << a <<
"\n";
1057 tabClone[k][j][i] = val;
1066 std::vector<std::vector<std::vector<std::vector<double> > > >& tab,
1067 const size_t n,
const std::vector<double>& efields,
1068 const std::vector<double>& bfields,
const std::vector<double>& angles,
1069 const unsigned int intp,
const std::pair<unsigned int, unsigned int>& extr,
1070 const double init,
const std::string& lbl) {
1072 if (tab.empty())
return;
1075 const auto nE = efields.size();
1076 const auto nB = bfields.size();
1077 const auto nA = angles.size();
1080 std::vector<std::vector<std::vector<std::vector<double> > > > tabClone;
1081 Init(nE, nB, nA, n, tabClone, init);
1084 for (
size_t l = 0; l < n; ++l) {
1085 for (
size_t i = 0; i < nE; ++i) {
1086 const double e = efields[i];
1087 for (
size_t j = 0; j < nB; ++j) {
1088 const double b = bfields[j];
1089 for (
size_t k = 0; k < nA; ++k) {
1090 const double a = angles[k];
1092 if (!
Interpolate(e, b, a, tab[l], val, intp, extr)) {
1094 <<
" Interpolation of " << lbl <<
" failed.\n"
1095 <<
" Cannot copy value to new grid at index " << l
1096 <<
", E = " << e <<
", B = " << b <<
", angle: " << a
1100 tabClone[l][k][j][i] = val;
1110 const size_t ia,
const double mu) {
1114 PrintOutOfRange(
m_className,
"SetIonMobility", ie, ib, ia);
1120 <<
" Ion mobility table not initialised.\n";
1125 std::cerr <<
m_className <<
"::SetIonMobility: Zero value not allowed.\n";
1131 std::cout <<
m_className <<
"::SetIonMobility:\n Ion mobility at E = "
1134 <<
m_bAngles[ia] <<
" set to " << mu <<
" cm2/(V ns).\n";
1140 const std::vector<double>& mobs,
1141 const bool negativeIons) {
1142 if (efields.size() != mobs.size()) {
1144 <<
" E-field and mobility arrays have different sizes.\n";
1161 for (
size_t i = 0; i < nE; ++i) {
1171 for (
size_t i = 0; i < nA; ++i) {
1172 for (
size_t j = 0; j < nB; ++j) {
1173 for (
size_t k = 0; k < nE; ++k) {
1186 const std::string& high) {
1191 const std::string& high) {
1196 const std::string& high) {
1201 const std::string& high) {
1206 const std::string& high) {
1211 const std::string& high) {
1216 const std::string& high,
1217 std::pair<unsigned int, unsigned int>& extr,
1218 const std::string& fcn) {
1223 std::cerr <<
m_className <<
"::SetExtrapolationMethod" << fcn <<
":\n"
1224 <<
" Unknown extrapolation method (" << low <<
")\n";
1230 std::cerr <<
m_className <<
"::SetExtrapolationMethod" << fcn <<
":\n"
1231 <<
" Unknown extrapolation method (" << high <<
")\n";
1237 std::transform(str.begin(), str.end(), str.begin(), toupper);
1239 if (str ==
"CONST" || str ==
"CONSTANT") {
1241 }
else if (str ==
"LIN" || str ==
"LINEAR") {
1243 }
else if (str ==
"EXP" || str ==
"EXPONENTIAL") {
1253 const std::vector<std::vector<std::vector<double> > >& tab)
const {
1255 if (tab.empty())
return 0;
1259 for (
size_t i = 0; i < nE; ++i) {
1261 for (
size_t k = 0; k < nA; ++k) {
1262 for (
size_t j = 0; j < nB; ++j) {
1263 if (tab[k][j][i] < -20.) {
1270 if (below)
continue;
1301 const double bx,
const double by,
const double bz,
1302 const double emag,
const double bmag)
const {
1303 const double eb = emag * bmag;
1305 const double einb = fabs(ex * bx + ey * by + ez * bz);
1306 if (einb > 0.2 * eb) {
1307 double exb[3] = {ex * by - ey * bx, ex * bz - ez * bx, ez * by - ey * bz};
1309 std::min(1., sqrt(exb[0] * exb[0] + exb[1] * exb[1] + exb[2] * exb[2]) / eb));
1311 return acos(std::min(1., einb / eb));
1315 const double e,
const double b,
const double a,
1316 const std::vector<std::vector<std::vector<double> > >& table,
double& y,
1317 const unsigned int intp,
1318 const std::pair<unsigned int, unsigned int>& extr)
const {
1319 if (table.empty()) {
1335 const double e,
const std::vector<double>& table,
1336 const std::vector<double>& fields,
const unsigned int intpMeth,
1337 const std::pair<unsigned int, unsigned int>& extr)
const {
1342 const auto nSizeTable = fields.size();
1344 if (e < 0. || nSizeTable < 1)
return 0.;
1348 if (nSizeTable == 1) {
1351 }
else if (e < fields[0]) {
1353 if (fields[0] >= fields[1]) {
1356 std::cerr <<
" First two field values coincide.\n";
1357 std::cerr <<
" No extrapolation to lower fields.\n";
1360 }
else if (extr.first == 1) {
1362 const double extr4 = (table[1] - table[0]) / (fields[1] - fields[0]);
1363 const double extr3 = table[0] - extr4 * fields[0];
1364 result = extr3 + extr4 * e;
1365 }
else if (extr.first == 2) {
1367 const double extr4 = log(table[1] / table[0]) / (fields[1] - fields[0]);
1368 const double extr3 = log(table[0] - extr4 * fields[0]);
1369 result = std::exp(std::min(50., extr3 + extr4 * e));
1373 }
else if (e > fields[nSizeTable - 1]) {
1375 if (fields[nSizeTable - 1] <= fields[nSizeTable - 2]) {
1378 std::cerr <<
" Last two field values coincide.\n";
1379 std::cerr <<
" No extrapolation to higher fields.\n";
1381 result = table[nSizeTable - 1];
1382 }
else if (extr.second == 1) {
1384 const double extr2 = (table[nSizeTable - 1] - table[nSizeTable - 2]) /
1385 (fields[nSizeTable - 1] - fields[nSizeTable - 2]);
1386 const double extr1 =
1387 table[nSizeTable - 1] - extr2 * fields[nSizeTable - 1];
1388 result = extr1 + extr2 * e;
1389 }
else if (extr.second == 2) {
1391 const double extr2 = log(table[nSizeTable - 1] / table[nSizeTable - 2]) /
1392 (fields[nSizeTable - 1] - fields[nSizeTable - 2]);
1393 const double extr1 =
1394 log(table[nSizeTable - 1]) - extr2 * fields[nSizeTable - 1];
1395 result = exp(std::min(50., extr1 + extr2 * e));
1397 result = table[nSizeTable - 1];
1409 std::vector<std::vector<std::vector<double> > >& tab,
1411 if (nE == 0 || nB == 0 || nA == 0) {
1412 std::cerr <<
m_className <<
"::Init: Invalid grid.\n";
1416 nA, std::vector<std::vector<double> >(nB, std::vector<double>(nE, val)));
1420 const size_t nE,
const size_t nB,
const size_t nA,
const size_t nT,
1421 std::vector<std::vector<std::vector<std::vector<double> > > >& tab,
1423 if (nE == 0 || nB == 0 || nA == 0 || nT == 0) {
1424 std::cerr <<
m_className <<
"::Init: Invalid grid.\n";
1428 tab.assign(nT, std::vector<std::vector<std::vector<double> > >(
1429 nA, std::vector<std::vector<double> >(
1430 nB, std::vector<double>(nE, val))));
virtual double IonMobility()
Low-field ion mobility [cm2 V-1 ns-1].
void ResetHoleAttachment()
virtual void GetComponent(const unsigned int i, std::string &label, double &f)
Get the name and fraction of a given component.
bool Interpolate(const double e, const double b, const double a, const std::vector< std::vector< std::vector< double > > > &table, double &y, const unsigned int intp, const std::pair< unsigned int, unsigned int > &extr) const
virtual bool GetPhotonCollision(const double e, int &type, int &level, double &e1, double &ctheta, int &nsec, double &esec)
virtual double UnScaleElectricField(const double e) const
void ResetElectronAttachment()
virtual double GetMassDensity() const
Get the mass density [g/cm3].
std::vector< double > m_bFields
virtual void GetElectronMomentum(const double e, double &px, double &py, double &pz, int &band)
void SetTemperature(const double t)
Set the temperature [K].
void ResetElectronLorentzAngle()
virtual bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
Ionisation coefficient [cm-1].
virtual double ScaleAttachment(const double eta) const
bool GetEntry(const size_t i, const size_t j, const size_t k, const std::string &fcn, const std::vector< std::vector< std::vector< double > > > &tab, double &val) const
void SetExtrapolationMethodIonDissociation(const std::string &extrLow, const std::string &extrHigh)
void SetInterpolationMethodIonDissociation(const unsigned int intrp)
double Interpolate1D(const double e, const std::vector< double > &table, const std::vector< double > &fields, const unsigned int intpMeth, const std::pair< unsigned int, unsigned int > &extr) const
double GetAngle(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const double e, const double b) const
virtual double ScaleDiffusion(const double d) const
virtual double ElectronMobility()
Low-field mobility [cm2 V-1 ns-1].
virtual bool HoleVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
Drift velocity [cm / ns].
virtual double ScaleLorentzAngle(const double lor) const
virtual bool ElectronLorentzAngle(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &lor)
Lorentz angle.
bool Diffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< double > > > &difL, const std::vector< std::vector< std::vector< double > > > &difT, double &dl, double &dt) const
std::vector< std::vector< std::vector< double > > > m_eAlp
std::vector< std::vector< std::vector< double > > > m_hAlp
void ResetIonDissociation()
virtual bool GetDielectricFunction(const double e, double &eps1, double &eps2, const unsigned int i=0)
Get the complex dielectric function at a given energy.
virtual void SetNumberDensity(const double n)
Set the number density [cm-3].
virtual bool ElectronVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
Drift velocity [cm / ns].
virtual bool IonVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
Ion drift velocity [cm / ns].
std::pair< unsigned int, unsigned int > m_extrAtt
void SetExtrapolationMethodTownsend(const std::string &extrLow, const std::string &extrHigh)
virtual void SetAtomicNumber(const double z)
Set the effective atomic number.
std::vector< std::vector< std::vector< double > > > m_iDifT
void SetExtrapolationMethodIonMobility(const std::string &extrLow, const std::string &extrHigh)
void PlotVelocity(const std::string &carriers, TPad *pad)
Plot the drift velocity as function of the electric field.
std::pair< unsigned int, unsigned int > m_extrVel
virtual double ScaleElectricField(const double e) const
virtual double ScaleDiffusionTensor(const double d) const
std::vector< std::vector< std::vector< double > > > m_hDifL
virtual double GetElectronNullCollisionRate(const int band=0)
Null-collision rate [ns-1].
size_t SetThreshold(const std::vector< std::vector< std::vector< double > > > &tab) const
std::vector< std::vector< std::vector< double > > > m_eVelE
std::vector< std::vector< std::vector< double > > > m_eVelX
std::vector< std::vector< std::vector< double > > > m_eDifL
void Init(const size_t nE, const size_t nB, const size_t nA, std::vector< std::vector< std::vector< double > > > &tab, const double val)
virtual bool ElectronCollision(const double e, int &type, int &level, double &e1, double &dx, double &dy, double &dz, std::vector< std::pair< Particle, double > > &secondaries, int &ndxc, int &band)
Sample the collision type. Update energy and direction vector.
virtual double ScaleTownsend(const double alpha) const
virtual double GetPhotonCollisionRate(const double e)
void SetDielectricConstant(const double eps)
Set the relative static dielectric constant.
virtual bool GetDeexcitationProduct(const unsigned int i, double &t, double &s, int &type, double &energy) const
virtual double GetElectronCollisionRate(const double e, const int band=0)
Collision rate [ns-1] for given electron energy.
bool GetExtrapolationIndex(std::string str, unsigned int &nb) const
void SetInterpolationMethodVelocity(const unsigned int intrp)
Set the degree of polynomial interpolation (usually 2).
virtual bool ElectronDiffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
Longitudinal and transverse diffusion coefficients [cm1/2].
void SetInterpolationMethodDiffusion(const unsigned int intrp)
void SetExtrapolationMethodDiffusion(const std::string &extrLow, const std::string &extrHigh)
std::vector< double > m_eFields
void GetFieldGrid(std::vector< double > &efields, std::vector< double > &bfields, std::vector< double > &angles)
Get the fields and E-B angles used in the transport tables.
std::vector< std::vector< std::vector< double > > > m_hDifT
virtual bool ElectronTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
Ionisation coefficient [cm-1].
void ResetElectronDiffusion()
void SetFieldGrid(double emin, double emax, const size_t ne, bool logE, double bmin=0., double bmax=0., const size_t nb=1, double amin=HalfPi, double amax=HalfPi, const size_t na=1)
Set the range of fields to be covered by the transport tables.
virtual bool GetOpticalDataRange(double &emin, double &emax, const unsigned int i=0)
Get the energy range [eV] of the available optical data.
std::vector< std::vector< std::vector< double > > > m_eAtt
virtual void SetMassDensity(const double rho)
Set the mass density [g/cm3].
void PlotAlphaEta(const std::string &carriers, TPad *pad)
Plot Townsend and attachment coefficients.
virtual double ScaleDissociation(const double diss) const
bool Alpha(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< double > > > &tab, unsigned int intp, const unsigned int thr, const std::pair< unsigned int, unsigned int > &extr, double &alpha) const
std::vector< double > m_bAngles
std::vector< std::vector< std::vector< double > > > m_iDifL
std::vector< std::vector< std::vector< double > > > m_hVelE
std::vector< std::vector< std::vector< double > > > m_eLor
std::vector< std::vector< std::vector< double > > > m_eDifT
virtual double GetElectronEnergy(const double px, const double py, const double pz, double &vx, double &vy, double &vz, const int band=0)
Dispersion relation (energy vs. wave vector)
void SetInterpolationMethodIonMobility(const unsigned int intrp)
void SetExtrapolationMethodVelocity(const std::string &extrLow, const std::string &extrHigh)
virtual bool ElectronAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
Attachment coefficient [cm-1].
virtual double HoleMobility()
Low-field mobility [cm2 V-1 ns-1].
virtual double NegativeIonMobility()
Low-field negative ion mobility [cm2 V-1 ns-1].
std::pair< unsigned int, unsigned int > m_extrDis
void PlotDiffusion(const std::string &carriers, TPad *pad)
Plot the diffusion coefficients as function of the electric field.
std::vector< std::vector< std::vector< double > > > m_hAtt
void SetPressure(const double p)
void SetExtrapolationMethod(const std::string &low, const std::string &high, std::pair< unsigned int, unsigned int > &extr, const std::string &fcn)
virtual bool NegativeIonVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
Negative ion drift velocity [cm / ns].
std::pair< unsigned int, unsigned int > m_extrAlp
std::vector< std::vector< std::vector< double > > > m_eVelB
void PlotAttachment(const std::string &carriers, TPad *pad)
Plot the attachment coefficient(s) as function of the electric field.
virtual void SetAtomicWeight(const double a)
Set the effective atomic weight.
bool SetIonMobility(const std::vector< double > &fields, const std::vector< double > &mobilities, const bool negativeIons=false)
void SetExtrapolationMethodAttachment(const std::string &extrLow, const std::string &extrHigh)
void ResetNegativeIonMobility()
std::pair< unsigned int, unsigned int > m_extrLor
unsigned int m_nComponents
std::pair< unsigned int, unsigned int > m_extrDif
void SetInterpolationMethodAttachment(const unsigned int intrp)
virtual bool HoleDiffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
Longitudinal and transverse diffusion coefficients [cm1/2].
virtual bool IonDissociation(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &diss)
Dissociation coefficient.
virtual void ResetTables()
Reset all tables of transport parameters.
std::vector< std::vector< std::vector< double > > > m_hVelX
virtual ~Medium()
Destructor.
std::pair< unsigned int, unsigned int > m_extrMob
void Clone(std::vector< std::vector< std::vector< double > > > &tab, const std::vector< double > &efields, const std::vector< double > &bfields, const std::vector< double > &angles, const unsigned int intp, const std::pair< unsigned int, unsigned int > &extr, const double init, const std::string &label)
void ResetHoleDiffusion()
std::vector< std::vector< std::vector< std::vector< double > > > > m_eDifM
std::vector< std::vector< std::vector< double > > > m_hVelB
bool Velocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< double > > > &velE, const std::vector< std::vector< std::vector< double > > > &velB, const std::vector< std::vector< std::vector< double > > > &velX, const double q, double &vx, double &vy, double &vz) const
std::vector< std::vector< std::vector< std::vector< double > > > > m_hDifM
std::vector< std::vector< std::vector< double > > > m_iMob
bool SetEntry(const size_t i, const size_t j, const size_t k, const std::string &fcn, std::vector< std::vector< std::vector< double > > > &tab, const double val)
void ResetElectronTownsend()
void PlotTownsend(const std::string &carriers, TPad *pad)
Plot the Townsend coefficient(s) as function of the electric field.
virtual bool HoleAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
Attachment coefficient [cm-1].
void ResetElectronVelocity()
void SetInterpolationMethodTownsend(const unsigned int intrp)
virtual bool GetPhotoAbsorptionCrossSection(const double e, double &sigma, const unsigned int i=0)
virtual bool IonDiffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
Longitudinal and transverse diffusion coefficients [cm1/2].
std::vector< std::vector< std::vector< double > > > m_iDis
static void Langevin(const double ex, const double ey, const double ez, double bx, double by, double bz, const double mu, double &vx, double &vy, double &vz)
std::vector< std::vector< std::vector< double > > > m_nMob
void SetCanvas(TPad *pad)
Set the canvas to be painted on.
Plot transport coefficients as function of electric and magnetic field.
void PlotAttachment(const std::string &carriers, const char xaxis)
Plot the attachment coefficient.
void SetMedium(Medium *m)
Set the medium from which to retrieve the transport coefficients.
void PlotAlphaEta(const std::string &carriers, const char xaxis)
Plot Townsend and attachment coefficients.
void PlotTownsend(const std::string &carriers, const char xaxis)
Plot the Townsend coefficient.
void PlotDiffusion(const std::string &carriers, const char xaxis)
Plot the transverse and longitudinal diffusion coefficients.
void PlotVelocity(const std::string &carriers, const char xaxis)
bool Boxin3(const std::vector< std::vector< std::vector< double > > > &value, const std::vector< double > &xAxis, const std::vector< double > &yAxis, const std::vector< double > &zAxis, const int nx, const int ny, const int nz, const double xx, const double yy, const double zz, double &f, const int iOrder)
double Divdif(const std::vector< double > &f, const std::vector< double > &a, int nn, double x, int mm)
void RndmDirection(double &dx, double &dy, double &dz, const double length=1.)
Draw a random (isotropic) direction vector.