Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentCST.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_CST_H
2#define G_COMPONENT_CST_H
3
4#include <map>
5
7
8namespace Garfield {
9
10/// Component for importing and interpolating field maps from CST.
11/// This interface assumes a certain format of the ascii files
12/// Please find the tools to extract the field data from CST
13/// in the correct way here: http://www.desy.de/~zenker/garfieldpp.html
14
16 public:
17 /// Constructor
19 /// Destructor
21
22 void ShiftComponent(const double xShift, const double yShift,
23 const double zShift);
24
25 void GetNumberOfMeshLines(unsigned int& nx, unsigned int& ny,
26 unsigned int& nz) const;
27 size_t GetNumberOfElements() const override { return m_nElements; }
28 bool GetElement(const size_t i, size_t& mat, bool& drift,
29 std::vector<size_t>& nodes) const override;
30 size_t GetNumberOfNodes() const override { return m_nNodes; }
31 bool GetNode(const size_t i, double& x, double& y, double& z) const override;
32
33 void GetElementBoundaries(unsigned int element, double& xmin, double& xmax,
34 double& ymin, double& ymax, double& zmin,
35 double& zmax) const;
36
37 Medium* GetMedium(const double x, const double y, const double z) override;
38 void ElectricField(const double x, const double y, const double z, double& ex,
39 double& ey, double& ez, Medium*& m, int& status) override;
40 void ElectricField(const double x, const double y, const double z, double& ex,
41 double& ey, double& ez, double& v, Medium*& m,
42 int& status) override;
43 void WeightingField(const double x, const double y, const double z,
44 double& wx, double& wy, double& wz,
45 const std::string& label) override;
46
47 double WeightingPotential(const double x, const double y, const double z,
48 const std::string& label) override;
49 /**
50 * Deprecated version of the interface based on text file import of field
51 * data.
52 * \param elist Information about the element material of mesh cells. Each
53 * line contains the element number
54 * and the material index:
55 * \code
56 * 0 3
57 * ...
58 * \endcode
59 * \param nlist Information about the mesh like this:
60 * \code
61 * xmax 136 ymax 79 zmax 425
62 * x−l i n e s
63 * 0
64 * 8 . 9 2 8 5 7 e −07
65 * 1 . 7 8 5 7 1 e −06
66 * ...
67 * y−l i n e s
68 * 0
69 * 8 . 9 2 8 5 7 e −07
70 * 1 . 7 8 5 7 1 e −06
71 * ...
72 * z−l i n e s
73 * 0.0027
74 * 0.00270674
75 * ...
76 * \endcode
77 * \param mplist Information about material properties used in the simulation:
78 * \code
79 * Materials 4
80 * Material 1 PERX 1 . 0 0 0 0 0 0
81 * Material 2 RSVX 0 . 0 0 0 0 0 0 PERX 0 . 1 0 0 0 0 0 0E+11
82 * Material 3 PERX 3 . 5 0 0 0 0 0
83 * Material 4 PERX 4 . 8 0 0 0 0 0
84 * \endcode
85 * \param prnsol Information about the node potentials. Each line contains
86 * the node number and the potential:
87 * \code
88 * 0 1000.00
89 * ...
90 * \endcode
91 * \param unit The units used in the nlist input file
92 */
93 bool Initialise(std::string elist, std::string nlist, std::string mplist,
94 std::string prnsol, std::string unit = "cm");
95 /**
96 * Import of field data based on binary files.
97 * See http://www.desy.de/~zenker/garfieldpp.html to get information about the
98 * binary files export from CST.
99 * \param dataFile The binary file containing the field data exported from
100 * CST.
101 * \param unit The units used in the binary file. They are not necessarily
102 * equal to CST units.
103 */
104
105 bool Initialise(std::string dataFile, std::string unit = "cm");
106 /**
107 * Initialise a weighting field.
108 * This function can handle the deprecated text based file format (see
109 * Initialise( std::string elist...) for
110 * the expected file format, which is similar to prnsol.
111 * It also also handles binary files including the weighting field.
112 * \param prnsol The input file (binary/text file)
113 * \param label The name of the weighting field to be added. If a weighting
114 * field with same name already exist it is replaced by the new one.
115 * \param isBinary Depending on the file type you use, adapt this switch.
116 *
117 */
118 bool SetWeightingField(std::string prnsol, std::string label,
119 bool isBinary = true);
120
121 // Range
122 void SetRange() override;
123 void SetRangeZ(const double zmin, const double zmax);
124 /**
125 * Use these functions to disable a certain field component.
126 * Is a field component is disabled ElectricField and WeightingField will
127 * return 0 for this component.
128 * This is useful if you want to have calculated global field distortions and
129 * you want to
130 * add the field of a GEM. If you would simply add both components the field
131 * component
132 * in drift direction would be added twice!
133 */
134 void DisableXField() { disableFieldComponent[0] = true; }
135 void DisableYField() { disableFieldComponent[1] = true; }
136 void DisableZField() { disableFieldComponent[2] = true; }
137 /**
138 * If you calculate the electric field component in \f$x\f$ direction along a
139 * line in x direction
140 * this field component will be constant inside mesh elements (by
141 * construction). This can be observed
142 * by plotting \f$E_x\f$ in \f$x\f$ direction. If you plot \f$E_x\f$ in y
143 * direction the field will
144 * be smooth (also by construction). Yuri Piadyk proposed also to shape the
145 * electric field.
146 * This is done as follows. The field component calculated as described above
147 * is assumed to appear
148 * in the center of the mesh element.
149 * ________________________
150 * | M1 P | M2 | x direction
151 * |----x---x-|-----x------|-->
152 * | | |
153 * | | |
154 * |__________|____________|
155 *
156 * element 1 element 2
157 *
158 * Lets consider only the \f$x\f$ direction and we want to calculate
159 * \f$E_x(P)\f$. The field in the
160 * center of the element containing \f$P\f$ is \f$E_x(M_1) = E_1\f$. Without
161 * shaping it is \f$E_1\f$ along the
162 * \f$x\f$ direction in everywhere in element 1.
163 * The idea of the shaping is to do a linear interpolation of the \f$E_x\f$
164 * between the field \f$E_1\f$
165 * and \f$E_x(M_2)=E_2\f$. This results in a smooth electric field \f$E_x\f$
166 * also in \f$x\f$ direction.
167 * If P would be left from \f$M_1\f$ the field in the left neighboring element
168 * would be considered.
169 * In addition it is also checked if the material in both elements used for
170 * the interpolation is the same.
171 * Else no interpolation is done.
172 * \remark This shaping gives you a nice and smooth field, but you introduce
173 * additional information.
174 * This information is not coming from the CST simulation, but from the
175 * assumption that the field between
176 * elements changes in a linear way, which might be wrong! So you might
177 * consider to increase the number
178 * of mesh cells used in the simulation rather than using this smoothing.
179 */
180 void EnableShaping() { doShaping = true; }
181 void DisableShaping() { doShaping = false; }
182 /**
183 * Calculate the element index from the position in the x/y/z position vectors
184 * (m_xlines, m_ylines, m_zlines).
185 * This is public since it is used in ViewFEMesh::DrawCST.
186 */
187 int Index2Element(const unsigned int i, const unsigned int j,
188 const unsigned int k) const;
189 /**
190 * Find the positions in the x/y/z position vectors (m_xlines, m_ylines,
191 * m_zlines) for a given point.
192 * The operator used for the comparison is <=. Therefore, the last entry in
193 * the vector will never be
194 * returned for a point inside the mesh.
195 */
196 bool Coordinate2Index(const double x, const double y, const double z,
197 unsigned int& i, unsigned int& j, unsigned int& k) const;
198
199 protected:
200 // Verify periodicities
201 void UpdatePeriodicity() override;
202 double GetElementVolume(const unsigned int i) override;
203 void GetAspectRatio(const unsigned int i, double& dmin,
204 double& dmax) override;
205
206 /**
207 * Calculate the index in the vectors m_xlines, m_ylines, m_zlines, which is
208 * before the given coordinate.
209 * \remark x, y, z need to be mapped before using this function!
210 * \param x The x coordinate mapped to the basic cell.
211 * \param y The y coordinate mapped to the basic cell.
212 * \param z The z coordinate mapped to the basic cell.
213 * \param i The index of the m_xlines vector, where m_xlines.at(i) < x <
214 * m_xlines.at(i+1).
215 * \param j The index of the m_ylines vector, where m_ylines.at(j) < y <
216 * m_ylines.at(j+1).
217 * \param k The index of the m_zlines vector, where m_zlines.at(k) < z <
218 * m_zlines.at(k+1).
219 * \param position_mapped The calculated mapped position (x,y,z) -> (x_mapped,
220 * y_mapped, z_mapped)
221 * \param mirrored Information if x, y, or z direction is mirrored.
222 */
223 bool Coordinate2Index(const double x, const double y, const double z,
224 unsigned int& i, unsigned int& j, unsigned int& k,
225 double* position_mapped, bool* mirrored) const;
226
227 private:
228 std::vector<double> m_xlines; ///< x positions used in the CST mesh
229 std::vector<double> m_ylines; ///< y positions used in the CST mesh
230 std::vector<double> m_zlines; ///< z positions used in the CST mesh
231 /// Potentials resulting from the CST simulation.
232 std::vector<float> m_potential;
233 /// Map of weighting field potentials
234 std::map<std::string, std::vector<float> > m_weightingFields;
235 /// Material id for each element (unsigned char since it uses only 1 byte)
236 std::vector<unsigned char> m_elementMaterial;
237
238 unsigned int m_nx = 0; ///< Number of mesh lines in x direction
239 unsigned int m_ny = 0; ///< Number of mesh lines in y direction
240 unsigned int m_nz = 0; ///< Number of mesh lines in z direction
241 size_t m_nElements = 0; ///< Number of elements
242 size_t m_nNodes = 0; ///< Number of nodes
243 // If true x,y,z fields of this component are disabled (e=0 V/cm).
244 bool disableFieldComponent[3] = {false, false, false};
245 bool doShaping = false;
246
247 void ElectricFieldBinary(const double x, const double y, const double z,
248 double& ex, double& ey, double& ez, double& v,
249 Medium*& m, int& status,
250 const bool calculatePotential = false) const;
251 float GetFieldComponent(const unsigned int i, const unsigned int j,
252 const unsigned int k, const double rx,
253 const double ry, const double rz,
254 const char component,
255 const std::vector<float>& potentials) const;
256
257 float GetPotential(const unsigned int i, const unsigned int j,
258 const unsigned int k,
259 const double rx, const double ry, const double rz,
260 const std::vector<float>& potentials) const;
261
262 void ShapeField(float& ex, float& ey, float& ez, const double rx,
263 const double ry, const double rz, const unsigned int i,
264 const unsigned int j, const unsigned int k,
265 const std::vector<float>& potentials) const;
266
267 /* Calculate the index (i,j,k) along x,y,z direction of the given element.
268 * i,j,k start at 0 and reach at maximum
269 * m_xlines-1,m_ylines-1,m_zlines-1
270 */
271 void Element2Index(const size_t element, unsigned int& i, unsigned int& j,
272 unsigned int& k) const;
273
274 int Index2Node(const unsigned int i, const unsigned int j,
275 const unsigned int k) const;
276
277 void Node2Index(const size_t node, unsigned int& i, unsigned int& j,
278 unsigned int& k) const;
279};
280
281}
282
283#endif
bool Coordinate2Index(const double x, const double y, const double z, unsigned int &i, unsigned int &j, unsigned int &k) const
void UpdatePeriodicity() override
Verify periodicities.
~ComponentCST()
Destructor.
Definition: ComponentCST.hh:20
bool GetElement(const size_t i, size_t &mat, bool &drift, std::vector< size_t > &nodes) const override
Return the material and node indices of a mesh element.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
size_t GetNumberOfElements() const override
Return the number of mesh elements.
Definition: ComponentCST.hh:27
size_t GetNumberOfNodes() const override
Definition: ComponentCST.hh:30
double GetElementVolume(const unsigned int i) override
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
bool Initialise(std::string elist, std::string nlist, std::string mplist, std::string prnsol, std::string unit="cm")
Definition: ComponentCST.cc:87
bool GetNode(const size_t i, double &x, double &y, double &z) const override
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
void GetElementBoundaries(unsigned int element, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax) const
void GetNumberOfMeshLines(unsigned int &nx, unsigned int &ny, unsigned int &nz) const
bool SetWeightingField(std::string prnsol, std::string label, bool isBinary=true)
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
void ShiftComponent(const double xShift, const double yShift, const double zShift)
void SetRange() override
Calculate x, y, z, V and angular ranges.
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax) override
void SetRangeZ(const double zmin, const double zmax)
ComponentCST()
Constructor.
Definition: ComponentCST.cc:80
int Index2Element(const unsigned int i, const unsigned int j, const unsigned int k) const
Base class for components based on finite-element field maps.
Abstract base class for media.
Definition: Medium.hh:13