14void PrintNotImplemented(
const std::string& cls,
const std::string& fcn) {
15 std::cerr << cls <<
"::" << fcn <<
": Function is not implemented.\n";
18void PrintOutOfRange(
const std::string& cls,
const std::string& fcn,
19 const unsigned int i,
const unsigned int j,
20 const unsigned int k) {
21 std::cerr << cls <<
"::" << fcn <<
": Index (" << i <<
", " << j <<
", " << k
22 <<
") out of range.\n";
25void PrintDataNotAvailable(
const std::string& cls,
const std::string& fcn) {
26 std::cerr << cls <<
"::" << fcn <<
": Data not available.\n";
29bool CheckFields(
const std::vector<double>& fields,
const std::string& hdr,
30 const std::string& lbl) {
32 std::cerr << hdr <<
": Number of " << lbl <<
" must be > 0.\n";
37 if (fields.front() < 0.) {
38 std::cerr << hdr <<
": " << lbl <<
" must be >= 0.\n";
42 const size_t nEntries = fields.size();
45 for (
size_t i = 1; i < nEntries; ++i) {
46 if (fields[i] <= fields[i - 1]) {
47 std::cerr << hdr <<
": " << lbl <<
" are not in ascending order.\n";
66 SetFieldGrid(100., 100000., 20,
true, 0., 0., 1, HalfPi, HalfPi, 1);
74 <<
" Temperature [K] must be greater than zero.\n";
84 <<
" Pressure [Torr] must be greater than zero.\n";
93 std::cerr <<
m_className <<
"::SetDielectricConstant:\n"
94 <<
" Dielectric constant must be >= 1.\n";
107 std::cerr <<
m_className <<
"::GetComponent: Index out of range.\n";
117 <<
" Atomic number must be >= 1.\n";
127 <<
" Atomic weight must be greater than zero.\n";
136 std::cerr <<
m_className <<
"::SetNumberDensity:\n"
137 <<
" Density [cm-3] must be greater than zero.\n";
147 <<
" Density [g/cm3] must be greater than zero.\n";
153 <<
" Atomic weight is not defined.\n";
161 const double bx,
const double by,
const double bz,
162 const std::vector<std::vector<std::vector<double> > >& velE,
163 const std::vector<std::vector<std::vector<double> > >& velB,
164 const std::vector<std::vector<std::vector<double> > >& velX,
165 const double q,
double& vx,
double& vy,
double& vz)
const {
169 if (velE.empty())
return false;
172 const double e = sqrt(ex * ex + ey * ey + ez * ez);
174 if (e < Small || e0 < Small)
return false;
177 const double b = sqrt(bx * bx + by * by + bz * bz);
179 const double ebang =
GetAngle(ex, ey, ez, bx, by, bz, e, b);
184 std::cerr <<
m_className <<
"::Velocity: Interpolation along E failed.\n";
189 const double mu = q * ve / e;
194 }
else if (velX.empty() || velB.empty()) {
196 const double mu = q * ve / e;
197 const double mu2 = mu * mu;
198 const double eb = bx * ex + by * ey + bz * ez;
199 const double f = mu / (1. + mu2 * b * b);
200 vx = f * (ex + mu * (ey * bz - ez * by) + mu2 * bx * eb);
201 vy = f * (ey + mu * (ez * bx - ex * bz) + mu2 * by * eb);
202 vz = f * (ez + mu * (ex * by - ey * bx) + mu2 * bz * eb);
208 double ue[3] = {ex / e, ey / e, ez / e};
209 double uexb[3] = {ey * bz - ez * by, ez * bx - ex * bz, ex * by - ey * bx};
211 sqrt(uexb[0] * uexb[0] + uexb[1] * uexb[1] + uexb[2] * uexb[2]);
222 double ubt[3] = {uexb[1] * ez - uexb[2] * ey, uexb[2] * ex - uexb[0] * ez,
223 uexb[0] * ey - uexb[1] * ex};
224 const double bt = sqrt(ubt[0] * ubt[0] + ubt[1] * ubt[1] + ubt[2] * ubt[2]);
236 std::cout << std::setprecision(5);
238 <<
" unit vector along E: (" << ue[0] <<
", " << ue[1]
239 <<
", " << ue[2] <<
")\n";
240 std::cout <<
" unit vector along E x B: (" << uexb[0] <<
", "
241 << uexb[1] <<
", " << uexb[2] <<
")\n";
242 std::cout <<
" unit vector along Bt: (" << ubt[0] <<
", " << ubt[1]
243 <<
", " << ubt[2] <<
")\n";
249 std::cerr <<
m_className <<
"::Velocity: Interpolation along ExB failed.\n";
254 std::cerr <<
m_className <<
"::Velocity: Interpolation along Bt failed.\n";
257 if (ex * bx + ey * by + ez * bz > 0.) {
262 vx = q * (ve * ue[0] + q * q * vbt * ubt[0] + q * vexb * uexb[0]);
263 vy = q * (ve * ue[1] + q * q * vbt * ubt[1] + q * vexb * uexb[1]);
264 vz = q * (ve * ue[2] + q * q * vbt * ubt[2] + q * vexb * uexb[2]);
270 const double bx,
const double by,
const double bz,
271 const std::vector<std::vector<std::vector<double> > >& difL,
272 const std::vector<std::vector<std::vector<double> > >& difT,
273 double& dl,
double& dt)
const {
277 const double e = sqrt(ex * ex + ey * ey + ez * ez);
279 if (e < Small || e0 < Small)
return true;
282 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
284 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
296 if (difL.empty() || difT.empty()) {
297 const double d = sqrt(2. * BoltzmannConstant *
m_temperature / e);
298 if (difL.empty()) dl = d;
299 if (difT.empty()) dt = d;
308 const double bx,
const double by,
const double bz,
309 const std::vector<std::vector<std::vector<std::vector<double> > > >& diff,
310 double cov[3][3])
const {
313 cov[0][0] = cov[0][1] = cov[0][2] = 0.;
314 cov[1][0] = cov[1][1] = cov[1][2] = 0.;
315 cov[2][0] = cov[2][1] = cov[2][2] = 0.;
317 if (diff.empty())
return false;
320 const double e = sqrt(ex * ex + ey * ey + ez * ez);
322 if (e < Small || e0 < Small)
return true;
325 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
327 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
329 for (
int j = 0; j < 6; ++j) {
338 cov[0][1] = cov[1][0] = y;
340 cov[0][2] = cov[2][0] = y;
342 cov[1][2] = cov[2][1] = y;
349 const double bx,
const double by,
const double bz,
350 const std::vector<std::vector<std::vector<double> > >& tab,
351 unsigned int intp,
const unsigned int thr,
352 const std::pair<unsigned int, unsigned int>& extr,
353 double& alpha)
const {
356 if (tab.empty())
return false;
359 const double e = sqrt(ex * ex + ey * ey + ez * ez);
361 if (e < Small || e0 < Small)
return true;
364 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
366 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
370 if (!
Interpolate(e0, b, ebang, tab, alpha, intp, extr)) alpha = -30.;
380 const double bx,
const double by,
const double bz,
381 double& vx,
double& vy,
double& vz) {
383 return Velocity(ex, ey, ez, bx, by, bz,
m_eVelE,
m_eVelB,
m_eVelX, -1.,
388 const double ez,
const double bx,
389 const double by,
const double bz,
double& dl,
396 const double ez,
const double bx,
397 const double by,
const double bz,
404 const double bx,
const double by,
const double bz,
407 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_eAlp,
m_intpAlp,
m_eThrAlp,
m_extrAlp,
417 const double ez,
const double bx,
418 const double by,
const double bz,
double& eta) {
420 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_eAtt,
m_intpAtt,
m_eThrAtt,
m_extrAtt,
430 const double ez,
const double bx,
431 const double by,
const double bz,
434 if (
m_eLor.empty())
return false;
437 const double e = sqrt(ex * ex + ey * ey + ez * ez);
439 if (e < Small || e0 < Small)
return true;
442 const double b =
m_tab2d ? sqrt(bx * bx + by * by + bz * bz) : 0.;
444 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
454 if (
m_eVelE.empty())
return -1.;
459 const double pz,
double& vx,
double& vy,
460 double& vz,
const int band) {
462 std::cerr <<
m_className <<
"::GetElectronEnergy:\n";
463 std::cerr <<
" Unknown band index.\n";
466 vx = SpeedOfLight * px / ElectronMass;
467 vy = SpeedOfLight * py / ElectronMass;
468 vz = SpeedOfLight * pz / ElectronMass;
470 return 0.5 * (px * px + py * py + pz * pz) / ElectronMass;
474 double& pz,
int& band) {
475 const double p = sqrt(2. * ElectronMass * e) / SpeedOfLight;
492 const double e,
int& type,
int& level,
double& e1,
double& dx,
double& dy,
493 double& dz, std::vector<std::pair<int, double> >& ,
494 int& ndxc,
int& band) {
505 double& s,
int& type,
506 double& energy)
const {
514 const double bx,
const double by,
const double bz,
515 double& vx,
double& vy,
double& vz) {
517 return Velocity(ex, ey, ez, bx, by, bz,
m_hVelE,
m_hVelB,
m_hVelX, +1.,
522 const double bx,
const double by,
const double bz,
523 double& dl,
double& dt) {
528 const double bx,
const double by,
const double bz,
535 const double bx,
const double by,
const double bz,
538 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_hAlp,
m_intpAlp,
m_hThrAlp,
m_extrAlp,
548 const double bx,
const double by,
const double bz,
551 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_hAtt,
m_intpAtt,
m_hThrAtt,
m_extrAtt,
561 if (
m_hVelE.empty())
return -1.;
566 const double bx,
const double by,
const double bz,
567 double& vx,
double& vy,
double& vz) {
569 if (
m_iMob.empty())
return false;
571 const double e = sqrt(ex * ex + ey * ey + ez * ez);
573 if (e < Small || e0 < Small)
return true;
575 const double b = sqrt(bx * bx + by * by + bz * bz);
578 const double ebang =
m_tab2d ?
GetAngle(ex, ey, ez, bx, by, bz, e, b) : 0.;
582 constexpr double q = 1.;
589 const double eb = bx * ex + by * ey + bz * ez;
590 const double mu2 = mu * mu;
591 const double f = mu / (1. + mu2 * b * b);
592 vx = f * (ex + mu * (ey * bz - ez * by) + mu2 * bx * eb);
593 vy = f * (ey + mu * (ez * bx - ex * bz) + mu2 * by * eb);
594 vz = f * (ez + mu * (ex * by - ey * bx) + mu2 * bz * eb);
601 const double bx,
const double by,
const double bz,
602 double& dl,
double& dt) {
608 const double bx,
const double by,
const double bz,
611 if (!
Alpha(ex, ey, ez, bx, by, bz,
m_iDis,
m_intpDis,
m_iThrDis,
m_extrDis,
625 const unsigned int i) {
627 std::cerr <<
m_className <<
"::GetOpticalDataRange: Index out of range.\n";
637 const unsigned int i) {
639 std::cerr <<
m_className <<
"::GetDielectricFunction: Index out of range.\n";
644 std::cerr <<
m_className <<
"::GetDielectricFunction: Energy must be > 0.\n";
655 const unsigned int i) {
657 std::cerr <<
m_className <<
"::GetPhotoAbsorptionCrossSection:\n";
658 std::cerr <<
" Component " << i <<
" does not exist.\n";
663 std::cerr <<
m_className <<
"::GetPhotoAbsorptionCrossSection:\n";
664 std::cerr <<
" Energy must be > 0.\n";
669 PrintNotImplemented(
m_className,
"GetPhotoAbsorptionCrossSection");
683 double& e1,
double& ctheta,
int& nsec,
694 double bmin,
double bmax,
const size_t nb,
695 double amin,
double amax,
const size_t na) {
699 <<
" Number of E-fields must be > 0.\n";
703 if (emin < 0. || emax < 0.) {
705 <<
" Electric fields must be positive.\n";
710 std::cerr <<
m_className <<
"::SetFieldGrid: Swapping min./max. E-field.\n";
711 std::swap(emin, emax);
719 <<
" Min. E-field must be non-zero for log. scale.\n";
724 <<
" Number of E-fields must be > 1 for log. scale.\n";
727 estep = pow(emax / emin, 1. / (ne - 1.));
730 if (ne > 1) estep = (emax - emin) / (ne - 1.);
736 <<
" Number of B-fields must be > 0.\n";
739 if (bmax < 0. || bmin < 0.) {
741 <<
" Magnetic fields must be positive.\n";
745 std::cerr <<
m_className <<
"::SetFieldGrid: Swapping min./max. B-field.\n";
746 std::swap(bmin, bmax);
749 const double bstep = nb > 1 ? (bmax - bmin) / (nb - 1.) : 0.;
754 <<
" Number of angles must be > 0.\n";
757 if (amax < 0. || amin < 0.) {
759 <<
" Angles must be positive.\n";
763 std::cerr <<
m_className <<
"::SetFieldGrid: Swapping min./max. angle.\n";
764 std::swap(amin, amax);
766 const double astep = na > 1 ? (amax - amin) / (na - 1.) : 0;
769 std::vector<double> eFieldsNew(ne);
770 std::vector<double> bFieldsNew(nb);
771 std::vector<double> bAnglesNew(na);
772 for (
size_t i = 0; i < ne; ++i) {
773 eFieldsNew[i] = logE ? emin * pow(estep, i) : emin + i * estep;
775 for (
size_t i = 0; i < nb; ++i) {
776 bFieldsNew[i] = bmin + i * bstep;
778 if (na == 1 && nb == 1 && fabs(bmin) < 1.e-4) {
779 bAnglesNew[0] = HalfPi;
781 for (
size_t i = 0; i < na; ++i) {
782 bAnglesNew[i] = amin + i * astep;
789 const std::vector<double>& bfields,
790 const std::vector<double>& angles) {
791 const std::string hdr =
m_className +
"::SetFieldGrid";
792 if (!CheckFields(efields, hdr,
"E-fields"))
return;
793 if (!CheckFields(bfields, hdr,
"B-fields"))
return;
794 if (!CheckFields(angles, hdr,
"angles"))
return;
797 std::cout <<
m_className <<
"::SetFieldGrid:\n E-fields:\n";
798 for (
const auto efield : efields) std::cout <<
" " << efield <<
"\n";
799 std::cout <<
" B-fields:\n";
800 for (
const auto bfield : bfields) std::cout <<
" " << bfield <<
"\n";
801 std::cout <<
" Angles:\n";
802 for (
const auto angle : angles) std::cout <<
" " << angle <<
"\n";
808 "electron velocity along E");
810 "electron velocity along Bt");
812 "electron velocity along ExB");
814 "electron longitudinal diffusion");
816 "electron transverse diffusion");
818 "electron Townsend coefficient");
820 "electron attachment coefficient");
822 "electron Lorentz angle");
825 "electron diffusion tensor");
830 "hole velocity along E");
832 "hole velocity along Bt");
834 "hole velocity along ExB");
836 "hole longitudinal diffusion");
838 "hole transverse diffusion");
840 "hole Townsend coefficient");
842 "hole attachment coefficient");
845 "hole diffusion tensor");
852 "ion longitudinal diffusion");
854 "ion transverse diffusion");
858 if (bfields.size() > 1 || angles.size() > 1)
m_tab2d =
true;
865 std::vector<double>& bfields,
866 std::vector<double>& angles) {
873 const unsigned int k,
const std::string& fcn,
874 std::vector<std::vector<std::vector<double> > >& tab,
889 const unsigned int k,
const std::string& fcn,
890 const std::vector<std::vector<std::vector<double> > >& tab,
923 const std::vector<double>& efields,
924 const std::vector<double>& bfields,
925 const std::vector<double>& angles,
926 const unsigned int intp,
927 const std::pair<unsigned int, unsigned int>& extr,
928 const double init,
const std::string& lbl) {
930 std::cout <<
m_className <<
"::Clone: Copying " << lbl <<
" to new grid.\n";
938 const auto nE = efields.size();
939 const auto nB = bfields.size();
940 const auto nA = angles.size();
943 std::vector<std::vector<std::vector<double> > > tabClone;
944 Init(nE, nB, nA, tabClone, init);
947 for (
size_t i = 0; i < nE; ++i) {
948 const double e = efields[i];
949 for (
size_t j = 0; j < nB; ++j) {
950 const double b = bfields[j];
951 for (
size_t k = 0; k < nA; ++k) {
952 const double a = angles[k];
956 <<
" Interpolation of " << lbl <<
" failed.\n"
957 <<
" Cannot copy value to new grid at E = " << e
958 <<
", B = " << b <<
", angle: " << a <<
"\n";
961 tabClone[k][j][i] = val;
971 std::vector<std::vector<std::vector<std::vector<double> > > >& tab,
972 const unsigned int n,
const std::vector<double>& efields,
973 const std::vector<double>& bfields,
const std::vector<double>& angles,
974 const unsigned int intp,
const std::pair<unsigned int, unsigned int>& extr,
975 const double init,
const std::string& lbl) {
977 if (tab.empty())
return;
980 const unsigned int nE = efields.size();
981 const unsigned int nB = bfields.size();
982 const unsigned int nA = angles.size();
985 std::vector<std::vector<std::vector<std::vector<double> > > > tabClone;
986 Init(nE, nB, nA, n, tabClone, init);
989 for (
unsigned int l = 0; l < n; ++l) {
990 for (
unsigned int i = 0; i < nE; ++i) {
991 const double e = efields[i];
992 for (
unsigned int j = 0; j < nB; ++j) {
993 const double b = bfields[j];
994 for (
unsigned int k = 0; k < nA; ++k) {
995 const double a = angles[k];
997 if (!
Interpolate(e, b, a, tab[l], val, intp, extr)) {
999 <<
" Interpolation of " << lbl <<
" failed.\n"
1000 <<
" Cannot copy value to new grid at index " << l
1001 <<
", E = " << e <<
", B = " << b <<
", angle: " << a
1005 tabClone[l][k][j][i] = val;
1015 const unsigned int ia,
const double mu) {
1019 PrintOutOfRange(
m_className,
"SetIonMobility", ie, ib, ia);
1025 <<
" Ion mobility table not initialised.\n";
1030 std::cerr <<
m_className <<
"::SetIonMobility: Zero value not allowed.\n";
1036 std::cout <<
m_className <<
"::SetIonMobility:\n Ion mobility at E = "
1039 <<
m_bAngles[ia] <<
" set to " << mu <<
" cm2/(V ns).\n";
1045 const std::vector<double>& mobs) {
1046 const int ne = efields.size();
1047 const int nm = mobs.size();
1050 <<
" E-field and mobility arrays have different sizes.\n";
1055 const unsigned int nEfields =
m_eFields.size();
1056 const unsigned int nBfields =
m_bFields.size();
1057 const unsigned int nAngles =
m_bAngles.size();
1058 Init(nEfields, nBfields, nAngles,
m_iMob, 0.);
1059 for (
unsigned int i = 0; i < nEfields; ++i) {
1066 for (
unsigned int i = 0; i < nAngles; ++i) {
1067 for (
unsigned int j = 0; j < nBfields; ++j) {
1068 for (
unsigned int k = 0; k < nEfields; ++k) {
1078 const std::string& high) {
1083 const std::string& high) {
1088 const std::string& high) {
1093 const std::string& high) {
1098 const std::string& high) {
1103 const std::string& high) {
1108 const std::string& high,
1109 std::pair<unsigned int, unsigned int>& extr,
1110 const std::string& fcn) {
1115 std::cerr <<
m_className <<
"::SetExtrapolationMethod" << fcn <<
":\n"
1116 <<
" Unknown extrapolation method (" << low <<
")\n";
1122 std::cerr <<
m_className <<
"::SetExtrapolationMethod" << fcn <<
":\n"
1123 <<
" Unknown extrapolation method (" << high <<
")\n";
1129 for (
unsigned int i = 0; i < str.length(); ++i) {
1130 str[i] = toupper(str[i]);
1133 if (str ==
"CONST" || str ==
"CONSTANT") {
1135 }
else if (str ==
"LIN" || str ==
"LINEAR") {
1137 }
else if (str ==
"EXP" || str ==
"EXPONENTIAL") {
1147 const std::vector<std::vector<std::vector<double> > >& tab)
const {
1149 if (tab.empty())
return 0;
1150 const unsigned int nE =
m_eFields.size();
1151 const unsigned int nB =
m_bFields.size();
1152 const unsigned int nA =
m_bAngles.size();
1153 for (
unsigned int i = 0; i < nE; ++i) {
1155 for (
unsigned int k = 0; k < nA; ++k) {
1156 for (
unsigned int j = 0; j < nB; ++j) {
1157 if (tab[k][j][i] < -20.) {
1164 if (below)
continue;
1195 const double bx,
const double by,
const double bz,
1196 const double e,
const double b)
const {
1197 const double eb = e * b;
1199 const double einb = fabs(ex * bx + ey * by + ez * bz);
1200 if (einb > 0.2 * eb) {
1201 const double ebxy = ex * by - ey * bx;
1202 const double ebxz = ex * bz - ez * bx;
1203 const double ebzy = ez * by - ey * bz;
1205 std::min(1., sqrt(ebxy * ebxy + ebxz * ebxz + ebzy * ebzy) / eb));
1207 return acos(std::min(1., einb / eb));
1211 const double e,
const double b,
const double a,
1212 const std::vector<std::vector<std::vector<double> > >& table,
double& y,
1213 const unsigned int intp,
1214 const std::pair<unsigned int, unsigned int>& extr)
const {
1215 if (table.empty()) {
1231 const double e,
const std::vector<double>& table,
1232 const std::vector<double>& fields,
const unsigned int intpMeth,
1233 const std::pair<unsigned int, unsigned int>& extr)
const {
1238 const int nSizeTable = fields.size();
1240 if (e < 0. || nSizeTable < 1)
return 0.;
1244 if (nSizeTable == 1) {
1247 }
else if (e < fields[0]) {
1249 if (fields[0] >= fields[1]) {
1252 std::cerr <<
" First two field values coincide.\n";
1253 std::cerr <<
" No extrapolation to lower fields.\n";
1256 }
else if (extr.first == 1) {
1258 const double extr4 = (table[1] - table[0]) / (fields[1] - fields[0]);
1259 const double extr3 = table[0] - extr4 * fields[0];
1260 result = extr3 + extr4 * e;
1261 }
else if (extr.first == 2) {
1263 const double extr4 = log(table[1] / table[0]) / (fields[1] - fields[0]);
1264 const double extr3 = log(table[0] - extr4 * fields[0]);
1265 result = std::exp(std::min(50., extr3 + extr4 * e));
1269 }
else if (e > fields[nSizeTable - 1]) {
1271 if (fields[nSizeTable - 1] <= fields[nSizeTable - 2]) {
1274 std::cerr <<
" Last two field values coincide.\n";
1275 std::cerr <<
" No extrapolation to higher fields.\n";
1277 result = table[nSizeTable - 1];
1278 }
else if (extr.second == 1) {
1280 const double extr2 = (table[nSizeTable - 1] - table[nSizeTable - 2]) /
1281 (fields[nSizeTable - 1] - fields[nSizeTable - 2]);
1282 const double extr1 =
1283 table[nSizeTable - 1] - extr2 * fields[nSizeTable - 1];
1284 result = extr1 + extr2 * e;
1285 }
else if (extr.second == 2) {
1287 const double extr2 = log(table[nSizeTable - 1] / table[nSizeTable - 2]) /
1288 (fields[nSizeTable - 1] - fields[nSizeTable - 2]);
1289 const double extr1 =
1290 log(table[nSizeTable - 1]) - extr2 * fields[nSizeTable - 1];
1291 result = exp(std::min(50., extr1 + extr2 * e));
1293 result = table[nSizeTable - 1];
1305 std::vector<std::vector<std::vector<double> > >& tab,
1307 if (nE == 0 || nB == 0 || nA == 0) {
1308 std::cerr <<
m_className <<
"::Init: Invalid grid.\n";
1312 nA, std::vector<std::vector<double> >(nB, std::vector<double>(nE, val)));
1316 const size_t nE,
const size_t nB,
const size_t nA,
const size_t nT,
1317 std::vector<std::vector<std::vector<std::vector<double> > > >& tab,
1319 if (nE == 0 || nB == 0 || nA == 0 || nT == 0) {
1320 std::cerr <<
m_className <<
"::Init: Invalid grid.\n";
1324 tab.assign(nT, std::vector<std::vector<std::vector<double> > >(
1325 nA, std::vector<std::vector<double> >(
1326 nB, std::vector<double>(nE, val))));
virtual double IonMobility()
Low-field 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
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].
unsigned int SetThreshold(const std::vector< std::vector< std::vector< double > > > &tab) const
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)
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.
virtual bool GetElectronCollision(const double e, int &type, int &level, double &e1, double &dx, double &dy, double &dz, std::vector< std::pair< int, double > > &secondaries, int &ndxc, int &band)
Sample the collision type. Update energy and direction vector.
std::vector< std::vector< std::vector< double > > > m_iDifT
bool GetEntry(const unsigned int i, const unsigned int j, const unsigned int k, const std::string &fcn, const std::vector< std::vector< std::vector< double > > > &tab, double &val) const
void SetExtrapolationMethodIonMobility(const std::string &extrLow, const std::string &extrHigh)
std::pair< unsigned int, unsigned int > m_extrVel
virtual double ScaleElectricField(const double e) const
bool SetEntry(const unsigned int i, const unsigned int j, const unsigned int k, const std::string &fcn, std::vector< std::vector< std::vector< double > > > &tab, const double val)
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].
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 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].
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].
std::pair< unsigned int, unsigned int > m_extrDis
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)
std::pair< unsigned int, unsigned int > m_extrAlp
std::vector< std::vector< std::vector< double > > > m_eVelB
virtual void SetAtomicWeight(const double a)
Set the effective atomic weight.
void SetExtrapolationMethodAttachment(const std::string &extrLow, const std::string &extrHigh)
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
void ResetElectronTownsend()
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
bool SetIonMobility(const std::vector< double > &fields, const std::vector< double > &mobilities)
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.