Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Garfield::SolidHole Class Reference

Box with a cylindrical hole. More...

#include <SolidHole.hh>

+ Inheritance diagram for Garfield::SolidHole:

Public Member Functions

 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.
 
 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, const double dx, const double dy, const double dz)
 
 ~SolidHole ()
 Destructor.
 
bool IsInside (const double x, const double y, const double z) const override
 Check whether a given point is inside the solid.
 
bool GetBoundingBox (double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const override
 Return the bounding box of the solid.
 
bool IsHole () const override
 Return true if the solid is a hole.
 
void SetHalfLengthX (const double lx)
 Set the half-length of the box along x.
 
void SetHalfLengthY (const double ly)
 Set the half-length of the box along y.
 
void SetHalfLengthZ (const double lz)
 Set the half-length of the box along z.
 
void SetUpperRadius (const double r)
 Set the radius at z = +lz.
 
void SetLowerRadius (const double r)
 Set the radius at z = -lz.
 
double GetHalfLengthX () const override
 Return the half-length along x.
 
double GetHalfLengthY () const override
 Return the half-length along y.
 
double GetHalfLengthZ () const override
 Return the half-length along z.
 
double GetUpperRadius () const override
 Return the upper radius (of a hole).
 
double GetLowerRadius () const override
 Return the lower radius (of a hole).
 
void SetSectors (const unsigned int n)
 
void SetAverageRadius (const bool average)
 
unsigned int GetSectors () const
 Return the order of the approximating polygon.
 
bool GetAverage () const
 Return the state of the "average-radius" flag.
 
bool SolidPanels (std::vector< Panel > &panels) override
 Retrieve the surface panels of the solid.
 
double GetDiscretisationLevel (const Panel &panel) override
 Retrieve the discretization level of a panel.
 
- Public Member Functions inherited from Garfield::Solid
 Solid ()=delete
 Default constructor.
 
 Solid (const double cx, const double cy, const double cz, const std::string &name)
 Constructor.
 
virtual ~Solid ()
 Destructor.
 
virtual bool IsInside (const double x, const double y, const double z) const =0
 Check whether a given point is inside the solid.
 
virtual bool GetBoundingBox (double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const =0
 Return the bounding box of the solid.
 
virtual bool IsBox () const
 Return true if the solid is a box.
 
virtual bool IsTube () const
 Return true if the solid is a tube.
 
virtual bool IsSphere () const
 Return true if the solid is a sphere.
 
virtual bool IsHole () const
 Return true if the solid is a hole.
 
virtual bool IsRidge () const
 Return true if the solid is a ridge.
 
bool GetCentre (double &x, double &y, double &z) const
 Retrieve the centre point of the solid.
 
bool GetOrientation (double &ctheta, double &stheta, double &cphi, double &sphi) const
 Retrieve the orientation (azimuthal and polar angles) of the solid.
 
virtual double GetHalfLengthX () const
 Return the half-length along x.
 
virtual double GetHalfLengthY () const
 Return the half-length along y.
 
virtual double GetHalfLengthZ () const
 Return the half-length along z.
 
virtual double GetInnerRadius () const
 Return the inner radius.
 
virtual double GetOuterRadius () const
 Return the outer radius.
 
virtual double GetRadius () const
 Return the radius.
 
virtual double GetLowerRadius () const
 Return the lower radius (of a hole).
 
virtual double GetUpperRadius () const
 Return the upper radius (of a hole).
 
virtual double GetRidgeOffset () const
 Return the x-offset of a ridge.
 
virtual double GetRidgeHeight () const
 Return the height of a ridge.
 
unsigned int GetId () const
 Get the ID of the solid.
 
virtual bool SolidPanels (std::vector< Panel > &panels)=0
 Retrieve the surface panels of the solid.
 
virtual double GetDiscretisationLevel (const Panel &panel)=0
 Retrieve the discretization level of a panel.
 
void SetBoundaryPotential (const double v)
 Apply Dirichlet boundary conditions (fixed voltage).
 
void SetBoundaryChargeDensity (const double q)
 Apply fixed-charge boundary conditions.
 
void SetBoundaryFloat ()
 Make the potential at the surface of the solid floating.
 
void SetBoundaryDielectric ()
 Make the surfaces of the solid dielectric-dielectric interfaces.
 
void SetBoundaryParallelField ()
 
void SetBoundaryPerpendicularField ()
 
BoundaryCondition GetBoundaryConditionType () const
 Retrieve the type of boundary condition.
 
double GetBoundaryPotential () const
 Retrieve the potential.
 
double GetBoundaryChargeDensity () const
 Retrieve the surface charge density.
 
void EnableDebugging (const bool on=true)
 Switch debugging messages on/off.
 

Additional Inherited Members

- Public Types inherited from Garfield::Solid
enum  BoundaryCondition {
  Voltage = 1 , Charge , Float , Dielectric ,
  DielectricCharge , ParallelField , PerpendicularField
}
 
- Protected Member Functions inherited from Garfield::Solid
void ToLocal (const double x, const double y, const double z, double &u, double &v, double &w) const
 
void ToGlobal (const double u, const double v, const double w, double &x, double &y, double &z) const
 
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.
 
void SetDirection (const double dx, const double dy, const double dz)
 
- Protected Attributes inherited from Garfield::Solid
double m_cX = 0.
 Centre of the solid.
 
double m_cY = 0.
 
double m_cZ = 0.
 
double m_dX = 0.
 Direction vector.
 
double m_dY = 0.
 
double m_dZ = 1.
 
double m_cPhi = 1.
 Azimuthal angle.
 
double m_sPhi = 0.
 
double m_cTheta = 1.
 Polar angle.
 
double m_sTheta = 0.
 
std::string m_className = "Solid"
 Class name.
 
bool m_debug = false
 Debug flag.
 
BoundaryCondition m_bctype = Voltage
 Type of boundary condition.
 
double m_volt = 0.
 Potential at the surface.
 
double m_charge = 0.
 Surface charge density.
 
double m_eps = 0.
 Dielectric constant.
 

Detailed Description

Box with a cylindrical hole.

Definition at line 10 of file SolidHole.hh.

Constructor & Destructor Documentation

◆ SolidHole() [1/2]

Garfield::SolidHole::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.

Definition at line 9 of file SolidHole.cc.

12 : Solid(cx, cy, cz, "SolidHole"),
13 m_rUp(rup),
14 m_rLow(rlow),
15 m_lX(lx),
16 m_lY(ly),
17 m_lZ(lz) {}
Solid()=delete
Default constructor.

◆ SolidHole() [2/2]

Garfield::SolidHole::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,
const double  dx,
const double  dy,
const double  dz 
)

Constructor from centre, upper/lower radii, half-lengths of the box and orientation.

Definition at line 19 of file SolidHole.cc.

23 : SolidHole(cx, cy, cz, rup, rlow, lx, ly, lz) {
24 SetDirection(dx, dy, dz);
25}
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.
Definition: SolidHole.cc:9
void SetDirection(const double dx, const double dy, const double dz)
Definition: Solid.cc:12

◆ ~SolidHole()

Garfield::SolidHole::~SolidHole ( )
inline

Destructor.

Definition at line 23 of file SolidHole.hh.

23{}

Member Function Documentation

◆ GetAverage()

bool Garfield::SolidHole::GetAverage ( ) const
inline

Return the state of the "average-radius" flag.

Definition at line 62 of file SolidHole.hh.

62{ return m_average; }

◆ GetBoundingBox()

bool Garfield::SolidHole::GetBoundingBox ( double &  xmin,
double &  ymin,
double &  zmin,
double &  xmax,
double &  ymax,
double &  zmax 
) const
overridevirtual

Return the bounding box of the solid.

Implements Garfield::Solid.

Definition at line 56 of file SolidHole.cc.

57 {
58 if (m_cTheta == 1. && m_cPhi == 1.) {
59 xmin = m_cX - m_lX;
60 xmax = m_cX + m_lX;
61 ymin = m_cY - m_lY;
62 ymax = m_cY + m_lY;
63 zmin = m_cZ - m_lZ;
64 zmax = m_cZ + m_lZ;
65 return true;
66 }
67
68 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_lZ * m_lZ);
69 xmin = m_cX - dd;
70 xmax = m_cX + dd;
71 ymin = m_cY - dd;
72 ymax = m_cY + dd;
73 zmin = m_cZ - dd;
74 zmax = m_cZ + dd;
75 return true;
76}
double m_cZ
Definition: Solid.hh:164
double m_cTheta
Polar angle.
Definition: Solid.hh:171
double m_cY
Definition: Solid.hh:164
double m_cX
Centre of the solid.
Definition: Solid.hh:164
double m_cPhi
Azimuthal angle.
Definition: Solid.hh:169
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314

