Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization 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 <array>
5
7
8namespace Garfield {
9
11
12class ComponentNeBem2d : public Component {
13 public:
18
20 void SetMedium(Medium* medium) { m_medium = medium; }
21
27 bool AddSegment(const double x0, const double y0, const double x1,
28 const double y1, const double v, const int ndiv = -1);
36 bool AddWire(const double x, const double y, const double d, const double v,
37 const int ntrap = 5);
45 bool AddRegion(const std::vector<double>& xp, const std::vector<double>& yp,
46 Medium* medium, const unsigned int bctype = 4,
47 const double v = 0., const int ndiv = -1);
48 void AddChargeDistribution(const double x, const double y, const double a,
49 const double b, const double rho);
51 void SetRangeZ(const double zmin, const double zmax);
52
54 bool Initialise();
55
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) {
63 }
64 void SetMaxNumberOfIterations(const unsigned int niter);
65
67 unsigned int GetNumberOfRegions() const { return m_regions.size(); }
69 bool GetRegion(const unsigned int i, std::vector<double>& xv,
70 std::vector<double>& yv, Medium*& medium, unsigned int& bctype,
71 double& v);
73 unsigned int GetNumberOfSegments() const { return m_segments.size(); }
75 bool GetSegment(const unsigned int i, double& x0, double& y0, double& x1,
76 double& x2, double& v) const;
78 unsigned int GetNumberOfWires() const { return m_wires.size(); }
80 bool GetWire(const unsigned int i, double& x, double& y, double& d, double& v,
81 double& q) const;
83 size_t GetNumberOfElements() const override { return m_elements.size(); }
85 bool GetElement(const unsigned int i, double& x0, double& y0, double& x1,
86 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;
95 using Component::ElectricField;
96 bool GetVoltageRange(double& vmin, double& vmax) override;
97
98 bool GetBoundingBox(double& xmin, double& ymin, double& zmin, double& xmax,
99 double& ymax, double& zmax) override;
100 bool GetElementaryCell(double& xmin, double& ymin, double& zmin, double& xmax,
101 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
116 unsigned int m_nDivisions = 5;
117 unsigned int m_nCollocationPoints = 1;
118 bool m_autoSize = false;
120 unsigned int m_nMaxIterations = 3;
121
123 Medium* m_medium = nullptr;
125 bool m_useRangeZ = false;
127 double m_zmin = -1.;
129 double m_zmax = 1.;
137 struct Region {
138 std::vector<double> xv;
139 std::vector<double> yv;
140 Medium* medium;
141 std::pair<BC, double> bc;
142 unsigned int depth;
143 int ndiv;
144 };
145
146 std::vector<Region> m_regions;
147
148 struct Segment {
149 std::array<double, 2> x0;
150 std::array<double, 2> x1;
153 std::pair<BC, double> bc;
154 int ndiv;
155 };
156
157 std::vector<Segment> m_segments;
158
159 struct Wire {
160 double x, y;
161 double r;
162 double v;
163 double q;
164 int ntrap;
165 };
166
167 std::vector<Wire> m_wires;
168
169 struct Element {
170 double x, y;
171 double a;
172 double cphi;
173 double sphi;
174 double q;
175 std::pair<BC, double> bc;
176 double lambda;
177 };
178
179 std::vector<Element> m_elements;
180
181 struct SpaceCharge {
182 double x, y;
183 double a, b;
184 double q;
185 double v0;
186 };
187 std::vector<SpaceCharge> m_spaceCharge;
188
190 void EliminateOverlaps(std::vector<Segment>& segments);
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
210 double LinePotential(const double a, const double x, const double y) const;
212 double WirePotential(const double r0, const double x, const double y) const;
214 void LineField(const double a, const double x, const double y, double& ex,
215 double& ey) const;
217 void WireField(const double r0, const double x, const double y, double& ex,
218 double& ey) const;
219
221 double BoxPotential(const double a, const double b, const double x,
222 const double y, const double v0) const;
224 void BoxField(const double a, const double b, const double x, const double y,
225 double& ex, double& ey) const;
226
227 void Reset() override;
228 void UpdatePeriodicity() override;
230 void ToLocal(const double xIn, const double yIn, const double cphi,
231 const double sphi, double& xOut, double& yOut) const;
233 void ToGlobal(const double xIn, const double yIn, const double cphi,
234 const double sphi, double& xOut, double& yOut) const;
235
237 int Field(const double x, const double y, const double z, double& ex,
238 double& ey, double& ez, double& v, Medium*& m, const bool opt);
239};
240} // namespace Garfield
241
242#endif
unsigned int GetNumberOfSegments() const
Return the number of conducting straight-line segments.
bool Solve(const std::vector< std::vector< double > > &inverseMatrix, const std::vector< double > &bc)
double m_zmax
Upper z limit.
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)
Add a conducting straight-line segment.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
std::vector< Wire > m_wires
Wires.
bool LUDecomposition(std::vector< std::vector< double > > &mat, std::vector< int > &index) const
void SplitElement(Element &oldElement, std::vector< Element > &elements)
bool GetVoltageRange(double &vmin, double &vmax) override
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.
void EliminateOverlaps(std::vector< Segment > &segments)
Split/merge overlapping segments.
double WirePotential(const double r0, const double x, const double y) const
Potential of a thin wire with radius r0.
void WireField(const double r0, const double x, const double y, double &ex, double &ey) const
Field of a thin wire with radius r0.
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
bool CheckConvergence(const double tol, std::vector< bool > &ok)
void EnableRandomCollocation(const bool on=true)
std::vector< Segment > m_segments
User-specified conducting straight-line segments.
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)
bool Discretise(const Segment &segment, std::vector< Element > &elements, const double lambda, const unsigned int ndiv)
Create elements from a straight-line segment.
unsigned int GetNumberOfRegions() const
Return the number of regions.
double LinePotential(const double a, const double x, const double y) const
Potential of a line segment (half-width a) in local coordinates.
void ToGlobal(const double xIn, const double yIn, const double cphi, const double sphi, double &xOut, double &yOut) const
Rotation from local to global coordinates.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status) override
std::vector< Element > m_elements
Straight-line boundary elements.
bool InvertMatrix(std::vector< std::vector< double > > &influenceMatrix, std::vector< std::vector< double > > &inverseMatrix) const
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.
int Field(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, const bool opt)
Evaluation of the electric field (and optionally potential).
unsigned int m_nDivisions
Default number elements per segment.
void SetMedium(Medium *medium)
Set the "background" medium.
BC
Boundary condition type.
@ Floating
Floating conductor (not implemented).
@ Charge
Fixed charge density (not implemented).
@ Dielectric
Dielectric-dielectric interface.
Medium * GetMedium(const double x, const double y, const double z) override
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.
void BoxField(const double a, const double b, const double x, const double y, double &ex, double &ey) const
Field of a uniformly charged rectangle.
bool AddWire(const double x, const double y, const double d, const double v, const int ntrap=5)
Add a wire.
size_t GetNumberOfElements() const override
Return the number of boundary elements.
void ToLocal(const double xIn, const double yIn, const double cphi, const double sphi, double &xOut, double &yOut) const
Rotation from global to local coordinates.
static const double InvTwoPiEpsilon0
ComponentNeBem2d()
Constructor.
void SetMaxNumberOfIterations(const unsigned int niter)
void UpdatePeriodicity() override
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
double BoxPotential(const double a, const double b, const double x, const double y, const double v0) const
Potential of a uniformly charged rectangle.
bool ComputeInfluenceMatrix(std::vector< std::vector< double > > &infmat) const
void LineField(const double a, const double x, const double y, double &ex, double &ey) const
Field of a line segment (half-width a) in local coordinates.
Medium * m_medium
Background medium.
std::vector< Region > m_regions
Regions.
std::vector< SpaceCharge > m_spaceCharge
unsigned int GetNumberOfWires() const
Return the number of wires.
double m_zmin
Lower z limit.
void LUSubstitution(const std::vector< std::vector< double > > &mat, const std::vector< int > &index, std::vector< double > &col) const
bool m_useRangeZ
Flag whether a z-range has been defined by the user.
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)
Add a region bounded by a polygon.
static const double InvEpsilon0
bool GetElementaryCell(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
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.
double lambda
Ratio of dielectric permittivities.
std::pair< BC, double > bc
Boundary condition.
double y
Coordinates of the element centre (collocation point).
double q
Charge density (solution).
int ndiv
Number of elements per edge segment.
Medium * medium
Medium associated to the region.
std::vector< double > xv
x-coordinates of the vertices.
unsigned int depth
Level in the hierarchy.
std::pair< BC, double > bc
Applied boundary condition.
std::vector< double > yv
y-coordinates of the vertices.
std::pair< BC, double > bc
Applied boundary condition.
std::array< double, 2 > x0
Coordinates of the start point.
std::array< double, 2 > x1
Coordinates of the end point.
double y
Coordinates of the centre.
int ntrap
Trap radius (in units of the wire radius).
double y
Coordinates of the centre.