Garfield++ 4.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 bool tesselated) const override
 
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.
 
void SetDiscretisationLevel (const double dis) override
 Set the discretisation level (for all panels).
 
double GetDiscretisationLevel (const Panel &panel) override
 Retrieve the discretisation level of a panel.
 
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
 
- 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 bool tesselated=false) const =0
 
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.
 
virtual bool IsExtrusion () const
 Return true if the solid is an extrusion.
 
virtual bool IsWire () const
 Return true if the solid is a wire.
 
void SetLabel (const std::string &label)
 Set a label.
 
std::string GetLabel () const
 Return the label.
 
bool GetCentre (double &x, double &y, double &z) const
 Retrieve the centre point of the solid.
 
bool GetDirection (double &dx, double &dy, double &dz) const
 Retrieve the direction vector.
 
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.
 
virtual bool GetProfile (std::vector< double > &xv, std::vector< double > &yv) const
 Get the vertices defining an extrusion.
 
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 void SetDiscretisationLevel (const double dis)=0
 Set the discretisation level (for all panels).
 
virtual double GetDiscretisationLevel (const Panel &panel)=0
 Retrieve the discretisation level of a panel.
 
virtual void Cut (const double x0, const double y0, const double z0, const double xn, const double yn, const double zn, std::vector< Panel > &panels)=0
 
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.
 
void SetColour (const int col)
 Set the colour of the solid.
 
int GetColour () const
 Get the colour of the solid.
 

Additional Inherited Members

- Public Types inherited from Garfield::Solid
enum  BoundaryCondition {
  Unknown = 0 , Voltage , Charge , Float ,
  Dielectric , DielectricCharge , ParallelField , PerpendicularField
}
 
- Static Public Member Functions inherited from Garfield::Solid
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)
 
- 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.
 
std::string m_label = ""
 Label.
 
bool m_debug = false
 Debug flag.
 
BoundaryCondition m_bctype = Unknown
 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.
 
int m_colour = -1
 Colour.
 

Detailed Description

Box with a cylindrical hole.

Definition at line 12 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 62 of file SolidHole.cc.

65 : Solid(cx, cy, cz, "SolidHole"),
66 m_rUp(rup),
67 m_rLow(rlow),
68 m_lX(lx),
69 m_lY(ly),
70 m_lZ(lz) {
71 Update();
72}
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 74 of file SolidHole.cc.

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

◆ ~SolidHole()

Garfield::SolidHole::~SolidHole ( )
inline

Destructor.

Definition at line 25 of file SolidHole.hh.

25{}

Member Function Documentation

◆ Cut()

void Garfield::SolidHole::Cut ( const double  x0,
const double  y0,
const double  z0,
const double  xn,
const double  yn,
const double  zn,
std::vector< Panel > &  panels 
)
overridevirtual

Implements Garfield::Solid.

Definition at line 428 of file SolidHole.cc.