◆ GetDiscretisationLevel()

double Garfield::SolidHole::GetDiscretisationLevel ( const Panel panel)
overridevirtual

Retrieve the discretization level of a panel.

Implements Garfield::Solid.

Definition at line 327 of file SolidHole.cc.

327 {
328
329 // Transform the normal vector to local coordinates.
330 double un = 0., vn = 0., wn = 0.;
331 VectorToLocal(panel.a, panel.b, panel.c, un, vn, wn);
332 // Transform one of the points (first).
333 double u1 = 0., v1 = 0., w1 = 0.;
334 ToLocal(panel.xv[0], panel.yv[0], panel.zv[0], u1, v1, w1);
335 // Identify the vector.
336 if (wn > std::max(std::abs(un), std::abs(vn))) {
337 return m_dis[0];
338 } else if (wn < -std::max(std::abs(un), std::abs(vn))) {
339 return m_dis[1];
340 } else if (un * u1 + vn * v1 + wn * w1 < 0) {
341 return m_dis[2];
342 } else if (un > std::max(std::abs(vn), std::abs(wn))) {
343 return m_dis[3];
344 } else if (un < -std::max(std::abs(vn), std::abs(wn))) {
345 return m_dis[4];
346 } else if (vn > std::max(std::abs(un), std::abs(wn))) {
347 return m_dis[5];
348 } else if (vn < -std::max(std::abs(un), std::abs(wn))) {
349 return m_dis[6];
350 }
351 if (m_debug) {
352 std::cout << m_className << "::GetDiscretisationLevel:\n"
353 << " Found no match for the panel; returning first value.\n";
354 }
355 return m_dis[0];
356}
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
void ToLocal(const double x, const double y, const double z, double &u, double &v, double &w) const
Definition: Solid.hh:190
bool m_debug
Debug flag.
Definition: Solid.hh:177
std::string m_className
Class name.
Definition: Solid.hh:174

