26 m_eTrapDensity(1.e13),
27 m_hTrapDensity(1.e13),
31 m_hasUserMobility(false),
32 m_hasUserSaturationVelocity(false),
33 m_opticalDataFile(
"OpticalData_CdTe.txt") {
53 std::string& label,
double& f) {
62 std::cerr <<
m_className <<
"::GetComponent:\n Index out of range.\n";
69 std::cerr <<
m_className <<
"::SetTrapCrossSection:\n"
70 <<
" Capture cross-section [cm2] must positive.\n";
76 std::cerr <<
m_className <<
"::SetTrapCrossSection:\n"
77 <<
" Capture cross-section [cm2] must be positive.n";
90 <<
" Trap density [cm-3] must be greater than zero.\n";
104 <<
" Trapping time [ns-1] must be greater than zero.\n";
111 <<
" Trapping time [ns-1] must be greater than zero.\n";
121 const double ez,
const double bx,
122 const double by,
const double bz,
double& vx,
123 double& vy,
double& vz) {
131 const double mu = -m_eMobility;
132 const double b2 = bx * bx + by * by + bz * bz;
139 const double muH = m_eHallFactor * mu;
140 const double muH2 = muH * muH;
141 const double eb = bx * ex + by * ey + bz * ez;
142 const double nom = 1. + muH2 * b2;
144 vx = mu * (ex + muH * (ey * bz - ez * by) + muH2 * bx * eb) / nom;
145 vy = mu * (ey + muH * (ez * bx - ex * bz) + muH2 * by * eb) / nom;
146 vz = mu * (ez + muH * (ex * by - ey * bx) + muH2 * bz * eb) / nom;
152 const double ez,
const double bx,
153 const double by,
const double bz,
165 const double ez,
const double bx,
166 const double by,
const double bz,
175 switch (m_trappingModel) {
177 eta = m_eTrapCs * m_eTrapDensity;
182 eta = m_eTrapTime * sqrt(vx * vx + vy * vy + vz * vz);
183 if (eta > 0.) eta = 1. / eta;
186 std::cerr <<
m_className <<
"::ElectronAttachment:\n"
187 <<
" Unknown model activated. Program bug!\n";
196 const double bx,
const double by,
const double bz,
197 double& vx,
double& vy,
double& vz) {
205 const double mu = m_hMobility;
206 const double b2 = bx * bx + by * by + bz * bz;
213 const double muH = m_hHallFactor * mu;
214 const double muH2 = muH * muH;
215 const double eb = bx * ex + by * ey + bz * ez;
216 const double nom = 1. + muH2 * b2;
218 vx = mu * (ex + muH * (ey * bz - ez * by) + muH2 * bx * eb) / nom;
219 vy = mu * (ey + muH * (ez * bx - ex * bz) + muH2 * by * eb) / nom;
220 vz = mu * (ez + muH * (ex * by - ey * bx) + muH2 * bz * eb) / nom;
226 const double bx,
const double by,
const double bz,
238 const double ez,
const double bx,
239 const double by,
const double bz,
double& eta) {
246 switch (m_trappingModel) {
248 eta = m_hTrapCs * m_hTrapDensity;
253 eta = m_hTrapTime * sqrt(vx * vx + vy * vy + vz * vz);
254 if (eta > 0.) eta = 1. / eta;
258 <<
" Unknown model activated. Program bug!\n";
267 if (mue <= 0. || muh <= 0.) {
268 std::cerr <<
m_className <<
"::SetLowFieldMobility:\n"
269 <<
" Mobility must be greater than zero.\n";
275 m_hasUserMobility =
true;
281 if (vsate <= 0. || vsath <= 0.) {
282 std::cout <<
m_className <<
"::SetSaturationVelocity:\n"
283 <<
" Restoring default values.\n";
284 m_hasUserSaturationVelocity =
false;
288 m_hasUserSaturationVelocity =
true;
294 const unsigned int i) {
297 std::cerr <<
m_className <<
"::GetOpticalDataRange:\n"
298 <<
" Medium has only one component.\n";
302 if (m_opticalDataTable.empty()) {
303 if (!LoadOpticalData(m_opticalDataFile)) {
304 std::cerr <<
m_className <<
"::GetOpticalDataRange:\n"
305 <<
" Optical data table could not be loaded.\n";
310 emin = m_opticalDataTable[0].energy;
311 emax = m_opticalDataTable.back().energy;
313 std::cout <<
m_className <<
"::GetOpticalDataRange:\n "
314 << emin <<
" < E [eV] < " << emax <<
"\n";
320 double& eps2,
const unsigned int i) {
323 std::cerr <<
m_className <<
"::GetDielectricFunction:\n"
324 <<
" Medium has only one component.\n";
329 if (m_opticalDataTable.empty()) {
330 if (!LoadOpticalData(m_opticalDataFile)) {
331 std::cerr <<
m_className <<
"::GetDielectricFunction:\n"
332 <<
" Optical data table could not be loaded.\n";
338 const double emin = m_opticalDataTable[0].energy;
339 const double emax = m_opticalDataTable.back().energy;
340 if (e < emin || e > emax) {
341 std::cerr <<
m_className <<
"::GetDielectricFunction:\n"
342 <<
" Requested energy (" << e <<
" eV)"
343 <<
" is outside the range of the optical data table.\n"
344 <<
" " << emin <<
" < E [eV] < " << emax <<
"\n";
351 int iUp = m_opticalDataTable.size() - 1;
353 while (iUp - iLo > 1) {
354 iM = (iUp + iLo) >> 1;
355 if (e >= m_opticalDataTable[iM].energy) {
365 const double logX0 = log(m_opticalDataTable[iLo].energy);
366 const double logX1 = log(m_opticalDataTable[iUp].energy);
367 const double logX = log(e);
368 if (m_opticalDataTable[iLo].eps1 <= 0. ||
369 m_opticalDataTable[iUp].eps1 <= 0.) {
370 eps1 = m_opticalDataTable[iLo].eps1 +
371 (e - m_opticalDataTable[iLo].energy) *
372 (m_opticalDataTable[iUp].eps1 - m_opticalDataTable[iLo].eps1) /
373 (m_opticalDataTable[iUp].energy - m_opticalDataTable[iLo].energy);
375 const double logY0 = log(m_opticalDataTable[iLo].eps1);
376 const double logY1 = log(m_opticalDataTable[iUp].eps1);
377 eps1 = logY0 + (logX - logX0) * (logY1 - logY0) / (logX1 - logX0);
383 const double logY0 = log(m_opticalDataTable[iLo].eps2);
384 const double logY1 = log(m_opticalDataTable[iUp].eps2);
385 eps2 = logY0 + (log(e) - logX0) * (logY1 - logY0) / (logX1 - logX0);
390bool MediumCdTe::LoadOpticalData(
const std::string& filename) {
393 char* pPath = getenv(
"GARFIELD_HOME");
396 <<
" Environment variable GARFIELD_HOME is not set.\n";
399 const std::string filepath = std::string(pPath) +
"/Data/" + filename;
402 std::ifstream infile;
403 infile.open(filepath.c_str(), std::ios::in);
407 <<
" Error opening file " << filename <<
".\n";
412 m_opticalDataTable.clear();
414 double lastEnergy = -1.;
415 double energy, eps1, eps2, loss;
419 std::istringstream dataStream;
421 while (!infile.eof()) {
424 std::getline(infile, line);
426 line.erase(line.begin(),
427 std::find_if(line.begin(), line.end(),
428 not1(std::ptr_fun<int, int>(isspace))));
430 if (line[0] ==
'#' || line[0] ==
'*' || (line[0] ==
'/' && line[1] ==
'/'))
433 dataStream.str(line);
434 dataStream >> energy >> eps1 >> eps2 >> loss;
435 if (dataStream.eof())
break;
438 std::cerr <<
m_className <<
"::LoadOpticalData:\n Error reading file "
439 << filename <<
" (line " << i <<
").\n";
448 if (energy <= lastEnergy) {
449 std::cerr <<
m_className <<
"::LoadOpticalData:\n Table is not in "
450 <<
"monotonically increasing order (line " << i <<
").\n "
451 << lastEnergy <<
" " << energy <<
" "
452 << eps1 <<
" " << eps2 <<
"\n";
457 std::cerr <<
m_className <<
"::LoadOpticalData:\n Negative value "
458 <<
"of the loss function (line " << i <<
").\n";
462 if (energy <= 0.)
continue;
464 data.energy = energy;
467 m_opticalDataTable.push_back(data);
471 const int nEntries = m_opticalDataTable.size();
473 std::cerr <<
m_className <<
"::LoadOpticalData:\n Importing data from "
474 << filepath <<
"failed.\n No valid data found.\n";
479 std::cout <<
m_className <<
"::LoadOpticalData:\n Read " << nEntries
480 <<
" values from file " << filepath <<
"\n";
void SetTrapDensity(const double n)
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)
bool ElectronAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
bool GetOpticalDataRange(double &emin, double &emax, const unsigned int i=0)
bool ElectronTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
void SetSaturationVelocity(const double vsate, const double vsath)
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)
void GetComponent(const unsigned int i, std::string &label, double &f)
void SetTrapCrossSection(const double ecs, const double hcs)
bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
bool GetDielectricFunction(const double e, double &eps1, double &eps2, const unsigned int i=0)
bool HoleAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
void SetLowFieldMobility(const double mue, const double muh)
void SetTrappingTime(const double etau, const double htau)
Abstract base class for media.
void SetTemperature(const double t)
virtual bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
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)
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)
virtual void SetAtomicNumber(const double z)
void SetDielectricConstant(const double eps)
virtual void EnableDrift()
virtual bool ElectronTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
virtual void SetMassDensity(const double rho)
virtual bool ElectronAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
virtual void EnablePrimaryIonisation()
virtual void SetAtomicWeight(const double a)
bool m_hasElectronVelocityE
std::vector< std::vector< std::vector< double > > > tabElectronTownsend
bool m_hasElectronAttachment
virtual bool HoleAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)