Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentChargedRing.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_CHARGED_RING_H
2#define G_COMPONENT_CHARGED_RING_H
3
4#include <array>
5#include <cmath>
6#include <string>
7
9
10namespace Garfield {
11
13
15 public:
20
23 void SetArea(const double xmin, const double ymin, const double zmin,
24 const double xmax, const double ymax, const double zmax);
26 void UnsetArea();
28 void SetMedium(Medium* medium) { m_medium = medium; }
29
30 Medium* GetMedium(const double x, const double y, const double z) override;
31 void ElectricField(const double x, const double y, const double z, double& ex,
32 double& ey, double& ez, Medium*& m, int& status) override;
33 void ElectricField(const double x, const double y, const double z, double& ex,
34 double& ey, double& ez, double& v, Medium*& m,
35 int& status) override;
36
38 bool GetVoltageRange(double& vmin, double& vmax) override;
39
40 bool GetBoundingBox(double& xmin, double& ymin, double& zmin, double& xmax,
41 double& ymax, double& zmax) override;
42
44 bool AddChargedRing(const double x, const double y, const double z,
45 const double N);
46
49 void SetSpacingTolerance(const double spacing_tolerance) {
50 m_dSpacingTolerance = spacing_tolerance;
51 }
52
54 void SetSelfFieldTolerance(const double self_field_tolerance) {
55 m_dSelfFieldTolerance = self_field_tolerance;
56 }
57
58 struct Ring {
59 double z, r, charge;
60 Ring(double z_, double r_, double charge_) {
61 z = z_;
62 r = r_;
63 // This is charge / (2Pi * 4PiEpsilon0) which allows for more
64 // efficient field calculation
65 charge = charge_;
66 }
67 };
68
70 void UpdateCentre(double x, double y) {
71 m_centre = {x, y};
72 m_bCentreSet = true;
73 }
74
75 void EnableDebugging() { m_bDebug = true; }
76
77 void ClearActiveRings() { m_vRings.clear(); }
78
79 std::size_t GetNumberOfRings() const { return m_vRings.size(); }
80
81 const std::vector<Ring>& GetRings() const { return m_vRings; }
82
83 private:
85 std::array<double, 3> m_xmin = {{0., 0., 0.}};
86 std::array<double, 3> m_xmax = {{0., 0., 0.}};
88 bool m_hasArea = false;
90 Medium* m_medium = nullptr;
91
92 void Reset() override;
93 void UpdatePeriodicity() override;
94
96 void GetEllipticIntegrals(double x, double& K, double& E) const;
97
98 bool InArea(const double x, const double y, const double z) {
99 if (x < m_xmin[0] || x > m_xmax[0] || y < m_xmin[1] || y > m_xmax[1] ||
100 z < m_xmin[2] || z > m_xmax[2]) {
101 return false;
102 }
103 return true;
104 }
105
106 enum class Elliptic : std::size_t { X, K, E };
107 static const constexpr std::size_t elliptic_size{29981};
108 static const std::array<std::array<double, 3>, elliptic_size> m_elliptic;
109
110 bool m_bDebug = false;
111
113 std::array<double, 2> m_centre = {0., 0.};
114
115 std::vector<Ring> m_vRings;
116
117 double m_dSelfFieldTolerance = 0.00001; // this is a decent value with
118 // minimal 'strangeness' in the field
120
121 bool m_bCentreSet = false;
122
123 static void GetCoulombBallField(const Ring& ring,
124 const double r, const double z,
125 double& eFieldZ, double& eFieldR);
126 void GetChargedRingField(const Ring& ring, double r, double z,
127 double& eFieldZ, double& eFieldR) const;
128
129};
130} // namespace Garfield
131#endif
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box coordinates.
static void GetCoulombBallField(const Ring &ring, const double r, const double z, double &eFieldZ, double &eFieldR)
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
Calculate the drift field at given point.
bool GetVoltageRange(double &vmin, double &vmax) override
Calculate the voltage range [V].
static const std::array< std::array< double, 3 >, elliptic_size > m_elliptic
void Reset() override
Reset the component.
void GetChargedRingField(const Ring &ring, double r, double z, double &eFieldZ, double &eFieldR) const
std::array< double, 2 > m_centre
centre of cylindrical symmetry (x,y)
void UpdatePeriodicity() override
Verify periodicities.
bool m_hasArea
Did we specify the active area explicitly?
bool InArea(const double x, const double y, const double z)
void UpdateCentre(double x, double y)
Set the axis of symmetry.
void SetSelfFieldTolerance(const double self_field_tolerance)
function to set the tolerance below which divergences are caught
void SetArea(const double xmin, const double ymin, const double zmin, const double xmax, const double ymax, const double zmax)
Set the limits of the active area explicitly (instead of using a Geometry object).
const std::vector< Ring > & GetRings() const
std::array< double, 3 > m_xmin
Active area.
static const constexpr std::size_t elliptic_size
void SetSpacingTolerance(const double spacing_tolerance)
function to set the tolerance below which two rings are considered the same.
void SetMedium(Medium *medium)
Set the medium in the active area.
void UnsetArea()
Remove the explicit limits of the active area.
bool AddChargedRing(const double x, const double y, const double z, const double N)
Add a ring of charge N*e at x,y,z.
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
void GetEllipticIntegrals(double x, double &K, double &E) const
Gets elliptic integrals via list.
Medium * m_medium
Medium in the active area.
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).
virtual void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)=0
Calculate the drift field at given point.
Component()=delete
Default constructor.
Abstract base class for components.
Definition Medium.hh:17
Ring(double z_, double r_, double charge_)