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