Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentParallelPlate.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_PP_H
2#define G_COMPONENT_PP_H
3
4#include <TF1.h>
5#include <TF2.h>
6
7#include <string>
8
11
12namespace Garfield {
13
14class Medium;
15class ComponentGrid;
16
18
19class ComponentParallelPlate : public Component {
20 public:
25
38 void Setup(const unsigned int N, std::vector<double> eps,
39 std::vector<double> d,
40 const double V, std::vector<int> sigmaIndex = {});
41
42 void ElectricField(const double x, const double y, const double z, double &ex,
43 double &ey, double &ez, Medium *&m, int &status) override;
44 void ElectricField(const double x, const double y, const double z, double &ex,
45 double &ey, double &ez, double &v, Medium *&m,
46 int &status) override;
47 using Component::ElectricField;
48 double WeightingPotential(const double x, const double y, const double z,
49 const std::string &label) override;
50
51 bool GetVoltageRange(double &vmin, double &vmax) override;
52
61 void AddPixel(double x, double z, double lx, double lz,
62 const std::string &label, bool fromAnode = true);
64 void AddStrip(double z, double lz, const std::string &label,
65 bool fromAnode = true);
66
69 void AddPlane(const std::string &label, bool fromAnode = true);
70
72 void SetMedium(Medium *medium) { m_medium = medium; }
73
81 void SetWeightingPotentialGrid(const double xmin, const double xmax,
82 const double xsteps, const double ymin,
83 const double ymax, const double ysteps,
84 const double zmin, const double zmax,
85 const double zsteps, const std::string &label);
86
89 void SetWeightingPotentialGrids(const double xmin, const double xmax,
90 const double xsteps, const double ymin,
91 const double ymax, const double ysteps,
92 const double zmin, const double zmax,
93 const double zsteps);
94
97 void LoadWeightingPotentialGrid(const std::string &label) {
98 for (auto &electrode : m_readout_p) {
99 if (electrode.label != label) continue;
100 if (electrode.grid.LoadWeightingField(label + "map", "xyz", true)) {
101 std::cout << m_className << "::LoadWeightingPotentialGrid: "
102 << "Weighting potential set for " << label << ".\n";
103 electrode.m_usegrid = true;
104 return;
105 }
106 }
107 std::cerr << m_className
108 << "::LoadWeightingPotentialGrid: Could not find file for "
109 << label << ".\n";
110 }
111
112 Medium *GetMedium(const double x, const double y, const double z) override;
113
114 bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax,
115 double &ymax, double &zmax) override;
116
117 // Obtain the index and permitivity of the layer at height z.
118 // TODO: getLayer -> GetLayer
119 bool getLayer(const double y, int &m, double &epsM) {
120 m = -1;
121 if (y < m_z[0]) return false;
122 for (int i = 1; i < m_N; i++) {
123 if (y <= m_z[i]) {
124 m = i;
125 break;
126 }
127 }
128 if (m == -1) return false;
129 epsM = m_epsHolder[m - 1];
130 return true;
131 }
132 // Obtain the relative permittivity from layer at index m
133 void getPermittivityFromLayer(int m, double &eps) {
134 eps = m_epsHolder.at(m - 1);
135 }
136 // Obtain the z-coordinate bounds of layer m
137 void getZBoundFromLayer(int m, double &zbottom, double &ztop) {
138 ztop = m_z.at(m);
139 zbottom = m_z.at(m - 1);
140 }
141 // Obtain number of layers
142 int NumberOfLayers() { return m_N - 1; }
143 // Get the indices of the gas gaps
144 void IndexOfGasGaps(std::vector<int> &indexGasGap) {
145 indexGasGap = {};
146 for (int i = 1; i < m_N; i++) {
147 if (!m_conductive[i]) indexGasGap.push_back(i);
148 }
149 }
150
151 void SetIntegrationPrecision(const double eps) { m_precision = eps; }
152
154
158
159 private:
160 double m_precision = 1.e-12;
161 static constexpr double m_Vw = 1.;
163 double m_V = 0.;
164
166
167 int m_N = 0;
168
170
171 std::vector<double> m_eps;
172 std::vector<double> m_epsHolder;
173 std::vector<double> m_d;
174 std::vector<double> m_z;
175
177 std::vector<bool> m_conductive;
178
180
183
184 std::vector<std::vector<std::vector<int>>> m_sigmaMatrix; // sigma_{i,j}^n,
185 // where n goes
186 // from 1 to N;
187 std::vector<std::vector<std::vector<int>>> m_thetaMatrix; // theta_{i,j}^n,
188 // where n goes
189 // from 1 to N;
190
191 std::vector<std::vector<double>> m_cMatrix;
192 std::vector<std::vector<double>> m_vMatrix;
193 std::vector<std::vector<double>> m_gMatrix;
194 std::vector<std::vector<double>> m_wMatrix;
195
197 double m_currentPosition = -1;
198
199 Medium *m_medium = nullptr;
200
202 struct Electrode {
203 std::string label;
205 double xpos, ypos;
206 double lx, ly;
207 bool formAnode = true;
208
209 bool m_usegrid = false;
211 };
212
214 enum structureelectrode { NotSet = -1, Plane, Strip, Pixel };
215
216 // Vectors storing the readout electrodes.
217 std::vector<std::string> m_readout;
218 std::vector<Electrode> m_readout_p;
219
220 // Functions that calculate the weighting potential
221 double IntegratePromptPotential(const Electrode &el, const double x,
222 const double y, const double z);
223
225
226 double FindWeightingPotentialInGrid(Electrode &el, const double x,
227 const double y, const double z);
228
229 // Construct the sigma matrix needed to calculate the w, v, c and g
230 // matrices
231 bool Nsigma(int N, std::vector<std::vector<int>> &sigmaMatrix);
232
233 // Construct the theta matrix needed to calculate the w, v, c and g
234 // matrices
235 bool Ntheta(int N, std::vector<std::vector<int>> &thetaMatrix,
236 std::vector<std::vector<int>> &sigmaMatrix);
237
238 // Construct the sigma and theta matrices.
239 void constructGeometryMatrices(const int N);
240
241 // Construct the w, v, c and g matrices needed for constructing
242 // the weighting potentials equations.
243 void constructGeometryFunction(const int N, const std::vector<double> &d);
244
245 // Build function h needed for the integrand of the weighting potential of a
246 // strip and pixel
248
249 // build integrand of weighting potential of a strip
251
252 // build integrand of weighting potential of a pixel
254
255 // weighting field of a plane in layer with index "indexLayer"
256 double constWEFieldLayer(const int indexLayer) {
257 double invEz = 0;
258 for (int i = 1; i <= m_N - 1; i++) {
259 invEz += m_d[i - 1] / m_epsHolder[i - 1];
260 }
261 return 1 / (m_epsHolder[indexLayer - 1] * invEz);
262 }
263
264 // weighting potential of a plane
265 double wpPlane(const double z) {
266 int im = -1;
267 double epsM = -1;
268 if (!getLayer(z, im, epsM)) return 0.;
269 double v = 1 - (z - m_z[im - 1]) * constWEFieldLayer(im);
270 for (int i = 1; i <= im - 1; i++) {
271 v -= m_d[i - 1] * constWEFieldLayer(i);
272 }
273
274 return v;
275 }
276
277 // electric field in layer with index "indexLayer"
278 double constEFieldLayer(const int indexLayer) {
279 if (m_conductive[indexLayer]) return 0.;
280 double invEz = 0;
281 for (int i = 1; i <= m_N - 1; i++) {
282 // TODO!
283 if (m_conductive[indexLayer]) continue;
284 invEz -= m_d[i - 1] / m_epsHolder[i - 1];
285 }
286 return m_V / (m_epsHolder[indexLayer - 1] * invEz);
287 }
288
289 // function to convert decimal to binary expressed in n digits.
290 bool decToBinary(int n, std::vector<int> &binaryNum);
291
292 // Rebuilds c, v, g and w matrix.
293 void LayerUpdate(const double z, const int im, const double epsM) {
294 if (z == m_currentPosition) return;
295
297
298 if (im != m_currentLayer) {
299 m_currentLayer = im;
300 for (int i = 0; i < im - 1; i++) m_eps[i] = m_epsHolder[i];
301 m_eps[im - 1] = epsM;
302 m_eps[im] = epsM;
303 for (int i = im + 1; i < m_N; i++) m_eps[i] = m_epsHolder[i - 1];
304 }
305
306 double diff1 = m_z[im] - z;
307 double diff2 = z - m_z[im - 1];
308
309 std::vector<double> d(m_N, 0.);
310 for (int i = 0; i < im - 1; i++) d[i] = m_d[i];
311 d[im - 1] = diff2;
312 d[im] = diff1;
313 for (int i = im + 1; i < m_N; i++) d[i] = m_d[i - 1];
314 // TODO::Construct c and g matrices only for im != m_currentLayer.
316 };
317
318 void UpdatePeriodicity() override;
319 void Reset() override;
320};
321} // namespace Garfield
322#endif
Component for interpolating field maps on a regular mesh.
void CalculateDynamicalWeightingPotential(const Electrode &el)
std::vector< bool > m_conductive
Flag whether a layer is conductive.
void constructGeometryMatrices(const int N)
void AddPlane(const std::string &label, bool fromAnode=true)
Add plane electrode, if you want to read the signal from the cathode set the second argument to false...
int m_currentLayer
Index of the current layer.
void AddStrip(double z, double lz, const std::string &label, bool fromAnode=true)
Add strip electrode.
TF2 m_wpPixelIntegral
Weighting potential integrand for pixels.
double m_V
Voltage difference between the parallel plates.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status) override
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
double FindWeightingPotentialInGrid(Electrode &el, const double x, const double y, const double z)
std::vector< std::vector< double > > m_cMatrix
c-matrixl.
void LoadWeightingPotentialGrid(const std::string &label)
This will load a previously calculated grid of time-dependent weighting potential values.
void SetWeightingPotentialGrids(const double xmin, const double xmax, const double xsteps, const double ymin, const double ymax, const double ysteps, const double zmin, const double zmax, const double zsteps)
This will calculate all electrodes time-dependent weighting potential on the specified grid.
std::vector< std::vector< std::vector< int > > > m_sigmaMatrix
std::vector< double > m_eps
relative permittivity of each layer
void constructGeometryFunction(const int N, const std::vector< double > &d)
void SetMedium(Medium *medium)
Setting the medium.
void getZBoundFromLayer(int m, double &zbottom, double &ztop)
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
std::vector< std::vector< double > > m_wMatrix
w-matrixl.
void SetWeightingPotentialGrid(const double xmin, const double xmax, const double xsteps, const double ymin, const double ymax, const double ysteps, const double zmin, const double zmax, const double zsteps, const std::string &label)
Calculate time-dependent weighting potential on a grid.
bool decToBinary(int n, std::vector< int > &binaryNum)
std::vector< std::vector< std::vector< int > > > m_thetaMatrix
double constWEFieldLayer(const int indexLayer)
void Setup(const unsigned int N, std::vector< double > eps, std::vector< double > d, const double V, std::vector< int > sigmaIndex={})
Define the geometry.
bool Ntheta(int N, std::vector< std::vector< int > > &thetaMatrix, std::vector< std::vector< int > > &sigmaMatrix)
Medium * GetMedium(const double x, const double y, const double z) override
void IndexOfGasGaps(std::vector< int > &indexGasGap)
double IntegratePromptPotential(const Electrode &el, const double x, const double y, const double z)
std::vector< double > m_d
thickness of each layer
double constEFieldLayer(const int indexLayer)
std::vector< std::vector< double > > m_vMatrix
v-matrixl.
bool getLayer(const double y, int &m, double &epsM)
bool GetVoltageRange(double &vmin, double &vmax) override
void LayerUpdate(const double z, const int im, const double epsM)
TF1 m_wpStripIntegral
Weighting potential integrand for strips.
void AddPixel(double x, double z, double lx, double lz, const std::string &label, bool fromAnode=true)
Add a pixel electrode.
void getPermittivityFromLayer(int m, double &eps)
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
std::vector< std::vector< double > > m_gMatrix
g-matrixl.
bool Nsigma(int N, std::vector< std::vector< int > > &sigmaMatrix)
Structure that captures the information of the electrodes under study.
bool m_usegrid
Enabling grid based calculations.