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