Garfield++ v2r0
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
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 virtual bool IsInBoundingBox(const double x, const double y,
108 const double z) const {
109 return x >= xMinBoundingBox && x <= xMaxBoundingBox &&
110 y >= yMinBoundingBox && y <= yMaxBoundingBox &&
111 z >= zMinBoundingBox && z <= zMaxBoundingBox;
112 }
113
114 void SetRange();
115 void SetRangeZ(const double zmin, const double zmax);
116 /**
117 * Use these functions to disable a certain field component.
118 * Is a field component is disabled ElectricField and WeightingField will
119 * return 0 for this component.
120 * This is useful if you want to have calculated global field distortions and
121 * you want to
122 * add the field of a GEM. If you would simply add both components the field
123 * component
124 * in drift direction would be added twice!
125 */
127 disableFieldComponent[0] = true;
128 };
130 disableFieldComponent[1] = true;
131 };
133 disableFieldComponent[2] = true;
134 };
135 /**
136 * If you calculate the electric field component in \f$x\f$ direction along a line in x direction
137 * this field component will be constant inside mesh elements (by 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 direction the field will
139 * be smooth (also by construction). Yuri Piadyk proposed also to shape the electric field.
140 * This is done as follows. The field component calculated as described above is assumed to appear
141 * in the center of the mesh element.
142 * ________________________
143 * | M1 P | M2 | x direction
144 * |----x---x-|-----x------|-->
145 * | | |
146 * | | |
147 * |__________|____________|
148 *
149 * element 1 element 2
150 *
151 * Lets consider only the \f$x\f$ direction and we want to calculate \f$E_x(P)\f$. The field in the
152 * center of the element containing \f$P\f$ is \f$E_x(M_1) = E_1\f$. Without shaping it is \f$E_1\f$ along the
153 * \f$x\f$ direction in everywhere in element 1.
154 * The idea of the shaping is to do a linear interpolation of the \f$E_x\f$ between the field \f$E_1\f$
155 * 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.
156 * If P would be left from \f$M_1\f$ the field in the left neighboring element would be considered.
157 * In addition it is also checked if the material in both elements used for the interpolation is the same.
158 * Else no interpolation is done.
159 * \remark This shaping gives you a nice and smooth field, but you introduce additional information.
160 * This information is not coming from the CST simulation, but from the assumption that the field between
161 * elements changes in a linear way, which might be wrong! So you might consider to increase the number
162 * of mesh cells used in the simulation rather than using this smoothing.
163 */
165 doShaping = true;
166 }
168 doShaping = false;
169 }
170 /**
171 * Calculate the element index from the position in the x/y/z position vectors (m_xlines, m_ylines, m_zlines).
172 * This is public since it is used in ViewFEMesh::DrawCST.
173 */
174 int Index2Element(const unsigned int i, const unsigned int j, const unsigned int k);
175 /**
176 * Find the positions in the x/y/z position vectors (m_xlines, m_ylines, m_zlines) for a given point.
177 * The operator used for the comparison is <=. Therefore, the last entry in the vector will never be
178 * returned for a point inside the mesh.
179 */
180 bool Coordinate2Index(const double x, const double y, const double z,
181 unsigned int &i, unsigned int &j, unsigned int &k);
182 protected:
183 // Verify periodicities
184 void UpdatePeriodicity();
185 double GetElementVolume(const unsigned int i);
186 void GetAspectRatio(const unsigned int i, double& dmin, double& dmax);
187// static bool Greater(const double& a, const double& b) {
188// return (a > b);
189// };
190
191// void GetNodesForElement(int element, std::vector<int>& nodes);
192
193 /**
194 * Calculate the index in the vectors m_xlines, m_ylines, m_zlines, which is before the given coordinate.
195 * \remark x, y, z need to be mapped before using this function!
196 * \param x The x coordinate mapped to the basic cell.
197 * \param y The y coordinate mapped to the basic cell.
198 * \param z The z coordinate mapped to the basic cell.
199 * \param i The index of the m_xlines vector, where m_xlines.at(i) < x < m_xlines.at(i+1).
200 * \param j The index of the m_ylines vector, where m_ylines.at(j) < y < m_ylines.at(j+1).
201 * \param k The index of the m_zlines vector, where m_zlines.at(k) < z < m_zlines.at(k+1).
202 * \param position_mapped The calculated mapped position (x,y,z) -> (x_mapped, y_mapped, z_mapped)
203 * \param mirrored Information if x, y, or z direction is mirrored.
204 * \param rcoordinate Information about rotation of the component. See ComponentFieldMap::MapCoordinates.
205 * \param rotation Information about rotation of the component. See ComponentFieldMap::MapCoordinates.
206 */
207 bool Coordinate2Index(const double x, const double y, const double z,
208 unsigned int &i, unsigned int &j, unsigned int &k,
209 double *position_mapped, bool *mirrored,
210 double &rcoordinate, double &rotation);
211
212 private:
213 std::vector<double> m_xlines; ///< x positions in used in the CST mesh
214 std::vector<double> m_ylines; ///< y positions in used in the CST mesh
215 std::vector<double> m_zlines; ///< z positions in used in the CST mesh
216 std::vector<float> m_potential; ///< Potentials resulting from the CST simulation.
217 std::map<std::string,std::vector<float> > m_weightingFields; ///<Map of weighting field potentials
218 std::vector<unsigned char> m_elementMaterial; ///< This is the material id for each element. unsigned char is used since it uses only 1byte
219 unsigned int m_nx; ///< Number of mesh lines in x direction
220 unsigned int m_ny; ///< Number of mesh lines in y direction
221 unsigned int m_nz; ///< Number of mesh lines in z direction
222 // If true x,y,z fields of this component are disabled (e=0 V/cm).
223 bool disableFieldComponent[3];
224 bool doShaping;
225 static const unsigned int headerSize = 1000; ///< Size of the header in binary files used in the CST export
226 void ElectricFieldBinary(const double x, const double y, const double z, double& ex,
227 double& ey, double& ez, double& v, Medium*& m,
228 int& status, const bool calculatePotential = false);
229 float GetFieldComponent(const unsigned int i, const unsigned int j, const unsigned int k,
230 const double rx, const double ry, const double rz,
231 const char component, const std::vector<float>* potentials);
232
233 float GetPotential(const unsigned int i,const unsigned int j,const unsigned int k,
234 const double rx,const double ry ,const double rz, const std::vector<float>* potentials);
235
236 void ShapeField(float &ex, float &ey, float &ez,
237 const double rx, const double ry, const double rz,
238 const unsigned int i, const unsigned int j, const unsigned int k,
239 std::vector<float>* potentials);
240
241 /* Calculate the index (i,j,k) along x,y,z direction of the given element.
242 * i,j,k start at 0 and reach at maximum
243 * m_xlines-1,m_ylines-1,m_zlines-1
244 */
245 void Element2Index(int element, unsigned int& i, unsigned int& j, unsigned int& k);
246
247 int Index2Node(const unsigned int i, const unsigned int j, const unsigned int k);
248};
249
250/// Helper struct for drawing the mesh with ViewFEMesh.
252 double p1[2];
253 double p2[2];
254 double p3[2];
255 double p4[2];
258};
259}
260
261#endif
void UpdatePeriodicity()
Verify periodicities.
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
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)
bool Initialise(std::string elist, std::string nlist, std::string mplist, std::string prnsol, std::string unit="cm")
Definition: ComponentCST.cc:34
double GetElementVolume(const unsigned int i)
virtual bool IsInBoundingBox(const double x, const double y, const double z) const
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax)
Medium * GetMedium(const double x, const double y, const double z)
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)
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 SetRange()
Calculate x, y, z, V and angular ranges.
void SetRangeZ(const double zmin, const double zmax)
Base class for components based on finite-element field maps.
Abstract base class for media.
Definition: Medium.hh:11
Helper struct for drawing the mesh with ViewFEMesh.