Garfield++ 3.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
7
8namespace Garfield {
9
10SolidBox::SolidBox(const double cx, const double cy, const double cz,
11 const double lx, const double ly, const double lz)
12 : Solid(cx, cy, cz, "SolidBox"), m_lX(lx), m_lY(ly), m_lZ(lz) {}
13
14SolidBox::SolidBox(const double cx, const double cy, const double cz,
15 const double lx, const double ly, const double lz,
16 const double dx, const double dy, const double dz)
17 : SolidBox(cx, cy, cz, lx, ly, lz) {
18 SetDirection(dx, dy, dz);
19}
20
21bool SolidBox::IsInside(const double x, const double y, const double z) const {
22 // Transform the point to local coordinates.
23 double u = x, v = y, w = z;
24 ToLocal(x, y, z, u, v, w);
25
26 // See whether the point is inside.
27 if (fabs(u) > m_lX || fabs(v) > m_lY || fabs(w) > m_lZ) {
28 if (m_debug) {
29 std::cout << "SolidBox::IsInside: (" << x << ", " << y << ", " << z
30 << ") is outside.\n";
31 }
32 return false;
33 }
34
35 if (m_debug) {
36 std::cout << "SolidBox::IsInside: (" << x << ", " << y << ", " << z
37 << ") is inside.\n";
38 }
39
40 return true;
41}
42
43bool SolidBox::GetBoundingBox(double& xmin, double& ymin, double& zmin,
44 double& xmax, double& ymax, double& zmax) const {
45 if (m_cTheta == 1. && m_cPhi == 1.) {
46 xmin = m_cX - m_lX;
47 xmax = m_cX + m_lX;
48 ymin = m_cY - m_lY;
49 ymax = m_cY + m_lY;
50 zmin = m_cZ - m_lZ;
51 zmax = m_cZ + m_lZ;
52 return true;
53 }
54
55 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_lZ * m_lZ);
56 xmin = m_cX - dd;
57 xmax = m_cX + dd;
58 ymin = m_cY - dd;
59 ymax = m_cY + dd;
60 zmin = m_cZ - dd;
61 zmax = m_cZ + dd;
62 return true;
63}
64
65void SolidBox::SetHalfLengthX(const double lx) {
66 if (lx > 0.) {
67 m_lX = lx;
68 } else {
69 std::cerr << "SolidBox::SetHalfLengthX: Half-length must be > 0.\n";
70 }
71}
72
73void SolidBox::SetHalfLengthY(const double ly) {
74 if (ly > 0.) {
75 m_lY = ly;
76 } else {
77 std::cerr << "SolidBox::SetHalfLengthY: Half-length must be > 0.\n";
78 }
79}
80
81void SolidBox::SetHalfLengthZ(const double lz) {
82 if (lz > 0.) {
83 m_lZ = lz;
84 } else {
85 std::cerr << "SolidBox::SetHalfLengthZ: Half-length must be > 0.\n";
86 }
87}
88
89bool SolidBox::SolidPanels(std::vector<Panel>& panels) {
90 const auto id = GetId();
91 const auto nPanels = panels.size();
92 double xv0, yv0, zv0;
93 double xv1, yv1, zv1;
94 double xv2, yv2, zv2;
95 double xv3, yv3, zv3;
96 // Draw the 6 sides of the box, start with the x = xmin face.
97 if (m_lY > 0 && m_lZ > 0) {
98 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
99 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
100 ToGlobal(-m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
101 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
102 // Colour(-m_cPhi * m_cTheta, -m_sPhi * m_cTheta, +m_sTheta, wcol);
103 Panel newpanel;
104 newpanel.a = -m_cPhi * m_cTheta;
105 newpanel.b = -m_sPhi * m_cTheta;
106 newpanel.c = +m_sTheta;
107 newpanel.xv = {xv0, xv1, xv2, xv3};
108 newpanel.yv = {yv0, yv1, yv2, yv3};
109 newpanel.zv = {zv0, zv1, zv2, zv3};
110 newpanel.colour = 0;
111 newpanel.volume = id;
112 panels.push_back(std::move(newpanel));
113 }
114 // The x = xmax face.
115 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
116 ToGlobal(+m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
117 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
118 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
119 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
120 Panel newpanel;
121 newpanel.a = m_cPhi * m_cTheta;
122 newpanel.b = m_sPhi * m_cTheta;
123 newpanel.c = -m_sTheta;
124 newpanel.xv = {xv0, xv1, xv2, xv3};
125 newpanel.yv = {yv0, yv1, yv2, yv3};
126 newpanel.zv = {zv0, zv1, zv2, zv3};
127 newpanel.colour = 0;
128 newpanel.volume = id;
129 panels.push_back(std::move(newpanel));
130 }
131 // The y = ymin face.
132 if (m_lX > 0 && m_lZ > 0) {
133 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
134 ToGlobal(+m_lX, -m_lY, -m_lZ, xv1, yv1, zv1);
135 ToGlobal(+m_lX, -m_lY, +m_lZ, xv2, yv2, zv2);
136 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
137 Panel newpanel;
138 newpanel.a = m_sPhi;
139 newpanel.b = -m_cPhi;
140 newpanel.c = 0;
141 newpanel.xv = {xv0, xv1, xv2, xv3};
142 newpanel.yv = {yv0, yv1, yv2, yv3};
143 newpanel.zv = {zv0, zv1, zv2, zv3};
144 newpanel.colour = 0;
145 newpanel.volume = id;
146 panels.push_back(std::move(newpanel));
147 }
148 // The y = ymax face.
149 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
150 ToGlobal(-m_lX, +m_lY, -m_lZ, xv0, yv0, zv0);
151 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
152 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
153 ToGlobal(-m_lX, +m_lY, +m_lZ, xv3, yv3, zv3);
154 Panel newpanel;
155 newpanel.a = -m_sPhi;
156 newpanel.b = +m_cPhi;
157 newpanel.c = 0;
158 newpanel.xv = {xv0, xv1, xv2, xv3};
159 newpanel.yv = {yv0, yv1, yv2, yv3};
160 newpanel.zv = {zv0, zv1, zv2, zv3};
161 newpanel.colour = 0;
162 newpanel.volume = id;
163 panels.push_back(std::move(newpanel));
164 }
165 // The z = zmin face.
166 if (m_lX > 0 && m_lY > 0) {
167 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
168 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
169 ToGlobal(+m_lX, +m_lY, -m_lZ, xv2, yv2, zv2);
170 ToGlobal(+m_lX, -m_lY, -m_lZ, xv3, yv3, zv3);
171 Panel newpanel;
172 newpanel.a = -m_cPhi * m_sTheta;
173 newpanel.b = -m_sPhi * m_sTheta;
174 newpanel.c = -m_cTheta;
175 newpanel.xv = {xv0, xv1, xv2, xv3};
176 newpanel.yv = {yv0, yv1, yv2, yv3};
177 newpanel.zv = {zv0, zv1, zv2, zv3};
178 newpanel.colour = 0;
179 newpanel.volume = id;
180 panels.push_back(std::move(newpanel));
181 }
182 // The z = zmax face.
183 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
184 ToGlobal(-m_lX, -m_lY, +m_lZ, xv0, yv0, zv0);
185 ToGlobal(-m_lX, +m_lY, +m_lZ, xv1, yv1, zv1);
186 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
187 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
188 Panel newpanel;
189 newpanel.a = +m_cPhi * m_sTheta;
190 newpanel.b = +m_sPhi * m_sTheta;
191 newpanel.c = +m_cTheta;
192 newpanel.xv = {xv0, xv1, xv2, xv3};
193 newpanel.yv = {yv0, yv1, yv2, yv3};
194 newpanel.zv = {zv0, zv1, zv2, zv3};
195 newpanel.colour = 0;
196 newpanel.volume = id;
197 panels.push_back(std::move(newpanel));
198 }
199 // Done, check panel count.
200 std::cout << "SolidBox::SolidPanels: " << panels.size() - nPanels
201 << " panels.\n";
202 return true;
203}
204
206
207 // Transform the normal vector to local coordinates.
208 double u = 0., v = 0., w = 0.;
209 VectorToLocal(panel.a, panel.b, panel.c, u, v, w);
210 // Identify the vector.
211 if (u > std::max(std::abs(v), std::abs(w))) {
212 return m_dis[0];
213 } else if (u < -std::max(std::abs(v), std::abs(w))) {
214 return m_dis[1];
215 } else if (v > std::max(std::abs(u), std::abs(w))) {
216 return m_dis[2];
217 } else if (v < -std::max(std::abs(u), std::abs(w))) {
218 return m_dis[3];
219 } else if (w > std::max(std::abs(u), std::abs(v))) {
220 return m_dis[4];
221 } else if (w < -std::max(std::abs(u), std::abs(v))) {
222 return m_dis[5];
223 }
224 if (m_debug) {
225 std::cout << m_className << "::GetDiscretisationLevel:\n"
226 << " Found no match for the panel; return first value.\n";
227 }
228 return m_dis[0];
229}
230
231}
void SetHalfLengthX(const double lx)
Definition: SolidBox.cc:65
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:10
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
Definition: SolidBox.cc:89
void SetHalfLengthZ(const double lz)
Definition: SolidBox.cc:81
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:43
bool IsInside(const double x, const double y, const double z) const override
Check whether a given point is inside the solid.
Definition: SolidBox.cc:21
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretization level of a panel.
Definition: SolidBox.cc:205
void SetHalfLengthY(const double ly)
Definition: SolidBox.cc:73
Abstract base class for solids.
Definition: Solid.hh:28
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
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_cX
Centre of the solid.
Definition: Solid.hh:164
double m_cPhi
Azimuthal angle.
Definition: Solid.hh:169
std::string m_className
Class name.
Definition: Solid.hh:174
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