Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
SolidBox.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
6#include "Garfield/Polygon.hh"
8
9namespace Garfield {
10
11SolidBox::SolidBox(const double cx, const double cy, const double cz,
12 const double lx, const double ly, const double lz)
13 : Solid(cx, cy, cz, "SolidBox"), m_lX(lx), m_lY(ly), m_lZ(lz) {}
14
15SolidBox::SolidBox(const double cx, const double cy, const double cz,
16 const double lx, const double ly, const double lz,
17 const double dx, const double dy, const double dz)
18 : SolidBox(cx, cy, cz, lx, ly, lz) {
19 SetDirection(dx, dy, dz);
20}
21
22bool SolidBox::IsInside(const double x, const double y, const double z,
23 const bool /*tesselated*/) const {
24 // Transform the point to local coordinates.
25 double u = x, v = y, w = z;
26 ToLocal(x, y, z, u, v, w);
27
28 // See whether the point is inside.
29 if (fabs(u) > m_lX || fabs(v) > m_lY || fabs(w) > m_lZ) {
30 return false;
31 }
32 return true;
33}
34
35bool SolidBox::GetBoundingBox(double& xmin, double& ymin, double& zmin,
36 double& xmax, double& ymax, double& zmax) const {
37 if (m_cTheta == 1. && m_cPhi == 1.) {
38 xmin = m_cX - m_lX;
39 xmax = m_cX + m_lX;
40 ymin = m_cY - m_lY;
41 ymax = m_cY + m_lY;
42 zmin = m_cZ - m_lZ;
43 zmax = m_cZ + m_lZ;
44 return true;
45 }
46
47 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_lZ * m_lZ);
48 xmin = m_cX - dd;
49 xmax = m_cX + dd;
50 ymin = m_cY - dd;
51 ymax = m_cY + dd;
52 zmin = m_cZ - dd;
53 zmax = m_cZ + dd;
54 return true;
55}
56
57void SolidBox::SetHalfLengthX(const double lx) {
58 if (lx > 0.) {
59 m_lX = lx;
60 } else {
61 std::cerr << "SolidBox::SetHalfLengthX: Half-length must be > 0.\n";
62 }
63}
64
65void SolidBox::SetHalfLengthY(const double ly) {
66 if (ly > 0.) {
67 m_lY = ly;
68 } else {
69 std::cerr << "SolidBox::SetHalfLengthY: Half-length must be > 0.\n";
70 }
71}
72
73void SolidBox::SetHalfLengthZ(const double lz) {
74 if (lz > 0.) {
75 m_lZ = lz;
76 } else {
77 std::cerr << "SolidBox::SetHalfLengthZ: Half-length must be > 0.\n";
78 }
79}
80
81bool SolidBox::SolidPanels(std::vector<Panel>& panels) {
82 const auto id = GetId();
83 const auto nPanels = panels.size();
84 double xv0, yv0, zv0;
85 double xv1, yv1, zv1;
86 double xv2, yv2, zv2;
87 double xv3, yv3, zv3;
88 // Draw the 6 sides of the box, start with the x = xmin face.
89 if (m_lY > 0 && m_lZ > 0) {
90 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
91 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
92 ToGlobal(-m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
93 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
94 Panel panel;
95 panel.a = -m_cPhi * m_cTheta;
96 panel.b = -m_sPhi * m_cTheta;
97 panel.c = +m_sTheta;
98 panel.xv = {xv0, xv1, xv2, xv3};
99 panel.yv = {yv0, yv1, yv2, yv3};
100 panel.zv = {zv0, zv1, zv2, zv3};
101 panel.colour = m_colour;
102 panel.volume = id;
103 panels.push_back(std::move(panel));
104 }
105 // The x = xmax face.
106 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
107 ToGlobal(+m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
108 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
109 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
110 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
111 Panel panel;
112 panel.a = m_cPhi * m_cTheta;
113 panel.b = m_sPhi * m_cTheta;
114 panel.c = -m_sTheta;
115 panel.xv = {xv0, xv1, xv2, xv3};
116 panel.yv = {yv0, yv1, yv2, yv3};
117 panel.zv = {zv0, zv1, zv2, zv3};
118 panel.colour = m_colour;
119 panel.volume = id;
120 panels.push_back(std::move(panel));
121 }
122 // The y = ymin face.
123 if (m_lX > 0 && m_lZ > 0) {
124 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
125 ToGlobal(+m_lX, -m_lY, -m_lZ, xv1, yv1, zv1);
126 ToGlobal(+m_lX, -m_lY, +m_lZ, xv2, yv2, zv2);
127 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
128 Panel panel;
129 panel.a = m_sPhi;
130 panel.b = -m_cPhi;
131 panel.c = 0;
132 panel.xv = {xv0, xv1, xv2, xv3};
133 panel.yv = {yv0, yv1, yv2, yv3};
134 panel.zv = {zv0, zv1, zv2, zv3};
135 panel.colour = m_colour;
136 panel.volume = id;
137 panels.push_back(std::move(panel));
138 }
139 // The y = ymax face.
140 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
141 ToGlobal(-m_lX, +m_lY, -m_lZ, xv0, yv0, zv0);
142 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
143 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
144 ToGlobal(-m_lX, +m_lY, +m_lZ, xv3, yv3, zv3);
145 Panel panel;
146 panel.a = -m_sPhi;
147 panel.b = +m_cPhi;
148 panel.c = 0;
149 panel.xv = {xv0, xv1, xv2, xv3};
150 panel.yv = {yv0, yv1, yv2, yv3};
151 panel.zv = {zv0, zv1, zv2, zv3};
152 panel.colour = m_colour;
153 panel.volume = id;
154 panels.push_back(std::move(panel));
155 }
156 // The z = zmin face.
157 if (m_lX > 0 && m_lY > 0) {
158 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
159 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
160 ToGlobal(+m_lX, +m_lY, -m_lZ, xv2, yv2, zv2);
161 ToGlobal(+m_lX, -m_lY, -m_lZ, xv3, yv3, zv3);
162 Panel panel;
163 panel.a = -m_cPhi * m_sTheta;
164 panel.b = -m_sPhi * m_sTheta;
165 panel.c = -m_cTheta;
166 panel.xv = {xv0, xv1, xv2, xv3};
167 panel.yv = {yv0, yv1, yv2, yv3};
168 panel.zv = {zv0, zv1, zv2, zv3};
169 panel.colour = m_colour;
170 panel.volume = id;
171 panels.push_back(std::move(panel));
172 }
173 // The z = zmax face.
174 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
175 ToGlobal(-m_lX, -m_lY, +m_lZ, xv0, yv0, zv0);
176 ToGlobal(-m_lX, +m_lY, +m_lZ, xv1, yv1, zv1);
177 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
178 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
179 Panel panel;
180 panel.a = +m_cPhi * m_sTheta;
181 panel.b = +m_sPhi * m_sTheta;
182 panel.c = +m_cTheta;
183 panel.xv = {xv0, xv1, xv2, xv3};
184 panel.yv = {yv0, yv1, yv2, yv3};
185 panel.zv = {zv0, zv1, zv2, zv3};
186 panel.colour = m_colour;
187 panel.volume = id;
188 panels.push_back(std::move(panel));
189 }
190 // Done, check panel count.
191 std::cout << "SolidBox::SolidPanels: " << panels.size() - nPanels
192 << " panels.\n";
193 return true;
194}
195
197
198 // Transform the normal vector to local coordinates.
199 double u = 0., v = 0., w = 0.;
200 VectorToLocal(panel.a, panel.b, panel.c, u, v, w);
201 // Identify the vector.
202 if (u > std::max(std::abs(v), std::abs(w))) {
203 return m_dis[0];
204 } else if (u < -std::max(std::abs(v), std::abs(w))) {
205 return m_dis[1];
206 } else if (v > std::max(std::abs(u), std::abs(w))) {
207 return m_dis[2];
208 } else if (v < -std::max(std::abs(u), std::abs(w))) {
209 return m_dis[3];
210 } else if (w > std::max(std::abs(u), std::abs(v))) {
211 return m_dis[4];
212 } else if (w < -std::max(std::abs(u), std::abs(v))) {
213 return m_dis[5];
214 }
215 if (m_debug) {
216 std::cout << m_className << "::GetDiscretisationLevel:\n"
217 << " Found no match for the panel; return first value.\n";
218 }
219 return m_dis[0];
220}
221
222void SolidBox::Cut(const double x0, const double y0, const double z0,
223 const double xn, const double yn, const double zn,
224 std::vector<Panel>& panels) {
225
226 //-----------------------------------------------------------------------
227 // PLABXC - Cuts box with a plane.
228 //-----------------------------------------------------------------------
229
230 std::vector<double> xv;
231 std::vector<double> yv;
232 std::vector<double> zv;
233 // Draw all 12 lines and cut.
234 // The line (xmin,ymin,zmin) to (xmax,ymin,zmin).
235 double x1, y1, z1;
236 ToGlobal(-m_lX, -m_lY, -m_lZ, x1, y1, z1);
237 double x2, y2, z2;
238 ToGlobal(+m_lX, -m_lY, -m_lZ, x2, y2, z2);
239 double xc, yc, zc;
240 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
241 xv.push_back(xc);
242 yv.push_back(yc);
243 zv.push_back(zc);
244 }
245 // ... to (xmin,ymax,zmin).
246 ToGlobal(-m_lX, +m_lY, -m_lZ, x2, y2, z2);
247 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
248 xv.push_back(xc);
249 yv.push_back(yc);
250 zv.push_back(zc);
251 }
252 // ... to (xmin,ymin,zmax).
253 ToGlobal(-m_lX, -m_lY, +m_lZ, x2, y2, z2);
254 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
255 xv.push_back(xc);
256 yv.push_back(yc);
257 zv.push_back(zc);
258 }
259 // The line (xmax,ymax,zmin) to (xmin,ymax,zmin).
260 ToGlobal(+m_lX, +m_lY, -m_lZ, x1, y1, z1);
261 ToGlobal(-m_lX, +m_lY, -m_lZ, x2, y2, z2);
262 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
263 xv.push_back(xc);
264 yv.push_back(yc);
265 zv.push_back(zc);
266 }
267 // ... to (xmax,ymin,zmin).
268 ToGlobal(+m_lX, -m_lY, -m_lZ, x2, y2, z2);
269 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
270 xv.push_back(xc);
271 yv.push_back(yc);
272 zv.push_back(zc);
273 }
274 // ... to (xmax,ymax,zmax).
275 ToGlobal(+m_lX, +m_lY, +m_lZ, x2, y2, z2);
276 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
277 xv.push_back(xc);
278 yv.push_back(yc);
279 zv.push_back(zc);
280 }
281 // The line (xmin,ymax,zmax) to (xmax,ymax,zmax).
282 ToGlobal(-m_lX, +m_lY, +m_lZ, x1, y1, z1);
283 ToGlobal(+m_lX, +m_lY, +m_lZ, x2, y2, z2);
284 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
285 xv.push_back(xc);
286 yv.push_back(yc);
287 zv.push_back(zc);
288 }
289 // ... to (xmin,ymin,zmax).
290 ToGlobal(-m_lX, -m_lY, +m_lZ, x2, y2, z2);
291 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
292 xv.push_back(xc);
293 yv.push_back(yc);
294 zv.push_back(zc);
295 }
296 // ... to (xmin,ymax,zmin).
297 ToGlobal(-m_lX, +m_lY, -m_lZ, x1, y1, z1);
298 ToGlobal(-m_lX, +m_lY, +m_lZ, x2, y2, z2);
299 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
300 xv.push_back(xc);
301 yv.push_back(yc);
302 zv.push_back(zc);
303 }
304 // The line (xmax,ymin,zmax) to (xmin,ymin,zmax).
305 ToGlobal(+m_lX, -m_lY, +m_lZ, x1, y1, z1);
306 ToGlobal(-m_lX, -m_lY, +m_lZ, x2, y2, z2);
307 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
308 xv.push_back(xc);
309 yv.push_back(yc);
310 zv.push_back(zc);
311 }
312 // ... to (xmax,ymax,zmax).
313 ToGlobal(+m_lX, +m_lY, +m_lZ, x2, y2, z2);
314 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
315 xv.push_back(xc);
316 yv.push_back(yc);
317 zv.push_back(zc);
318 }
319 // ... to (xmax,ymin,zmin).
320 ToGlobal(+m_lX, -m_lY, -m_lZ, x2, y2, z2);
321 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
322 xv.push_back(xc);
323 yv.push_back(yc);
324 zv.push_back(zc);
325 }
326
327 // Get rid of butterflies.
329 if (xv.size() >= 3) {
330 Panel panel;
331 panel.a = xn;
332 panel.b = yn;
333 panel.c = zn;
334 panel.xv = xv;
335 panel.yv = yv;
336 panel.zv = zv;
337 panel.colour = m_colour;
338 panel.volume = GetId();
339 panels.push_back(std::move(panel));
340 }
341}
342
343}
void SetHalfLengthX(const double lx)
Definition: SolidBox.cc:57
SolidBox(const double cx, const double cy, const double cz, const double lx, const double ly, const double lz)
Constructor from centre and half-widths.
Definition: SolidBox.cc:11
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
Definition: SolidBox.cc:81
bool IsInside(const double x, const double y, const double z, const bool tesselated) const override
Definition: SolidBox.cc:22
void SetHalfLengthZ(const double lz)
Definition: SolidBox.cc:73
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const override
Return the bounding box of the solid.
Definition: SolidBox.cc:35
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretisation level of a panel.
Definition: SolidBox.cc:196
void Cut(const double x0, const double y0, const double z0, const double xn, const double yn, const double zn, std::vector< Panel > &panels) override
Definition: SolidBox.cc:222
void SetHalfLengthY(const double ly)
Definition: SolidBox.cc:65
Abstract base class for solids.
Definition: Solid.hh:28
double m_cZ
Definition: Solid.hh:202
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:253
double m_cTheta
Polar angle.
Definition: Solid.hh:209
static bool Intersect(const double x1, const double y1, const double z1, const double x2, const double y2, const double z2, const double x0, const double y0, const double z0, const double a, const double b, const double c, double &xc, double &yc, double &zc)
Definition: Solid.cc:52
unsigned int GetId() const
Get the ID of the solid.
Definition: Solid.hh:137
void ToLocal(const double x, const double y, const double z, double &u, double &v, double &w) const
Definition: Solid.hh:234
void SetDirection(const double dx, const double dy, const double dz)
Definition: Solid.cc:12
int m_colour
Colour.
Definition: Solid.hh:230
double m_sPhi
Definition: Solid.hh:207
void ToGlobal(const double u, const double v, const double w, double &x, double &y, double &z) const
Definition: Solid.hh:246
double m_sTheta
Definition: Solid.hh:209
double m_cY
Definition: Solid.hh:202
bool m_debug
Debug flag.
Definition: Solid.hh:218
double m_cX
Centre of the solid.
Definition: Solid.hh:202
double m_cPhi
Azimuthal angle.
Definition: Solid.hh:207
std::string m_className
Class name.
Definition: Solid.hh:212
void EliminateButterflies(std::vector< double > &xp, std::vector< double > &yp, std::vector< double > &zp)
Definition: Polygon.cc:355
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 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
int colour
Colour index.
Definition: Solid.hh:21