Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation 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
7#include "Component.hh"
8
9namespace Garfield {
10
11/// Interpolation in a field map created by Sentaurus Device.
12
13template<size_t N>
15 public:
16 /// Default constructor
18 /// Constructor
19 ComponentTcadBase(const std::string& name) : Component(name) {
20 m_regions.reserve(10);
21 m_vertices.reserve(10000);
22 m_elements.reserve(10000);
23 }
24 /// Destructor
25 virtual ~ComponentTcadBase() {}
26
27 /** Import mesh and field map from files.
28 * \param gridfilename name of the .grd file containing the mesh
29 * \param datafilename name of the .dat file containing the nodal solution
30 */
31 bool Initialise(const std::string& gridfilename,
32 const std::string& datafilename);
33
34 /** Import field maps defining the prompt weighting field and potential.
35 * \param datfile1 .dat file containing the field map at nominal bias.
36 * \param datfile2 .dat file containing the field map for a configuration
37 with the potential at the electrode to be read out
38 increased by a small voltage dv.
39 * \param dv increase in electrode potential between the two field maps.
40 * \param label name of the electrode
41 *
42 * The field maps must use the same mesh as the drift field.
43 */
44 bool SetWeightingField(const std::string& datfile1,
45 const std::string& datfile2, const double dv,
46 const std::string& label);
47 /// Shift the maps of weighting field/potential for a given electrode
48 /// with respect to the original mesh. If the electrode does not exist
49 /// yet, a new one will be added to the list.
50 bool SetWeightingFieldShift(const std::string& label,
51 const double x, const double y, const double z);
52 /// Import time-dependent weighting potentials at t > 0.
53 bool SetWeightingPotential(const std::string& datfile1,
54 const std::string& datfile2, const double dv,
55 const double t, const std::string& label);
56 /// Import time-dependent weighting fields at t > 0.
57 bool SetWeightingField(const std::string& datfile1,
58 const std::string& datfile2, const double dv,
59 const double t, const std::string& label);
60
61 /// List all currently defined regions.
62 void PrintRegions() const;
63 /// Get the number of regions in the device.
64 size_t GetNumberOfRegions() const { return m_regions.size(); }
65 /// Get the name and "active volume" flag of a region.
66 void GetRegion(const size_t ireg, std::string& name, bool& active) const;
67 /// Make a region active ("driftable").
68 void SetDriftRegion(const size_t ireg);
69 /// Make a region inactive.
70 void UnsetDriftRegion(const size_t ireg);
71 /// Set the medium to be associated to a given region.
72 void SetMedium(const size_t ireg, Medium* m);
73 /// Set the medium to be associated to all regions with a given material.
74 void SetMedium(const std::string& material, Medium* m);
75
76 /// Get the number of elements in the mesh.
77 size_t GetNumberOfElements() const { return m_elements.size(); }
78 /// Get the number of vertices in the mesh.
79 size_t GetNumberOfNodes() const { return m_vertices.size(); }
80
81 /// Switch use of the imported velocity map on/off.
82 void EnableVelocityMap(const bool on);
83
84 /// Get the number of donor states found in the map.
85 size_t GetNumberOfDonors() { return m_donors.size(); }
86 /// Get the number of acceptor states found in the map.
87 size_t GetNumberOfAcceptors() { return m_acceptors.size(); }
88
89 /** Set the properties of a donor-type defect state.
90 * \param donorNumber index of the donor
91 * \param exsec cross-section [cm2] for electrons
92 * \param hxsec cross-section [cm2] for holes
93 * \param concentration defect density [cm-3]
94 */
95 bool SetDonor(const size_t donorNumber, const double exsec,
96 const double hxsec, const double concentration);
97 /// Set the properties of an acceptor-type defect state.
98 bool SetAcceptor(const size_t acceptorNumber, const double exsec,
99 const double hxsec, const double concentration);
100
101 /// Switch use of the imported impact ionisation map on/off.
102 void EnableAlphaMap(const bool on) { m_useAlphaMap = on; }
103
104 /// Switch use of the imported trapping map on/off.
105 void EnableAttachmentMap(const bool on) { m_useAttachmentMap = on; }
106
107 /// Get the electron mobility at a given point in the mesh.
108 bool GetElectronMobility(const double x, const double y, const double z,
109 double& mob);
110 /// Get the hole mobility at a given point in the mesh.
111 bool GetHoleMobility(const double x, const double y, const double z,
112 double& mob);
113
114 void WeightingField(const double x, const double y, const double z,
115 double& wx, double& wy, double& wz,
116 const std::string& label) override;
117 double WeightingPotential(const double x, const double y, const double z,
118 const std::string& label) override;
119 void DelayedWeightingField(const double x, const double y,
120 const double z, const double t, double& wx,
121 double& wy, double& wz,
122 const std::string& label) override;
123 double DelayedWeightingPotential(const double x, const double y,
124 const double z, const double t,
125 const std::string& label) override;
126
127 bool GetVoltageRange(double& vmin, double& vmax) override;
128
129 bool HasVelocityMap() const override {
130 return m_useVelocityMap && !(m_eVelocity.empty() && m_hVelocity.empty());
131 }
132 bool ElectronVelocity(const double x, const double y, const double z,
133 double& vx, double& vy, double& vz) override;
134 bool HoleVelocity(const double x, const double y, const double z,
135 double& vx, double& vy, double& vz) override;
136
137 bool HasTownsendMap() const override {
138 return m_useAlphaMap && !(m_eAlpha.empty() && m_hAlpha.empty());
139 }
140 bool HasAttachmentMap() const override {
141 return (m_useAttachmentMap && !(m_acceptors.empty() && m_donors.empty()));
142 }
143 bool ElectronAttachment(const double x, const double y, const double z,
144 double& eta) override;
145 bool HoleAttachment(const double x, const double y, const double z,
146 double& eta) override;
147
148 bool GetElectronLifetime(const double x, const double y, const double z,
149 double& etau) override;
150 bool GetHoleLifetime(const double x, const double y, const double z,
151 double& htau) override;
152
153 bool ElectronTownsend(const double x, const double y, const double z,
154 double& alpha) override;
155 bool HoleTownsend(const double x, const double y, const double z,
156 double& alpha) override;
157
158 protected:
159 // Max. number of vertices per element
160 static constexpr size_t nMaxVertices = 4;
161
162 // Regions
163 struct Region {
164 // Name of the region (from Tcad)
165 std::string name;
166 // Material of the region (from Tcad)
167 std::string material;
168 // Flag indicating if the region is active (i. e. a drift medium)
169 bool drift;
170 // Medium object associated to the region
172 };
173 std::vector<Region> m_regions;
174
175 // Vertex coordinates [cm].
176 std::vector<std::array<double, N> > m_vertices;
177
178 // Elements
179 struct Element {
180 // Indices of vertices
181 unsigned int vertex[nMaxVertices];
182 // Type of element
183 // 0: Point
184 // 1: Segment (line)
185 // 2: Triangle
186 // 3: Rectangle
187 // 4: Polygon
188 // 5: Tetrahedron
189 // 6: Pyramid
190 // 7: Prism
191 // 8: Brick
192 // 9: Tetrabrick
193 // 10: Polyhedron
194 // In 2D, types 1 - 3 are supported.
195 // In 3D, only types 2 and 5 are supported.
196 unsigned int type;
197 // Associated region
198 unsigned int region;
199 // Bounding box
200 std::array<float, N> bbMin;
201 std::array<float, N> bbMax;
202 };
203 std::vector<Element> m_elements;
204
205 // Potential [V] at each vertex.
206 std::vector<double> m_epot;
207 // Electric field [V / cm].
208 std::vector<std::array<double, N> > m_efield;
209
210 // Weighting field and potential at each vertex.
211 std::vector<std::array<double, N> > m_wfield;
212 std::vector<double> m_wpot;
213 // Weighting field labels and offsets.
214 std::vector<std::string> m_wlabel;
215 std::vector<std::array<double, 3> > m_wshift;
216
217 // Delayed weighting field and potential.
218 std::vector<std::vector<std::array<double, N> > > m_dwf;
219 std::vector<std::vector<double> > m_dwp;
220 // Times corresponding to the delayed weighting fields/potentials.
221 std::vector<double> m_dwtf;
222 std::vector<double> m_dwtp;
223
224 // Velocities [cm / ns]
225 std::vector<std::array<double, N> > m_eVelocity;
226 std::vector<std::array<double, N> > m_hVelocity;
227 // Mobilities [cm2 / (V ns)]
228 std::vector<double> m_eMobility;
229 std::vector<double> m_hMobility;
230 // Impact ionisation coefficients [1 / cm]
231 std::vector<double> m_eAlpha;
232 std::vector<double> m_hAlpha;
233 // Lifetimes [ns]
234 std::vector<double> m_eLifetime;
235 std::vector<double> m_hLifetime;
236 // Trap occupations [dimensionless]
237 std::vector<std::vector<float> > m_donorOcc;
238 std::vector<std::vector<float> > m_acceptorOcc;
239 // Attachment coefficients [1 / cm]
240 std::vector<double> m_eAttachment;
241 std::vector<double> m_hAttachment;
242
243 struct Defect {
244 // Electron cross-section
245 double xsece;
246 // Hole cross-section
247 double xsech;
248 // Concentration
249 double conc;
250 };
251 std::vector<Defect> m_donors;
252 std::vector<Defect> m_acceptors;
253
254 // Use velocity map or not.
255 bool m_useVelocityMap = false;
256 // Use trapping map or not.
257 bool m_useAttachmentMap = false;
258 // Use impact ionisation map or not.
259 bool m_useAlphaMap = false;
260
261 // Bounding box.
262 std::array<double, 3> m_bbMin = {{0., 0., 0.}};
263 std::array<double, 3> m_bbMax = {{0., 0., 0.}};
264
265 // Voltage range
266 double m_pMin = 0.;
267 double m_pMax = 0.;
268
269 void UpdatePeriodicity() override;
270
271 void Cleanup();
272
273 static unsigned int ElementVertices(const Element& element) {
274 return std::min(element.type + 1, 4U);
275 }
276 virtual bool Interpolate(const double x, const double y, const double z,
277 const std::vector<double>& field, double& f) = 0;
278 virtual bool Interpolate(const double x, const double y, const double z,
279 const std::vector<std::array<double, N> >& field,
280 double& fx, double& fy, double& fz) = 0;
281 virtual void FillTree() = 0;
282
283 size_t FindRegion(const std::string& name) const;
284 void MapCoordinates(std::array<double, N>& x,
285 std::array<bool, N>& mirr) const;
286 bool InBoundingBox(const std::array<double, N>& x) const {
287 for (size_t i = 0; i < N; ++i) {
288 if (x[i] < m_bbMin[i] || x[i] > m_bbMax[i]) return false;
289 }
290 return true;
291 }
292 void UpdateAttachment();
293
294 bool LoadGrid(const std::string& gridfilename);
295 bool LoadData(const std::string& datafilename);
296 bool ReadDataset(std::ifstream& datafile, const std::string& dataset);
297 bool LoadWeightingField(const std::string& datafilename,
298 std::vector<std::array<double, N> >& wf,
299 std::vector<double>& wp);
300
301 bool GetOffset(const std::string& label,
302 double& dx, double& dy, double& dz) const;
303};
304}
305#endif
bool GetElectronLifetime(const double x, const double y, const double z, double &etau) override
bool InBoundingBox(const std::array< double, N > &x) const
std::vector< double > m_hMobility
bool HasTownsendMap() const override
Does the component have maps of the Townsend coefficient?
bool LoadGrid(const std::string &gridfilename)
bool SetWeightingPotential(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.
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
std::vector< std::vector< float > > m_acceptorOcc
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
std::vector< std::string > m_wlabel
size_t FindRegion(const std::string &name) const
std::vector< std::array< double, 3 > > m_wshift
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
Does the component have velocity maps?
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)
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
Calculate the voltage range [V].
bool HoleAttachment(const double x, const double y, const double z, double &eta) override
Get the hole attachment coefficient.
std::vector< std::vector< double > > m_dwp
std::vector< double > m_eAttachment
std::vector< double > m_hAlpha
std::vector< Region > m_regions
bool HoleTownsend(const double x, const double y, const double z, double &alpha) override
Get the hole Townsend coefficient.
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::array< double, 3 > m_bbMax
bool ReadDataset(std::ifstream &datafile, const std::string &dataset)
size_t GetNumberOfNodes() const
Get the number of vertices in the mesh.
static constexpr size_t nMaxVertices
size_t GetNumberOfRegions() const
Get the number of regions in the device.
bool LoadData(const std::string &datafilename)
std::vector< std::array< double, N > > m_efield
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 GetHoleLifetime(const double x, const double y, const double z, double &htau) override
bool GetOffset(const std::string &label, double &dx, double &dy, double &dz) const
void MapCoordinates(std::array< double, N > &x, std::array< bool, N > &mirr) const
void PrintRegions() const
List all currently defined regions.
void EnableAttachmentMap(const bool on)
Switch use of the imported trapping map on/off.
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
Get the electron attachment coefficient.
std::vector< std::vector< std::array< double, N > > > m_dwf
void EnableAlphaMap(const bool on)
Switch use of the imported impact ionisation map on/off.
std::vector< Defect > m_donors
size_t GetNumberOfElements() const
Get the number of elements in the mesh.
size_t GetNumberOfAcceptors()
Get the number of acceptor states found in the map.
bool HasAttachmentMap() const override
Does the component have attachment maps?
bool SetWeightingFieldShift(const std::string &label, const double x, const double y, const double z)
bool Initialise(const std::string &gridfilename, const std::string &datafilename)
std::vector< double > m_eMobility
virtual ~ComponentTcadBase()
Destructor.
void UpdatePeriodicity() override
Verify periodicities.
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
Get the electron drift velocity.
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").
bool HoleVelocity(const double x, const double y, const double z, double &vx, double &vy, double &vz) override
Get the hole drift velocity.
std::vector< std::array< double, N > > m_wfield
bool SetDonor(const size_t donorNumber, const double exsec, const double hxsec, const double concentration)
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
Get the electron Townsend coefficient.
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
std::vector< double > m_hAttachment
std::array< double, 3 > m_bbMin
std::vector< double > m_eLifetime
Component()=delete
Default constructor.
Abstract base class for media.
Definition Medium.hh:16