Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentTcadBase.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_TCAD_BASE_H
2#define G_COMPONENT_TCAD_BASE_H
3
4#include <algorithm>
5#include <array>
6#include <map>
7
9
10namespace Garfield {
11
13
14template <size_t N>
15class ComponentTcadBase : public Component {
16 public:
20 ComponentTcadBase(const std::string& name) : Component(name) {
21 m_regions.reserve(10);
22 m_vertices.reserve(10000);
23 m_elements.reserve(10000);
24 }
25
26 virtual ~ComponentTcadBase() {}
27
32 bool Initialise(const std::string& gridfilename,
33 const std::string& datafilename);
34
45 bool SetWeightingField(const std::string& datfile1,
46 const std::string& datfile2, const double dv,
47 const std::string& label);
48
50 bool SetWeightingPotential(const std::string& datfile1,
51 const std::string& datfile2, const double dv,
52 const std::string& label) {
53 return SetWeightingField(datfile1, datfile2, dv, label);
54 }
55
58 bool SetWeightingFieldShift(const std::string& label, const double x,
59 const double y, const double z);
61 bool SetDynamicWeightingPotential(const std::string& datfile1,
62 const std::string& datfile2,
63 const double dv, const double t,
64 const std::string& label);
66 bool SetDynamicWeightingField(const std::string& datfile1,
67 const std::string& datfile2, const double dv,
68 const double t, const std::string& label);
69
71 void PrintRegions() const;
73 size_t GetNumberOfRegions() const { return m_regions.size(); }
75 void GetRegion(const size_t ireg, std::string& name, bool& active) const;
77 void SetDriftRegion(const size_t ireg);
79 void UnsetDriftRegion(const size_t ireg);
81 void SetMedium(const size_t ireg, Medium* m);
83 void SetMedium(const std::string& material, Medium* m);
84
85 size_t GetNumberOfElements() const override { return m_elements.size(); }
86 bool GetElementNodes(const size_t i,
87 std::vector<size_t>& nodes) const override;
88 bool GetElementRegion(const size_t i, size_t& region,
89 bool& active) const override;
90 size_t GetNumberOfNodes() const override { return m_vertices.size(); }
91
93 void EnableVelocityMap(const bool on);
94
96 size_t GetNumberOfDonors() { return m_donors.size(); }
98 size_t GetNumberOfAcceptors() { return m_acceptors.size(); }
99
106 bool SetDonor(const size_t donorNumber, const double exsec,
107 const double hxsec, const double concentration);
109 bool SetAcceptor(const size_t acceptorNumber, const double exsec,
110 const double hxsec, const double concentration);
111
113 void EnableAlphaMap(const bool on = true) { m_useAlphaMap = on; }
114
116 void EnableTrapOccupationMap(const bool on = true);
118 void EnableLifetimeMap(const bool on = true);
119
121 bool GetElectronMobility(const double x, const double y, const double z,
122 double& mob);
124 bool GetHoleMobility(const double x, const double y, const double z,
125 double& mob);
126
127 double ElectronLifetime(const double x, const double y, const double z);
128 double HoleLifetime(const double x, const double y, const double z);
129
130 void WeightingField(const double x, const double y, const double z,
131 double& wx, double& wy, double& wz,
132 const std::string& label) override;
133 double WeightingPotential(const double x, const double y, const double z,
134 const std::string& label) override;
135 const std::vector<double>& DelayedSignalTimes(
136 const std::string& label) override {
137 if (m_dwtp.count(label) > 0) return m_dwtp[label];
138 static const std::vector<double> emptyVector;
139 return emptyVector;
140 }
141 void DelayedWeightingField(const double x, const double y, const double z,
142 const double t, double& wx, double& wy, double& wz,
143 const std::string& label) override;
144 double DelayedWeightingPotential(const double x, const double y,
145 const double z, const double t,
146 const std::string& label) override;
147
148 bool GetVoltageRange(double& vmin, double& vmax) override;
149
150 bool HasVelocityMap() const override {
151 return m_useVelocityMap && !(m_eVelocity.empty() && m_hVelocity.empty());
152 }
153 bool ElectronVelocity(const double x, const double y, const double z,
154 double& vx, double& vy, double& vz) override;
155 bool HoleVelocity(const double x, const double y, const double z, double& vx,
156 double& vy, double& vz) override;
157
158 bool HasTownsendMap() const override {
159 return m_useAlphaMap && !(m_eAlpha.empty() && m_hAlpha.empty());
160 }
161 bool HasAttachmentMap() const override {
162 return ((m_useTrapOccMap || m_useLifetimeMap) &&
163 !(m_eEta.empty() && m_hEta.empty()));
164 }
165 bool HasMobilityMap() const override {
166 return !(m_eMobility.empty() && m_hMobility.empty());
167 }
168 bool ElectronAttachment(const double x, const double y, const double z,
169 double& eta) override;
170 bool HoleAttachment(const double x, const double y, const double z,
171 double& eta) override;
172 bool ElectronMobility(const double x, const double y, const double z,
173 double& mu) override;
174 bool HoleMobility(const double x, const double y, const double z,
175 double& mu) override;
176
177 bool ElectronTownsend(const double x, const double y, const double z,
178 double& alpha) override;
179 bool HoleTownsend(const double x, const double y, const double z,
180 double& alpha) override;
181
182 protected:
183 // Max. number of vertices per element
184 static constexpr size_t nMaxVertices = 4;
185
186 // Regions
187 struct Region {
188 // Name of the region (from Tcad)
189 std::string name;
190 // Material of the region (from Tcad)
191 std::string material;
192 // Flag indicating if the region is active (i. e. a drift medium)
193 bool drift;
194 // Medium object associated to the region
195 Medium* medium;
196 };
197 std::vector<Region> m_regions;
198
199 // Vertex coordinates [cm].
200 std::vector<std::array<double, N> > m_vertices;
201
202 // Elements
203 struct Element {
204 // Indices of vertices
205 unsigned int vertex[nMaxVertices];
206 // Type of element
207 // 0: Point
208 // 1: Segment (line)
209 // 2: Triangle
210 // 3: Rectangle
211 // 4: Polygon
212 // 5: Tetrahedron
213 // 6: Pyramid
214 // 7: Prism
215 // 8: Brick
216 // 9: Tetrabrick
217 // 10: Polyhedron
218 // In 2D, types 1 - 3 are supported.
219 // In 3D, only types 2 and 5 are supported.
220 unsigned int type;
221 // Associated region
222 unsigned int region;
223 // Bounding box
224 std::array<float, N> bbMin;
225 std::array<float, N> bbMax;
226 };
227 std::vector<Element> m_elements;
228
229 // Potential [V] at each vertex.
230 std::vector<double> m_epot;
231 // Electric field [V / cm].
232 std::vector<std::array<double, N> > m_efield;
233
234 // Weighting field and potential at each vertex.
235 std::map<std::string, std::vector<std::array<double, N> > > m_wfield;
236 std::map<std::string, std::vector<double> > m_wpot;
237 // Weighting field labels and offsets.
238 std::map<std::string, std::vector<double> > m_wshift;
239
240 // Delayed weighting field and potential.
241 std::map<std::string, std::vector<std::vector<std::array<double, N> > > >
243 std::map<std::string, std::vector<std::vector<double> > > m_dwp;
244 // Times corresponding to the delayed weighting fields/potentials.
245 std::map<std::string, std::vector<double> > m_dwtf;
246 std::map<std::string, std::vector<double> > m_dwtp;
247
248 // Velocities [cm / ns]
249 std::vector<std::array<double, N> > m_eVelocity;
250 std::vector<std::array<double, N> > m_hVelocity;
251 // Mobilities [cm2 / (V ns)]
252 std::vector<double> m_eMobility;
253 std::vector<double> m_hMobility;
254 // Impact ionisation coefficients [1 / cm]
255 std::vector<double> m_eAlpha;
256 std::vector<double> m_hAlpha;
257 // Lifetimes [ns]
258 std::vector<double> m_eLifetime;
259 std::vector<double> m_hLifetime;
260 // Trap occupations [dimensionless]
261 std::vector<std::vector<float> > m_donorOcc;
262 std::vector<std::vector<float> > m_acceptorOcc;
263 // Attachment coefficients [1 / cm]
264 std::vector<double> m_eEta;
265 std::vector<double> m_hEta;
266
267 struct Defect {
268 // Electron cross-section
269 double xsece;
270 // Hole cross-section
271 double xsech;
272 // Concentration
273 double conc;
274 };
275 std::vector<Defect> m_donors;
276 std::vector<Defect> m_acceptors;
277
278 // Use velocity map or not.
279 bool m_useVelocityMap = false;
280 // Use trap occupation probability map or not.
281 bool m_useTrapOccMap = false;
282 // Use lifetime map or not.
283 bool m_useLifetimeMap = false;
284 // Use impact ionisation map or not.
285 bool m_useAlphaMap = false;
286
287 // Bounding box.
288 std::array<double, 3> m_bbMin = {{0., 0., 0.}};
289 std::array<double, 3> m_bbMax = {{0., 0., 0.}};
290
291 // Voltage range
292 double m_pMin = 0.;
293 double m_pMax = 0.;
294
295 void UpdatePeriodicity() override;
296
297 void Cleanup();
298
299 static unsigned int ElementVertices(const Element& element) {
300 return std::min(element.type + 1, 4U);
301 }
302 virtual bool Interpolate(const double x, const double y, const double z,
303 const std::vector<double>& field, double& f) = 0;
304 virtual bool Interpolate(const double x, const double y, const double z,
305 const std::vector<std::array<double, N> >& field,
306 double& fx, double& fy, double& fz) = 0;
307 virtual void FillTree() = 0;
308
309 size_t FindRegion(const std::string& name) const;
310 void MapCoordinates(std::array<double, N>& x,
311 std::array<bool, N>& mirr) const;
312 bool InBoundingBox(const std::array<double, N>& x) const {
313 for (size_t i = 0; i < N; ++i) {
314 if (x[i] < m_bbMin[i] || x[i] > m_bbMax[i]) return false;
315 }
316 return true;
317 }
321
322 bool GetOffset(const std::string& label, double& dx, double& dy,
323 double& dz) const;
324 bool LoadGrid(const std::string& gridfilename);
325 bool LoadData(const std::string& datafilename);
326 bool ReadDataset(std::ifstream& datafile, const std::string& dataset);
327 bool LoadWeightingField(const std::string& datafilename,
328 std::vector<std::array<double, N> >& wf,
329 std::vector<double>& wp);
330};
331} // namespace Garfield
332#endif
bool HoleMobility(const double x, const double y, const double z, double &mu) override
std::map< std::string, std::vector< double > > m_dwtf
bool InBoundingBox(const std::array< double, N > &x) const
std::vector< double > m_hMobility
bool HasTownsendMap() const override
size_t GetNumberOfElements() const override
bool LoadGrid(const std::string &gridfilename)
bool HasMobilityMap() const override
void EnableTrapOccupationMap(const bool on=true)
Use the imported trapping map or not.
void GetRegion(const size_t ireg, std::string &name, bool &active) const
Get the name and "active volume" flag of a region.
void UnsetDriftRegion(const size_t ireg)
Make a region inactive.
ComponentTcadBase(const std::string &name)
Constructor.
std::vector< Defect > m_acceptors
virtual void FillTree()=0
bool GetElementRegion(const size_t i, size_t &region, bool &active) const override
std::vector< std::vector< float > > m_acceptorOcc
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
size_t FindRegion(const std::string &name) const
virtual bool Interpolate(const double x, const double y, const double z, const std::vector< double > &field, double &f)=0
bool GetElectronMobility(const double x, const double y, const double z, double &mob)
Get the electron mobility at a given point in the mesh.
bool HasVelocityMap() const override
bool GetElementNodes(const size_t i, std::vector< size_t > &nodes) const override
std::vector< std::vector< float > > m_donorOcc
std::vector< std::array< double, N > > m_vertices
bool GetHoleMobility(const double x, const double y, const double z, double &mob)
Get the hole mobility at a given point in the mesh.
bool SetWeightingField(const std::string &datfile1, const std::string &datfile2, const double dv, const std::string &label)
Import field maps defining the prompt weighting field and potential.
std::vector< Element > m_elements
void EnableVelocityMap(const bool on)
Switch use of the imported velocity map on/off.
bool GetVoltageRange(double &vmin, double &vmax) override
bool SetDynamicWeightingPotential(const std::string &datfile1, const std::string &datfile2, const double dv, const double t, const std::string &label)
Import time-dependent weighting potentials at t >= 0.
bool HoleAttachment(const double x, const double y, const double z, double &eta) override
void SetMedium(const std::string &material, Medium *m)
Set the medium to be associated to all regions with a given material.
std::vector< double > m_hAlpha
std::vector< Region > m_regions
bool ElectronMobility(const double x, const double y, const double z, double &mu) override
bool HoleTownsend(const double x, const double y, const double z, double &alpha) override
std::vector< double > m_eAlpha
bool LoadWeightingField(const std::string &datafilename, std::vector< std::array< double, N > > &wf, std::vector< double > &wp)
std::vector< std::array< double, N > > m_hVelocity
static unsigned int ElementVertices(const Element &element)
std::map< std::string, std::vector< std::vector< double > > > m_dwp
std::array< double, 3 > m_bbMax
bool ReadDataset(std::ifstream &datafile, const std::string &dataset)
std::map< std::string, std::vector< double > > m_wshift
static constexpr size_t nMaxVertices
bool SetDynamicWeightingField(const std::string &datfile1, const std::string &datfile2, const double dv, const double t, const std::string &label)
Import time-dependent weighting fields at t >= 0.
size_t GetNumberOfRegions() const
Get the number of regions in the device.
bool SetWeightingPotential(const std::string &datfile1, const std::string &datfile2, const double dv, const std::string &label)
Import field maps defining the prompt weighting field and potential.
bool LoadData(const std::string &datafilename)
void EnableAlphaMap(const bool on=true)
Use the imported impact ionisation map or not.
double HoleLifetime(const double x, const double y, const double z)
std::vector< std::array< double, N > > m_efield
std::map< std::string, std::vector< double > > m_wpot
std::vector< std::array< double, N > > m_eVelocity
std::vector< double > m_hLifetime
size_t GetNumberOfDonors()
Get the number of donor states found in the map.
bool GetOffset(const std::string &label, double &dx, double &dy, double &dz) const
const std::vector< double > & DelayedSignalTimes(const std::string &label) override
void MapCoordinates(std::array< double, N > &x, std::array< bool, N > &mirr) const
void PrintRegions() const
List all currently defined regions.
void EnableLifetimeMap(const bool on=true)
Use the imported lifetime map or not.
virtual bool Interpolate(const double x, const double y, const double z, const std::vector< std::array< double, N > > &field, double &fx, double &fy, double &fz)=0
bool SetAcceptor(const size_t acceptorNumber, const double exsec, const double hxsec, const double concentration)
Set the properties of an acceptor-type defect state.
ComponentTcadBase()=delete
Default constructor.
bool ElectronAttachment(const double x, const double y, const double z, double &eta) override
std::vector< Defect > m_donors
size_t GetNumberOfAcceptors()
Get the number of acceptor states found in the map.
bool HasAttachmentMap() const override
bool SetWeightingFieldShift(const std::string &label, const double x, const double y, const double z)
Shift the maps of weighting field/potential for a given electrode with respect to the original mesh.
bool Initialise(const std::string &gridfilename, const std::string &datafilename)
Import mesh and field map from files.
std::vector< double > m_eMobility
virtual ~ComponentTcadBase()
Destructor.
void UpdatePeriodicity() override
void DelayedWeightingField(const double x, const double y, const double z, const double t, double &wx, double &wy, double &wz, const std::string &label) override
bool ElectronVelocity(const double x, const double y, const double z, double &vx, double &vy, double &vz) override
std::map< std::string, std::vector< std::vector< std::array< double, N > > > > m_dwf
double DelayedWeightingPotential(const double x, const double y, const double z, const double t, const std::string &label) override
void SetDriftRegion(const size_t ireg)
Make a region active ("driftable").
size_t GetNumberOfNodes() const override
bool HoleVelocity(const double x, const double y, const double z, double &vx, double &vy, double &vz) override
std::map< std::string, std::vector< double > > m_dwtp
bool SetDonor(const size_t donorNumber, const double exsec, const double hxsec, const double concentration)
Set the properties of a donor-type defect state.
void SetMedium(const size_t ireg, Medium *m)
Set the medium to be associated to a given region.
bool ElectronTownsend(const double x, const double y, const double z, double &alpha) override
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
double ElectronLifetime(const double x, const double y, const double z)
std::array< double, 3 > m_bbMin
std::vector< double > m_eLifetime
std::map< std::string, std::vector< std::array< double, N > > > m_wfield