Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
SolidRidge.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
6
7namespace Garfield {
8
9SolidRidge::SolidRidge(const double cx, const double cy, const double cz,
10 const double lx, const double ly, const double hz,
11 const double hx)
12 : Solid(cx, cy, cz, "SolidRidge"),
13 m_lX(lx),
14 m_lY(ly),
15 m_hz(hz),
16 m_hx(hx) {}
17
18SolidRidge::SolidRidge(const double cx, const double cy, const double cz,
19 const double lx, const double ly, const double hz,
20 const double hx,
21 const double dx, const double dy, const double dz)
22 : SolidRidge(cx, cy, cz, lx, ly, hz, hx) {
23 SetDirection(dx, dy, dz);
24}
25
26bool SolidRidge::IsInside(const double x, const double y, const double z) const {
27 // Transform the point to local coordinates.
28 double u = x, v = y, w = z;
29 ToLocal(x, y, z, u, v, w);
30
31 bool inside = true;
32 if (fabs(u) > m_lX || fabs(v) > m_lY || w < 0. || w > m_hz) {
33 return false;
34 } else if (u >= m_hx && m_hz * u + (m_lX - m_hx) * v > m_hz * m_lX) {
35 inside = false;
36 } else if (u <= m_hx && -m_hz * u + (m_lX + m_hx) * v > m_hz * m_lX) {
37 inside = false;
38 }
39 if (m_debug) {
40 std::cout << "SolidRidge::IsInside: (" << x << ", " << y << ", " << z;
41 if (inside) {
42 std::cout << ") is inside.\n";
43 } else {
44 std::cout << ") is outside.\n";
45 }
46 }
47 return inside;
48}
49
50bool SolidRidge::GetBoundingBox(double& xmin, double& ymin, double& zmin,
51 double& xmax, double& ymax, double& zmax) const {
52 if (m_cTheta == 1. && m_cPhi == 1.) {
53 xmin = m_cX - m_lX;
54 xmax = m_cX + m_lX;
55 ymin = m_cY - m_lY;
56 ymax = m_cY + m_lY;
57 zmin = m_cZ;
58 zmax = m_cZ + m_hz;
59 return true;
60 }
61
62 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_hz * m_hz);
63 xmin = m_cX - dd;
64 xmax = m_cX + dd;
65 ymin = m_cY - dd;
66 ymax = m_cY + dd;
67 zmin = m_cZ - dd;
68 zmax = m_cZ + dd;
69 return true;
70}
71
72void SolidRidge::SetHalfLengthX(const double lx) {
73 if (lx <= 0.) {
74 std::cerr << "SolidRidge::SetHalfLengthX: Half-length must be > 0.\n";
75 return;
76 }
77 m_lX = lx;
78}
79
80void SolidRidge::SetHalfLengthY(const double ly) {
81 if (ly <= 0.) {
82 std::cerr << "SolidRidge::SetHalfLengthY: Half-length must be > 0.\n";
83 return;
84 }
85 m_lY = ly;
86}
87
88void SolidRidge::SetRidgeHeight(const double hz) {
89 if (hz <= 0.) {
90 std::cerr << "SolidRidge::SetRidgeHeight: Height must be > 0.\n";
91 return;
92 }
93 m_hz = hz;
94}
95
96bool SolidRidge::SolidPanels(std::vector<Panel>& panels) {
97 const auto id = GetId();
98 const unsigned int nPanels = panels.size();
99 // Direction vector.
100 const double fnorm = sqrt(m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ);
101 if (fnorm <= 0) {
102 std::cerr << "SolidRidge::SolidPanels:\n"
103 << " Zero norm direction vector; no panels generated.\n";
104 return false;
105 }
106 double xv0, yv0, zv0;
107 double xv1, yv1, zv1;
108 double xv2, yv2, zv2;
109 double xv3, yv3, zv3;
110
111 // Draw the 5 sides of the ridge, start with the floor.
112 ToGlobal(-m_lX, -m_lY, 0, xv0, yv0, zv0);
113 ToGlobal(-m_lX, +m_lY, 0, xv1, yv1, zv1);
114 ToGlobal(+m_lX, +m_lY, 0, xv2, yv2, zv2);
115 ToGlobal(+m_lX, -m_lY, 0, xv3, yv3, zv3);
116
117 Panel base;
118 base.a = -m_cPhi * m_sTheta;
119 base.b = -m_sPhi * m_sTheta;
120 base.c = -m_cTheta;
121 base.xv = {xv0, xv1, xv2, xv3};
122 base.yv = {yv0, yv1, yv2, yv3};
123 base.zv = {zv0, zv1, zv2, zv3};
124 base.colour = 0;
125 base.volume = id;
126 panels.push_back(std::move(base));
127
128 // Side triangles at y=ymin and y=ymax.
129 for (unsigned int i = 0; i < 2; ++i) {
130 const double y = i == 0 ? -m_lY : +m_lY;
131 ToGlobal(-m_lX, y, 0, xv0, yv0, zv0);
132 ToGlobal(+m_lX, y, 0, xv1, yv1, zv1);
133 ToGlobal(m_hx, y, m_hz, xv2, yv2, zv2);
134
135 const double a = i == 0 ? +m_sPhi : -m_sPhi;
136 const double b = i == 0 ? -m_cPhi : +m_cPhi;
137 Panel side;
138 side.a = a;
139 side.b = b;
140 side.c = 0.;
141 side.xv = {xv0, xv1, xv2};
142 side.yv = {yv0, yv1, yv2};
143 side.zv = {zv0, zv1, zv2};
144 side.colour = 0;
145 side.volume = id;
146 panels.push_back(std::move(side));
147 }
148
149 // The roof, parts at +x and -x.
150 for (unsigned int i = 0; i < 2; ++i) {
151 const double x = i == 0 ? +m_lX : -m_lX;
152 ToGlobal(x, -m_lY, 0, xv0, yv0, zv0);
153 ToGlobal(x, +m_lY, 0, xv1, yv1, zv1);
154 ToGlobal(m_hx, +m_lY, m_hz, xv2, yv2, zv2);
155 ToGlobal(m_hx, -m_lY, m_hz, xv3, yv3, zv3);
156 const double dx = i == 0 ? m_lX - m_hx : m_lX + m_hx;
157 const double s = sqrt(m_hz * m_hz + dx * dx);
158 const double xroof = i == 0 ? m_hz / s : -m_hz / s;
159 const double zroof = dx / s;
160
161 Panel roof;
162 roof.a = m_cPhi * m_cTheta * xroof + m_cPhi * m_sTheta * zroof;
163 roof.b = m_sPhi * m_cTheta * xroof + m_sPhi * m_sTheta * zroof;
164 roof.c = -m_sTheta * xroof + m_cTheta * zroof;
165 roof.xv = {xv0, xv1, xv2, xv3};
166 roof.yv = {yv0, yv1, yv2, yv3};
167 roof.zv = {zv0, zv1, zv2, zv3};
168 roof.colour = 0;
169 roof.volume = id;
170 panels.push_back(std::move(roof));
171 }
172 std::cout << "SolidRidge::SolidPanels: " << panels.size() - nPanels
173 << " panels.\n";
174 return true;
175}
176
178
179 // Transform the normal vector to local coordinates.
180 double u = 0., v = 0., w = 0.;
181 VectorToLocal(panel.a, panel.b, panel.c, u, v, w);
182 // Identify the vector.
183 if (v > std::max(std::abs(u), std::abs(w))) {
184 return m_dis[2];
185 } else if (v < -std::max(std::abs(u), std::abs(w))) {
186 return m_dis[3];
187 } else if (w < -std::max(std::abs(u), std::abs(v))) {
188 return m_dis[4];
189 } else if (u > 0) {
190 return m_dis[0];
191 } else if (u < 0) {
192 return m_dis[1];
193 }
194 if (m_debug) {
195 std::cout << m_className << "::GetDiscretisationLevel:\n"
196 << " Found no match for the panel; return first value.\n";
197 }
198 return m_dis[0];
199}
200
201}
Triangular prism (Toblerone bar).
Definition: SolidRidge.hh:10
SolidRidge(const double cx, const double cy, const double cz, const double lx, const double ly, const double hz, const double offsetx)
Constructor from centre, half-lengths, height and x-offset.
Definition: SolidRidge.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: SolidRidge.cc:50
void SetRidgeHeight(const double hz)
Set the height of the ridge.
Definition: SolidRidge.cc:88
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretization level of a panel.
Definition: SolidRidge.cc:177
void SetHalfLengthX(const double lx)
Set the half-length along x.
Definition: SolidRidge.cc:72
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
Definition: SolidRidge.cc:96
bool IsInside(const double x, const double y, const double z) const override
Check whether a given point is inside the solid.
Definition: SolidRidge.cc:26
void SetHalfLengthY(const double ly)
Set the half-length along y.
Definition: SolidRidge.cc:80
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
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