28 m_hasUserMobility(false),
29 m_hasOpticalData(false),
30 opticalDataFile(
"OpticalData_GaAs.txt") {
63 std::cerr <<
m_className <<
"::SetTrapCrossSection:\n";
64 std::cerr <<
" Capture cross-section [cm2] must positive.\n";
70 std::cerr <<
m_className <<
"::SetTrapCrossSection:\n";
71 std::cerr <<
" Capture cross-section [cm2] must be positive.n";
84 std::cerr <<
" Trap density [cm-3] must be greater than zero.\n";
98 std::cerr <<
" Trapping time [ns-1] must be positive.\n";
104 std::cerr <<
m_className <<
"::SetTrappingTime:\n";
105 std::cerr <<
" Trapping time [ns-1] must be positive.\n";
115 const double ez,
const double bx,
116 const double by,
const double bz,
double& vx,
117 double& vy,
double& vz) {
125 double mu = eMobility;
127 const double b =
sqrt(bx * bx + by * by + bz * bz);
134 const double muH = eHallFactor * mu;
135 const double eb = bx * ex + by * ey + bz * ez;
136 const double nom = 1. +
pow(muH * b, 2);
138 vx = mu * (ex + muH * (ey * bz - ez * by) + muH * muH * bx * eb) / nom;
139 vy = mu * (ey + muH * (ez * bx - ex * bz) + muH * muH * by * eb) / nom;
140 vz = mu * (ez + muH * (ex * by - ey * bx) + muH * muH * bz * eb) / nom;
146 const double ez,
const double bx,
147 const double by,
const double bz,
159 const double ez,
const double bx,
160 const double by,
const double bz,
169 switch (trappingModel) {
171 eta = eTrapCs * eTrapDensity;
176 eta = eTrapTime *
sqrt(vx * vx + vy * vy + vz * vz);
177 if (eta > 0.) eta = 1. / eta;
180 std::cerr <<
m_className <<
"::ElectronAttachment:\n";
181 std::cerr <<
" Unknown model activated. Program bug!\n";
190 const double bx,
const double by,
const double bz,
191 double& vx,
double& vy,
double& vz) {
199 double mu = hMobility;
200 const double b =
sqrt(bx * bx + by * by + bz * bz);
207 const double muH = hHallFactor * mu;
208 const double eb = bx * ex + by * ey + bz * ez;
209 const double nom = 1. +
pow(muH * b, 2);
211 vx = mu * (ex + muH * (ey * bz - ez * by) + muH * muH * bx * eb) / nom;
212 vy = mu * (ey + muH * (ez * bx - ex * bz) + muH * muH * by * eb) / nom;
213 vz = mu * (ez + muH * (ex * by - ey * bx) + muH * muH * bz * eb) / nom;
219 const double bx,
const double by,
const double bz,
231 const double ez,
const double bx,
232 const double by,
const double bz,
double& eta) {
239 switch (trappingModel) {
241 eta = hTrapCs * hTrapDensity;
246 eta = hTrapTime *
sqrt(vx * vx + vy * vy + vz * vz);
247 if (eta > 0.) eta = 1. / eta;
251 std::cerr <<
" Unknown model activated. Program bug!\n";
260 if (mue <= 0. || muh <= 0.) {
261 std::cerr <<
m_className <<
"::SetLowFieldMobility:\n";
262 std::cerr <<
" Mobility must be greater than zero.\n";
268 m_hasUserMobility =
true;
273 const unsigned int& i) {
276 std::cerr <<
m_className <<
"::GetOpticalDataRange:\n";
277 std::cerr <<
" Medium has only one component.\n";
281 if (!m_hasOpticalData) {
282 if (!LoadOpticalData(opticalDataFile)) {
283 std::cerr <<
m_className <<
"::GetOpticalDataRange:\n";
284 std::cerr <<
" Optical data table could not be loaded.\n";
287 m_hasOpticalData =
true;
290 emin = opticalDataTable[0].energy;
291 emax = opticalDataTable.back().energy;
293 std::cout <<
m_className <<
"::GetOpticalDataRange:\n";
294 std::cout <<
" " << emin <<
" < E [eV] < " << emax <<
"\n";
300 double& eps2,
const unsigned int& i) {
303 std::cerr <<
m_className <<
"::GetDielectricFunction:\n";
304 std::cerr <<
" Medium has only one component.\n";
309 if (!m_hasOpticalData) {
310 if (!LoadOpticalData(opticalDataFile)) {
311 std::cerr <<
m_className <<
"::GetDielectricFunction:\n";
312 std::cerr <<
" Optical data table could not be loaded.\n";
315 m_hasOpticalData =
true;
319 const double emin = opticalDataTable[0].energy;
320 const double emax = opticalDataTable.back().energy;
321 if (e < emin || e > emax) {
322 std::cerr <<
m_className <<
"::GetDielectricFunction:\n";
323 std::cerr <<
" Requested energy (" << e <<
" eV) "
324 <<
" is outside the range of the optical data table.\n";
325 std::cerr <<
" " << emin <<
" < E [eV] < " << emax <<
"\n";
332 int iUp = opticalDataTable.size() - 1;
334 while (iUp - iLow > 1) {
335 iM = (iUp + iLow) >> 1;
336 if (e >= opticalDataTable[iM].energy) {
346 const double logX0 = log(opticalDataTable[iLow].energy);
347 const double logX1 = log(opticalDataTable[iUp].energy);
348 const double logX = log(e);
349 if (opticalDataTable[iLow].eps1 <= 0. || opticalDataTable[iUp].eps1 <= 0.) {
350 eps1 = opticalDataTable[iLow].eps1 +
351 (e - opticalDataTable[iLow].energy) *
352 (opticalDataTable[iUp].eps1 - opticalDataTable[iLow].eps1) /
353 (opticalDataTable[iUp].energy - opticalDataTable[iLow].energy);
355 const double logY0 = log(opticalDataTable[iLow].eps1);
356 const double logY1 = log(opticalDataTable[iUp].eps1);
357 eps1 = logY0 + (logX - logX0) * (logY1 - logY0) / (logX1 - logX0);
363 const double logY0 = log(opticalDataTable[iLow].eps2);
364 const double logY1 = log(opticalDataTable[iUp].eps2);
365 eps2 = logY0 + (log(e) - logX0) * (logY1 - logY0) / (logX1 - logX0);
370bool MediumGaAs::LoadOpticalData(
const std::string filename) {
373 char* pPath = getenv(
"GARFIELD_HOME");
375 std::cerr <<
m_className <<
"::LoadOpticalData:\n";
376 std::cerr <<
" Environment variable GARFIELD_HOME is not set.\n";
379 std::string filepath = pPath;
380 filepath = filepath +
"/Data/" + filename;
383 std::ifstream infile;
384 infile.open(filepath.c_str(), std::ios::in);
387 std::cerr <<
m_className <<
"::LoadOpticalData:\n";
388 std::cerr <<
" Error opening file " << filename <<
".\n";
393 opticalDataTable.clear();
395 double lastEnergy = -1.;
396 double energy, eps1, eps2, loss;
400 std::istringstream dataStream;
402 while (!infile.eof()) {
405 std::getline(infile, line);
407 line.erase(line.begin(),
408 std::find_if(line.begin(), line.end(),
409 not1(std::ptr_fun<int, int>(isspace))));
411 if (line[0] ==
'#' || line[0] ==
'*' || (line[0] ==
'/' && line[1] ==
'/'))
414 dataStream.str(line);
415 dataStream >> energy >> eps1 >> eps2 >> loss;
416 if (dataStream.eof())
break;
419 std::cerr <<
m_className <<
"::LoadOpticalData:\n";
420 std::cerr <<
" Error reading file " << filename <<
" (line " << i
430 if (energy <= lastEnergy) {
431 std::cerr <<
m_className <<
"::LoadOpticalData:\n";
432 std::cerr <<
" Table is not in monotonically "
433 <<
"increasing order (line " << i <<
").\n";
434 std::cerr <<
" " << lastEnergy <<
" " << energy <<
" " << eps1
435 <<
" " << eps2 <<
"\n";
440 std::cerr <<
m_className <<
"::LoadOpticalData:\n";
441 std::cerr <<
" Negative value of the loss function "
442 <<
"(line " << i <<
").\n";
446 if (energy <= 0.)
continue;
448 data.energy = energy;
451 opticalDataTable.push_back(data);
455 const int nEntries = opticalDataTable.size();
457 std::cerr <<
m_className <<
"::LoadOpticalData:\n";
458 std::cerr <<
" Import of data from file " << filepath <<
"failed.\n";
459 std::cerr <<
" No valid data found.\n";
464 std::cout <<
m_className <<
"::LoadOpticalData:\n";
465 std::cout <<
" Read " << nEntries <<
" values from file " << filepath
DoubleAc pow(const DoubleAc &f, double p)
DoubleAc sqrt(const DoubleAc &f)
DoubleAc exp(const DoubleAc &f)
bool ElectronAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
void SetTrapCrossSection(const double ecs, const double hcs)
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 SetTrapDensity(const double n)
bool GetDielectricFunction(const double &e, double &eps1, double &eps2, const unsigned int &i=0)
void SetTrappingTime(const double etau, const double htau)
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)
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 HoleAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
void SetLowFieldMobility(const double mue, const double muh)
virtual void SetAtomicWeight(const double &a)
virtual void SetMassDensity(const double &rho)
virtual bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
bool m_hasElectronTownsend
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 void SetAtomicNumber(const double &z)
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 EnableDrift()
void SetTemperature(const double &t)
void SetDielectricConstant(const double &eps)
virtual bool ElectronTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
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()
bool m_hasElectronVelocityE
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)