Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
AvalancheMC.hh
Go to the documentation of this file.
1#ifndef G_AVALANCHE_MC_H
2#define G_AVALANCHE_MC_H
3
4#include <array>
5#include <string>
6#include <vector>
7
9#include "Sensor.hh"
10#include "ViewDrift.hh"
11
12namespace Garfield {
13
14/// Calculate drift lines and avalanches based on macroscopic transport
15/// coefficients, using Monte Carlo integration.
16
18 public:
19 /// Constructor
21 /// Destructor
23
24 /// Set the sensor.
25 void SetSensor(Sensor* s);
26
27 /// Switch on drift line plotting.
28 void EnablePlotting(ViewDrift* view);
29 /// Switch off drift line plotting.
30 void DisablePlotting() { m_viewer = nullptr; }
31
32 /// Switch on calculation of induced currents (default: disabled).
33 void EnableSignalCalculation(const bool on = true) { m_doSignal = on; }
34 /// Set the number of points to be used when averaging the
35 /// signal vector over a time bin in the Sensor class.
36 /// The averaging is done with a \f$2\times navg + 1\f$ point
37 /// Newton-Raphson integration. Default: 1.
38 void SetSignalAveragingOrder(const unsigned int navg) { m_navg = navg; }
39 /// Use the weighting potential (as opposed to the weighting field)
40 /// for calculating the induced signal.
41 void UseWeightingPotential(const bool on = true) {
42 m_useWeightingPotential = on;
43 }
44
45 /// Switch on calculation of induced charge (default: disabled).
46 void EnableInducedChargeCalculation(const bool on = true) {
47 m_doInducedCharge = on;
48 }
49
50 /** Switch on Runge-Kutta-Fehlberg stepping (as opposed to simple
51 * straight-line steps. */
52 void EnableRKFSteps(const bool on = true) { m_doRKF = on; }
53
54 /** Switch on equilibration of multiplication and attachment
55 * over the drift line (default: enabled). */
56 void EnableProjectedPathIntegration(const bool on = true) {
57 m_doEquilibration = on;
58 }
59
60 /// Switch on diffusion (default: enabled).
61 void EnableDiffusion() { m_useDiffusion = true; }
62 /// Switch off diffusion.
63 void DisableDiffusion() { m_useDiffusion = false; }
64
65 /** Switch on attachment (and multiplication) for drift line calculation
66 * (default: enabled). For avalanches the flag is ignored. */
67 void EnableAttachment() { m_useAttachment = true; }
68 /// Switch off attachment and multiplication.
69 void DisableAttachment() { m_useAttachment = false; }
70
71 /// Retrieve the attachment coefficient from the component.
72 void EnableAttachmentMap(const bool on = true) { m_useAttachmentMap = on; }
73
74 /// Retrieve the drift velocity from the component.
75 void EnableVelocityMap(const bool on = true) { m_useVelocityMap = on; }
76
77 /// Enable use of magnetic field in stepping algorithm.
78 void EnableMagneticField(const bool on = true) { m_useBfield = on; }
79
80 /** Set a maximum avalanche size (ignore further multiplication
81 once this size has been reached). */
82 void EnableAvalancheSizeLimit(const unsigned int size) { m_sizeCut = size; }
83 /// Do not limit the maximum avalanche size.
84 void DisableAvalancheSizeLimit() { m_sizeCut = 0; }
85 /// Return the currently set avalanche size limit.
86 int GetAvalancheSizeLimit() const { return m_sizeCut; }
87
88 /// Use fixed-time steps (default 20 ps).
89 void SetTimeSteps(const double d = 0.02);
90 /// Use fixed distance steps (default 10 um).
91 void SetDistanceSteps(const double d = 0.001);
92 /** Use exponentially distributed time steps with mean equal
93 * to the specified multiple of the collision time (default model).*/
94 void SetCollisionSteps(const unsigned int n = 100);
95 /// Retrieve the step distance from a user-supplied function.
96 void SetStepDistanceFunction(double (*f)(double x, double y, double z));
97
98 /// Define a time interval (only carriers inside the interval are drifted).
99 void SetTimeWindow(const double t0, const double t1);
100 /// Do not limit the time interval within which carriers are drifted.
101 void UnsetTimeWindow() { m_hasTimeWindow = false; }
102
103 /// Set multiplication factor for the signal induced by electrons.
104 void SetElectronSignalScalingFactor(const double scale) { m_scaleE = scale; }
105 /// Set multiplication factor for the signal induced by holes.
106 void SetHoleSignalScalingFactor(const double scale) { m_scaleH = scale; }
107 /// Set multiplication factor for the signal induced by ions.
108 void SetIonSignalScalingFactor(const double scale) { m_scaleI = scale; }
109
110 /// Return the number of electrons and ions/holes in the avalanche.
111 void GetAvalancheSize(unsigned int& ne, unsigned int& ni) const {
112 ne = m_nElectrons;
113 ni = std::max(m_nIons, m_nHoles);
114 }
115
116 /// Return the number of points along the last simulated drift line.
117 unsigned int GetNumberOfDriftLinePoints() const { return m_drift.size(); }
118 /// Return the coordinates and time of a point along the last drift line.
119 void GetDriftLinePoint(const unsigned int i, double& x, double& y, double& z,
120 double& t) const;
121
122 /** Return the number of electron trajectories in the last
123 * simulated avalanche (including captured electrons). */
124 unsigned int GetNumberOfElectronEndpoints() const {
125 return m_endpointsElectrons.size();
126 }
127 /** Return the number of hole trajectories in the last
128 * simulated avalanche (including captured holes). */
129 unsigned int GetNumberOfHoleEndpoints() const {
130 return m_endpointsHoles.size();
131 }
132 /// Return the number of ion trajectories.
133 unsigned int GetNumberOfIonEndpoints() const {
134 return m_endpointsIons.size();
135 }
136
137 /** Return the coordinates and time of start and end point of a given
138 * electron drift line.
139 * \param i index of the drift line
140 * \param x0,y0,z0,t0 coordinates and time of the starting point
141 * \param x1,y1,z1,t1 coordinates and time of the end point
142 * \param status status code (see GarfieldConstants.hh)
143 */
144 void GetElectronEndpoint(const unsigned int i, double& x0, double& y0,
145 double& z0, double& t0, double& x1, double& y1,
146 double& z1, double& t1, int& status) const;
147 void GetHoleEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
148 double& t0, double& x1, double& y1, double& z1,
149 double& t1, int& status) const;
150 void GetIonEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
151 double& t0, double& x1, double& y1, double& z1,
152 double& t1, int& status) const;
153
154 /// Simulate the drift line of an electron from a given starting point.
155 bool DriftElectron(const double x0, const double y0, const double z0,
156 const double t0);
157 /// Simulate the drift line of a hole from a given starting point.
158 bool DriftHole(const double x0, const double y0, const double z0,
159 const double t0);
160 /// Simulate the drift line of an ion from a given starting point.
161 bool DriftIon(const double x0, const double y0, const double z0,
162 const double t0);
163 /** Simulate an avalanche initiated by an electron at a given starting point.
164 * \param x0,y0,z0,t0 coordinates and time of the initial electron
165 * \param hole simulate the hole component of the avalanche or not
166 */
167 bool AvalancheElectron(const double x0, const double y0, const double z0,
168 const double t0, const bool hole = false);
169 /// Simulate an avalanche initiated by a hole at a given starting point.
170 bool AvalancheHole(const double x0, const double y0, const double z0,
171 const double t0, const bool electron = false);
172 /// Simulate an avalanche initiated by an electron-hole pair.
173 bool AvalancheElectronHole(const double x0, const double y0, const double z0,
174 const double t0);
175 bool ResumeAvalanche(const bool electron = true, const bool hole = true);
176
177 /// Switch debugging messages on/off (default: off).
178 void EnableDebugging(const bool on = true) { m_debug = on; }
179
180 private:
181 std::string m_className = "AvalancheMC";
182
183 Sensor* m_sensor = nullptr;
184
185 enum class Particle { Electron = 0, Ion, Hole };
186
187 struct DriftPoint {
188 std::array<double, 3> x; ///< Position.
189 double t; ///< Time.
190 Particle particle; ///< Charge carrier type.
191 unsigned int n; ///< Number of charge carriers.
192 };
193 /// Current drift line
194 std::vector<DriftPoint> m_drift;
195
196 enum class StepModel {
197 FixedTime,
198 FixedDistance,
199 CollisionTime,
200 UserDistance
201 };
202 /// Step size model.
203 StepModel m_stepModel = StepModel::CollisionTime;
204
205 /// Fixed time step
206 double m_tMc = 0.02;
207 /// Fixed distance step
208 double m_dMc = 0.001;
209 /// Sample step size according to collision time
210 int m_nMc = 100;
211 /// User function returning the step size
212 double (*m_fStep)(double x, double y, double z) = nullptr;
213
214 /// Flag whether a time window should be used.
215 bool m_hasTimeWindow = false;
216 /// Lower limit of the time window.
217 double m_tMin = 0.;
218 /// Upper limit of the time window.
219 double m_tMax = 0.;
220
221 /// Max. avalanche size.
222 unsigned int m_sizeCut = 0;
223
224 /// Number of electrons produced
225 unsigned int m_nElectrons = 0;
226 /// Number of holes produced
227 unsigned int m_nHoles = 0;
228 /// Number of ions produced
229 unsigned int m_nIons = 0;
230
231 struct EndPoint {
232 std::array<double, 3> x0; ///< Starting point.
233 std::array<double, 3> x1; ///< End point.
234 double t0, t1; ///< Start and end time.
235 int status; ///< Status flag at the end point.
236 };
237 /// Endpoints of all electrons in the avalanche (including captured ones)
238 std::vector<EndPoint> m_endpointsElectrons;
239 /// Endpoints of all holes in the avalanche (including captured ones)
240 std::vector<EndPoint> m_endpointsHoles;
241 /// Endpoints of all ions in the avalanche
242 std::vector<EndPoint> m_endpointsIons;
243
244 ViewDrift* m_viewer = nullptr;
245
246 bool m_doSignal = false;
247 unsigned int m_navg = 1;
248 bool m_useWeightingPotential = true;
249 bool m_doInducedCharge = false;
250 bool m_doEquilibration = true;
251 bool m_doRKF = false;
252 bool m_useDiffusion = true;
253 bool m_useAttachment = true;
254 bool m_useBfield = false;
255 /// Scaling factor for electron signals.
256 double m_scaleE = 1.;
257 /// Scaling factor for hole signals.
258 double m_scaleH = 1.;
259 /// Scaling factor for ion signals.
260 double m_scaleI = 1.;
261
262 /// Take attachment coefficients from the component.
263 bool m_useAttachmentMap = false;
264 /// Take the drift velocities from the component.
265 bool m_useVelocityMap = false;
266
267 bool m_debug = false;
268
269 /// Compute a drift line with starting point x0.
270 bool DriftLine(const std::array<double, 3>& x0, const double t0,
271 const Particle particle,
272 std::vector<DriftPoint>& secondaries,
273 const bool aval = false);
274 /// Compute an avalanche.
275 bool Avalanche(std::vector<DriftPoint>& aval,
276 const bool withElectrons, const bool withHoles);
277
278 void AddPoint(const std::array<double, 3>& x, const double t,
279 const Particle particle, const unsigned int n,
280 std::vector<DriftPoint>& points) {
281 DriftPoint point;
282 point.x = x;
283 point.t = t;
284 point.particle = particle;
285 point.n = n;
286 points.push_back(std::move(point));
287 }
288 void AddEndPoint(const std::array<double, 3>& x0, const double t0,
289 const std::array<double, 3>& x1, const double t1,
290 const int status, const Particle particle) {
291 EndPoint endPoint;
292 endPoint.x0 = x0;
293 endPoint.t0 = t0;
294 endPoint.x1 = x1;
295 endPoint.t1 = t1;
296 endPoint.status = status;
297 if (particle == Particle::Electron) {
298 m_endpointsElectrons.push_back(std::move(endPoint));
299 } else if (particle == Particle::Hole) {
300 m_endpointsHoles.push_back(std::move(endPoint));
301 } else if (particle == Particle::Ion) {
302 m_endpointsIons.push_back(std::move(endPoint));
303 }
304 }
305
306 /// Compute electric and magnetic field at a given position.
307 int GetField(const std::array<double, 3>& x, std::array<double, 3>& e,
308 std::array<double, 3>& b, Medium*& medium) const;
309 /// Retrieve the low-field mobility.
310 double GetMobility(const Particle particle, Medium* medium) const;
311 /// Compute the drift velocity.
312 bool GetVelocity(const Particle particle, Medium* medium,
313 const std::array<double, 3>& x,
314 const std::array<double, 3>& e,
315 const std::array<double, 3>& b,
316 std::array<double, 3>& v) const;
317 /// Compute the diffusion coefficients.
318 bool GetDiffusion(const Particle particle, Medium* medium,
319 const std::array<double, 3>& e,
320 const std::array<double, 3>& b, double& dl,
321 double& dt) const;
322 /// Compute the attachment coefficient.
323 double GetAttachment(const Particle particle, Medium* medium,
324 const std::array<double, 3>& x,
325 const std::array<double, 3>& e,
326 const std::array<double, 3>& b) const;
327 /// Compute end point and effective velocity for a step.
328 void StepRKF(const Particle particle, const std::array<double, 3>& x0,
329 const std::array<double, 3>& v0, const double dt,
330 std::array<double, 3>& xf, std::array<double, 3>& vf,
331 int& status) const;
332 /// Add a diffusion step.
333 void AddDiffusion(const double step, const double dl, const double dt,
334 std::array<double, 3>& x,
335 const std::array<double, 3>& v) const;
336 /// Terminate a drift line close to the boundary.
337 void Terminate(const std::array<double, 3>& x0, const double t0,
338 std::array<double, 3>& x, double& t) const;
339 /// Compute multiplication and losses along the current drift line.
340 bool ComputeGainLoss(const Particle particle,
341 std::vector<DriftPoint>& driftLine, int& status,
342 std::vector<DriftPoint>& secondaries,
343 const bool semiconductor = false);
344 /// Compute Townsend and attachment coefficients along the current drift line.
345 bool ComputeAlphaEta(const Particle particle,
346 const std::vector<DriftPoint>& driftLine,
347 std::vector<double>& alphas,
348 std::vector<double>& etas) const;
349 bool Equilibrate(std::vector<double>& alphas) const;
350 /// Compute the induced signal for the current drift line.
351 void ComputeSignal(const Particle particle, const double q,
352 const std::vector<DriftPoint>& driftLine) const;
353 /// Compute the induced charge for the current drift line.
354 void ComputeInducedCharge(const double q,
355 const std::vector<DriftPoint>& driftLine) const;
356 void PrintError(const std::string& fcn, const std::string& par,
357 const Particle particle,
358 const std::array<double, 3>& x) const;
359};
360} // namespace Garfield
361
362#endif
void GetDriftLinePoint(const unsigned int i, double &x, double &y, double &z, double &t) const
Return the coordinates and time of a point along the last drift line.
Definition: AvalancheMC.cc:114
void EnablePlotting(ViewDrift *view)
Switch on drift line plotting.
Definition: AvalancheMC.cc:38
void DisableAvalancheSizeLimit()
Do not limit the maximum avalanche size.
Definition: AvalancheMC.hh:84
void SetTimeSteps(const double d=0.02)
Use fixed-time steps (default 20 ps).
Definition: AvalancheMC.cc:47
void EnableDebugging(const bool on=true)
Switch debugging messages on/off (default: off).
Definition: AvalancheMC.hh:178
bool AvalancheElectronHole(const double x0, const double y0, const double z0, const double t0)
Simulate an avalanche initiated by an electron-hole pair.
Definition: AvalancheMC.cc:533
void EnableSignalCalculation(const bool on=true)
Switch on calculation of induced currents (default: disabled).
Definition: AvalancheMC.hh:33
bool DriftIon(const double x0, const double y0, const double z0, const double t0)
Simulate the drift line of an ion from a given starting point.
Definition: AvalancheMC.cc:224
unsigned int GetNumberOfIonEndpoints() const
Return the number of ion trajectories.
Definition: AvalancheMC.hh:133
void DisablePlotting()
Switch off drift line plotting.
Definition: AvalancheMC.hh:30
void SetIonSignalScalingFactor(const double scale)
Set multiplication factor for the signal induced by ions.
Definition: AvalancheMC.hh:108
void SetTimeWindow(const double t0, const double t1)
Define a time interval (only carriers inside the interval are drifted).
Definition: AvalancheMC.cc:102
void GetIonEndpoint(const unsigned int i, double &x0, double &y0, double &z0, double &t0, double &x1, double &y1, double &z1, double &t1, int &status) const
Definition: AvalancheMC.cc:147
void UseWeightingPotential(const bool on=true)
Definition: AvalancheMC.hh:41
bool DriftElectron(const double x0, const double y0, const double z0, const double t0)
Simulate the drift line of an electron from a given starting point.
Definition: AvalancheMC.cc:186
bool ResumeAvalanche(const bool electron=true, const bool hole=true)
Definition: AvalancheMC.cc:541
void UnsetTimeWindow()
Do not limit the time interval within which carriers are drifted.
Definition: AvalancheMC.hh:101
void GetElectronEndpoint(const unsigned int i, double &x0, double &y0, double &z0, double &t0, double &x1, double &y1, double &z1, double &t1, int &status) const
Definition: AvalancheMC.cc:166
void GetAvalancheSize(unsigned int &ne, unsigned int &ni) const
Return the number of electrons and ions/holes in the avalanche.
Definition: AvalancheMC.hh:111
void GetHoleEndpoint(const unsigned int i, double &x0, double &y0, double &z0, double &t0, double &x1, double &y1, double &z1, double &t1, int &status) const
Definition: AvalancheMC.cc:127
void EnableRKFSteps(const bool on=true)
Definition: AvalancheMC.hh:52
~AvalancheMC()
Destructor.
Definition: AvalancheMC.hh:22
void EnableVelocityMap(const bool on=true)
Retrieve the drift velocity from the component.
Definition: AvalancheMC.hh:75
AvalancheMC()
Constructor.
Definition: AvalancheMC.cc:27
void EnableMagneticField(const bool on=true)
Enable use of magnetic field in stepping algorithm.
Definition: AvalancheMC.hh:78
void SetSensor(Sensor *s)
Set the sensor.
Definition: AvalancheMC.cc:29
void DisableAttachment()
Switch off attachment and multiplication.
Definition: AvalancheMC.hh:69
void EnableDiffusion()
Switch on diffusion (default: enabled).
Definition: AvalancheMC.hh:61
unsigned int GetNumberOfHoleEndpoints() const
Definition: AvalancheMC.hh:129
void EnableAttachmentMap(const bool on=true)
Retrieve the attachment coefficient from the component.
Definition: AvalancheMC.hh:72
void SetStepDistanceFunction(double(*f)(double x, double y, double z))
Retrieve the step distance from a user-supplied function.
Definition: AvalancheMC.cc:92
void SetElectronSignalScalingFactor(const double scale)
Set multiplication factor for the signal induced by electrons.
Definition: AvalancheMC.hh:104
void DisableDiffusion()
Switch off diffusion.
Definition: AvalancheMC.hh:63
void SetHoleSignalScalingFactor(const double scale)
Set multiplication factor for the signal induced by holes.
Definition: AvalancheMC.hh:106
int GetAvalancheSizeLimit() const
Return the currently set avalanche size limit.
Definition: AvalancheMC.hh:86
void EnableAvalancheSizeLimit(const unsigned int size)
Definition: AvalancheMC.hh:82
void SetCollisionSteps(const unsigned int n=100)
Definition: AvalancheMC.cc:77
unsigned int GetNumberOfDriftLinePoints() const
Return the number of points along the last simulated drift line.
Definition: AvalancheMC.hh:117
unsigned int GetNumberOfElectronEndpoints() const
Definition: AvalancheMC.hh:124
bool AvalancheElectron(const double x0, const double y0, const double z0, const double t0, const bool hole=false)
Definition: AvalancheMC.cc:517
void EnableInducedChargeCalculation(const bool on=true)
Switch on calculation of induced charge (default: disabled).
Definition: AvalancheMC.hh:46
void SetSignalAveragingOrder(const unsigned int navg)
Definition: AvalancheMC.hh:38
void SetDistanceSteps(const double d=0.001)
Use fixed distance steps (default 10 um).
Definition: AvalancheMC.cc:62
bool AvalancheHole(const double x0, const double y0, const double z0, const double t0, const bool electron=false)
Simulate an avalanche initiated by a hole at a given starting point.
Definition: AvalancheMC.cc:525
bool DriftHole(const double x0, const double y0, const double z0, const double t0)
Simulate the drift line of a hole from a given starting point.
Definition: AvalancheMC.cc:205
void EnableProjectedPathIntegration(const bool on=true)
Definition: AvalancheMC.hh:56
Visualize drift lines and tracks.
Definition: ViewDrift.hh:18