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