10 const double rup,
const double rlow,
11 const double lx,
const double ly,
const double lz)
12 :
Solid(cx, cy, cz,
"SolidHole"),
20 const double rup,
const double rlow,
21 const double lx,
const double ly,
const double lz,
22 const double dx,
const double dy,
const double dz)
23 :
SolidHole(cx, cy, cz, rup, rlow, lx, ly, lz) {
29 double u = x, v = y, w = z;
32 if (fabs(u) > m_lX || fabs(v) > m_lY || fabs(w) > m_lZ) {
34 std::cout <<
"SolidHole::IsInside: (" << x <<
", " << y <<
", " << z
40 const double r = m_rLow + (w + m_lZ) * (m_rUp - m_rLow) / (2 * m_lZ);
41 if (u * u + v * v < r * r) {
43 std::cout <<
"SolidHole::IsInside: (" << x <<
", " << y <<
", " << z
50 std::cout <<
"SolidHole::IsInside: (" << x <<
", " << y <<
", " << z
57 double& xmax,
double& ymax,
double& zmax)
const {
68 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_lZ * m_lZ);
80 std::cerr <<
"SolidHole::SetUpperRadius: Radius must be > 0.\n";
88 std::cerr <<
"SolidHole::SetLowerRadius: Radius must be > 0.\n";
96 std::cerr <<
"SolidHole::SetHalfLengthX: Half-length must be > 0.\n";
104 std::cerr <<
"SolidHole::SetHalfLengthY: Half-length must be > 0.\n";
112 std::cerr <<
"SolidHole::SetHalfLengthZ: Half-length must be > 0.\n";
120 std::cerr <<
"SolidHole::SetSectors: Number must be > 0.\n";
127 const auto id =
GetId();
128 const unsigned int nPanels = panels.size();
132 std::cerr <<
"SolidHole::SolidPanels:\n"
133 <<
" Zero norm direction vector; no panels generated.\n";
141 const double alpha = Pi / (4. * (m_n - 1.));
142 const double f = 2. / (1. + asinh(tan(alpha)) * cos(alpha) / tan(alpha));
147 double xv0, yv0, zv0;
148 double xv1, yv1, zv1;
149 double xv2, yv2, zv2;
150 double xv3, yv3, zv3;
152 if (m_lY > 0 && m_lZ > 0) {
153 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
154 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
155 ToGlobal(-m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
156 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
161 newpanel.
xv = {xv0, xv1, xv2, xv3};
162 newpanel.
yv = {yv0, yv1, yv2, yv3};
163 newpanel.
zv = {zv0, zv1, zv2, zv3};
166 panels.push_back(std::move(newpanel));
169 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
170 ToGlobal(+m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
171 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
172 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
173 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
178 newpanel.
xv = {xv0, xv1, xv2, xv3};
179 newpanel.
yv = {yv0, yv1, yv2, yv3};
180 newpanel.
zv = {zv0, zv1, zv2, zv3};
183 panels.push_back(std::move(newpanel));
186 if (m_lX > 0 && m_lZ > 0) {
187 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
188 ToGlobal(+m_lX, -m_lY, -m_lZ, xv1, yv1, zv1);
189 ToGlobal(+m_lX, -m_lY, +m_lZ, xv2, yv2, zv2);
190 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
195 newpanel.
xv = {xv0, xv1, xv2, xv3};
196 newpanel.
yv = {yv0, yv1, yv2, yv3};
197 newpanel.
zv = {zv0, zv1, zv2, zv3};
200 panels.push_back(std::move(newpanel));
203 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
204 ToGlobal(-m_lX, +m_lY, -m_lZ, xv0, yv0, zv0);
205 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
206 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
207 ToGlobal(-m_lX, +m_lY, +m_lZ, xv3, yv3, zv3);
212 newpanel.
xv = {xv0, xv1, xv2, xv3};
213 newpanel.
yv = {yv0, yv1, yv2, yv3};
214 newpanel.
zv = {zv0, zv1, zv2, zv3};
217 panels.push_back(std::move(newpanel));
219 const double phi0 = -0.5 * HalfPi;
220 const double dphi = HalfPi / double(m_n - 1);
222 for (
int iside = -1; iside <= 1; iside += 2) {
223 const double r = iside == -1 ? r1 : r2;
224 const double w = m_lZ * iside;
232 for (
unsigned int i = 0; i < m_n - 1; ++i) {
234 const double phi1 = phi0 + dphi * i;
235 const double phi2 = phi1 + dphi;
236 const double t1 = tan(phi1);
237 const double t2 = tan(phi2);
238 ToGlobal(r * cos(phi1), r * sin(phi1), w, xv0, yv0, zv0);
239 ToGlobal(r * cos(phi2), r * sin(phi2), w, xv3, yv3, zv3);
240 ToGlobal(m_lX, m_lY * t1, w, xv1, yv1, zv1);
241 ToGlobal(m_lX, m_lY * t2, w, xv2, yv2, zv2);
242 newpanel.
xv = {xv0, xv1, xv2, xv3};
243 newpanel.
yv = {yv0, yv1, yv2, yv3};
244 newpanel.
zv = {zv0, zv1, zv2, zv3};
245 panels.push_back(newpanel);
247 const double phi3 = phi1 + HalfPi;
248 const double phi4 = phi3 + dphi;
249 ToGlobal(r * cos(phi3), r * sin(phi3), w, xv0, yv0, zv0);
250 ToGlobal(r * cos(phi4), r * sin(phi4), w, xv3, yv3, zv3);
251 ToGlobal(-m_lX * t1, m_lY, w, xv1, yv1, zv1);
252 ToGlobal(-m_lX * t2, m_lY, w, xv2, yv2, zv2);
253 newpanel.
xv = {xv0, xv1, xv2, xv3};
254 newpanel.
yv = {yv0, yv1, yv2, yv3};
255 newpanel.
zv = {zv0, zv1, zv2, zv3};
256 panels.push_back(newpanel);
258 const double phi5 = phi3 + HalfPi;
259 const double phi6 = phi5 + dphi;
260 ToGlobal(r * cos(phi5), r * sin(phi5), w, xv0, yv0, zv0);
261 ToGlobal(r * cos(phi6), r * sin(phi6), w, xv3, yv3, zv3);
262 ToGlobal(-m_lX, -m_lY * t1, w, xv1, yv1, zv1);
263 ToGlobal(-m_lX, -m_lY * t2, w, xv2, yv2, zv2);
264 newpanel.
xv = {xv0, xv1, xv2, xv3};
265 newpanel.
yv = {yv0, yv1, yv2, yv3};
266 newpanel.
zv = {zv0, zv1, zv2, zv3};
267 panels.push_back(newpanel);
269 const double phi7 = phi5 + HalfPi;
270 const double phi8 = phi7 + dphi;
271 ToGlobal(r * cos(phi7), r * sin(phi7), w, xv0, yv0, zv0);
272 ToGlobal(r * cos(phi8), r * sin(phi8), w, xv3, yv3, zv3);
273 ToGlobal(m_lX * t1, -m_lY, w, xv1, yv1, zv1);
274 ToGlobal(m_lX * t2, -m_lY, w, xv2, yv2, zv2);
275 newpanel.
xv = {xv0, xv1, xv2, xv3};
276 newpanel.
yv = {yv0, yv1, yv2, yv3};
277 newpanel.
zv = {zv0, zv1, zv2, zv3};
278 panels.push_back(newpanel);
282 const double alpha = atan2((r1 - r2) * cos(Pi / (4 * (m_n - 1))),
284 const double ci = cos(alpha);
285 const double si = sin(alpha);
287 ToGlobal(r1 * cos(phi0), r1 * sin(phi0), -m_lZ, xv0, yv0, zv0);
288 ToGlobal(r2 * cos(phi0), r2 * sin(phi0), +m_lZ, xv1, yv1, zv1);
290 const unsigned int nPoints = 4 * m_n - 3;
291 for (
unsigned int i = 1; i < nPoints; ++i) {
293 const double phi = phi0 + dphi * i;
294 ToGlobal(r2 * cos(phi), r2 * sin(phi), +m_lZ, xv2, yv2, zv2);
295 ToGlobal(r1 * cos(phi), r1 * sin(phi), -m_lZ, xv3, yv3, zv3);
298 const double phim = phi0 + dphi * (i - 0.5);
299 const double cm = cos(phim);
300 const double sm = sin(phim);
308 newpanel.
xv = {xv0, xv1, xv2, xv3};
309 newpanel.
yv = {yv0, yv1, yv2, yv3};
310 newpanel.
zv = {zv0, zv1, zv2, zv3};
313 panels.push_back(std::move(newpanel));
322 std::cout <<
"SolidHole::SolidPanels: " << panels.size() - nPanels
330 double un = 0., vn = 0., wn = 0.;
333 double u1 = 0., v1 = 0., w1 = 0.;
336 if (wn > std::max(std::abs(un), std::abs(vn))) {
338 }
else if (wn < -std::max(std::abs(un), std::abs(vn))) {
340 }
else if (un * u1 + vn * v1 + wn * w1 < 0) {
342 }
else if (un > std::max(std::abs(vn), std::abs(wn))) {
344 }
else if (un < -std::max(std::abs(vn), std::abs(wn))) {
346 }
else if (vn > std::max(std::abs(un), std::abs(wn))) {
348 }
else if (vn < -std::max(std::abs(un), std::abs(wn))) {
352 std::cout <<
m_className <<
"::GetDiscretisationLevel:\n"
353 <<
" Found no match for the panel; returning first value.\n";
Box with a cylindrical hole.
void SetHalfLengthY(const double ly)
Set the half-length of the box along y.
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const override
Return the bounding box of the solid.
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretization level of a panel.
void SetSectors(const unsigned int n)
void SetHalfLengthX(const double lx)
Set the half-length of the box along x.
void SetLowerRadius(const double r)
Set the radius at z = -lz.
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
void SetHalfLengthZ(const double lz)
Set the half-length of the box along z.
bool IsInside(const double x, const double y, const double z) const override
Check whether a given point is inside the solid.
void SetUpperRadius(const double r)
Set the radius at z = +lz.
SolidHole(const double cx, const double cy, const double cz, const double rup, const double rlow, const double lx, const double ly, const double lz)
Constructor from centre, upper/lower radii, half-lengths of the box.
Abstract base class for solids.
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.
double m_cTheta
Polar angle.
double m_dX
Direction vector.
unsigned int GetId() const
Get the ID of the solid.
void ToLocal(const double x, const double y, const double z, double &u, double &v, double &w) const
void SetDirection(const double dx, const double dy, const double dz)
void ToGlobal(const double u, const double v, const double w, double &x, double &y, double &z) const
double m_cX
Centre of the solid.
double m_cPhi
Azimuthal angle.
std::string m_className
Class name.
std::vector< double > zv
Z-coordinates of vertices.
int volume
Reference to solid to which the panel belongs.
double a
Perpendicular vector.
double colour
Colour index.
std::vector< double > xv
X-coordinates of vertices.
std::vector< double > yv
Y-coordinates of vertices.