Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
MediumGaN.cc
Go to the documentation of this file.
1#include <algorithm>
2#include <cmath>
3#include <fstream>
4#include <iostream>
5#include <sstream>
6
10#include "Garfield/Random.hh"
11
12namespace Garfield {
13
15 m_className = "MediumGaN";
16 m_name = "GaN";
17
18 // J. Wang et al.,
19 // Review of using gallium nitride for ionizing radiation detection,
20 // Appl. Phys. Rev. 2 (2015),
21 // http://dx.doi.org/10.1063/1.4929913
22
23 SetTemperature(300.);
26 SetAtomicWeight(41.865);
27 SetMassDensity(6.15);
28
31 m_microscopic = false;
32
33 m_w = 8.9;
34 m_fano = 0.1;
35}
36
37void MediumGaN::GetComponent(const unsigned int i, std::string& label,
38 double& f) {
39 if (i == 0) {
40 label = "Ga";
41 f = 0.5;
42 } else if (i == 1) {
43 label = "N";
44 f = 0.5;
45 }
46}
47
48bool MediumGaN::ElectronVelocity(const double ex, const double ey,
49 const double ez, const double bx,
50 const double by, const double bz, double& vx,
51 double& vy, double& vz) {
52 vx = vy = vz = 0.;
53 if (m_isChanged) {
54 UpdateTransportParameters();
55 m_isChanged = false;
56 }
57 if (!m_eVelE.empty()) {
58 // Interpolation in user table.
59 return Medium::ElectronVelocity(ex, ey, ez, bx, by, bz, vx, vy, vz);
60 }
61 // Calculate the mobility.
62 const double emag = sqrt(ex * ex + ey * ey + ez * ez);
63 constexpr double vsat = 1.27e-2;
64 constexpr double ec = 172.e3;
65 const double e0 = emag / ec;
66 const double e1 = pow(e0, 4.19);
67 const double den = 1. + e1 + 3.24 * pow(e0, 0.885);
68 const double mu = -(m_eMobility + vsat * e1 / emag) / den;
69 const double b2 = bx * bx + by * by + bz * bz;
70 if (b2 < Small) {
71 vx = mu * ex;
72 vy = mu * ey;
73 vz = mu * ez;
74 } else {
75 // Hall mobility
76 const double muH = m_eHallFactor * mu;
77 const double mu2 = muH * muH;
78 const double eb = bx * ex + by * ey + bz * ez;
79 const double f = muH / (1. + mu2 * b2);
80 // Compute the drift velocity using the Langevin equation.
81 vx = f * (ex + muH * (ey * bz - ez * by) + mu2 * bx * eb);
82 vy = f * (ey + muH * (ez * bx - ex * bz) + mu2 * by * eb);
83 vz = f * (ez + muH * (ex * by - ey * bx) + mu2 * bz * eb);
84 }
85 return true;
86}
87
88bool MediumGaN::ElectronTownsend(const double ex, const double ey,
89 const double ez, const double bx,
90 const double by, const double bz,
91 double& alpha) {
92 alpha = 0.;
93 if (m_isChanged) {
94 UpdateTransportParameters();
95 m_isChanged = false;
96 }
97 if (!m_eAlp.empty()) {
98 // Interpolation in user table.
99 return Medium::ElectronTownsend(ex, ey, ez, bx, by, bz, alpha);
100 }
101 const double emag = sqrt(ex * ex + ey * ey + ez * ez);
102 if (emag > Small) {
103 alpha = m_eImpactA * exp(-m_eImpactB / emag);
104 }
105 return true;
106}
107
108bool MediumGaN::ElectronAttachment(const double ex, const double ey,
109 const double ez, const double bx,
110 const double by, const double bz,
111 double& eta) {
112 eta = 0.;
113 if (!m_eAtt.empty()) {
114 // Interpolation in user table.
115 return Medium::ElectronAttachment(ex, ey, ez, bx, by, bz, eta);
116 }
117 return true;
118}
119
120bool MediumGaN::HoleVelocity(const double ex, const double ey, const double ez,
121 const double bx, const double by, const double bz,
122 double& vx, double& vy, double& vz) {
123 vx = vy = vz = 0.;
124 if (m_isChanged) {
125 UpdateTransportParameters();
126 m_isChanged = false;
127 }
128 if (!m_hVelE.empty()) {
129 // Interpolation in user table.
130 return Medium::HoleVelocity(ex, ey, ez, bx, by, bz, vx, vy, vz);
131 }
132 // Calculate the mobility.
133 const double emag = sqrt(ex * ex + ey * ey + ez * ez);
134 // Values for saturation velocity and exponent from Sentaurus Synopsys.
135 constexpr double vsat = 7.e-3;
136 constexpr double beta = 0.725;
137 constexpr double invbeta = 1. / beta;
138 const double r = m_hMobility * emag / vsat;
139 const double mu = m_hMobility / pow(1. + pow(r, beta), invbeta);
140 const double b2 = bx * bx + by * by + bz * bz;
141 if (b2 < Small) {
142 vx = mu * ex;
143 vy = mu * ey;
144 vz = mu * ez;
145 } else {
146 // Hall mobility
147 const double muH = m_hHallFactor * mu;
148 const double mu2 = muH * muH;
149 const double eb = bx * ex + by * ey + bz * ez;
150 const double f = mu / (1. + mu2 * b2);
151 // Compute the drift velocity using the Langevin equation.
152 vx = f * (ex + muH * (ey * bz - ez * by) + mu2 * bx * eb);
153 vy = f * (ey + muH * (ez * bx - ex * bz) + mu2 * by * eb);
154 vz = f * (ez + muH * (ex * by - ey * bx) + mu2 * bz * eb);
155 }
156 return true;
157}
158
159bool MediumGaN::HoleTownsend(const double ex, const double ey, const double ez,
160 const double bx, const double by, const double bz,
161 double& alpha) {
162 alpha = 0.;
163 if (m_isChanged) {
164 UpdateTransportParameters();
165 m_isChanged = false;
166 }
167 if (!m_hAlp.empty()) {
168 // Interpolation in user table.
169 return Medium::HoleTownsend(ex, ey, ez, bx, by, bz, alpha);
170 }
171 const double emag = sqrt(ex * ex + ey * ey + ez * ez);
172 if (emag > Small) {
173 alpha = m_hImpactA * exp(-m_hImpactB / emag);
174 }
175 return true;
176}
177
178bool MediumGaN::HoleAttachment(const double ex, const double ey,
179 const double ez, const double bx,
180 const double by, const double bz, double& eta) {
181 eta = 0.;
182 if (!m_hAtt.empty()) {
183 // Interpolation in user table.
184 return Medium::HoleAttachment(ex, ey, ez, bx, by, bz, eta);
185 }
186 return true;
187}
188
190
191 if (c < 0.) {
192 std::cerr << m_className << "::SetElectronConcentration:\n"
193 << " Concentration cannot be negative.\n";
194 return;
195 }
196 m_eDensity = c;
197}
198
199void MediumGaN::SetLowFieldMobility(const double mue, const double muh) {
200
201 if (mue <= 0. || muh <= 0.) {
202 std::cerr << m_className << "::SetLowFieldMobility:\n"
203 << " Mobility must be greater than zero.\n";
204 return;
205 }
206 m_eMobility = mue;
207 m_hMobility = muh;
208 m_userMobility = true;
209 m_isChanged = true;
210}
211
213 m_userMobility = false;
214 m_isChanged = true;
215}
216
217void MediumGaN::UpdateTransportParameters() {
218
219 if (m_userMobility) return;
220 const double t = m_temperature / 300.;
221
222 // Electron low field mobility.
223 // - F. Schwierz, Solid-State Electronics 49 (2005), 889
224 // https://doi.org/10.1016/j.sse.2005.03.006
225 const double eMuMin = 0.080e-6 * pow(t, -0.2);
226 const double eMuMax = 1.405e-6 * pow(t, -2.85);
227 const double cRef = 7.78e16 * pow(t, 1.3);
228 const double alpha = 0.71 * pow(t, 0.31);
229 const double den = 1. + pow(m_eDensity / cRef, alpha);
230 m_eMobility = eMuMin + (eMuMax - eMuMin) / den;
231 // Low-field mobility for holes (using only the lattice mobility).
232 // - T. TMnatsakanov et al., Solid-State Electronics 47 (2003), 111
233 // https://doi.org/10.1016/S0038-1101(02)00256-3
234 m_hMobility = 0.170e-6 * pow(t, -5.);
235
236}
237}
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) override
Drift velocity [cm / ns].
Definition: MediumGaN.cc:120
void GetComponent(const unsigned int i, std::string &label, double &f) override
Get the name and fraction of a given component.
Definition: MediumGaN.cc:37
void SetElectronConcentration(const double c)
Set the electron concentration [cm-3].
Definition: MediumGaN.cc:189
void SetLowFieldMobility(const double mue, const double muh)
Set the low-field mobility values [cm2 / (V ns)] explicitly.
Definition: MediumGaN.cc:199
bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha) override
Ionisation coefficient [cm-1].
Definition: MediumGaN.cc:159
bool ElectronTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha) override
Ionisation coefficient [cm-1].
Definition: MediumGaN.cc:88
bool HoleAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta) override
Attachment coefficient [cm-1].
Definition: MediumGaN.cc:178
MediumGaN()
Constructor.
Definition: MediumGaN.cc:14
void UnsetLowFieldMobility()
Use the default mobility models.
Definition: MediumGaN.cc:212
bool ElectronAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta) override
Attachment coefficient [cm-1].
Definition: MediumGaN.cc:108
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) override
Drift velocity [cm / ns].
Definition: MediumGaN.cc:48
Abstract base class for media.
Definition: Medium.hh:13
void SetTemperature(const double t)
Set the temperature [K].
Definition: Medium.cc:71
bool m_microscopic
Definition: Medium.hh:523
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].
Definition: Medium.cc:534
double m_fano
Definition: Medium.hh:519
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].
Definition: Medium.cc:513
std::vector< std::vector< std::vector< double > > > m_eAlp
Definition: Medium.hh:546
std::vector< std::vector< std::vector< double > > > m_hAlp
Definition: Medium.hh:558
virtual void EnableDrift(const bool on=true)
Switch electron/ion/hole on/off.
Definition: Medium.hh:67
std::string m_name
Definition: Medium.hh:502
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].
Definition: Medium.cc:379
virtual void EnablePrimaryIonisation(const bool on=true)
Make the medium ionisable or non-ionisable.
Definition: Medium.hh:69
virtual void SetAtomicNumber(const double z)
Set the effective atomic number.
Definition: Medium.cc:114
std::vector< std::vector< std::vector< double > > > m_eVelE
Definition: Medium.hh:541
void SetDielectricConstant(const double eps)
Set the relative static dielectric constant.
Definition: Medium.cc:91
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].
Definition: Medium.cc:403
std::vector< std::vector< std::vector< double > > > m_eAtt
Definition: Medium.hh:547
virtual void SetMassDensity(const double rho)
Set the mass density [g/cm3].
Definition: Medium.cc:144
std::vector< std::vector< std::vector< double > > > m_hVelE
Definition: Medium.hh:553
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].
Definition: Medium.cc:416
std::vector< std::vector< std::vector< double > > > m_hAtt
Definition: Medium.hh:559
virtual void SetAtomicWeight(const double a)
Set the effective atomic weight.
Definition: Medium.cc:124
std::string m_className
Definition: Medium.hh:493
bool m_isChanged
Definition: Medium.hh:527
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].
Definition: Medium.cc:547
double m_temperature
Definition: Medium.hh:504