◆ GetHalfLengthX()

double Garfield::SolidHole::GetHalfLengthX ( ) const
inlineoverridevirtual

Return the half-length along x.

Reimplemented from Garfield::Solid.

Definition at line 41 of file SolidHole.hh.

41{ return m_lX; }

◆ GetHalfLengthY()

double Garfield::SolidHole::GetHalfLengthY ( ) const
inlineoverridevirtual

Return the half-length along y.

Reimplemented from Garfield::Solid.

Definition at line 42 of file SolidHole.hh.

42{ return m_lY; }

◆ GetHalfLengthZ()

double Garfield::SolidHole::GetHalfLengthZ ( ) const
inlineoverridevirtual

Return the half-length along z.

Reimplemented from Garfield::Solid.

Definition at line 43 of file SolidHole.hh.

43{ return m_lZ; }

◆ GetLowerRadius()

double Garfield::SolidHole::GetLowerRadius ( ) const
inlineoverridevirtual

Return the lower radius (of a hole).

Reimplemented from Garfield::Solid.

Definition at line 45 of file SolidHole.hh.

45{ return m_rLow; }

◆ GetSectors()

unsigned int Garfield::SolidHole::GetSectors ( ) const
inline

Return the order of the approximating polygon.

Definition at line 60 of file SolidHole.hh.

