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