Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentNeBem2d.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_NEBEM_2D_H
2#define G_COMPONENT_NEBEM_2D_H
3
4#include "Component.hh"
5
6namespace Garfield {
7
8/// Two-dimensional implementation of the nearly exact Boundary %Element Method.
9
11 public:
12 /// Constructor
14 /// Destructor
16
17 Medium* GetMedium(const double x, const double y, const double z) override;
18
19 void ElectricField(const double x, const double y, const double z, double& ex,
20 double& ey, double& ez, Medium*& m, int& status) override;
21 void ElectricField(const double x, const double y, const double z, double& ex,
22 double& ey, double& ez, double& v, Medium*& m,
23 int& status) override;
24 bool GetVoltageRange(double& vmin, double& vmax) override;
25
26 bool GetBoundingBox(double& xmin, double& ymin, double& zmin,
27 double& xmax, double& ymax, double& zmax) override;
28 bool GetElementaryCell(double& xmin, double& ymin, double& zmin,
29 double& xmax, double& ymax, double& zmax) override;
30
31 bool IsWireCrossed(const double x0, const double y0, const double z0,
32 const double x1, const double y1, const double z1,
33 double& xc, double& yc, double& zc, const bool centre,
34 double& rc) override;
35 bool IsInTrapRadius(const double q0, const double x0, const double y0,
36 const double z0, double& xw, double& yx,
37 double& rw) override;
38
39 /// Set the "background" medium.
40 void SetMedium(Medium* medium) { m_medium = medium; }
41
42 /** Add a conducting straight-line segment.
43 * \param x0,y0,x1,y1 coordinates of start and end point.
44 * \param v applied potential.
45 * \param ndiv number of elements in which to split the segment.
46 */
47 bool AddSegment(const double x0, const double y0, const double x1,
48 const double y1, const double v, const int ndiv = -1);
49 /** Add a wire.
50 * \param x,y centre of the wire.
51 * \param d wire diameter.
52 * \param v applied potential.
53 * \param ntrap multiple of the wire radius within which a particle is
54 considered to be trapped by the wire.
55 */
56 bool AddWire(const double x, const double y, const double d, const double v,
57 const int ntrap = 5);
58 /** Add a region bounded by a polygon.
59 * \param xp,yp x/y-coordinates of the vertices of the polygon.
60 * \param medium pointer to the medium associated to the region.
61 * \param bctype 1: fixed voltage, 4: dielectric-dielectric interface.
62 * \param v applied potential.
63 * \param ndiv number of elements on each edge segment.
64 */
65 bool AddRegion(const std::vector<double>& xp,
66 const std::vector<double>& yp, Medium* medium,
67 const unsigned int bctype = 4, const double v = 0.,
68 const int ndiv = -1);
69 void AddChargeDistribution(const double x, const double y,
70 const double a, const double b,
71 const double rho);
72 /// Set the extent of the drift region along z.
73 void SetRangeZ(const double zmin, const double zmax);
74
75 /// Discretise the geometry and compute the solution.
76 bool Initialise();
77
78 /// Set the default number of elements per segment.
79 void SetNumberOfDivisions(const unsigned int ndiv);
80
81 void SetNumberOfCollocationPoints(const unsigned int ncoll);
82 void EnableAutoResizing(const bool on = true) { m_autoSize = on; }
83 void EnableRandomCollocation(const bool on = true) {
84 m_randomCollocation = on;
85 }
86 void SetMaxNumberOfIterations(const unsigned int niter);
87
88 /// Return the number of regions.
89 unsigned int GetNumberOfRegions() const { return m_regions.size(); }
90 /// Return the properties of a given region.
91 bool GetRegion(const unsigned int i,
92 std::vector<double>& xv, std::vector<double>& yv,
93 Medium*& medium, unsigned int& bctype, double& v);
94 /// Return the number of conducting straight-line segments.
95 unsigned int GetNumberOfSegments() const { return m_segments.size(); }
96 /// Return the coordinates and voltage of a given straight-line segment.
97 bool GetSegment(const unsigned int i, double& x0, double& y0,
98 double& x1, double& x2, double& v) const;
99 /// Return the number of wires.
100 unsigned int GetNumberOfWires() const { return m_wires.size(); }
101 /// Return the coordinates, diameter, potential and charge of a given wire.
102 bool GetWire(const unsigned int i, double& x, double& y, double& d,
103 double& v, double& q) const;
104 /// Return the number of boundary elements.
105 unsigned int GetNumberOfElements() const { return m_elements.size(); }
106 /// Return the coordinates and charge of a given boundary element.
107 bool GetElement(const unsigned int i, double& x0, double& y0,
108 double& x1, double& y1, double& q) const;
109 private:
110 static const double InvEpsilon0;
111 static const double InvTwoPiEpsilon0;
112
113 /// Default number elements per segment.
114 unsigned int m_nDivisions = 5;
115 unsigned int m_nCollocationPoints = 1;
116 bool m_autoSize = false;
117 bool m_randomCollocation = false;
118 unsigned int m_nMaxIterations = 3;
119
120 /// Background medium.
121 Medium* m_medium = nullptr;
122 /// Flag whether a z-range has been defined by the user.
123 bool m_useRangeZ = false;
124 /// Lower z limit.
125 double m_zmin = -1.;
126 /// Upper z limit.
127 double m_zmax = 1.;
128 /// Boundary condition type.
129 enum BC {
130 Voltage = 1, ///< Fixed potential.
131 Charge, ///< Fixed charge density (not implemented).
132 Floating, ///< Floating conductor (not implemented).
133 Dielectric ///< Dielectric-dielectric interface.
134 };
135 struct Region {
136 std::vector<double> xv; ///< x-coordinates of the vertices.
137 std::vector<double> yv; ///< y-coordinates of the vertices.
138 Medium* medium; ///< Medium associated to the region.
139 std::pair<BC, double> bc; ///< Applied boundary condition.
140 unsigned int depth; ///< Level in the hierarchy.
141 int ndiv; ///< Number of elements per edge segment.
142 };
143 /// Regions.
144 std::vector<Region> m_regions;
145
146 struct Segment {
147 std::array<double, 2> x0; ///< Coordinates of the start point.
148 std::array<double, 2> x1; ///< Coordinates of the end point.
149 int region1; ///< Inner region.
150 int region2; ///< Outer region.
151 std::pair<BC, double> bc; ///< Applied boundary condition.
152 int ndiv; ///< Number of elements.
153 };
154 /// User-specified conducting straight-line segments.
155 std::vector<Segment> m_segments;
156
157 struct Wire {
158 double x, y; ///< Coordinates of the centre.
159 double r; ///< Radius.
160 double v; ///< Potential.
161 double q; ///< Charge.
162 int ntrap; ///< Trap radius (in units of the wire radius).
163 };
164 /// Wires.
165 std::vector<Wire> m_wires;
166
167 struct Element {
168 double x, y; ///< Coordinates of the element centre (collocation point).
169 double a; ///< Half-length.
170 double cphi; ///< Rotation.
171 double sphi; ///< Rotation.
172 double q; ///< Charge density (solution).
173 std::pair<BC, double> bc; ///< Boundary condition.
174 double lambda; ///< Ratio of dielectric permittivities.
175 };
176 /// Straight-line boundary elements.
177 std::vector<Element> m_elements;
178
179 struct SpaceCharge {
180 double x, y; ///< Coordinates of the centre.
181 double a, b; ///< Half-lengths.
182 double q; ///< Charge density.
183 double v0; ///< Offset.
184 };
185 std::vector<SpaceCharge> m_spaceCharge;
186
187 /// Split/merge overlapping segments.
188 void EliminateOverlaps(std::vector<Segment>& segments);
189 /// Create elements from a straight-line segment.
190 bool Discretise(const Segment& segment, std::vector<Element>& elements,
191 const double lambda, const unsigned int ndiv);
192
193 bool ComputeInfluenceMatrix(std::vector<std::vector<double> >& infmat) const;
194 bool InvertMatrix(std::vector<std::vector<double> >& influenceMatrix,
195 std::vector<std::vector<double> >& inverseMatrix) const;
196 bool LUDecomposition(std::vector<std::vector<double> >& mat,
197 std::vector<int>& index) const;
198 void LUSubstitution(const std::vector<std::vector<double> >& mat,
199 const std::vector<int>& index,
200 std::vector<double>& col) const;
201
202 bool Solve(const std::vector<std::vector<double> >& inverseMatrix,
203 const std::vector<double>& bc);
204 bool CheckConvergence(const double tol, std::vector<bool>& ok);
205 void SplitElement(Element& oldElement, std::vector<Element>& elements);
206
207 /// Potential of a line segment (half-width a) in local coordinates.
208 double LinePotential(const double a, const double x, const double y) const;
209 /// Potential of a thin wire with radius r0.
210 double WirePotential(const double r0, const double x, const double y) const;
211 /// Field of a line segment (half-width a) in local coordinates.
212 void LineField(const double a, const double x, const double y, double& ex,
213 double& ey) const;
214 /// Field of a thin wire with radius r0.
215 void WireField(const double r0, const double x, const double y, double& ex,
216 double& ey) const;
217
218 /// Potential of a uniformly charged rectangle.
219 double BoxPotential(const double a, const double b,
220 const double x, const double y, const double v0) const;
221 /// Field of a uniformly charged rectangle.
222 void BoxField(const double a, const double b,
223 const double x, const double y,
224 double& ex, double& ey) const;
225
226 void Reset() override;
227 void UpdatePeriodicity() override;
228 /// Rotation from global to local coordinates.
229 void ToLocal(const double xIn, const double yIn,
230 const double cphi, const double sphi,
231 double& xOut, double& yOut) const;
232 /// Rotation from local to global coordinates.
233 void ToGlobal(const double xIn, const double yIn,
234 const double cphi, const double sphi,
235 double& xOut, double& yOut) const;
236
237 /// Evaluation of the electric field (and optionally potential).
238 int Field(const double x, const double y, const double z, double& ex,
239 double& ey, double& ez, double& v, Medium*& m, const bool opt);
240};
241}
242
243#endif
Two-dimensional implementation of the nearly exact Boundary Element Method.
unsigned int GetNumberOfSegments() const
Return the number of conducting straight-line segments.
void SetNumberOfDivisions(const unsigned int ndiv)
Set the default number of elements per segment.
bool AddSegment(const double x0, const double y0, const double x1, const double y1, const double v, const int ndiv=-1)
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
bool GetVoltageRange(double &vmin, double &vmax) override
Calculate the voltage range [V].
bool GetSegment(const unsigned int i, double &x0, double &y0, double &x1, double &x2, double &v) const
Return the coordinates and voltage of a given straight-line segment.
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box coordinates.
void EnableRandomCollocation(const bool on=true)
void SetRangeZ(const double zmin, const double zmax)
Set the extent of the drift region along z.
void EnableAutoResizing(const bool on=true)
void SetNumberOfCollocationPoints(const unsigned int ncoll)
unsigned int GetNumberOfRegions() const
Return the number of regions.
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
unsigned int GetNumberOfElements() const
Return the number of boundary elements.
bool Initialise()
Discretise the geometry and compute the solution.
bool GetRegion(const unsigned int i, std::vector< double > &xv, std::vector< double > &yv, Medium *&medium, unsigned int &bctype, double &v)
Return the properties of a given region.
void SetMedium(Medium *medium)
Set the "background" medium.
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
void AddChargeDistribution(const double x, const double y, const double a, const double b, const double rho)
bool GetWire(const unsigned int i, double &x, double &y, double &d, double &v, double &q) const
Return the coordinates, diameter, potential and charge of a given wire.
bool AddWire(const double x, const double y, const double d, const double v, const int ntrap=5)
void SetMaxNumberOfIterations(const unsigned int niter)
unsigned int GetNumberOfWires() const
Return the number of wires.
bool IsInTrapRadius(const double q0, const double x0, const double y0, const double z0, double &xw, double &yx, double &rw) override
bool AddRegion(const std::vector< double > &xp, const std::vector< double > &yp, Medium *medium, const unsigned int bctype=4, const double v=0., const int ndiv=-1)
bool GetElementaryCell(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the coordinates of the elementary cell.
bool GetElement(const unsigned int i, double &x0, double &y0, double &x1, double &y1, double &q) const
Return the coordinates and charge of a given boundary element.
Abstract base class for components.
Definition: Component.hh:13
Abstract base class for media.
Definition: Medium.hh:13
int Solve(void)
Definition: neBEM.c:2441
int InvertMatrix(void)
Definition: neBEM.c:1236
Definition: neBEM.h:155