60{ return m_n; }

◆ GetUpperRadius()

double Garfield::SolidHole::GetUpperRadius ( ) const
inlineoverridevirtual

Return the upper radius (of a hole).

Reimplemented from Garfield::Solid.

Definition at line 44 of file SolidHole.hh.

44{ return m_rUp; }

◆ IsHole()

bool Garfield::SolidHole::IsHole ( ) const
inlineoverridevirtual

Return true if the solid is a hole.

Reimplemented from Garfield::Solid.

Definition at line 28 of file SolidHole.hh.

28{ return true; }

◆ IsInside()

bool Garfield::SolidHole::IsInside ( const double  x,
const double  y,
const double  z 
) const
overridevirtual

Check whether a given point is inside the solid.

Implements Garfield::Solid.

Definition at line 27 of file SolidHole.cc.

27 {
28 // Transform the point to local coordinates.
29 double u = x, v = y, w = z;
30 ToLocal(x, y, z, u, v, w);
31
32 if (fabs(u) > m_lX || fabs(v) > m_lY || fabs(w) > m_lZ) {
33 if (m_debug) {
34 std::cout << "SolidHole::IsInside: (" << x << ", " << y << ", " << z
35 << ") is outside.\n";
36 }
37 return false;
38 }
39
40 const double r = m_rLow + (w + m_lZ) * (m_rUp - m_rLow) / (2 * m_lZ);
41 if (u * u + v * v < r * r) {
42 if (m_debug) {
43 std::cout << "SolidHole::IsInside: (" << x << ", " << y << ", " << z
44 << ") is outside.\n";
45 }
46 return false;
47 }
48
49 if (m_debug) {
50 std::cout << "SolidHole::IsInside: (" << x << ", " << y << ", " << z
51 << ") is inside.\n";
52 }
53 return false;
54}
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615

◆ SetAverageRadius()

void Garfield::SolidHole::SetAverageRadius ( const bool  average)
inline

By default, the polygon used for approximating the hole when calculating surface panels is inscribed in a circle of the specified radius. If the "average-radius" flag is activated, then the radius will be interpreted as the mean radius of the polygon that approximates the cylinder.

Definition at line 57 of file SolidHole.hh.

57{ m_average = average; }

◆ SetHalfLengthX()

void Garfield::SolidHole::SetHalfLengthX ( const double  lx)

Set the half-length of the box along x.

Definition at line 94 of file SolidHole.cc.

94 {
95 if (lx <= 0.) {
96 std::cerr << "SolidHole::SetHalfLengthX: Half-length must be > 0.\n";
97 return;
98 }
99 m_lX = lx;
100}

◆ SetHalfLengthY()

void Garfield::SolidHole::SetHalfLengthY ( const double  ly)

Set the half-length of the box along y.

Definition at line 102 of file SolidHole.cc.

102 {
103 if (ly <= 0.) {
104 std::cerr << "SolidHole::SetHalfLengthY: Half-length must be > 0.\n";
105 return;
106 }
107 m_lY = ly;
108}

◆ SetHalfLengthZ()

void Garfield::SolidHole::SetHalfLengthZ ( const double  lz)

Set the half-length of the box along z.

Definition at line 110 of file SolidHole.cc.

110 {
111 if (lz <= 0.) {
112 std::cerr << "SolidHole::SetHalfLengthZ: Half-length must be > 0.\n";
113 return;
114 }
115 m_lZ = lz;
116}