430 {
431
432 //-----------------------------------------------------------------------
433 // PLACHC - Cuts a cylindrical hole with a plane.
434 //-----------------------------------------------------------------------
435
436 // Adjust the mean radii if requested.
437 double r1 = m_rLow;
438 double r2 = m_rUp;
439 if (m_average) {
440 r1 *= m_fp;
441 r2 *= m_fp;
442 }
443 std::array<double, 8> xbox;
444 std::array<double, 8> ybox;
445 std::array<double, 8> zbox;
446 // Loop over the boxes that make up the hole.
447 const double dphi = HalfPi / (m_n - 1.);
448 for (unsigned int i = 1; i <= m_n - 1; ++i) {
449 const double phi1 = dphi * (i - 1.);
450 const double phi2 = dphi * i;
451 const double t1 = tan(-0.5 * HalfPi + phi1);
452 const double t2 = tan(-0.5 * HalfPi + phi2);
453 // The boxes ending at x=xmax.
454 for (int iside : {-1, 1}) {
455 const double r = iside < 0 ? r1 : r2;
456 const double w = iside * m_lZ;
457 const unsigned int k = iside < 0 ? 0 : 4;
458 const double phi0 = -0.5 * HalfPi;
459 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
460 xbox[k], ybox[k], zbox[k]);
461 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
462 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
463 ToGlobal(m_lX, m_lY * t1, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
464 ToGlobal(m_lX, m_lY * t2, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
465 }
466 std::vector<double> xv;
467 std::vector<double> yv;
468 std::vector<double> zv;
469 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
470 if (xv.size() >= 3) {
471 Panel panel;
472 panel.a = xn;
473 panel.b = yn;
474 panel.c = zn;
475 panel.xv = xv;
476 panel.yv = yv;
477 panel.zv = zv;
478 panel.colour = m_colour;
479 panel.volume = GetId();
480 panels.push_back(std::move(panel));
481 }
482 xv.clear();
483 yv.clear();
484 zv.clear();
485 // The panels for y=ymax.
486 for (int iside : {-1, 1}) {
487 const double r = iside < 0 ? r1 : r2;
488 const double w = iside * m_lZ;
489 const unsigned int k = iside < 0 ? 0 : 4;
490 const double phi0 = 0.5 * HalfPi;
491 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
492 xbox[k], ybox[k], zbox[k]);
493 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
494 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
495 ToGlobal(-m_lX * t1, m_lY, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
496 ToGlobal(-m_lX * t2, m_lY, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
497 }
498 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
499 if (xv.size() >= 3) {
500 Panel panel;
501 panel.a = xn;
502 panel.b = yn;
503 panel.c = zn;
504 panel.xv = xv;
505 panel.yv = yv;
506 panel.zv = zv;
507 panel.colour = m_colour;
508 panel.volume = GetId();
509 panels.push_back(std::move(panel));
510 }
511 xv.clear();
512 yv.clear();
513 zv.clear();
514 // The panels for x=xmin.
515 for (int iside : {-1, 1}) {
516 const double r = iside < 0 ? r1 : r2;
517 const double w = iside * m_lZ;
518 const unsigned int k = iside < 0 ? 0 : 4;
519 const double phi0 = 1.5 * HalfPi;
520 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
521 xbox[k], ybox[k], zbox[k]);
522 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
523 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
524 ToGlobal(-m_lX, -m_lY * t1, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
525 ToGlobal(-m_lX, -m_lY * t2, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
526 }
527 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
528 if (xv.size() >= 3) {
529 Panel panel;
530 panel.a = xn;
531 panel.b = yn;
532 panel.c = zn;
533 panel.xv = xv;
534 panel.yv = yv;
535 panel.zv = zv;
536 panel.colour = m_colour;
537 panel.volume = GetId();
538 panels.push_back(std::move(panel));
539 }
540 xv.clear();
541 yv.clear();
542 zv.clear();
543 // The panels for y=ymin.
544 for (int iside : {-1, 1}) {
545 const double r = iside < 0 ? r1 : r2;
546 const double w = iside * m_lZ;
547 const unsigned int k = iside < 0 ? 0 : 4;
548 const double phi0 = -1.5 * HalfPi;
549 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
550 xbox[k], ybox[k], zbox[k]);
551 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
552 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
553 ToGlobal(m_lX * t1, -m_lY, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
554 ToGlobal(m_lX * t2, -m_lY, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
555
556 }
557 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
558 if (xv.size() >= 3) {
559 Panel panel;
560 panel.a = xn;
561 panel.b = yn;
562 panel.c = zn;
563 panel.xv = xv;
564 panel.yv = yv;
565 panel.zv = zv;
566 panel.colour = m_colour;
567 panel.volume = GetId();
568 panels.push_back(std::move(panel));
569 }
570 }
571}
unsigned int GetId() const
Get the ID of the solid.
Definition: Solid.hh:137
int m_colour
Colour.
Definition: Solid.hh:230
void ToGlobal(const double u, const double v, const double w, double &x, double &y, double &z) const
Definition: Solid.hh:246
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:432
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:384

◆ GetAverage()

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

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

Definition at line 68 of file SolidHole.hh.

68{ 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 127 of file SolidHole.cc.

128 {
129 if (m_cTheta == 1. && m_cPhi == 1.) {
130 xmin = m_cX - m_lX;
131 xmax = m_cX + m_lX;
132 ymin = m_cY - m_lY;
133 ymax = m_cY + m_lY;
134 zmin = m_cZ - m_lZ;
135 zmax = m_cZ + m_lZ;
136 return true;
137 }
138
139 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_lZ * m_lZ);
140 xmin = m_cX - dd;
141 xmax = m_cX + dd;
142 ymin = m_cY - dd;
143 ymax = m_cY + dd;
144 zmin = m_cZ - dd;
145 zmax = m_cZ + dd;
146 return true;
147}
double m_cZ
Definition: Solid.hh:202
double m_cTheta
Polar angle.
Definition: Solid.hh:209
double m_cY
Definition: Solid.hh:202
double m_cX
Centre of the solid.
Definition: Solid.hh:202
double m_cPhi
Azimuthal angle.
Definition: Solid.hh:207
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314

◆ GetDiscretisationLevel()

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

Retrieve the discretisation level of a panel.

Implements Garfield::Solid.

Definition at line 397 of file SolidHole.cc.

397 {
398
399 // Transform the normal vector to local coordinates.
400 double un = 0., vn = 0., wn = 0.;
401 VectorToLocal(panel.a, panel.b, panel.c, un, vn, wn);
402 // Transform one of the points (first).
403 double u1 = 0., v1 = 0., w1 = 0.;
404 ToLocal(panel.xv[0], panel.yv[0], panel.zv[0], u1, v1, w1);
405 // Identify the vector.
406 if (wn > std::max(std::abs(un), std::abs(vn))) {
407 return m_dis[0];
408 } else if (wn < -std::max(std::abs(un), std::abs(vn))) {
409 return m_dis[1];
410 } else if (un * u1 + vn * v1 + wn * w1 < 0) {
411 return m_dis[2];
412 } else if (un > std::max(std::abs(vn), std::abs(wn))) {
413 return m_dis[3];
414 } else if (un < -std::max(std::abs(vn), std::abs(wn))) {
415 return m_dis[4];
416 } else if (vn > std::max(std::abs(un), std::abs(wn))) {
417 return m_dis[5];
418 } else if (vn < -std::max(std::abs(un), std::abs(wn))) {
419 return m_dis[6];
420 }
421 if (m_debug) {
422 std::cout << m_className << "::GetDiscretisationLevel:\n"
423 << " Found no match for the panel; returning first value.\n";
424 }
425 return m_dis[0];
426}
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
void ToLocal(const double x, const double y, const double z, double &u, double &v, double &w) const
Definition: Solid.hh:234
bool m_debug
Debug flag.
Definition: Solid.hh:218
std::string m_className
Class name.
Definition: Solid.hh:212

◆ GetHalfLengthX()

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

Return the half-length along x.

Reimplemented from Garfield::Solid.

Definition at line 44 of file SolidHole.hh.

44{ return m_lX; }

◆ GetHalfLengthY()

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

Return the half-length along y.

Reimplemented from Garfield::Solid.

Definition at line 45 of file SolidHole.hh.

45{ return m_lY; }

◆ GetHalfLengthZ()

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

Return the half-length along z.

Reimplemented from Garfield::Solid.

Definition at line 46 of file SolidHole.hh.

46{ return m_lZ; }

◆ GetLowerRadius()

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

Return the lower radius (of a hole).

Reimplemented from Garfield::Solid.

Definition at line 48 of file SolidHole.hh.

48{ return m_rLow; }

◆ GetSectors()

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

Return the order of the approximating polygon.

Definition at line 66 of file SolidHole.hh.

66{ return m_n; }

◆ GetUpperRadius()

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

Return the upper radius (of a hole).

Reimplemented from Garfield::Solid.

Definition at line 47 of file SolidHole.hh.

47{ 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 31 of file SolidHole.hh.

31{ return true; }

◆ IsInside()

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

Check whether a given point is inside the solid. If requested, use the tesselated approximation of the solid (if applicable).

Implements Garfield::Solid.

Definition at line 93 of file SolidHole.cc.

94 {
95 // Transform the point to local coordinates.
96 double u = x, v = y, w = z;
97 ToLocal(x, y, z, u, v, w);
98
99 if (fabs(u) > m_lX || fabs(v) > m_lY || fabs(w) > m_lZ) {
100 return false;
101 }
102
103 double r = m_rLow + (w + m_lZ) * (m_rUp - m_rLow) / (2 * m_lZ);
104 if (!tesselated) return (u * u + v * v >= r * r);
105 const double rho = sqrt(u * u + v * v);
106 if (m_average) r *= m_fp;
107 if (rho > r) return true;
108 if (rho < r * m_fi) return false;
109
110 std::vector<double> xp;
111 std::vector<double> yp;
112 const double phi0 = -0.5 * HalfPi;
113 const double dphi = HalfPi / double(m_n - 1);
114 const unsigned int nP = 4 * (m_n - 1);
115 for (unsigned int i = 0; i < nP; ++i) {
116 // Bottom and top of the line along the axis of the cylinder.
117 const double phi = phi0 + dphi * i;
118 xp.push_back(r * cos(phi));
119 yp.push_back(r * sin(phi));
120 }
121 bool inside = false;
122 bool edge = false;
123 Polygon::Inside(xp, yp, u, v, inside, edge);
124 return !inside;
125}
void Inside(const std::vector< double > &xpl, const std::vector< double > &ypl, const double x, const double y, bool &inside, bool &edge)
Definition: Polygon.cc:187
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 60 of file SolidHole.hh.

60 {
61 m_average = average;
62 Update();
63 }

◆ SetDiscretisationLevel()

void Garfield::SolidHole::SetDiscretisationLevel ( const double  dis)
inlineoverridevirtual

Set the discretisation level (for all panels).

Implements Garfield::Solid.

Definition at line 71 of file SolidHole.hh.

71 {
72 m_dis.fill(dis);
73 }

◆ SetHalfLengthX()

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

Set the half-length of the box along x.

Definition at line 165 of file SolidHole.cc.

165 {
166 if (lx <= 0.) {
167 std::cerr << "SolidHole::SetHalfLengthX: Half-length must be > 0.\n";
168 return;
169 }
170 m_lX = lx;
171}

◆ SetHalfLengthY()

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

Set the half-length of the box along y.

Definition at line 173 of file SolidHole.cc.

173 {
174 if (ly <= 0.) {
175 std::cerr << "SolidHole::SetHalfLengthY: Half-length must be > 0.\n";
176 return;
177 }
178 m_lY = ly;
179}

◆ SetHalfLengthZ()

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

Set the half-length of the box along z.

Definition at line 181 of file SolidHole.cc.

181 {
182 if (lz <= 0.) {
183 std::cerr << "SolidHole::SetHalfLengthZ: Half-length must be > 0.\n";
184 return;
185 }
186 m_lZ = lz;
187}

◆ SetLowerRadius()

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

Set the radius at z = -lz.

Definition at line 157 of file SolidHole.cc.

157 {
158 if (r <= 0.) {
159 std::cerr << "SolidHole::SetLowerRadius: Radius must be > 0.\n";
160 return;
161 }
162 m_rLow = r;
163}

◆ 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 189 of file SolidHole.cc.

189 {
190 if (n < 1) {
191 std::cerr << "SolidHole::SetSectors: Number must be > 0.\n";
192 return;
193 }
194 m_n = n;
195 Update();
196}

◆ SetUpperRadius()

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

Set the radius at z = +lz.

Definition at line 149 of file SolidHole.cc.

149 {
150 if (r <= 0.) {
151 std::cerr << "SolidHole::SetUpperRadius: Radius must be > 0.\n";
152 return;
153 }
154 m_rUp = r;
155}

◆ SolidPanels()

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

Retrieve the surface panels of the solid.

Implements Garfield::Solid.

Definition at line 198 of file SolidHole.cc.

198 {
199 const auto id = GetId();
200 const auto nPanels = panels.size();
201 // Direction vector.
202 const double fnorm = sqrt(m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ);
203 if (fnorm <= 0) {
204 std::cerr << "SolidHole::SolidPanels:\n"
205 << " Zero norm direction vector; no panels generated.\n";
206 return false;
207 }
208
209 // Set the mean or the outer radius.
210 double r1 = m_rLow;
211 double r2 = m_rUp;
212 if (m_average) {
213 r1 *= m_fp;
214 r2 *= m_fp;
215 }
216
217 double xv0, yv0, zv0;
218 double xv1, yv1, zv1;
219 double xv2, yv2, zv2;
220 double xv3, yv3, zv3;
221 // Draw the 6 sides of the box, start with the x=xmin face.
222 if (m_lY > 0 && m_lZ > 0) {
223 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
224 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
225 ToGlobal(-m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
226 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
227 Panel panel;
228 panel.a = -m_cPhi * m_cTheta;
229 panel.b = -m_sPhi * m_cTheta;
230 panel.c = +m_sTheta;
231 panel.xv = {xv0, xv1, xv2, xv3};
232 panel.yv = {yv0, yv1, yv2, yv3};
233 panel.zv = {zv0, zv1, zv2, zv3};
234 panel.colour = m_colour;
235 panel.volume = id;
236 panels.push_back(std::move(panel));
237 }
238 // The x=xmax face.
239 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
240 ToGlobal(+m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
241 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
242 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
243 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
244 Panel panel;
245 panel.a = m_cPhi * m_cTheta;
246 panel.b = m_sPhi * m_cTheta;
247 panel.c = -m_sTheta;
248 panel.xv = {xv0, xv1, xv2, xv3};
249 panel.yv = {yv0, yv1, yv2, yv3};
250 panel.zv = {zv0, zv1, zv2, zv3};
251 panel.colour = m_colour;
252 panel.volume = id;
253 panels.push_back(std::move(panel));
254 }
255 // The y=ymin face.
256 if (m_lX > 0 && m_lZ > 0) {
257 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
258 ToGlobal(+m_lX, -m_lY, -m_lZ, xv1, yv1, zv1);
259 ToGlobal(+m_lX, -m_lY, +m_lZ, xv2, yv2, zv2);
260 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
261 Panel panel;
262 panel.a = m_sPhi;
263 panel.b = -m_cPhi;
264 panel.c = 0;
265 panel.xv = {xv0, xv1, xv2, xv3};
266 panel.yv = {yv0, yv1, yv2, yv3};
267 panel.zv = {zv0, zv1, zv2, zv3};
268 panel.colour = m_colour;
269 panel.volume = id;
270 panels.push_back(std::move(panel));
271 }
272 // The y=ymax face.
273 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
274 ToGlobal(-m_lX, +m_lY, -m_lZ, xv0, yv0, zv0);
275 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
276 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
277 ToGlobal(-m_lX, +m_lY, +m_lZ, xv3, yv3, zv3);
278 Panel panel;
279 panel.a = -m_sPhi;
280 panel.b = m_cPhi;
281 panel.c = 0;
282 panel.xv = {xv0, xv1, xv2, xv3};
283 panel.yv = {yv0, yv1, yv2, yv3};
284 panel.zv = {zv0, zv1, zv2, zv3};
285 panel.colour = m_colour;
286 panel.volume = id;
287 panels.push_back(std::move(panel));
288 }
289 const double phi0 = -0.5 * HalfPi;
290 const double dphi = HalfPi / double(m_n - 1);
291 // The faces at constant z have a hole, and are drawn in parts.
292 for (int iside = -1; iside <= 1; iside += 2) {
293 const double r = iside == -1 ? r1 : r2;
294 const double w = m_lZ * iside;
295 Panel panel;
296 panel.a = iside * m_cPhi * m_sTheta;
297 panel.b = iside * m_sPhi * m_sTheta;
298 panel.c = iside * m_cTheta;
299 panel.colour = m_colour;
300 panel.volume = id;
301 // Loop over the panels.
302 for (unsigned int i = 0; i < m_n - 1; ++i) {
303 // The panels for x=xmax.
304 const double phi1 = phi0 + dphi * i;
305 const double phi2 = phi1 + dphi;
306 const double t1 = tan(phi1);
307 const double t2 = tan(phi2);
308 ToGlobal(r * cos(phi1), r * sin(phi1), w, xv0, yv0, zv0);
309 ToGlobal(r * cos(phi2), r * sin(phi2), w, xv3, yv3, zv3);
310 ToGlobal(m_lX, m_lY * t1, w, xv1, yv1, zv1);
311 ToGlobal(m_lX, m_lY * t2, w, xv2, yv2, zv2);
312 panel.xv = {xv0, xv1, xv2, xv3};
313 panel.yv = {yv0, yv1, yv2, yv3};
314 panel.zv = {zv0, zv1, zv2, zv3};
315 panels.push_back(panel);
316 // The panels for y=ymax.
317 const double phi3 = phi1 + HalfPi;
318 const double phi4 = phi3 + dphi;
319 ToGlobal(r * cos(phi3), r * sin(phi3), w, xv0, yv0, zv0);
320 ToGlobal(r * cos(phi4), r * sin(phi4), w, xv3, yv3, zv3);
321 ToGlobal(-m_lX * t1, m_lY, w, xv1, yv1, zv1);
322 ToGlobal(-m_lX * t2, m_lY, w, xv2, yv2, zv2);
323 panel.xv = {xv0, xv1, xv2, xv3};
324 panel.yv = {yv0, yv1, yv2, yv3};
325 panel.zv = {zv0, zv1, zv2, zv3};
326 panels.push_back(panel);
327 // The panels for x=xmin.
328 const double phi5 = phi3 + HalfPi;
329 const double phi6 = phi5 + dphi;
330 ToGlobal(r * cos(phi5), r * sin(phi5), w, xv0, yv0, zv0);
331 ToGlobal(r * cos(phi6), r * sin(phi6), w, xv3, yv3, zv3);
332 ToGlobal(-m_lX, -m_lY * t1, w, xv1, yv1, zv1);
333 ToGlobal(-m_lX, -m_lY * t2, w, xv2, yv2, zv2);
334 panel.xv = {xv0, xv1, xv2, xv3};
335 panel.yv = {yv0, yv1, yv2, yv3};
336 panel.zv = {zv0, zv1, zv2, zv3};
337 panels.push_back(panel);
338 // The panels for y=ymin.
339 const double phi7 = phi5 + HalfPi;
340 const double phi8 = phi7 + dphi;
341 ToGlobal(r * cos(phi7), r * sin(phi7), w, xv0, yv0, zv0);
342 ToGlobal(r * cos(phi8), r * sin(phi8), w, xv3, yv3, zv3);
343 ToGlobal(m_lX * t1, -m_lY, w, xv1, yv1, zv1);
344 ToGlobal(m_lX * t2, -m_lY, w, xv2, yv2, zv2);
345 panel.xv = {xv0, xv1, xv2, xv3};
346 panel.yv = {yv0, yv1, yv2, yv3};
347 panel.zv = {zv0, zv1, zv2, zv3};
348 panels.push_back(panel);
349 }
350 }
351 // The panels of the central cylinder, compute the projection angles.
352 const double alpha = atan2((r1 - r2) * cos(Pi / (4 * (m_n - 1))),
353 2 * m_lZ);
354 const double ci = cos(alpha);
355 const double si = sin(alpha);
356 // Initialise loop.
357 ToGlobal(r1 * cos(phi0), r1 * sin(phi0), -m_lZ, xv0, yv0, zv0);
358 ToGlobal(r2 * cos(phi0), r2 * sin(phi0), +m_lZ, xv1, yv1, zv1);
359 // Go around the cylinder.
360 const unsigned int nPoints = 4 * m_n - 3;
361 for (unsigned int i = 1; i < nPoints; ++i) {
362 // Bottom and top of the line along the axis of the cylinder.
363 const double phi = phi0 + dphi * i;
364 ToGlobal(r2 * cos(phi), r2 * sin(phi), +m_lZ, xv2, yv2, zv2);
365 ToGlobal(r1 * cos(phi), r1 * sin(phi), -m_lZ, xv3, yv3, zv3);
366 // Store the plane.
367 Panel panel;
368 const double phim = phi0 + dphi * (i - 0.5);
369 const double cm = cos(phim);
370 const double sm = sin(phim);
371 panel.a = -m_cPhi * m_cTheta * cm * ci +
372 m_sPhi * sm * ci -
373 m_cPhi * m_sTheta * si;
374 panel.b = -m_sPhi * m_cTheta * cm * ci -
375 m_cPhi * sm * ci -
376 m_sPhi * m_sTheta * si;
377 panel.c = m_sTheta * cm * ci - m_cTheta * si;
378 panel.xv = {xv0, xv1, xv2, xv3};
379 panel.yv = {yv0, yv1, yv2, yv3};
380 panel.zv = {zv0, zv1, zv2, zv3};
381 panel.colour = m_colour;
382 panel.volume = id;
383 panels.push_back(std::move(panel));
384 // Shift the points.
385 xv0 = xv3;
386 yv0 = yv3;
387 zv0 = zv3;
388 xv1 = xv2;
389 yv1 = yv2;
390 zv1 = zv2;
391 }
392 std::cout << "SolidHole::SolidPanels: " << panels.size() - nPanels
393 << " panels.\n";
394 return true;
395}
double m_dZ
Definition: Solid.hh:205
double m_dX
Direction vector.
Definition: Solid.hh:205
double m_sPhi
Definition: Solid.hh:207
double m_sTheta
Definition: Solid.hh:209
double m_dY
Definition: Solid.hh:205

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