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