◆ SetLowerRadius()

void Garfield::SolidHole::SetLowerRadius ( const double  r)

Set the radius at z = -lz.

Definition at line 86 of file SolidHole.cc.

86 {
87 if (r <= 0.) {
88 std::cerr << "SolidHole::SetLowerRadius: Radius must be > 0.\n";
89 return;
90 }
91 m_rLow = r;
92}

◆ SetSectors()

void Garfield::SolidHole::SetSectors ( const unsigned int  n)

When calculating the surface panels, the hole is approximated as a polygon with a finite number of panels. The number of corners of the polygon equals $4(n - 1)$. Thus, $n = 2$ will produce a square, $n = 3$ an octagon etc.

Definition at line 118 of file SolidHole.cc.

118 {
119 if (n < 1) {
120 std::cerr << "SolidHole::SetSectors: Number must be > 0.\n";
121 return;
122 }
123 m_n = n;
124}

◆ SetUpperRadius()

void Garfield::SolidHole::SetUpperRadius ( const double  r)

Set the radius at z = +lz.

Definition at line 78 of file SolidHole.cc.

78 {
79 if (r <= 0.) {
80 std::cerr << "SolidHole::SetUpperRadius: Radius must be > 0.\n";
81 return;
82 }
83 m_rUp = r;
84}

◆ SolidPanels()

bool Garfield::SolidHole::SolidPanels ( std::vector< Panel > &  panels)
overridevirtual

Retrieve the surface panels of the solid.

Implements Garfield::Solid.

Definition at line 126 of file SolidHole.cc.

