Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization measurement in gases and semiconductors
Loading...
Searching...
No Matches
AvalancheMicroscopic.hh
Go to the documentation of this file.
1#ifndef G_AVALANCHE_MICROSCOPIC_H
2#define G_AVALANCHE_MICROSCOPIC_H
3
4#include <array>
5#include <cstddef>
6#include <string>
7#include <utility>
8#include <vector>
9
12
13class TH1;
14
15namespace Garfield {
16
17class AvalancheMicroscopicGPU;
18class Medium;
19class ViewDrift;
20class Sensor;
21
23
25 public:
29 AvalancheMicroscopic(Sensor* sensor);
32
34 void SetSensor(Sensor* sensor);
35
37 void EnablePlotting(ViewDrift* view, const std::size_t nColl = 100);
39 void DisablePlotting() { m_viewer = nullptr; }
41 void EnableExcitationMarkers(const bool on = true) { m_plotExcitations = on; }
43 void EnableIonisationMarkers(const bool on = true) { m_plotIonisations = on; }
45 void EnableAttachmentMarkers(const bool on = true) { m_plotAttachments = on; }
46
48 void EnableSignalCalculation(const bool on = true) { m_doSignal = on; }
51 void UseWeightingPotential(const bool on = true) {
53 }
54
56 void EnableWeightingFieldIntegration(const bool on = true) {
58 }
59
61 void UseInducedCharge(const bool on = true) { m_doInducedCharge = on; }
62
64 void EnablePathLengthComputation(const bool on = true) {
66 }
67
75
82 void SetDistanceHistogram(TH1* histo, const char opt = 'r');
84 void EnableDistanceHistogramming(const int type);
86 void DisableDistanceHistogramming(const int type);
93
95 void EnableDriftLines(const bool on = true) { m_storeDriftLines = on; }
96
99 void EnablePhotonTransport(const bool on = true) { m_usePhotons = on; }
100
102 void EnableBandStructure(const bool on = true) { m_useBandStructure = on; }
103
105 void EnableNullCollisionSteps(const bool on = true, const int nSteps = 1) {
107 m_nullCollScale = nSteps <= 1 ? 1. : 1. / nSteps;
108 }
109
111 void EnableRKNSteps(const bool on = true) { m_rknSteps = on; }
114 void SetRKNTolerance(const double sTol = 1.e-10,
115 const double sMinStep = 1.e-5) {
116 m_rknsteperrortol = sTol;
117 m_rknMinh = sMinStep;
118 }
119
122 void SetElectronTransportCut(const double cut) { m_deltaCut = cut; }
124 double GetElectronTransportCut() const { return m_deltaCut; }
125
127 void SetPhotonTransportCut(const double cut) { m_gammaCut = cut; }
129 double GetPhotonTransportCut() const { return m_gammaCut; }
130
133 void EnableAvalancheSizeLimit(const unsigned int size) { m_sizeCut = size; }
137 int GetAvalancheSizeLimit() const { return m_sizeCut; }
138
140 void EnableMagneticField(const bool on = true) {
141 m_useBfieldAuto = false;
142 m_useBfield = on;
143 }
144
146 void SetCollisionSteps(const unsigned int n) { m_nCollSkip = n; }
147
149 void SetTimeWindow(const double t0, const double t1);
152
154 void GetAvalancheSize(int& ne, int& ni) const {
155 ne = m_nElectrons;
156 ni = m_nIons;
157 }
158
159 std::pair<int, int> GetAvalancheSize() const {
160 return std::make_pair(m_nElectrons, m_nIons);
161 }
162 void GetAvalancheSize(int& ne, int& nh, int& ni) const {
163 ne = m_nElectrons;
164 nh = m_nHoles;
165 ni = m_nIons;
166 }
167
168 void GetAvalancheSizeGPU(int& ne, int& ni) const {
169 ne = m_nElectronsGPU;
170 ni = m_nIonsGPU;
171 }
172
173 struct Point {
174 double x, y, z;
175 double t;
176 double energy;
177 double kx, ky, kz;
178 int band;
179 };
180
181 struct Electron {
182 int status = 0;
183 std::vector<Point> path;
184 size_t weight = 1;
185 double pathLength = 0.;
186 };
187
188 struct Seed {
191 size_t w = 1;
192 };
193
194 const std::vector<Electron>& GetElectrons() const { return m_electrons; }
195 const std::vector<Electron>& GetHoles() const { return m_holes; }
198 size_t GetNumberOfElectronEndpoints() const { return m_electrons.size(); }
199 unsigned int GetNumberOfElectronEndpointsGPU() const {
200 return m_electrons_gpu.size();
201 }
202
210 void GetElectronEndpoint(const size_t i, double& x0, double& y0, double& z0,
211 double& t0, double& e0, double& x1, double& y1,
212 double& z1, double& t1, double& e1,
213 int& status) const;
214 void GetElectronEndpointGPU(const size_t i, double& x0, double& y0,
215 double& z0, double& t0, double& e0, double& x1,
216 double& y1, double& z1, double& t1, double& e1,
217 int& status) const;
218 size_t GetNumberOfElectronDriftLinePoints(const size_t i = 0) const;
219 void GetElectronDriftLinePoint(double& x, double& y, double& z, double& t,
220 const size_t ip, const size_t ie = 0) const;
221
222 size_t GetNumberOfPhotons() const { return m_photons.size(); }
223 // Status codes:
224 // -2: photon absorbed by gas molecule
225 void GetPhoton(const size_t i, double& e, double& x0, double& y0, double& z0,
226 double& t0, double& x1, double& y1, double& z1, double& t1,
227 int& status) const;
228
236 bool DriftElectron(const double x, const double y, const double z,
237 const double t, const double e, const double dx = 0.,
238 const double dy = 0., const double dz = 0.,
239 const size_t w = 1);
240
242 bool AvalancheElectron(const double x, const double y, const double z,
243 const double t, const double e, const double dx = 0.,
244 const double dy = 0., const double dz = 0.,
245 const size_t w = 1);
247 void AddElectron(const double x, const double y, const double z,
248 const double t, const double e, const double dx = 0.,
249 const double dy = 0., const double dz = 0.,
250 const size_t w = 1);
253
255 void SetUserHandleStep(void (*f)(double x, double y, double z, double t,
256 double e, double dx, double dy, double dz,
257 bool hole));
261 void SetUserHandleCollision(void (*f)(double x, double y, double z, double t,
262 int type, int level, Medium* m,
263 double e0, double e1, double dx0,
264 double dy0, double dz0, double dx1,
265 double dy1, double dz1));
269 void SetUserHandleAttachment(void (*f)(double x, double y, double z, double t,
270 int type, int level, Medium* m));
274 void SetUserHandleInelastic(void (*f)(double x, double y, double z, double t,
275 int type, int level, Medium* m));
280 void SetUserHandleIonisation(void (*f)(double x, double y, double z, double t,
281 int type, int level, Medium* m));
284
286 void EnableDebugging() { m_debug = true; }
287 void DisableDebugging() { m_debug = false; }
288
289 // class to store CPU/GPU benchmark comparisons
290 struct Statistics {
291 std::vector<double> gpu_stack_process_time;
292 std::vector<double> cpu_stack_process_time;
293 std::vector<double> gpu_stack_transport_time;
294 std::vector<double> cpu_stack_transport_time;
295
296 std::vector<size_t> stack_old_size;
297 std::vector<size_t> stack_new_size;
298 };
299
301
302 void SetRunModeOptions(MPRunMode mode, int device = -1);
303 void SetMaxNumShowerLoops(int max_loops) { m_maxNumShowerLoops = max_loops; }
304 void SetShowProgress(bool show_progress) { m_showProgress = show_progress; }
305 void SetDebugShowerIterationAndElectronID(int iter_num, int elec_id) {
306 m_debugShowerLoopNum = iter_num;
307 m_debugElectronID = elec_id;
308 }
309
310 private:
311 std::string m_className = "AvalancheMicroscopic";
312
318 bool m_showProgress{false};
320
322
323 Sensor* m_sensor = nullptr;
324
325 std::vector<Electron> m_electrons;
326 std::vector<Electron> m_electrons_gpu;
327 std::vector<Electron> m_holes;
328
329 std::vector<Seed> m_stackStoreCPU;
330 std::vector<Electron> m_stackStoreGPU;
331
332 struct Photon {
333 int status;
334 double energy;
335 double x0, y0, z0, t0;
336 double x1, y1, z1, t1;
337 };
338 std::vector<Photon> m_photons;
339
343 int m_nHoles = 0;
345 int m_nIons = 0;
346
350 int m_nHolesGPU = 0;
352 int m_nIonsGPU = 0;
353
354 ViewDrift* m_viewer = nullptr;
355 bool m_plotExcitations = true;
356 bool m_plotIonisations = true;
357 bool m_plotAttachments = true;
358
359 TH1* m_histElectronEnergy = nullptr;
360 TH1* m_histHoleEnergy = nullptr;
361 TH1* m_histDistance = nullptr;
363 std::vector<int> m_distanceHistogramType;
364
365 TH1* m_histSecondary = nullptr;
366
367 bool m_doSignal = true;
370 bool m_doInducedCharge = false;
371
373 bool m_storeDriftLines = false;
374 bool m_usePhotons = false;
377 bool m_useBfieldAuto = true;
378 bool m_useBfield = false;
379
380 bool m_rknSteps = false;
381 double m_rknsteperrortol = 1.e-10;
382 double m_rknMinh = 1.e-5;
383 double m_nullCollScale = 1.;
384
385 // Transport cuts
386 double m_deltaCut = 0.;
387 double m_gammaCut = 0.;
388
389 // Max. avalanche size
390 unsigned int m_sizeCut = 0;
391
392 size_t m_nCollSkip = 100;
393 size_t m_nCollPlot = 100;
394
395 bool m_hasTimeWindow = false;
396 double m_tMin = 0.;
397 double m_tMax = 0.;
398
399 // User procedures
400 void (*m_userHandleStep)(double x, double y, double z, double t, double e,
401 double dx, double dy, double dz,
402 bool hole) = nullptr;
403 void (*m_userHandleCollision)(double x, double y, double z, double t,
404 int type, int level, Medium* m, double e0,
405 double e1, double dx0, double dy0, double dz0,
406 double dx1, double dy1, double dz1) = nullptr;
407 void (*m_userHandleAttachment)(double x, double y, double z, double t,
408 int type, int level, Medium* m) = nullptr;
409 void (*m_userHandleInelastic)(double x, double y, double z, double t,
410 int type, int level, Medium* m) = nullptr;
411 void (*m_userHandleIonisation)(double x, double y, double z, double t,
412 int type, int level, Medium* m) = nullptr;
413
414 // Switch on/off debugging messages
415 bool m_debug = false;
416
417 bool TransportElectrons(std::vector<Seed>& stack, const bool aval);
419 const Seed& seed, const bool signal,
420 std::vector<double>& ts, std::vector<std::array<double, 3> >& xs,
421 std::vector<Point>& path, std::vector<Seed>& stack);
423 const Seed& seed, const bool signal,
424 std::vector<double>& ts, std::vector<std::array<double, 3> >& xs,
425 std::vector<Point>& path, std::vector<Seed>& stack);
427 const Seed& seed, const bool signal,
428 std::vector<double>& ts, std::vector<std::array<double, 3> >& xs,
429 std::vector<Point>& path, std::vector<Seed>& stack);
430 void TransportPhoton(const double x, const double y, const double z,
431 const double t, const double e, const size_t w,
432 std::vector<Seed>& stack);
433
435 const bool aval, std::vector<Seed>& stack,
436 std::vector<Seed>& newParticles, const bool signal,
437 const bool useBfield, const bool sc);
438 void Terminate(double x0, double y0, double z0, double t0, double& x1,
439 double& y1, double& z1, double& t1) const;
440
441 void CreatePenningElectron(const double x, const double y, const double z,
442 const double t, const size_t w,
443 const double ds, const double dt, const double ep,
444 const int level, std::vector<Seed>& stack) const;
445 void PlotCollision(const int cstype, const size_t did, const double x,
446 const double y, const double z, size_t& nCollPlot) const;
448 const int cstype, const double x, const double y, const double z,
449 const double t, const int level, Medium* medium,
450 const double en1, const double en,
451 const double kx, const double ky, const double kz,
452 const double kx1, const double ky1, const double kz1) const;
453 void FillDistanceHistogram(const int cstype, const double x, const double y,
454 const double z, double& xLast, double& yLast,
455 double& zLast) const;
456
457 public:
458 std::vector<Seed> GetStackOld() {
459 return m_stackStoreCPU;
460 }
461 std::vector<Electron> GetStackOldGPU() { return m_stackStoreGPU; }
462
464};
465} // namespace Garfield
466
467#endif
void EnablePlotting(ViewDrift *view, const std::size_t nColl=100)
Switch on drift line plotting.
void SetRunModeOptions(MPRunMode mode, int device=-1)
bool AvalancheElectron(const double x, const double y, const double z, const double t, const double e, const double dx=0., const double dy=0., const double dz=0., const size_t w=1)
Calculate an avalanche initiated by a given electron.
void EnablePathLengthComputation(const bool on=true)
Compute and store the path length of each trajectory (default: off).
void UnsetUserHandleCollision()
Deactivate the user handle called at every collision.
void AddElectron(const double x, const double y, const double z, const double t, const double e, const double dx=0., const double dy=0., const double dz=0., const size_t w=1)
Add an electron to the list of particles to be transported.
void EnableDistanceHistogramming(const int type)
Fill distance distribution histograms for a given collision type.
void UnsetTimeWindow()
Do not restrict the time interval within which carriers are simulated.
void UseWeightingPotential(const bool on=true)
Use the weighting potential (as opposed to the weighting field) for calculating the induced current.
void SetDistanceHistogram(TH1 *histo, const char opt='r')
Fill histograms of the distance between successive collisions.
void EnableWeightingFieldIntegration(const bool on=true)
Integrate the weighting field over a drift line step when calculating the induced current (default: o...
void EnableAvalancheSizeLimit(const unsigned int size)
Set a max.
void SetUserHandleStep(void(*f)(double x, double y, double z, double t, double e, double dx, double dy, double dz, bool hole))
Set a callback function to be called at every step.
void EnableHoleEnergyHistogramming(TH1 *histo)
Fill a histogram with the hole energy distribution.
int TransportElectronBfield(const Seed &seed, const bool signal, std::vector< double > &ts, std::vector< std::array< double, 3 > > &xs, std::vector< Point > &path, std::vector< Seed > &stack)
std::vector< Electron > m_electrons_gpu
void EnablePhotonTransport(const bool on=true)
Switch on photon transport.
void SetUserHandleCollision(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m, double e0, double e1, double dx0, double dy0, double dz0, double dx1, double dy1, double dz1))
Set a callback function to be called at every (real) collision.
void FillDistanceHistogram(const int cstype, const double x, const double y, const double z, double &xLast, double &yLast, double &zLast) const
void CallUserHandles(const int cstype, const double x, const double y, const double z, const double t, const int level, Medium *medium, const double en1, const double en, const double kx, const double ky, const double kz, const double kx1, const double ky1, const double kz1) const
void EnableDriftLines(const bool on=true)
Switch on storage of drift lines (default: off).
void EnableNullCollisionSteps(const bool on=true, const int nSteps=1)
Switch on update of coordinates for null-collision steps (default: off).
void SetUserHandleIonisation(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m))
Set a user handling procedure, to be called at every ionising collision or excitation followed by Pen...
void UnsetUserHandleAttachment()
Deactivate the user handle called at every attachment.
void(* m_userHandleCollision)(double x, double y, double z, double t, int type, int level, Medium *m, double e0, double e1, double dx0, double dy0, double dz0, double dx1, double dy1, double dz1)
bool DriftElectron(const double x, const double y, const double z, const double t, const double e, const double dx=0., const double dy=0., const double dz=0., const size_t w=1)
Calculate an electron drift line.
void GetAvalancheSizeGPU(int &ne, int &ni) const
Return the number of electrons and ions in the avalanche.
void GetElectronEndpointGPU(const size_t i, double &x0, double &y0, double &z0, double &t0, double &e0, double &x1, double &y1, double &z1, double &t1, double &e1, int &status) const
void DisableHoleEnergyHistogramming()
Stop histogramming the hole energy distribution.
void CreatePenningElectron(const double x, const double y, const double z, const double t, const size_t w, const double ds, const double dt, const double ep, const int level, std::vector< Seed > &stack) const
size_t GetNumberOfElectronDriftLinePoints(const size_t i=0) const
void GetPhoton(const size_t i, double &e, double &x0, double &y0, double &z0, double &t0, double &x1, double &y1, double &z1, double &t1, int &status) const
void SetDebugShowerIterationAndElectronID(int iter_num, int elec_id)
void SetPhotonTransportCut(const double cut)
Set an energy threshold for photon transport.
const std::vector< Electron > & GetElectrons() const
void(* m_userHandleAttachment)(double x, double y, double z, double t, int type, int level, Medium *m)
size_t GetNumberOfElectronEndpoints() const
Return the number of electron trajectories in the last simulated avalanche (including captured electr...
void EnableIonisationMarkers(const bool on=true)
Draw a marker at every ionising collision or not.
void(* m_userHandleIonisation)(double x, double y, double z, double t, int type, int level, Medium *m)
void UseInducedCharge(const bool on=true)
Switch on calculation of the total induced charge (default: off).
void Terminate(double x0, double y0, double z0, double t0, double &x1, double &y1, double &z1, double &t1) const
void PlotCollision(const int cstype, const size_t did, const double x, const double y, const double z, size_t &nCollPlot) const
void DisableSecondaryEnergyHistogramming()
Stop histogramming the secondary electron energy distribution.
int m_nIonsGPU
Number of ions produced.
void EnableRKNSteps(const bool on=true)
Switch on Runge-Kutta-Nystrom stepping (default: off).
int m_nHolesGPU
Number of holes produced.
AvalancheMicroscopic(Sensor *sensor)
Constructor.
void DisableAvalancheSizeLimit()
Do not apply a limit on the avalanche size.
void(* m_userHandleStep)(double x, double y, double z, double t, double e, double dx, double dy, double dz, bool hole)
int TransportElectronSc(const Seed &seed, const bool signal, std::vector< double > &ts, std::vector< std::array< double, 3 > > &xs, std::vector< Point > &path, std::vector< Seed > &stack)
int m_nHoles
Number of holes produced.
unsigned int GetNumberOfElectronEndpointsGPU() const
AvalancheMicroscopic()
Default constructor.
int m_nElectrons
Number of electrons produced.
void EnableBandStructure(const bool on=true)
Switch on stepping according to band structure E(k), for semiconductors.
int m_nElectronsGPU
Number of electrons produced.
double GetPhotonTransportCut() const
Retrieve the energy threshold for transporting photons.
void SetRKNTolerance(const double sTol=1.e-10, const double sMinStep=1.e-5)
Set error tolerance and minimum step size on Runge-Kutta-Nystrom method (default: 1....
void SetCollisionSteps(const unsigned int n)
Set number of collisions to be skipped for storing drift lines.
bool TransportElectrons(std::vector< Seed > &stack, const bool aval)
void GetAvalancheSize(int &ne, int &ni) const
Return the number of electrons and ions in the avalanche.
std::vector< Electron > m_stackStoreGPU
void SetUserHandleAttachment(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m))
Set a user handling procedure, to be called at every attachment.
int TransportElectron(const Seed &seed, const bool signal, std::vector< double > &ts, std::vector< std::array< double, 3 > > &xs, std::vector< Point > &path, std::vector< Seed > &stack)
void SetSensor(Sensor *sensor)
Set the sensor.
void(* m_userHandleInelastic)(double x, double y, double z, double t, int type, int level, Medium *m)
void EnableExcitationMarkers(const bool on=true)
Draw a marker at every excitation or not.
void EnableSignalCalculation(const bool on=true)
Switch calculation of induced currents on or off (default: enabled).
void DisablePlotting()
Switch off drift line plotting.
void UnsetUserHandleStep()
Deactivate the user handle called at every step.
std::vector< Electron > GetStackOldGPU()
void EnableMagneticField(const bool on=true)
Switch on/off using the magnetic field in the stepping algorithm.
double GetElectronTransportCut() const
Retrieve the value of the energy threshold.
void EnableElectronEnergyHistogramming(TH1 *histo)
Fill a histogram with the electron energy distribution.
bool ResumeAvalanche()
Continue the avalanche simulation from the current set of electrons.
void UnsetUserHandleIonisation()
Deactivate the user handle called at every ionisation.
void EnableAttachmentMarkers(const bool on=true)
Draw a marker at every attachment or not.
void DisableDistanceHistogramming()
Stop filling distance distribution histograms.
void GetAvalancheSize(int &ne, int &nh, int &ni) const
void GetElectronEndpoint(const size_t i, double &x0, double &y0, double &z0, double &t0, double &e0, double &x1, double &y1, double &z1, double &t1, double &e1, int &status) const
Return the coordinates and time of start and end point of a given electron drift line.
AvalancheMicroscopicGPU * m_gpuInterface
void EnableSecondaryEnergyHistogramming(TH1 *histo)
Fill histograms of the energy of electrons emitted in ionising collisions.
void SetElectronTransportCut(const double cut)
Set a (lower) energy threshold for electron transport.
int GetAvalancheSizeLimit() const
Retrieve the currently set size limit.
void DisableElectronEnergyHistogramming()
Stop histogramming the electron energy distribution.
void EnableDebugging()
Switch on debugging messages.
bool transportParticleStack(const bool aval, std::vector< Seed > &stack, std::vector< Seed > &newParticles, const bool signal, const bool useBfield, const bool sc)
void TransportPhoton(const double x, const double y, const double z, const double t, const double e, const size_t w, std::vector< Seed > &stack)
void SetShowProgress(bool show_progress)
const std::vector< Electron > & GetHoles() const
int m_nIons
Number of ions produced.
std::pair< int, int > GetAvalancheSize() const
Return the number of electrons and ions in the avalanche.
void SetUserHandleInelastic(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m))
Set a user handling procedure, to be called at every inelastic collision.
void DisableDistanceHistogramming(const int type)
Stop filling distance distribution histograms for a given collision type.
void GetElectronDriftLinePoint(double &x, double &y, double &z, double &t, const size_t ip, const size_t ie=0) const
void UnsetUserHandleInelastic()
Deactivate the user handle called at every inelastic collision.
void SetTimeWindow(const double t0, const double t1)
Define a time interval (only carriers inside the interval are simulated).
Visualize drift lines and tracks.
Definition ViewDrift.hh:18