Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentNeBem3d.hh
Go to the documentation of this file.
1#ifndef G_COMPONENT_NEBEM_3D_H
2#define G_COMPONENT_NEBEM_3D_H
3
4#include <map>
5
6#include "Component.hh"
7
8namespace Garfield {
9
10/// Interface to neBEM.
11
13 public:
14 /// Constructor
16 /// Destructor
18
19 Medium* GetMedium(const double x, const double y, const double z) override;
20 void ElectricField(const double x, const double y, const double z, double& ex,
21 double& ey, double& ez, Medium*& m, int& status) override;
22 void ElectricField(const double x, const double y, const double z, double& ex,
23 double& ey, double& ez, double& v, Medium*& m,
24 int& status) override;
25 bool GetVoltageRange(double& vmin, double& vmax) override;
26
27 void WeightingField(const double x, const double y, const double z,
28 double& wx, double& wy, double& wz,
29 const std::string& label) override;
30 double WeightingPotential(const double x, const double y,
31 const double z, const std::string& label) override;
32
33 /// Add a plane at constant x.
34 void AddPlaneX(const double x, const double voltage);
35 /// Add a plane at constant y.
36 void AddPlaneY(const double y, const double voltage);
37 /// Add a plane at constant z.
38 void AddPlaneZ(const double z, const double voltage);
39 /// Get the number of equipotential planes at constant x.
40 unsigned int GetNumberOfPlanesX() const;
41 /// Get the number of equipotential planes at constant y.
42 unsigned int GetNumberOfPlanesY() const;
43 /// Get the number of equipotential planes at constant z.
44 unsigned int GetNumberOfPlanesZ() const;
45 /// Retrieve the parameters of a plane at constant x.
46 bool GetPlaneX(const unsigned int i, double& x, double& v) const;
47 /// Retrieve the parameters of a plane at constant y.
48 bool GetPlaneY(const unsigned int i, double& y, double& v) const;
49 /// Retrieve the parameters of a plane at constant z.
50 bool GetPlaneZ(const unsigned int i, double& z, double& v) const;
51
52 unsigned int GetNumberOfPrimitives() const { return m_primitives.size(); }
53 bool GetPrimitive(const unsigned int i, double& a, double& b, double& c,
54 std::vector<double>& xv, std::vector<double>& yv,
55 std::vector<double>& zv, int& interface, double& v,
56 double& q, double& lambda) const;
57 bool GetPrimitive(const unsigned int i, double& a, double& b, double& c,
58 std::vector<double>& xv, std::vector<double>& yv,
59 std::vector<double>& zv, int& vol1, int& vol2) const;
60 bool GetVolume(const unsigned int vol, int& shape, int& material,
61 double& eps, double& potential, double& charge, int& bc);
62 int GetVolume(const double x, const double y, const double z);
63
64 unsigned int GetNumberOfElements() const { return m_elements.size(); }
65 bool GetElement(const unsigned int i,
66 std::vector<double>& xv, std::vector<double>& yv,
67 std::vector<double>& zv, int& interface, double& bc,
68 double& lambda) const;
69
70 /// Retrieve surface panels, remove contacts and cut polygons to rectangles
71 /// and right-angle triangles.
72 bool Initialise();
73
74 /// Set the default value of the target linear size of the elements
75 /// produced by neBEM's discretisation process.
76 void SetTargetElementSize(const double length);
77 /// Set the smallest and largest allowed number of elements along
78 /// the lenght of a primitive.
79 void SetMinMaxNumberOfElements(const unsigned int nmin,
80 const unsigned int nmax);
81
82 /// Invert the influence matrix using lower-upper (LU) decomposition.
83 void UseLUInversion() { m_inversion = Inversion::LU; }
84 /// Invert the influence matrix using singular value decomposition.
85 void UseSVDInversion() { m_inversion = Inversion::SVD; }
86
87 /// Set the parameters \f$n_x, n_y, n_z\f$ defining the number of periodic
88 /// copies that neBEM will use when dealing with periodic configurations.
89 /// neBEM will use \f$2 \times n + 1\f$ copies (default: \f$n = 5\f$).
90 void SetPeriodicCopies(const unsigned int nx, const unsigned int ny,
91 const unsigned int nz);
92 /// Retrieve the number of periodic copies used by neBEM.
93 void GetPeriodicCopies(unsigned int& nx, unsigned int& ny,
94 unsigned int& nz) const {
95 nx = m_nCopiesX;
96 ny = m_nCopiesY;
97 nz = m_nCopiesZ;
98 }
99 /// Set the periodic length [cm] in the x-direction.
100 void SetPeriodicityX(const double s);
101 /// Set the periodic length [cm] in the y-direction.
102 void SetPeriodicityY(const double s);
103 /// Set the periodic length [cm] in the z-direction.
104 void SetPeriodicityZ(const double s);
105 /// Set the periodic length [cm] in the x-direction.
106 void SetMirrorPeriodicityX(const double s);
107 /// Set the periodic length [cm] in the y-direction.
108 void SetMirrorPeriodicityY(const double s);
109 /// Set the periodic length [cm] in the z-direction.
110 void SetMirrorPeriodicityZ(const double s);
111 /// Get the periodic length in the x-direction.
112 bool GetPeriodicityX(double& s) const;
113 /// Get the periodic length in the y-direction.
114 bool GetPeriodicityY(double& s) const;
115 /// Get the periodic length in the z-direction.
116 bool GetPeriodicityZ(double& s) const;
117
118 /// Set the number of threads to be used by neBEM.
119 void SetNumberOfThreads(const unsigned int n) {
120 m_nThreads = n > 0 ? n : 1;
121 }
122
123 protected:
124 void Reset() override;
125 void UpdatePeriodicity() override;
126
127 private:
128 struct Primitive {
129 /// Perpendicular vector
130 double a, b, c;
131 /// X-coordinates of vertices
132 std::vector<double> xv;
133 /// Y-coordinates of vertices
134 std::vector<double> yv;
135 /// Z-coordinates of vertices
136 std::vector<double> zv;
137 /// Interface type.
138 int interface;
139 /// Potential
140 double v;
141 /// Charge
142 double q;
143 /// Ratio of dielectric constants
144 double lambda;
145 /// Target element size.
146 double elementSize;
147 /// Volumes.
148 int vol1, vol2;
149 };
150 /// List of primitives.
151 std::vector<Primitive> m_primitives;
152
153 struct Element {
154 /// Local origin.
155 std::array<double, 3> origin;
156 double lx;
157 double lz;
158 /// Area.
159 double dA;
160 /// Direction cosines.
161 std::array<std::array<double, 3>, 3> dcos;
162 /// X-coordinates of vertices
163 std::vector<double> xv;
164 /// Y-coordinates of vertices
165 std::vector<double> yv;
166 /// Z-coordinates of vertices
167 std::vector<double> zv;
168 /// Interface type.
169 int interface;
170 /// Ratio of dielectric permittivities.
171 double lambda;
172 /// Collocation point.
173 std::array<double, 3> collocationPoint;
174 /// Boundary condition.
175 double bc;
176 /// Fixed charge density.
177 double assigned;
178 /// Solution (accumulated charge).
179 double solution;
180 };
181 /// List of elements.
182 std::vector<Element> m_elements;
183
184 /// Plane existence.
185 std::array<bool, 6> m_ynplan{{false, false, false, false, false, false}};
186 /// Plane coordinates.
187 std::array<double, 6> m_coplan{{0., 0., 0., 0., 0., 0.}};
188 /// Plane potentials.
189 std::array<double, 6> m_vtplan{{0., 0., 0., 0., 0., 0.}};
190
191 // Number of threads to be used by neBEM.
192 unsigned int m_nThreads = 1;
193
194 static constexpr double MinDist = 1.e-6;
195 /// Target size of elements [cm].
196 double m_targetElementSize = 50.0e-4;
197 /// Smallest number of elements produced along the axis of a primitive.
198 unsigned int m_minNbElementsOnLength = 1;
199 /// Largest number of elements produced along the axis of a primitive.
200 unsigned int m_maxNbElementsOnLength = 100;
201 /// Periodic lengths.
202 std::array<double, 3> m_periodicLength{{0., 0., 0.}};
203 /// Number of periodic copies along x.
204 unsigned int m_nCopiesX = 5;
205 /// Number of periodic copies along y.
206 unsigned int m_nCopiesY = 5;
207 /// Number of periodic copies along z.
208 unsigned int m_nCopiesZ = 5;
209
210 enum class Inversion { LU = 0, SVD };
211 Inversion m_inversion = Inversion::LU;
212
213 /// Electrode labels and corresponding neBEM weighting field indices.
214 std::map<std::string, int> m_wfields;
215
216 /// Reduce panels to the basic period.
217 void ShiftPanels(std::vector<Panel>& panels) const;
218 /// Isolate the parts of polygon 1 that are not hidden by 2 and vice versa.
219 bool EliminateOverlaps(const Panel& panel1, const Panel& panel2,
220 std::vector<Panel>& panelsOut,
221 std::vector<int>& itypo);
222
223 bool TraceEnclosed(const std::vector<double>& xl1,
224 const std::vector<double>& yl1,
225 const std::vector<double>& xl2,
226 const std::vector<double>& yl2, const Panel& originalPanel,
227 std::vector<Panel>& newPanels) const;
228
229 void TraceNonOverlap(
230 const std::vector<double>& xp1, const std::vector<double>& yp1,
231 const std::vector<double>& xl1, const std::vector<double>& yl1,
232 const std::vector<double>& xl2, const std::vector<double>& yl2,
233 const std::vector<int>& flags1, const std::vector<int>& flags2,
234 const std::vector<int>& links1, const std::vector<int>& links2,
235 std::vector<bool>& mark1, int ip1, const Panel& originalPanel,
236 std::vector<Panel>& newPanels) const;
237
238 void TraceOverlap(
239 const std::vector<double>& xp1, const std::vector<double>& yp1,
240 const std::vector<double>& xp2, const std::vector<double>& yp2,
241 const std::vector<double>& xl1, const std::vector<double>& yl1,
242 const std::vector<double>& xl2, const std::vector<double>& yl2,
243 const std::vector<int>& flags1, const std::vector<int>& links1,
244 const std::vector<int>& links2, std::vector<bool>& mark1, int ip1,
245 int ip2, const Panel& originalPanel, std::vector<Panel>& newPanels) const;
246
247 /// Split a polygon into rectangles and right-angled triangles.
248 bool MakePrimitives(const Panel& panelIn,
249 std::vector<Panel>& panelsOut) const;
250
251 /// Check whether a polygon contains parallel lines.
252 /// If it does, split it in rectangular and non-rectangular parts.
253 bool SplitTrapezium(const Panel panelIn, std::vector<Panel>& stack,
254 std::vector<Panel>& panelsOut, const double epsang) const;
255
256 unsigned int NbOfSegments(const double length, const double target) const;
257 bool DiscretizeWire(const Primitive& primitive, const double targetSize,
258 std::vector<Element>& elements) const;
259 bool DiscretizeTriangle(const Primitive& primitive, const double targetSize,
260 std::vector<Element>& elements) const;
261 bool DiscretizeRectangle(const Primitive& prim, const double targetSize,
262 std::vector<Element>& elements) const;
263 int InterfaceType(const Solid::BoundaryCondition bc) const;
264};
265
266extern ComponentNeBem3d* gComponentNeBem3d;
267
268}
269
270#endif
bool GetPlaneZ(const unsigned int i, double &z, double &v) const
Retrieve the parameters of a plane at constant z.
bool GetPlaneY(const unsigned int i, double &y, double &v) const
Retrieve the parameters of a plane at constant y.
void AddPlaneZ(const double z, const double voltage)
Add a plane at constant z.
bool GetPeriodicityX(double &s) const
Get the periodic length in the x-direction.
unsigned int GetNumberOfPrimitives() const
bool GetPeriodicityZ(double &s) const
Get the periodic length in the z-direction.
void Reset() override
Reset the component.
void SetMirrorPeriodicityX(const double s)
Set the periodic length [cm] in the x-direction.
void SetPeriodicityX(const double s)
Set the periodic length [cm] in the x-direction.
void UpdatePeriodicity() override
Verify periodicities.
bool GetVoltageRange(double &vmin, double &vmax) override
Calculate the voltage range [V].
unsigned int GetNumberOfPlanesY() const
Get the number of equipotential planes at constant y.
bool GetPeriodicityY(double &s) const
Get the periodic length in the y-direction.
unsigned int GetNumberOfPlanesZ() const
Get the number of equipotential planes at constant z.
void SetNumberOfThreads(const unsigned int n)
Set the number of threads to be used by neBEM.
void AddPlaneY(const double y, const double voltage)
Add a plane at constant y.
void AddPlaneX(const double x, const double voltage)
Add a plane at constant x.
void SetMirrorPeriodicityZ(const double s)
Set the periodic length [cm] in the z-direction.
void SetPeriodicityZ(const double s)
Set the periodic length [cm] in the z-direction.
bool GetVolume(const unsigned int vol, int &shape, int &material, double &eps, double &potential, double &charge, int &bc)
void SetPeriodicityY(const double s)
Set the periodic length [cm] in the y-direction.
void UseSVDInversion()
Invert the influence matrix using singular value decomposition.
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
unsigned int GetNumberOfPlanesX() const
Get the number of equipotential planes at constant x.
bool GetElement(const unsigned int i, std::vector< double > &xv, std::vector< double > &yv, std::vector< double > &zv, int &interface, double &bc, double &lambda) const
void SetTargetElementSize(const double length)
void SetMirrorPeriodicityY(const double s)
Set the periodic length [cm] in the y-direction.
void SetPeriodicCopies(const unsigned int nx, const unsigned int ny, const unsigned int nz)
bool GetPrimitive(const unsigned int i, double &a, double &b, double &c, std::vector< double > &xv, std::vector< double > &yv, std::vector< double > &zv, int &interface, double &v, double &q, double &lambda) const
void SetMinMaxNumberOfElements(const unsigned int nmin, const unsigned int nmax)
unsigned int GetNumberOfElements() const
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
void UseLUInversion()
Invert the influence matrix using lower-upper (LU) decomposition.
bool GetPlaneX(const unsigned int i, double &x, double &v) const
Retrieve the parameters of a plane at constant x.
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
void GetPeriodicCopies(unsigned int &nx, unsigned int &ny, unsigned int &nz) const
Retrieve the number of periodic copies used by neBEM.
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
Abstract base class for components.
Definition: Component.hh:13
Abstract base class for media.
Definition: Medium.hh:13
ComponentNeBem3d * gComponentNeBem3d
neBEMGLOBAL int * InterfaceType
Definition: neBEM.h:68
Definition: neBEM.h:155