126 {
127 const auto id = GetId();
128 const unsigned int nPanels = panels.size();
129 // Direction vector.
130 const double fnorm = sqrt(m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ);
131 if (fnorm <= 0) {
132 std::cerr << "SolidHole::SolidPanels:\n"
133 << " Zero norm direction vector; no panels generated.\n";
134 return false;
135 }
136
137 // Set the mean or the outer radius.
138 double r1 = m_rLow;
139 double r2 = m_rUp;
140 if (m_average) {
141 const double alpha = Pi / (4. * (m_n - 1.));
142 const double f = 2. / (1. + asinh(tan(alpha)) * cos(alpha) / tan(alpha));
143 r1 *= f;
144 r2 *= f;
145 }
146
147 double xv0, yv0, zv0;
148 double xv1, yv1, zv1;
149 double xv2, yv2, zv2;
150 double xv3, yv3, zv3;
151 // Draw the 6 sides of the box, start with the x=xmin face.
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);
157 Panel newpanel;
158 newpanel.a = -m_cPhi * m_cTheta;
159 newpanel.b = -m_sPhi * m_cTheta;
160 newpanel.c = +m_sTheta;
161 newpanel.xv = {xv0, xv1, xv2, xv3};
162 newpanel.yv = {yv0, yv1, yv2, yv3};
163 newpanel.zv = {zv0, zv1, zv2, zv3};
164 newpanel.colour = 0;
165 newpanel.volume = id;
166 panels.push_back(std::move(newpanel));
167 }
168 // The x=xmax face.
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);
174 Panel newpanel;
175 newpanel.a = m_cPhi * m_cTheta;
176 newpanel.b = m_sPhi * m_cTheta;
177 newpanel.c = -m_sTheta;
178 newpanel.xv = {xv0, xv1, xv2, xv3};
179 newpanel.yv = {yv0, yv1, yv2, yv3};
180 newpanel.zv = {zv0, zv1, zv2, zv3};
181 newpanel.colour = 0;
182 newpanel.volume = id;
183 panels.push_back(std::move(newpanel));
184 }
185 // The y=ymin face.
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);
191 Panel newpanel;
192 newpanel.a = m_sPhi;
193 newpanel.b = -m_cPhi;
194 newpanel.c = 0;
195 newpanel.xv = {xv0, xv1, xv2, xv3};
196 newpanel.yv = {yv0, yv1, yv2, yv3};
197 newpanel.zv = {zv0, zv1, zv2, zv3};
198 newpanel.colour = 0;
199 newpanel.volume = id;
200 panels.push_back(std::move(newpanel));
201 }
202 // The y=ymax face.
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);
208 Panel newpanel;
209 newpanel.a = -m_sPhi;
210 newpanel.b = m_cPhi;
211 newpanel.c = 0;
212 newpanel.xv = {xv0, xv1, xv2, xv3};
213 newpanel.yv = {yv0, yv1, yv2, yv3};
214 newpanel.zv = {zv0, zv1, zv2, zv3};
215 newpanel.colour = 0;
216 newpanel.volume = id;
217 panels.push_back(std::move(newpanel));
218 }
219 const double phi0 = -0.5 * HalfPi;
220 const double dphi = HalfPi / double(m_n - 1);
221 // The faces at constant z have a hole, and are drawn in parts.
222 for (int iside = -1; iside <= 1; iside += 2) {
223 const double r = iside == -1 ? r1 : r2;
224 const double w = m_lZ * iside;
225 Panel newpanel;
226 newpanel.a = iside * m_cPhi * m_sTheta;
227 newpanel.b = iside * m_sPhi * m_sTheta;
228 newpanel.c = iside * m_cTheta;
229 newpanel.colour = 0;
230 newpanel.volume = id;
231 // Loop over the panels.
232 for (unsigned int i = 0; i < m_n - 1; ++i) {
233 // The panels for x=xmax.
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);
246 // The panels for y=ymax.
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);
257 // The panels for x=xmin.
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);
268 // The panels for y=ymin.
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);
279 }
280 }
281 // The panels of the central cylinder, compute the projection angles.
282 const double alpha = atan2((r1 - r2) * cos(Pi / (4 * (m_n - 1))),
283 2 * m_lZ);
284 const double ci = cos(alpha);
285 const double si = sin(alpha);
286 // Initialise loop.
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);
289 // Go around the cylinder.
290 const unsigned int nPoints = 4 * m_n - 3;
291 for (unsigned int i = 1; i < nPoints; ++i) {
292 // Bottom and top of the line along the axis of the cylinder.
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);
296 // Store the plane.
297 Panel newpanel;
298 const double phim = phi0 + dphi * (i - 0.5);
299 const double cm = cos(phim);
300 const double sm = sin(phim);
301 newpanel.a = -m_cPhi * m_cTheta * cm * ci +
302 m_sPhi * sm * ci -
303 m_cPhi * m_sTheta * si;
304 newpanel.b = -m_sPhi * m_cTheta * cm * ci -
305 m_cPhi * sm * ci -
306 m_sPhi * m_sTheta * si;
307 newpanel.c = m_sTheta * cm * ci - m_cTheta * si;
308 newpanel.xv = {xv0, xv1, xv2, xv3};
309 newpanel.yv = {yv0, yv1, yv2, yv3};
310 newpanel.zv = {zv0, zv1, zv2, zv3};
311 newpanel.colour = 0;
312 newpanel.volume = id;
313 panels.push_back(std::move(newpanel));
314 // Shift the points.
315 xv0 = xv3;
316 yv0 = yv3;
317 zv0 = zv3;
318 xv1 = xv2;
319 yv1 = yv2;
320 zv1 = zv2;
321 }
322 std::cout << "SolidHole::SolidPanels: " << panels.size() - nPanels
323 << " panels.\n";
324 return true;
325}
double m_dZ
Definition: Solid.hh:167
double m_dX
Direction vector.
Definition: Solid.hh:167
unsigned int GetId() const
Get the ID of the solid.
Definition: Solid.hh:117
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_dY
Definition: Solid.hh:167
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:432
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:384

The documentation for this class was generated from the following files: