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