Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
SolidTube.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
6
7namespace Garfield {
8
9SolidTube::SolidTube(const double cx, const double cy, const double cz,
10 const double rmin, const double rmax, const double lz)
11 : Solid(cx, cy, cz, "SolidTube"),
12 m_rMin(rmin),
13 m_rMax(rmax),
14 m_r(rmax),
15 m_lZ(lz) {}
16
17SolidTube::SolidTube(const double cx, const double cy, const double cz,
18 const double rmin, const double rmax, const double lz,
19 const double dx, const double dy, const double dz)
20 : SolidTube(cx, cy, cz, rmin, rmax, lz) {
21 SetDirection(dx, dy, dz);
22}
23
24SolidTube::SolidTube(const double cx, const double cy, const double cz,
25 const double r, const double lz)
26 : SolidTube(cx, cy, cz, 0., r, lz) {}
27
28SolidTube::SolidTube(const double cx, const double cy, const double cz,
29 const double r, const double lz, const double dx,
30 const double dy, const double dz)
31 : SolidTube(cx, cy, cz, 0., r, lz, dx, dy, dz) {}
32
33bool SolidTube::IsInside(const double x, const double y, const double z) const {
34 // Transform the point to local coordinates.
35 double u = x, v = y, w = z;
36 ToLocal(x, y, z, u, v, w);
37
38 if (fabs(w) > m_lZ) {
39 if (m_debug) {
40 std::cout << "SolidTube::IsInside: (" << x << ", " << y << ", " << z
41 << ") is outside.\n";
42 }
43 return false;
44 }
45
46 const double r = sqrt(u * u + v * v);
47 if (r >= m_rMin && r <= m_rMax) {
48 if (m_debug) {
49 std::cout << "SolidTube::IsInside: (" << x << ", " << y << ", " << z
50 << ") is inside.\n";
51 }
52 return true;
53 }
54
55 if (m_debug) {
56 std::cout << "SolidTube::IsInside: (" << x << ", " << y << ", " << z
57 << ") is outside.\n";
58 }
59 return false;
60}
61
62bool SolidTube::GetBoundingBox(double& xmin, double& ymin, double& zmin,
63 double& xmax, double& ymax, double& zmax) const {
64 if (m_cTheta == 1. && m_cPhi == 1.) {
65 xmin = m_cX - m_rMax;
66 xmax = m_cX + m_rMax;
67 ymin = m_cY - m_rMax;
68 ymax = m_cY + m_rMax;
69 zmin = m_cZ - m_lZ;
70 zmax = m_cZ + m_lZ;
71 return true;
72 }
73
74 const double dd = sqrt(m_rMax * m_rMax + m_lZ * m_lZ);
75 xmin = m_cX - dd;
76 xmax = m_cX + dd;
77 ymin = m_cY - dd;
78 ymax = m_cY + dd;
79 zmin = m_cZ - dd;
80 zmax = m_cZ + dd;
81 return true;
82}
83
84void SolidTube::SetInnerRadius(const double rmin) {
85 if (rmin <= 0.) {
86 std::cerr << "SolidTube::SetInnerRadius: Radius must be > 0.\n";
87 return;
88 }
89 if (rmin >= m_rMax) {
90 std::cerr << "SolidTube::SetInnerRadius:\n";
91 std::cerr << " Inner radius must be smaller than outer radius.\n";
92 return;
93 }
94 m_rMin = rmin;
95}
96
97void SolidTube::SetOuterRadius(const double rmax) {
98 if (rmax <= 0.) {
99 std::cerr << "SolidTube::SetOuterRadius: Radius must be > 0.\n";
100 return;
101 }
102 if (rmax <= m_rMin) {
103 std::cerr << "SolidTube::SetOuterRadius:\n";
104 std::cerr << " Outer radius must be greater than inner radius.\n";
105 return;
106 }
107 m_rMax = rmax;
108}
109
110void SolidTube::SetRadius(const double r) {
111 if (r <= 0.) {
112 std::cerr << "SolidTube::SetRadius: Radius must be > 0.\n";
113 return;
114 }
115 m_r = r;
116}
117
118void SolidTube::SetHalfLength(const double lz) {
119 if (lz <= 0.) {
120 std::cerr << "SolidTube::SetHalfLength: Half-length must be > 0.\n";
121 return;
122 }
123 m_lZ = lz;
124}
125
126void SolidTube::SetSectors(const unsigned int n) {
127 if (n < 1) {
128 std::cerr << "SolidTube::SetSectors: Number must be > 0.\n";
129 return;
130 }
131 m_n = n;
132}
133
134bool SolidTube::SolidPanels(std::vector<Panel>& panels) {
135 // AROT Rotation angle: m_rot
136 // N Number of sectors: m_n
137 // R Radius of cylinder: m_r
138 // ZL half-length m_lZ
139 // X0 centre m_cX
140 // Y0 centre m_cY
141 // Z0 centre m_cZ
142 // A direction vector m_dX
143 // B direction vector m_dY
144 // C direction vector m_dZ
145
146 const auto id = GetId();
147 const unsigned int nPanels = panels.size();
148 // Direction vector.
149 const double fnorm = sqrt(m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ);
150 if (fnorm <= 0) {
151 std::cerr << "SolidTube::SolidPanels:\n"
152 << " Zero norm direction vector; no panels generated.\n";
153 return false;
154 }
155
156 // Set the mean or the outer radius.
157 double r = m_r;
158 if (m_average) {
159 const double alpha = Pi / (4. * (m_n - 1.));
160 r = 2 * m_r / (1. + asinh(tan(alpha)) * cos(alpha) / tan(alpha));
161 }
162
163 const unsigned int nPoints = 4 * (m_n - 1);
164 // Create the top lid.
165 if (m_toplid) {
166 std::vector<double> xv;
167 std::vector<double> yv;
168 std::vector<double> zv;
169 for (unsigned int i = 1; i <= nPoints; i++) {
170 const double alpha = m_rot + HalfPi * (i - 1.) / (m_n - 1.);
171 double x, y, z;
172 ToGlobal(r * cos(alpha), r * sin(alpha), m_lZ, x, y, z);
173 // Rotate into place.
174 xv.push_back(x);
175 yv.push_back(y);
176 zv.push_back(z);
177 }
178 Panel newpanel;
179 newpanel.a = m_cPhi * m_sTheta;
180 newpanel.b = m_sPhi * m_sTheta;
181 newpanel.c = m_cTheta;
182 newpanel.xv = xv;
183 newpanel.yv = yv;
184 newpanel.zv = zv;
185 newpanel.colour = 0;
186 newpanel.volume = id;
187 panels.push_back(std::move(newpanel));
188 }
189 // Create the bottom lid.
190 if (m_bottomlid) {
191 std::vector<double> xv;
192 std::vector<double> yv;
193 std::vector<double> zv;
194 for (unsigned int i = 1; i <= nPoints; i++) {
195 const double alpha = m_rot + HalfPi * (i - 1.) / (m_n - 1.);
196 double x, y, z;
197 ToGlobal(r * cos(alpha), r * sin(alpha), -m_lZ, x, y, z);
198 // Rotate into place.
199 xv.push_back(x);
200 yv.push_back(y);
201 zv.push_back(z);
202 }
203 Panel newpanel;
204 newpanel.a = -m_cPhi * m_sTheta;
205 newpanel.b = -m_sPhi * m_sTheta;
206 newpanel.c = -m_cTheta;
207 newpanel.xv = xv;
208 newpanel.yv = yv;
209 newpanel.zv = zv;
210 newpanel.colour = 0;
211 newpanel.volume = id;
212 panels.push_back(std::move(newpanel));
213 }
214 // Create the side panels.
215 double u = r * cos(m_rot);
216 double v = r * sin(m_rot);
217 // Rotate into place.
218 double xv0, yv0, zv0;
219 ToGlobal(u, v, -m_lZ, xv0, yv0, zv0);
220 double xv1, yv1, zv1;
221 ToGlobal(u, v, +m_lZ, xv1, yv1, zv1);
222 // Go around the cylinder.
223 for (unsigned int i = 2; i <= nPoints + 1; i++) {
224 // Bottom and top of the line along the axis of the cylinder.
225 double alpha = m_rot + HalfPi * (i - 1.) / (m_n - 1.);
226 u = r * cos(alpha);
227 v = r * sin(alpha);
228 // Rotate into place.
229 double xv2, yv2, zv2;
230 ToGlobal(u, v, +m_lZ, xv2, yv2, zv2);
231 double xv3, yv3, zv3;
232 ToGlobal(u, v, -m_lZ, xv3, yv3, zv3);
233 // Store the plane.
234 Panel newpanel;
235 alpha = m_rot + HalfPi * (i - 1.5) / (m_n - 1.);
236 const double cAlpha = cos(alpha);
237 const double sAlpha = sin(alpha);
238 newpanel.a = m_cPhi * m_cTheta * cAlpha - m_sPhi * sAlpha;
239 newpanel.b = m_sPhi * m_cTheta * cAlpha + m_cPhi * sAlpha;
240 newpanel.c = -m_sTheta * cAlpha;
241 newpanel.xv = {xv0, xv1, xv2, xv3};
242 newpanel.yv = {yv0, yv1, yv2, yv3};
243 newpanel.zv = {zv0, zv1, zv2, zv3};
244 newpanel.colour = 0;
245 newpanel.volume = id;
246 panels.push_back(std::move(newpanel));
247 // Shift the points.
248 xv0 = xv3;
249 yv0 = yv3;
250 zv0 = zv3;
251 xv1 = xv2;
252 yv1 = yv2;
253 zv1 = zv2;
254 }
255 std::cout << "SolidTube::SolidPanels: " << panels.size() - nPanels
256 << " panels.\n";
257 return true;
258}
259
261
262 // Transform the normal vector to local coordinates.
263 double u = 0., v = 0., w = 0.;
264 VectorToLocal(panel.a, panel.b, panel.c, u, v, w);
265 // Identify the vector.
266 if (w > std::max(std::abs(u), std::abs(v))) {
267 return m_dis[0];
268 } else if (w < -std::max(std::abs(u), std::abs(v))) {
269 return m_dis[1];
270 }
271 return m_dis[2];
272}
273
274}
Cylindrical tube.
Definition: SolidTube.hh:10
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
Definition: SolidTube.cc:134
void SetInnerRadius(const double rmin)
Definition: SolidTube.cc:84
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretization level of a panel.
Definition: SolidTube.cc:260
void SetOuterRadius(const double rmax)
Definition: SolidTube.cc:97
void SetSectors(const unsigned int n)
Definition: SolidTube.cc:126
void SetHalfLength(const double lz)
Definition: SolidTube.cc:118
void SetRadius(const double r)
Definition: SolidTube.cc:110
bool IsInside(const double x, const double y, const double z) const override
Check whether a given point is inside the solid.
Definition: SolidTube.cc:33
SolidTube(const double cx, const double cy, const double cz, const double rmin, const double rmax, const double lz)
Constructor from centre, inner/outer radii, and half-length.
Definition: SolidTube.cc:9
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const override
Return the bounding box of the solid.
Definition: SolidTube.cc:62
Abstract base class for solids.
Definition: Solid.hh:28
double m_dZ
Definition: Solid.hh:167
double m_cZ
Definition: Solid.hh:164
void VectorToLocal(const double x, const double y, const double z, double &u, double &v, double &w)
Transform a vector from global to local coordinates.
Definition: Solid.hh:209
double m_cTheta
Polar angle.
Definition: Solid.hh:171
double m_dX
Direction vector.
Definition: Solid.hh:167
unsigned int GetId() const
Get the ID of the solid.
Definition: Solid.hh:117
void ToLocal(const double x, const double y, const double z, double &u, double &v, double &w) const
Definition: Solid.hh:190
void SetDirection(const double dx, const double dy, const double dz)
Definition: Solid.cc:12
double m_sPhi
Definition: Solid.hh:169
void ToGlobal(const double u, const double v, const double w, double &x, double &y, double &z) const
Definition: Solid.hh:202
double m_sTheta
Definition: Solid.hh:171
double m_cY
Definition: Solid.hh:164
bool m_debug
Debug flag.
Definition: Solid.hh:177
double m_dY
Definition: Solid.hh:167
double m_cX
Centre of the solid.
Definition: Solid.hh:164
double m_cPhi
Azimuthal angle.
Definition: Solid.hh:169
Surface panel.
Definition: Solid.hh:11
std::vector< double > zv
Z-coordinates of vertices.
Definition: Solid.hh:19
int volume
Reference to solid to which the panel belongs.
Definition: Solid.hh:23
double a
Perpendicular vector.
Definition: Solid.hh:13
double c
Definition: Solid.hh:13
double colour
Colour index.
Definition: Solid.hh:21
double b
Definition: Solid.hh:13
std::vector< double > xv
X-coordinates of vertices.
Definition: Solid.hh:15
std::vector< double > yv
Y-coordinates of vertices.
Definition: Solid.hh:17