Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentAnalyticField.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_ANALYTIC_FIELD_H
2#define G_COMPONENT_ANALYTIC_FIELD_H
3
4#include <mutex>
5#include <cmath>
6#include <complex>
7
8#include "Component.hh"
10
11namespace Garfield {
12
13/// Semi-analytic calculation of two-dimensional configurations
14/// consisting of wires, planes, and tubes.
15
17 public:
18 /// Constructor
20 /// Destructor
22
23 Medium* GetMedium(const double x, const double y, const double z) override;
24 void ElectricField(const double x, const double y, const double z, double& ex,
25 double& ey, double& ez, Medium*& m, int& status) override {
26 m = nullptr;
27 // Calculate the field.
28 double v = 0.;
29 status = Field(x, y, z, ex, ey, ez, v, false);
30 // If the field is ok, get the medium.
31 if (status == 0) {
32 m = m_geometry ? m_geometry->GetMedium(x, y, z) : m_medium;
33 if (!m) {
34 status = -6;
35 } else if (!m->IsDriftable()) {
36 status = -5;
37 }
38 }
39 }
40
41 void ElectricField(const double x, const double y, const double z, double& ex,
42 double& ey, double& ez, double& v, Medium*& m,
43 int& status) override {
44 m = nullptr;
45 // Calculate the field.
46 status = Field(x, y, z, ex, ey, ez, v, true);
47 // If the field is ok, get the medium.
48 if (status == 0) {
49 m = m_geometry ? m_geometry->GetMedium(x, y, z) : m_medium;
50 if (!m) {
51 status = -6;
52 } else if (!m->IsDriftable()) {
53 status = -5;
54 }
55 }
56 }
57
58 bool GetVoltageRange(double& pmin, double& pmax) override;
59
60 void WeightingField(const double x, const double y, const double z,
61 double& wx, double& wy, double& wz,
62 const std::string& label) override {
63 wx = wy = wz = 0.;
64 if (!m_sigset) PrepareSignals();
65 Wfield(x, y, z, wx, wy, wz, label);
66 }
67 double WeightingPotential(const double x, const double y, const double z,
68 const std::string& label) override {
69 if (!m_sigset) PrepareSignals();
70 return Wpot(x, y, z, label);
71 }
72
73 bool GetBoundingBox(double& x0, double& y0, double& z0, double& x1,
74 double& y1, double& z1) override;
75 bool GetElementaryCell(double& x0, double& y0, double& z0, double& x1,
76 double& y1, double& z1) override;
77
78 bool IsWireCrossed(const double x0, const double y0, const double z0,
79 const double x1, const double y1, const double z1,
80 double& xc, double& yc, double& zc, const bool centre,
81 double& rc) override;
82
83 bool IsInTrapRadius(const double q0, const double x0, const double y0,
84 const double z0, double& xw, double& yx,
85 double& rw) override;
86
87
88 /// Set the medium inside the cell.
89 void SetMedium(Medium* medium) { m_medium = medium; }
90 /// Add a wire at (x, y) .
91 void AddWire(const double x, const double y, const double diameter,
92 const double voltage, const std::string& label,
93 const double length = 100., const double tension = 50.,
94 const double rho = 19.3, const int ntrap = 5);
95 /// Add a tube.
96 void AddTube(const double radius, const double voltage, const int nEdges,
97 const std::string& label);
98 /// Add a plane at constant x.
99 void AddPlaneX(const double x, const double voltage,
100 const std::string& label);
101 /// Add a plane at constant y.
102 void AddPlaneY(const double y, const double voltage,
103 const std::string& label);
104 /// Add a plane at constant radius.
105 void AddPlaneR(const double r, const double voltage,
106 const std::string& label);
107 /// Add a plane at constant phi.
108 void AddPlanePhi(const double phi, const double voltage,
109 const std::string& label);
110 /** Add a strip in the y or z direction on an existing plane at constant x.
111 * \param direction 'y' or 'z'.
112 * \param x coordinate of the plane.
113 * \param smin lower limit of the strip in y or z.
114 * \param smax upper limit of the strip in y or z.
115 * \param label weighting field identifier.
116 * \param gap distance to the opposite plane (optional).
117 */
118 void AddStripOnPlaneX(const char direction, const double x, const double smin,
119 const double smax, const std::string& label,
120 const double gap = -1.);
121 /// Add a strip in the x or z direction on an existing plane at constant y.
122 void AddStripOnPlaneY(const char direction, const double y, const double smin,
123 const double smax, const std::string& label,
124 const double gap = -1.);
125 /// Add a strip in the phi or z direction on an existing plane at constant radius.
126 void AddStripOnPlaneR(const char direction, const double r, const double smin,
127 const double smax, const std::string& label,
128 const double gap = -1.);
129 /// Add a strip in the r or z direction on an existing plane at constant phi.
130 void AddStripOnPlanePhi(const char direction, const double phi, const double smin,
131 const double smax, const std::string& label,
132 const double gap = -1.);
133 /** Add a pixel on an existing plane at constant x.
134 * \param x coordinate of the plane.
135 * \param ymin lower limit of the pixel cell in y,
136 * \param ymax upper limit of the pixel cell in y.
137 * \param zmin lower limit of the pixel cell in z.
138 * \param zmax upper limit of the pixel cell in z.
139 * \param label weighting field identifier.
140 * \param gap distance to the opposite plane (optional).
141 * \param rot rotation angle (rad) of the pixel (optional).
142 */
143 void AddPixelOnPlaneX(const double x, const double ymin, const double ymax,
144 const double zmin, const double zmax,
145 const std::string& label, const double gap = -1.,
146 const double rot = 0.);
147 /// Add a pixel on an existing plane at constant y.
148 void AddPixelOnPlaneY(const double y, const double xmin, const double xmax,
149 const double zmin, const double zmax,
150 const std::string& label, const double gap = -1.,
151 const double rot = 0.);
152 /// Add a pixel on an existing plane at constant radius.
153 void AddPixelOnPlaneR(const double r,
154 const double phimin, const double phimax,
155 const double zmin, const double zmax,
156 const std::string& label, const double gap = -1.);
157 /// Add a pixel on an existing plane at constant phi.
158 void AddPixelOnPlanePhi(const double phi,
159 const double rmin, const double rmax,
160 const double zmin, const double zmax,
161 const std::string& label, const double gap = -1.);
162
163 /// Set the periodic length [cm] in the x-direction.
164 void SetPeriodicityX(const double s);
165 /// Set the periodic length [cm] in the y-direction.
166 void SetPeriodicityY(const double s);
167 /// Set the periodicity [degree] in phi.
168 void SetPeriodicityPhi(const double phi);
169 /// Get the periodic length in the x-direction.
170 bool GetPeriodicityX(double& s);
171 /// Get the periodic length in the y-direction.
172 bool GetPeriodicityY(double& s);
173 /// Get the periodicity [degree] in phi.
174 bool GetPeriodicityPhi(double& s);
175
176 /// Use Cartesian coordinates (default).
178 /// Use polar coordinates.
179 void SetPolarCoordinates();
180 /// Are polar coordinates being used?
181 bool IsPolar() const { return m_polar; }
182
183 /// Print all available information on the cell.
184 void PrintCell();
185
186 /// Add a point charge.
187 void AddCharge(const double x, const double y, const double z,
188 const double q);
189 /// Remove all point charges.
190 void ClearCharges();
191 /// Print a list of the point charges.
192 void PrintCharges() const;
193
194 /** Return the cell type.
195 * Cells are classified according to the number
196 * and orientation of planes, the presence of
197 * periodicities and the location of the wires
198 * as one of the following types:
199 *
200 * A non-periodic cells with at most 1 x- and 1 y-plane
201 * B1X x-periodic cells without x-planes and at most 1 y-plane
202 * B1Y y-periodic cells without y-planes and at most 1 x-plane
203 * B2X cells with 2 x-planes and at most 1 y-plane
204 * B2Y cells with 2 y-planes and at most 1 x-plane
205 * C1 doubly periodic cells without planes
206 * C2X doubly periodic cells with x-planes
207 * C2Y doubly periodic cells with y-planes
208 * C3 double periodic cells with x- and y-planes
209 * D1 round tubes without axial periodicity
210 * D2 round tubes with axial periodicity
211 * D3 polygonal tubes without axial periodicity
212 */
213 std::string GetCellType() {
214 if (!m_cellset) {
215 if (CellCheck()) CellType();
216 }
217 return GetCellType(m_cellType);
218 }
219
220 /// Setup the weighting field for a given group of wires or planes.
221 void AddReadout(const std::string& label);
222
223 /** Calculate multipole moments for a given wire.
224 * \param iw Index of the wire.
225 * \param order Order of the highest multipole moment.
226 * \param print Print information about the fitting process.
227 * \param plot Plot the potential and multipole fit around the wire.
228 * \param rmult Distance in multiples of the wire radius
229 * at which the decomposition is to be carried out.
230 * \param eps Used in the fit for calculating the covariance matrix.
231 * \param nMaxIter Maximum number of iterations in the fit.
232 **/
233 bool MultipoleMoments(const unsigned int iw, const unsigned int order = 4,
234 const bool print = false, const bool plot = false,
235 const double rmult = 1., const double eps = 1.e-4,
236 const unsigned int nMaxIter = 20);
237 /// Request dipole terms be included for each of the wires (default: off).
238 void EnableDipoleTerms(const bool on = true);
239 /// Check the quality of the capacitance matrix inversion (default: off).
240 void EnableChargeCheck(const bool on = true) { m_chargeCheck = on; }
241
242 /// Get the number of wires.
243 unsigned int GetNumberOfWires() const { return m_nWires; }
244 /// Retrieve the parameters of a wire.
245 bool GetWire(const unsigned int i, double& x, double& y, double& diameter,
246 double& voltage, std::string& label, double& length,
247 double& charge, int& ntrap) const;
248
249 /// Get the number of equipotential planes at constant x.
250 unsigned int GetNumberOfPlanesX() const;
251 /// Get the number of equipotential planes at constant y.
252 unsigned int GetNumberOfPlanesY() const;
253 /// Get the number of equipotential planes at constant radius.
254 unsigned int GetNumberOfPlanesR() const;
255 /// Get the number of equipotential planes at constant phi.
256 unsigned int GetNumberOfPlanesPhi() const;
257 /// Retrieve the parameters of a plane at constant x.
258 bool GetPlaneX(const unsigned int i, double& x, double& voltage,
259 std::string& label) const;
260 /// Retrieve the parameters of a plane at constant y.
261 bool GetPlaneY(const unsigned int i, double& y, double& voltage,
262 std::string& label) const;
263 /// Retrieve the parameters of a plane at constant radius.
264 bool GetPlaneR(const unsigned int i, double& r, double& voltage,
265 std::string& label) const;
266 /// Retrieve the parameters of a plane at constant phi.
267 bool GetPlanePhi(const unsigned int i, double& phi, double& voltage,
268 std::string& label) const;
269 /// Retrieve the tube parameters.
270 bool GetTube(double& r, double& voltage, int& nEdges,
271 std::string& label) const;
272
273 /// Calculate the electric field at a given wire position, as if the wire
274 /// itself were not there, but with the presence of its mirror images.
275 bool ElectricFieldAtWire(const unsigned int iw, double& ex, double& ey);
276
277 /// Set the number of grid lines at which the electrostatic force
278 /// as function of the wire displacement is computed.
279 void SetScanningGrid(const unsigned int nX, const unsigned int nY);
280 /// Specify explicitly the boundaries of the the scanning area (i. e. the
281 /// area in which the electrostatic force acting on a wire is computed).
282 void SetScanningArea(const double xmin, const double xmax, const double ymin,
283 const double ymax);
284 /// Set the scanning area to the largest area around each wire
285 /// which is free from other cell elements.
286 void SetScanningAreaLargest() { m_scanRange = ScanningRange::Largest; }
287 /// Set the scanning area based on the zeroth-order estimates of the
288 /// wire shift, enlarged by a scaling factor. This is the default behaviour.
289 void SetScanningAreaFirstOrder(const double scale = 2.);
290 /// Switch on/off extrapolation of electrostatic forces beyond the
291 /// scanning area (default: off).
292 void EnableExtrapolation(const bool on = true) { m_extrapolateForces = on; }
293
294 /// Set the gravity orientation.
295 void SetGravity(const double dx, const double dy, const double dz);
296 /// Get the gravity orientation.
297 void GetGravity(double& dx, double& dy, double& dz) const;
298
299 /** Calculate a table of the forces acting on a wire.
300 * \param iw index of the wire
301 * \param xMap coordinates of the grid lines in x
302 * \param yMap coordinates of the grid lines in y
303 * \param fxMap x-components of the force at the grid points
304 * \param fyMap y-components of the force at the grid points
305 **/
306 bool ForcesOnWire(const unsigned int iw, std::vector<double>& xMap,
307 std::vector<double>& yMap,
308 std::vector<std::vector<double> >& fxMap,
309 std::vector<std::vector<double> >& fyMap);
310 /** Compute the sag profile of a wire.
311 * \param iw index of the wire
312 * \param detailed flag to request a detailed calculation of the profile
313 or only a fast one.
314 * \param csag coordinate along the wire.
315 * \param xsag x components of the sag profile.
316 * \param ysag y components of the sag profile.
317 * \param stretch relative elongation.
318 * \param print flag to print the calculation results or not.
319 **/
320 bool WireDisplacement(const unsigned int iw, const bool detailed,
321 std::vector<double>& csag, std::vector<double>& xsag,
322 std::vector<double>& ysag, double& stretch,
323 const bool print = true);
324 /// Set the number of shots used for numerically solving the wire sag
325 /// differential equation.
326 void SetNumberOfShots(const unsigned int n) { m_nShots = n; }
327 /// Set the number of integration steps within each shot (must be >= 1).
328 void SetNumberOfSteps(const unsigned int n);
329
330 enum Cell {
344 Unknown
345 };
346
347 private:
348 std::mutex m_mutex;
349
350 Medium* m_medium = nullptr;
351
352 bool m_chargeCheck = false;
353
354 bool m_cellset = false;
355 bool m_sigset = false;
356
357 bool m_polar = false;
358
359 // Cell type.
360 Cell m_cellType;
361
362 // Bounding box
363 double m_xmin, m_xmax;
364 double m_ymin, m_ymax;
365 double m_zmin, m_zmax;
366
367 // Voltage range
368 double m_vmin, m_vmax;
369
370 // Periodicities
371 bool m_perx = false;
372 bool m_pery = false;
373 double m_sx, m_sy;
374
375 // Signals
376 int m_nFourier = 1;
377 Cell m_cellTypeFourier = A00;
378 bool m_fperx = false;
379 bool m_fpery = false;
380 int m_mxmin = 0;
381 int m_mxmax = 0;
382 int m_mymin = 0;
383 int m_mymax = 0;
384 int m_mfexp = 0;
385
386 std::vector<std::string> m_readout;
387
388 // Wires
389 unsigned int m_nWires;
390 struct Wire {
391 double x, y; ///< Location.
392 double r; ///< Radius.
393 double v; ///< Potential.
394 double e; ///< Charge.
395 std::string type; ///< Label.
396 double u; ///< Length.
397 int ind; ///< Readout group.
398 /// Trap radius. Particle is "trapped" if within nTrap * radius of wire.
399 int nTrap;
400 double tension; ///< Stretching weight.
401 double density; ///< Density.
402 };
403 std::vector<Wire> m_w;
404
405 // Option for computation of dipole terms
406 bool m_dipole;
407 // Dipole angle and amplitude
408 std::vector<double> m_cosph2;
409 std::vector<double> m_sinph2;
410 std::vector<double> m_amp2;
411
412 // Parameters for B2 type cells
413 std::vector<double> m_b2sin;
414 // Parameters for C type cells
415 int m_mode;
416 std::complex<double> m_zmult;
417 double m_p1, m_p2, m_c1;
418 // Parameters for D3 type cells
419 // Conformal mapping in polygons
420 std::vector<std::complex<double> > wmap;
421 double m_kappa;
422
423 // Reference potential
424 double m_v0;
425 double m_corvta, m_corvtb, m_corvtc;
426
427 // Planes
428 // Existence
429 bool m_ynplan[4];
430 bool m_ynplax, m_ynplay;
431 // Coordinates
432 double m_coplan[4];
433 double m_coplax, m_coplay;
434 // Voltages
435 double m_vtplan[4];
436
437 struct Strip {
438 std::string type; ///< Label.
439 int ind; ///< Readout group.
440 double smin, smax; ///< Coordinates.
441 double gap; ///< Distance to the opposite electrode.
442 };
443
444 struct Pixel {
445 std::string type; ///< Label.
446 int ind = 0; ///< Readout group.
447 double smin = 0., smax = 0.; ///< Coordinates in x/y.
448 double zmin = 0., zmax = 0.; ///< Coordinates in z.
449 double gap = -1.; ///< Distance to the opposite electrode.
450 double cphi = 1.; ///< Rotation.
451 double sphi = 0.; ///< Rotation.
452 };
453
454 struct Plane {
455 std::string type; ///< Label.
456 int ind; ///< Readout group.
457 double ewxcor, ewycor; ///< Background weighting fields
458 std::vector<Strip> strips1; ///< x/y strips.
459 std::vector<Strip> strips2; ///< z strips.
460 std::vector<Pixel> pixels; ///< Pixels.
461 };
462 std::array<Plane, 5> m_planes;
463
464 // Tube
465 bool m_tube = false;
466 int m_mtube = 0;
467 int m_ntube = 1;
468 double m_cotube = 1.;
469 double m_cotube2 = 1.;
470 double m_vttube = 0.;
471
472 // Capacitance matrix
473 std::vector<std::vector<double> > m_a;
474 // Signal matrix
475 std::vector<std::vector<std::complex<double> > > m_sigmat;
476 // Induced charges on planes
477 std::vector<std::vector<double> > m_qplane;
478
479 // Point charges
480 struct Charge3d {
481 double x, y, z; ///< Coordinates.
482 double e; ///< Charge.
483 };
484 std::vector<Charge3d> m_ch3d;
485 unsigned int m_nTermBessel = 10;
486 unsigned int m_nTermPoly = 100;
487
488 bool m_useElectrostaticForce = true;
489 bool m_useGravitationalForce = true;
490 // Gravity
491 std::array<double, 3> m_down{{0, 0, 1}};
492 // Number of shots used for solving the wire sag differential equations
493 unsigned int m_nShots = 2;
494 // Number of integration steps within each shot.
495 unsigned int m_nSteps = 20;
496 // Options for setting the range of wire shifts
497 // for which the forces are computed.
498 enum class ScanningRange { Largest = 0, FirstOrder, User };
499 ScanningRange m_scanRange = ScanningRange::FirstOrder;
500 // Limits of the user-specified scanning range.
501 double m_xScanMin = 0.;
502 double m_xScanMax = 0.;
503 double m_yScanMin = 0.;
504 double m_yScanMax = 0.;
505 // Scaling factor for first-order estimate of the scanning range.
506 double m_scaleRange = 2.;
507 // Number of grid lines at which the forces are stored.
508 unsigned int m_nScanX = 11;
509 unsigned int m_nScanY = 11;
510 // Extrapolate beyond the scanning range or not.
511 bool m_extrapolateForces = false;
512
513 void UpdatePeriodicity() override;
514 void Reset() override {
515 CellInit();
516 m_medium = nullptr;
517 }
518
519 void CellInit();
520 bool Prepare();
521 bool CellCheck();
522 bool WireCheck() const;
523 bool CellType();
524 std::string GetCellType(const Cell) const;
525 bool PrepareStrips();
526 bool PrepareSignals();
527 bool SetupWireSignals();
528 bool SetupPlaneSignals();
529
530 // Calculation of charges
531 bool Setup();
532 bool SetupA00();
533 bool SetupB1X();
534 bool SetupB1Y();
535 bool SetupB2X();
536 bool SetupB2Y();
537 bool SetupC10();
538 bool SetupC2X();
539 bool SetupC2Y();
540 bool SetupC30();
541 bool SetupD10();
542 bool SetupD20();
543 bool SetupD30();
544
545 bool IprA00(const int mx, const int my);
546 bool IprB2X(const int my);
547 bool IprB2Y(const int mx);
548 bool IprC2X();
549 bool IprC2Y();
550 bool IprC30();
551 bool IprD10();
552 bool IprD30();
553
554 bool SetupDipoleTerms();
555
556 // Inversion of capacitance matrix
557 bool Charge();
558
559 // Evaluation of the electric field
560 int Field(const double xin, const double yin, const double zin, double& ex,
561 double& ey, double& ez, double& volt, const bool opt);
562 void FieldA00(const double xpos, const double ypos, double& ex, double& ey,
563 double& volt, const bool opt) const;
564 void FieldB1X(const double xpos, const double ypos, double& ex, double& ey,
565 double& volt, const bool opt) const;
566 void FieldB1Y(const double xpos, const double ypos, double& ex, double& ey,
567 double& volt, const bool opt) const;
568 void FieldB2X(const double xpos, const double ypos, double& ex, double& ey,
569 double& volt, const bool opt) const;
570 void FieldB2Y(const double xpos, const double ypos, double& ex, double& ey,
571 double& volt, const bool opt) const;
572 void FieldC10(const double xpos, const double ypos, double& ex, double& ey,
573 double& volt, const bool opt) const;
574 void FieldC2X(const double xpos, const double ypos, double& ex, double& ey,
575 double& volt, const bool opt) const;
576 void FieldC2Y(const double xpos, const double ypos, double& ex, double& ey,
577 double& volt, const bool opt) const;
578 void FieldC30(const double xpos, const double ypos, double& ex, double& ey,
579 double& volt, const bool opt) const;
580 void FieldD10(const double xpos, const double ypos, double& ex, double& ey,
581 double& volt, const bool opt) const;
582 void FieldD20(const double xpos, const double ypos, double& ex, double& ey,
583 double& volt, const bool opt) const;
584 void FieldD30(const double xpos, const double ypos, double& ex, double& ey,
585 double& volt, const bool opt) const;
586
587 // Field due to point charges
588 void Field3dA00(const double x, const double y, const double z, double& ex,
589 double& ey, double& ez, double& volt);
590 void Field3dB2X(const double x, const double y, const double z, double& ex,
591 double& ey, double& ez, double& volt);
592 void Field3dB2Y(const double x, const double y, const double z, double& ex,
593 double& ey, double& ez, double& volt);
594 void Field3dD10(const double x, const double y, const double z, double& ex,
595 double& ey, double& ez, double& volt);
596 // Evaluation of the weighting field
597 bool Wfield(const double x, const double y, const double z,
598 double& ex, double& ey, double& ez,
599 const std::string& label) const;
600 void WfieldWireA00(const double xpos, const double ypos, double& ex,
601 double& ey, const int mx, const int my,
602 const int sw) const;
603 void WfieldWireB2X(const double xpos, const double ypos, double& ex,
604 double& ey, const int my, const int sw) const;
605 void WfieldWireB2Y(const double xpos, const double ypos, double& ex,
606 double& ey, const int mx, const int sw) const;
607 void WfieldWireC2X(const double xpos, const double ypos, double& ex,
608 double& ey, const int sw) const;
609 void WfieldWireC2Y(const double xpos, const double ypos, double& ex,
610 double& ey, const int sw) const;
611 void WfieldWireC30(const double xpos, const double ypos, double& ex,
612 double& ey, const int sw) const;
613 void WfieldWireD10(const double xpos, const double ypos, double& ex,
614 double& ey, const int sw) const;
615 void WfieldWireD30(const double xpos, const double ypos, double& ex,
616 double& ey, const int sw) const;
617 void WfieldPlaneA00(const double xpos, const double ypos, double& ex,
618 double& ey, const int mx, const int my,
619 const int iplane) const;
620 void WfieldPlaneB2X(const double xpos, const double ypos, double& ex,
621 double& ey, const int my, const int iplane) const;
622 void WfieldPlaneB2Y(const double xpos, const double ypos, double& ex,
623 double& ey, const int mx, const int iplane) const;
624 void WfieldPlaneC2X(const double xpos, const double ypos, double& ex,
625 double& ey, const int iplane) const;
626 void WfieldPlaneC2Y(const double xpos, const double ypos, double& ex,
627 double& ey, const int iplane) const;
628 void WfieldPlaneC30(const double xpos, const double ypos, double& ex,
629 double& ey, const int iplane) const;
630 void WfieldPlaneD10(const double xpos, const double ypos, double& ex,
631 double& ey, const int iplane) const;
632 void WfieldPlaneD30(const double xpos, const double ypos, double& ex,
633 double& ey, const int iplane) const;
634 void WfieldStripZ(const double xpos, const double ypos, double& ex,
635 double& ey, const int ip, const Strip& strip) const;
636 void WfieldStripXy(const double xpos, const double ypos, const double zpos,
637 double& ex, double& ey, double& ez,
638 const int ip, const Strip& strip) const;
639 void WfieldPixel(const double xpos, const double ypos, const double zpos,
640 double& ex, double& ey, double& ez,
641 const int ip, const Pixel& pixel) const;
642
643 // Evaluation of the weighting potential.
644 double Wpot(const double x, const double y, const double z,
645 const std::string& label) const;
646 double WpotWireA00(const double x, const double y,
647 const int mx, const int my, const int sw) const;
648 double WpotWireB2X(const double x, const double y,
649 const int my, const int sw) const;
650 double WpotWireB2Y(const double x, const double y,
651 const int mx, const int sw) const;
652 double WpotWireC2X(const double x, const double y, const int sw) const;
653 double WpotWireC2Y(const double x, const double y, const int sw) const;
654 double WpotWireC30(const double x, const double y, const int sw) const;
655 double WpotWireD10(const double x, const double y, const int sw) const;
656 double WpotWireD30(const double x, const double y, const int sw) const;
657 double WpotPlaneA00(const double x, const double y,
658 const int mx, const int my, const int ip) const;
659 double WpotPlaneB2X(const double x, const double y,
660 const int my, const int ip) const;
661 double WpotPlaneB2Y(const double x, const double y,
662 const int mx, const int ip) const;
663 double WpotPlaneC2X(const double x, const double y, const int ip) const;
664 double WpotPlaneC2Y(const double x, const double y, const int ip) const;
665 double WpotPlaneC30(const double x, const double y, const int ip) const;
666 double WpotPlaneD10(const double x, const double y, const int ip) const;
667 double WpotPlaneD30(const double x, const double y, const int ip) const;
668 double WpotStripZ(const double x, const double y,
669 const int ip, const Strip& strip) const;
670 double WpotStripXy(const double x, const double y, const double z,
671 const int ip, const Strip& strip) const;
672 double WpotPixel(const double x, const double y, const double z,
673 const int ip, const Pixel& pixel) const;
674
675// Functions for calculating the electric field at a given wire position,
676 // as if the wire itself were not there but with the presence
677 // of its mirror images.
678 void FieldAtWireA00(const double xpos, const double ypos, double& ex,
679 double& ey, const std::vector<bool>& cnalso) const;
680 void FieldAtWireB1X(const double xpos, const double ypos, double& ex,
681 double& ey, const std::vector<bool>& cnalso) const;
682 void FieldAtWireB1Y(const double xpos, const double ypos, double& ex,
683 double& ey, const std::vector<bool>& cnalso) const;
684 void FieldAtWireB2X(const double xpos, const double ypos, double& ex,
685 double& ey, const std::vector<bool>& cnalso) const;
686 void FieldAtWireB2Y(const double xpos, const double ypos, double& ex,
687 double& ey, const std::vector<bool>& cnalso) const;
688 void FieldAtWireC10(const double xpos, const double ypos, double& ex,
689 double& ey, const std::vector<bool>& cnalso) const;
690 void FieldAtWireC2X(const double xpos, const double ypos, double& ex,
691 double& ey, const std::vector<bool>& cnalso) const;
692 void FieldAtWireC2Y(const double xpos, const double ypos, double& ex,
693 double& ey, const std::vector<bool>& cnalso) const;
694 void FieldAtWireC30(const double xpos, const double ypos, double& ex,
695 double& ey, const std::vector<bool>& cnalso) const;
696 void FieldAtWireD10(const double xpos, const double ypos, double& ex,
697 double& ey, const std::vector<bool>& cnalso) const;
698 void FieldAtWireD20(const double xpos, const double ypos, double& ex,
699 double& ey, const std::vector<bool>& cnalso) const;
700 void FieldAtWireD30(const double xpos, const double ypos, double& ex,
701 double& ey, const std::vector<bool>& cnalso) const;
702
703 void DipoleFieldA00(const double xpos, const double ypos, double& ex,
704 double& ey, double& volt, const bool opt) const;
705 void DipoleFieldB1X(const double xpos, const double ypos, double& ex,
706 double& ey, double& volt, const bool opt) const;
707 void DipoleFieldB1Y(const double xpos, const double ypos, double& ex,
708 double& ey, double& volt, const bool opt) const;
709 void DipoleFieldB2X(const double xpos, const double ypos, double& ex,
710 double& ey, double& volt, const bool opt) const;
711 void DipoleFieldB2Y(const double xpos, const double ypos, double& ex,
712 double& ey, double& volt, const bool opt) const;
713
714 // Auxiliary functions for C type cells
715 double Ph2(const double xpos, const double ypos) const;
716 double Ph2Lim(const double radius) const {
717 return -log(abs(m_zmult) * radius * (1. - 3. * m_p1 + 5. * m_p2));
718 }
719 void E2Sum(const double xpos, const double ypos, double& ex,
720 double& ey) const;
721
722 // Mapping function for D30 type cells
723 void ConformalMap(const std::complex<double>& z, std::complex<double>& ww,
724 std::complex<double>& wd) const;
725
726 bool InTube(const double x0, const double y0, const double a,
727 const int n) const;
728
729 bool SagDetailed(const Wire& wire, const std::vector<double>& xMap,
730 const std::vector<double>& yMap,
731 const std::vector<std::vector<double> >& fxMap,
732 const std::vector<std::vector<double> >& fyMap,
733 std::vector<double>& csag, std::vector<double>& xsag,
734 std::vector<double>& ysag) const;
735 bool GetForceRatio(const Wire& wire, const double coor,
736 const std::array<double, 2>& bend,
737 const std::array<double, 2>& dbend,
738 std::array<double, 2>& f, const std::vector<double>& xMap,
739 const std::vector<double>& yMap,
740 const std::vector<std::vector<double> >& fxMap,
741 const std::vector<std::vector<double> >& fyMap) const;
742 bool FindZeroes(const Wire& wire, const double h, std::vector<double>& x,
743 const std::vector<double>& xMap,
744 const std::vector<double>& yMap,
745 const std::vector<std::vector<double> >& fxMap,
746 const std::vector<std::vector<double> >& fyMap) const;
747 bool StepRKN(const Wire& wire, const double h, double& x,
748 std::array<double, 2>& y, std::array<double, 2>& yp,
749 const std::vector<double>& xMap, const std::vector<double>& yMap,
750 const std::vector<std::vector<double> >& fxMap,
751 const std::vector<std::vector<double> >& fyMap) const;
752 bool Trace(const Wire& wire, const double h, const std::vector<double>& xx,
753 std::vector<double>& f, const std::vector<double>& xMap,
754 const std::vector<double>& yMap,
755 const std::vector<std::vector<double> >& fxMap,
756 const std::vector<std::vector<double> >& fyMap) const;
757};
758} // namespace Garfield
759
760#endif
void PrintCell()
Print all available information on the cell.
void SetGravity(const double dx, const double dy, const double dz)
Set the gravity orientation.
bool GetVoltageRange(double &pmin, double &pmax) override
Calculate the voltage range [V].
void SetPolarCoordinates()
Use polar coordinates.
void SetPeriodicityX(const double s)
Set the periodic length [cm] in the x-direction.
void EnableDipoleTerms(const bool on=true)
Request dipole terms be included for each of the wires (default: off).
bool GetPeriodicityY(double &s)
Get the periodic length in the y-direction.
void SetCartesianCoordinates()
Use Cartesian coordinates (default).
void AddPixelOnPlanePhi(const double phi, const double rmin, const double rmax, const double zmin, const double zmax, const std::string &label, const double gap=-1.)
Add a pixel on an existing plane at constant phi.
void AddTube(const double radius, const double voltage, const int nEdges, const std::string &label)
Add a tube.
void AddPlaneX(const double x, const double voltage, const std::string &label)
Add a plane at constant x.
void EnableChargeCheck(const bool on=true)
Check the quality of the capacitance matrix inversion (default: off).
void AddPixelOnPlaneX(const double x, const double ymin, const double ymax, const double zmin, const double zmax, const std::string &label, const double gap=-1., const double rot=0.)
bool IsPolar() const
Are polar coordinates being used?
void SetMedium(Medium *medium)
Set the medium inside the cell.
void AddCharge(const double x, const double y, const double z, const double q)
Add a point charge.
unsigned int GetNumberOfWires() const
Get the number of wires.
void SetScanningGrid(const unsigned int nX, const unsigned int nY)
void SetNumberOfSteps(const unsigned int n)
Set the number of integration steps within each shot (must be >= 1).
void SetNumberOfShots(const unsigned int n)
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status) override
Calculate the drift field [V/cm] and potential [V] at (x, y, z).
void AddPixelOnPlaneR(const double r, const double phimin, const double phimax, const double zmin, const double zmax, const std::string &label, const double gap=-1.)
Add a pixel on an existing plane at constant radius.
bool GetWire(const unsigned int i, double &x, double &y, double &diameter, double &voltage, std::string &label, double &length, double &charge, int &ntrap) const
Retrieve the parameters of a wire.
bool GetPlaneR(const unsigned int i, double &r, double &voltage, std::string &label) const
Retrieve the parameters of a plane at constant radius.
bool WireDisplacement(const unsigned int iw, const bool detailed, std::vector< double > &csag, std::vector< double > &xsag, std::vector< double > &ysag, double &stretch, const bool print=true)
void GetGravity(double &dx, double &dy, double &dz) const
Get the gravity orientation.
void AddStripOnPlaneX(const char direction, const double x, const double smin, const double smax, const std::string &label, const double gap=-1.)
void ClearCharges()
Remove all point charges.
unsigned int GetNumberOfPlanesY() const
Get the number of equipotential planes at constant y.
void AddPlanePhi(const double phi, const double voltage, const std::string &label)
Add a plane at constant phi.
void AddPlaneR(const double r, const double voltage, const std::string &label)
Add a plane at constant radius.
bool ElectricFieldAtWire(const unsigned int iw, double &ex, double &ey)
bool MultipoleMoments(const unsigned int iw, const unsigned int order=4, const bool print=false, const bool plot=false, const double rmult=1., const double eps=1.e-4, const unsigned int nMaxIter=20)
void AddWire(const double x, const double y, const double diameter, const double voltage, const std::string &label, const double length=100., const double tension=50., const double rho=19.3, const int ntrap=5)
Add a wire at (x, y) .
void EnableExtrapolation(const bool on=true)
unsigned int GetNumberOfPlanesX() const
Get the number of equipotential planes at constant x.
bool GetPeriodicityX(double &s)
Get the periodic length in the x-direction.
bool GetTube(double &r, double &voltage, int &nEdges, std::string &label) const
Retrieve the tube parameters.
bool GetPlaneX(const unsigned int i, double &x, double &voltage, std::string &label) const
Retrieve the parameters of a plane at constant x.
void AddPlaneY(const double y, const double voltage, const std::string &label)
Add a plane at constant y.
bool IsInTrapRadius(const double q0, const double x0, const double y0, const double z0, double &xw, double &yx, double &rw) override
bool GetElementaryCell(double &x0, double &y0, double &z0, double &x1, double &y1, double &z1) override
Get the coordinates of the elementary cell.
void SetPeriodicityPhi(const double phi)
Set the periodicity [degree] in phi.
bool GetPeriodicityPhi(double &s)
Get the periodicity [degree] in phi.
bool GetPlanePhi(const unsigned int i, double &phi, double &voltage, std::string &label) const
Retrieve the parameters of a plane at constant phi.
void AddStripOnPlaneY(const char direction, const double y, const double smin, const double smax, const std::string &label, const double gap=-1.)
Add a strip in the x or z direction on an existing plane at constant y.
bool GetBoundingBox(double &x0, double &y0, double &z0, double &x1, double &y1, double &z1) override
Get the bounding box coordinates.
bool ForcesOnWire(const unsigned int iw, std::vector< double > &xMap, std::vector< double > &yMap, std::vector< std::vector< double > > &fxMap, std::vector< std::vector< double > > &fyMap)
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
void SetScanningAreaFirstOrder(const double scale=2.)
bool IsWireCrossed(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, double &xc, double &yc, double &zc, const bool centre, double &rc) override
void AddReadout(const std::string &label)
Setup the weighting field for a given group of wires or planes.
void AddPixelOnPlaneY(const double y, const double xmin, const double xmax, const double zmin, const double zmax, const std::string &label, const double gap=-1., const double rot=0.)
Add a pixel on an existing plane at constant y.
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
void SetPeriodicityY(const double s)
Set the periodic length [cm] in the y-direction.
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
unsigned int GetNumberOfPlanesPhi() const
Get the number of equipotential planes at constant phi.
void AddStripOnPlaneR(const char direction, const double r, const double smin, const double smax, const std::string &label, const double gap=-1.)
Add a strip in the phi or z direction on an existing plane at constant radius.
void PrintCharges() const
Print a list of the point charges.
void SetScanningArea(const double xmin, const double xmax, const double ymin, const double ymax)
bool GetPlaneY(const unsigned int i, double &y, double &voltage, std::string &label) const
Retrieve the parameters of a plane at constant y.
unsigned int GetNumberOfPlanesR() const
Get the number of equipotential planes at constant radius.
void AddStripOnPlanePhi(const char direction, const double phi, const double smin, const double smax, const std::string &label, const double gap=-1.)
Add a strip in the r or z direction on an existing plane at constant phi.
Abstract base class for components.
Definition: Component.hh:13
Geometry * m_geometry
Pointer to the geometry.
Definition: Component.hh:332
virtual Medium * GetMedium(const double x, const double y, const double z, const bool tesselated=false) const =0
Retrieve the medium at a given point.
Abstract base class for media.
Definition: Medium.hh:13
bool IsDriftable() const
Is charge carrier transport enabled in this medium?
Definition: Medium.hh:74