Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Polyhedra Class Reference

#include <G4Polyhedra.hh>

+ Inheritance diagram for G4Polyhedra:

Classes

struct  surface_element
 

Public Member Functions

 G4Polyhedra (const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
 
 G4Polyhedra (const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numRZ, const G4double r[], const G4double z[])
 
virtual ~G4Polyhedra ()
 
EInside Inside (const G4ThreeVector &p) const
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 
G4double DistanceToIn (const G4ThreeVector &p) const
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
 
void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
G4GeometryType GetEntityType () const
 
G4VSolidClone () const
 
G4double GetCubicVolume ()
 
G4double GetSurfaceArea ()
 
G4ThreeVector GetPointOnSurface () const
 
std::ostream & StreamInfo (std::ostream &os) const
 
G4PolyhedronCreatePolyhedron () const
 
G4bool Reset ()
 
G4int GetNumSide () const
 
G4double GetStartPhi () const
 
G4double GetEndPhi () const
 
G4double GetSinStartPhi () const
 
G4double GetCosStartPhi () const
 
G4double GetSinEndPhi () const
 
G4double GetCosEndPhi () const
 
G4bool IsOpen () const
 
G4bool IsGeneric () const
 
G4int GetNumRZCorner () const
 
G4PolyhedraSideRZ GetCorner (const G4int index) const
 
G4PolyhedraHistoricalGetOriginalParameters () const
 
void SetOriginalParameters (G4PolyhedraHistorical *pars)
 
 G4Polyhedra (__void__ &)
 
 G4Polyhedra (const G4Polyhedra &source)
 
G4Polyhedraoperator= (const G4Polyhedra &source)
 
- Public Member Functions inherited from G4VCSGfaceted
 G4VCSGfaceted (const G4String &name)
 
virtual ~G4VCSGfaceted ()
 
 G4VCSGfaceted (const G4VCSGfaceted &source)
 
G4VCSGfacetedoperator= (const G4VCSGfaceted &source)
 
virtual G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
 
virtual EInside Inside (const G4ThreeVector &p) const
 
virtual G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
 
virtual G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 
virtual G4double DistanceToIn (const G4ThreeVector &p) const
 
virtual G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const
 
virtual G4double DistanceToOut (const G4ThreeVector &p) const
 
virtual G4GeometryType GetEntityType () const
 
virtual std::ostream & StreamInfo (std::ostream &os) const
 
virtual G4PolyhedronCreatePolyhedron () const =0
 
virtual void DescribeYourselfTo (G4VGraphicsScene &scene) const
 
virtual G4VisExtent GetExtent () const
 
virtual G4PolyhedronGetPolyhedron () const
 
G4int GetCubVolStatistics () const
 
G4double GetCubVolEpsilon () const
 
void SetCubVolStatistics (G4int st)
 
void SetCubVolEpsilon (G4double ep)
 
G4int GetAreaStatistics () const
 
G4double GetAreaAccuracy () const
 
void SetAreaStatistics (G4int st)
 
void SetAreaAccuracy (G4double ep)
 
virtual G4double GetCubicVolume ()
 
virtual G4double GetSurfaceArea ()
 
 G4VCSGfaceted (__void__ &)
 
- Public Member Functions inherited from G4VSolid
 G4VSolid (const G4String &name)
 
virtual ~G4VSolid ()
 
G4bool operator== (const G4VSolid &s) const
 
G4String GetName () const
 
void SetName (const G4String &name)
 
G4double GetTolerance () const
 
virtual void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const
 
virtual G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
 
virtual EInside Inside (const G4ThreeVector &p) const =0
 
virtual G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p) const =0
 
virtual void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
virtual G4double GetCubicVolume ()
 
virtual G4double GetSurfaceArea ()
 
virtual G4GeometryType GetEntityType () const =0
 
virtual G4ThreeVector GetPointOnSurface () const
 
virtual G4VSolidClone () const
 
virtual std::ostream & StreamInfo (std::ostream &os) const =0
 
void DumpInfo () const
 
virtual void DescribeYourselfTo (G4VGraphicsScene &scene) const =0
 
virtual G4VisExtent GetExtent () const
 
virtual G4PolyhedronCreatePolyhedron () const
 
virtual G4PolyhedronGetPolyhedron () const
 
virtual const G4VSolidGetConstituentSolid (G4int no) const
 
virtual G4VSolidGetConstituentSolid (G4int no)
 
virtual const G4DisplacedSolidGetDisplacedSolidPtr () const
 
virtual G4DisplacedSolidGetDisplacedSolidPtr ()
 
 G4VSolid (__void__ &)
 
 G4VSolid (const G4VSolid &rhs)
 
G4VSolidoperator= (const G4VSolid &rhs)
 
G4double EstimateCubicVolume (G4int nStat, G4double epsilon) const
 
G4double EstimateSurfaceArea (G4int nStat, G4double ell) const
 

Protected Member Functions

void SetOriginalParameters (G4ReduciblePolygon *rz)
 
void Create (G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
 
void CopyStuff (const G4Polyhedra &source)
 
void DeleteStuff ()
 
void SetSurfaceElements () const
 
- Protected Member Functions inherited from G4VCSGfaceted
virtual G4double DistanceTo (const G4ThreeVector &p, const G4bool outgoing) const
 
G4ThreeVector GetPointOnSurfaceGeneric () const
 
void CopyStuff (const G4VCSGfaceted &source)
 
void DeleteStuff ()
 
- Protected Member Functions inherited from G4VSolid
void CalculateClippedPolygonExtent (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipCrossSection (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipBetweenSections (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipPolygon (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const
 

Protected Attributes

G4int numSide = 0
 
G4double startPhi
 
G4double endPhi
 
G4bool phiIsOpen = false
 
G4bool genericPgon = false
 
G4int numCorner = 0
 
G4PolyhedraSideRZcorners = nullptr
 
G4PolyhedraHistoricaloriginal_parameters = nullptr
 
G4EnclosingCylinderenclosingCylinder = nullptr
 
std::vector< surface_element > * fElements = nullptr
 
- Protected Attributes inherited from G4VCSGfaceted
G4int numFace = 0
 
G4VCSGface ** faces = nullptr
 
G4double fCubicVolume = 0.0
 
G4double fSurfaceArea = 0.0
 
G4bool fRebuildPolyhedron = false
 
G4PolyhedronfpPolyhedron = nullptr
 
- Protected Attributes inherited from G4VSolid
G4double kCarTolerance
 

Detailed Description

Definition at line 74 of file G4Polyhedra.hh.

Constructor & Destructor Documentation

◆ G4Polyhedra() [1/4]

G4Polyhedra::G4Polyhedra ( const G4String name,
G4double  phiStart,
G4double  phiTotal,
G4int  numSide,
G4int  numZPlanes,
const G4double  zPlane[],
const G4double  rInner[],
const G4double  rOuter[] 
)

Definition at line 71 of file G4Polyhedra.cc.

79 : G4VCSGfaceted( name )
80{
81 if (theNumSide <= 0)
82 {
83 std::ostringstream message;
84 message << "Solid must have at least one side - " << GetName() << G4endl
85 << " No sides specified !";
86 G4Exception("G4Polyhedra::G4Polyhedra()", "GeomSolids0002",
87 FatalErrorInArgument, message);
88 }
89
90 //
91 // Calculate conversion factor from G3 radius to G4 radius
92 //
93 G4double phiTotal = thePhiTotal;
94 if ( (phiTotal <=0) || (phiTotal >= twopi*(1-DBL_EPSILON)) )
95 { phiTotal = twopi; }
96 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
97
98 //
99 // Some historical stuff
100 //
102
103 original_parameters->numSide = theNumSide;
106 original_parameters->Num_z_planes = numZPlanes;
107 original_parameters->Z_values = new G4double[numZPlanes];
108 original_parameters->Rmin = new G4double[numZPlanes];
109 original_parameters->Rmax = new G4double[numZPlanes];
110
111 for (G4int i=0; i<numZPlanes; ++i)
112 {
113 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
114 {
115 if( (rInner[i] > rOuter[i+1])
116 ||(rInner[i+1] > rOuter[i]) )
117 {
118 DumpInfo();
119 std::ostringstream message;
120 message << "Cannot create a Polyhedra with no contiguous segments."
121 << G4endl
122 << " Segments are not contiguous !" << G4endl
123 << " rMin[" << i << "] = " << rInner[i]
124 << " -- rMax[" << i+1 << "] = " << rOuter[i+1] << G4endl
125 << " rMin[" << i+1 << "] = " << rInner[i+1]
126 << " -- rMax[" << i << "] = " << rOuter[i];
127 G4Exception("G4Polyhedra::G4Polyhedra()", "GeomSolids0002",
128 FatalErrorInArgument, message);
129 }
130 }
131 original_parameters->Z_values[i] = zPlane[i];
132 original_parameters->Rmin[i] = rInner[i]/convertRad;
133 original_parameters->Rmax[i] = rOuter[i]/convertRad;
134 }
135
136
137 //
138 // Build RZ polygon using special PCON/PGON GEANT3 constructor
139 //
141 new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
142 rz->ScaleA( 1/convertRad );
143
144 //
145 // Do the real work
146 //
147 Create( phiStart, phiTotal, theNumSide, rz );
148
149 delete rz;
150}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4PolyhedraHistorical * original_parameters
Definition: G4Polyhedra.hh:189
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
Definition: G4Polyhedra.cc:188
void ScaleA(G4double scale)
G4String GetName() const
void DumpInfo() const
#define DBL_EPSILON
Definition: templates.hh:66

◆ G4Polyhedra() [2/4]

G4Polyhedra::G4Polyhedra ( const G4String name,
G4double  phiStart,
G4double  phiTotal,
G4int  numSide,
G4int  numRZ,
const G4double  r[],
const G4double  z[] 
)

Definition at line 154 of file G4Polyhedra.cc.

161 : G4VCSGfaceted( name ), genericPgon(true)
162{
163 if (theNumSide <= 0)
164 {
165 std::ostringstream message;
166 message << "Solid must have at least one side - " << GetName() << G4endl
167 << " No sides specified !";
168 G4Exception("G4Polyhedra::G4Polyhedra()", "GeomSolids0002",
169 FatalErrorInArgument, message);
170 }
171
172 G4ReduciblePolygon* rz = new G4ReduciblePolygon( r, z, numRZ );
173
174 Create( phiStart, phiTotal, theNumSide, rz );
175
176 // Set original_parameters struct for consistency
177 //
179
180 delete rz;
181}
G4bool genericPgon
Definition: G4Polyhedra.hh:186
void SetOriginalParameters(G4PolyhedraHistorical *pars)

◆ ~G4Polyhedra()

G4Polyhedra::~G4Polyhedra ( )
virtual

Definition at line 371 of file G4Polyhedra.cc.

372{
373 delete [] corners;
374 delete original_parameters;
375 delete enclosingCylinder;
376 delete fElements;
377 delete fpPolyhedron;
378 corners = nullptr;
379 original_parameters = nullptr;
380 enclosingCylinder = nullptr;
381 fElements = nullptr;
382 fpPolyhedron = nullptr;
383}
G4PolyhedraSideRZ * corners
Definition: G4Polyhedra.hh:188
std::vector< surface_element > * fElements
Definition: G4Polyhedra.hh:194
G4EnclosingCylinder * enclosingCylinder
Definition: G4Polyhedra.hh:191
G4Polyhedron * fpPolyhedron

◆ G4Polyhedra() [3/4]

G4Polyhedra::G4Polyhedra ( __void__ &  a)

Definition at line 364 of file G4Polyhedra.cc.

365 : G4VCSGfaceted(a), startPhi(0.), endPhi(0.)
366{
367}
G4double endPhi
Definition: G4Polyhedra.hh:184
G4double startPhi
Definition: G4Polyhedra.hh:183

◆ G4Polyhedra() [4/4]

G4Polyhedra::G4Polyhedra ( const G4Polyhedra source)

Definition at line 387 of file G4Polyhedra.cc.

388 : G4VCSGfaceted( source )
389{
390 CopyStuff( source );
391}
void CopyStuff(const G4Polyhedra &source)
Definition: G4Polyhedra.cc:412

Member Function Documentation

◆ BoundingLimits()

void G4Polyhedra::BoundingLimits ( G4ThreeVector pMin,
G4ThreeVector pMax 
) const
virtual

Reimplemented from G4VSolid.

Definition at line 555 of file G4Polyhedra.cc.

557{
558 G4double rmin = kInfinity, rmax = -kInfinity;
559 G4double zmin = kInfinity, zmax = -kInfinity;
560 for (G4int i=0; i<GetNumRZCorner(); ++i)
561 {
562 G4PolyhedraSideRZ corner = GetCorner(i);
563 if (corner.r < rmin) rmin = corner.r;
564 if (corner.r > rmax) rmax = corner.r;
565 if (corner.z < zmin) zmin = corner.z;
566 if (corner.z > zmax) zmax = corner.z;
567 }
568
569 G4double sphi = GetStartPhi();
570 G4double ephi = GetEndPhi();
571 G4double dphi = IsOpen() ? ephi-sphi : twopi;
572 G4int ksteps = GetNumSide();
573 G4double astep = dphi/ksteps;
574 G4double sinStep = std::sin(astep);
575 G4double cosStep = std::cos(astep);
576
577 G4double sinCur = GetSinStartPhi();
578 G4double cosCur = GetCosStartPhi();
579 if (!IsOpen()) rmin = 0.;
580 G4double xmin = rmin*cosCur, xmax = xmin;
581 G4double ymin = rmin*sinCur, ymax = ymin;
582 for (G4int k=0; k<ksteps+1; ++k)
583 {
584 G4double x = rmax*cosCur;
585 if (x < xmin) xmin = x;
586 if (x > xmax) xmax = x;
587 G4double y = rmax*sinCur;
588 if (y < ymin) ymin = y;
589 if (y > ymax) ymax = y;
590 if (rmin > 0)
591 {
592 G4double xx = rmin*cosCur;
593 if (xx < xmin) xmin = xx;
594 if (xx > xmax) xmax = xx;
595 G4double yy = rmin*sinCur;
596 if (yy < ymin) ymin = yy;
597 if (yy > ymax) ymax = yy;
598 }
599 G4double sinTmp = sinCur;
600 sinCur = sinCur*cosStep + cosCur*sinStep;
601 cosCur = cosCur*cosStep - sinTmp*sinStep;
602 }
603 pMin.set(xmin,ymin,zmin);
604 pMax.set(xmax,ymax,zmax);
605
606 // Check correctness of the bounding box
607 //
608 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
609 {
610 std::ostringstream message;
611 message << "Bad bounding box (min >= max) for solid: "
612 << GetName() << " !"
613 << "\npMin = " << pMin
614 << "\npMax = " << pMax;
615 G4Exception("G4Polyhedra::BoundingLimits()", "GeomMgt0001",
616 JustWarning, message);
617 DumpInfo();
618 }
619}
@ JustWarning
double z() const
double x() const
double y() const
void set(double x, double y, double z)
G4int GetNumRZCorner() const
G4double GetSinStartPhi() const
G4bool IsOpen() const
G4double GetEndPhi() const
G4int GetNumSide() const
G4PolyhedraSideRZ GetCorner(const G4int index) const
G4double GetStartPhi() const
G4double GetCosStartPhi() const

Referenced by CalculateExtent().

◆ CalculateExtent()

G4bool G4Polyhedra::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pmin,
G4double pmax 
) const
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 623 of file G4Polyhedra.cc.

627{
628 G4ThreeVector bmin, bmax;
629 G4bool exist;
630
631 // Check bounding box (bbox)
632 //
633 BoundingLimits(bmin,bmax);
634 G4BoundingEnvelope bbox(bmin,bmax);
635#ifdef G4BBOX_EXTENT
636 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
637#endif
638 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
639 {
640 return exist = (pMin < pMax) ? true : false;
641 }
642
643 // To find the extent, RZ contour of the polycone is subdivided
644 // in triangles. The extent is calculated as cumulative extent of
645 // all sub-polycones formed by rotation of triangles around Z
646 //
647 G4TwoVectorList contourRZ;
648 G4TwoVectorList triangles;
649 std::vector<G4int> iout;
650 G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
651 G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
652
653 // get RZ contour, ensure anticlockwise order of corners
654 for (G4int i=0; i<GetNumRZCorner(); ++i)
655 {
656 G4PolyhedraSideRZ corner = GetCorner(i);
657 contourRZ.push_back(G4TwoVector(corner.r,corner.z));
658 }
660 G4double area = G4GeomTools::PolygonArea(contourRZ);
661 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
662
663 // triangulate RZ countour
664 if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
665 {
666 std::ostringstream message;
667 message << "Triangulation of RZ contour has failed for solid: "
668 << GetName() << " !"
669 << "\nExtent has been calculated using boundary box";
670 G4Exception("G4Polyhedra::CalculateExtent()",
671 "GeomMgt1002",JustWarning,message);
672 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
673 }
674
675 // set trigonometric values
676 G4double sphi = GetStartPhi();
677 G4double ephi = GetEndPhi();
678 G4double dphi = IsOpen() ? ephi-sphi : twopi;
679 G4int ksteps = GetNumSide();
680 G4double astep = dphi/ksteps;
681 G4double sinStep = std::sin(astep);
682 G4double cosStep = std::cos(astep);
683 G4double sinStart = GetSinStartPhi();
684 G4double cosStart = GetCosStartPhi();
685
686 // allocate vector lists
687 std::vector<const G4ThreeVectorList *> polygons;
688 polygons.resize(ksteps+1);
689 for (G4int k=0; k<ksteps+1; ++k)
690 {
691 polygons[k] = new G4ThreeVectorList(3);
692 }
693
694 // main loop along triangles
695 pMin = kInfinity;
696 pMax = -kInfinity;
697 G4int ntria = triangles.size()/3;
698 for (G4int i=0; i<ntria; ++i)
699 {
700 G4double sinCur = sinStart;
701 G4double cosCur = cosStart;
702 G4int i3 = i*3;
703 for (G4int k=0; k<ksteps+1; ++k) // rotate triangle
704 {
705 G4ThreeVectorList* ptr = const_cast<G4ThreeVectorList*>(polygons[k]);
706 G4ThreeVectorList::iterator iter = ptr->begin();
707 iter->set(triangles[i3+0].x()*cosCur,
708 triangles[i3+0].x()*sinCur,
709 triangles[i3+0].y());
710 iter++;
711 iter->set(triangles[i3+1].x()*cosCur,
712 triangles[i3+1].x()*sinCur,
713 triangles[i3+1].y());
714 iter++;
715 iter->set(triangles[i3+2].x()*cosCur,
716 triangles[i3+2].x()*sinCur,
717 triangles[i3+2].y());
718
719 G4double sinTmp = sinCur;
720 sinCur = sinCur*cosStep + cosCur*sinStep;
721 cosCur = cosCur*cosStep - sinTmp*sinStep;
722 }
723
724 // set sub-envelope and adjust extent
725 G4double emin,emax;
726 G4BoundingEnvelope benv(polygons);
727 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
728 if (emin < pMin) pMin = emin;
729 if (emax > pMax) pMax = emax;
730 if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
731 }
732 // free memory
733 for (G4int k=0; k<ksteps+1; ++k) { delete polygons[k]; polygons[k]=0;}
734 return (pMin < pMax);
735}
std::vector< G4ThreeVector > G4ThreeVectorList
std::vector< G4TwoVector > G4TwoVectorList
Definition: G4GeomTools.hh:42
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
bool G4bool
Definition: G4Types.hh:86
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
Definition: G4GeomTools.cc:193
static void RemoveRedundantVertices(G4TwoVectorList &polygon, std::vector< G4int > &iout, G4double tolerance=0.0)
Definition: G4GeomTools.cc:305
static G4double PolygonArea(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:76
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition: G4Polyhedra.cc:555
G4double kCarTolerance
Definition: G4VSolid.hh:302
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const

◆ Clone()

G4VSolid * G4Polyhedra::Clone ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 755 of file G4Polyhedra.cc.

756{
757 return new G4Polyhedra(*this);
758}

◆ ComputeDimensions()

void G4Polyhedra::ComputeDimensions ( G4VPVParameterisation p,
const G4int  n,
const G4VPhysicalVolume pRep 
)
virtual

Reimplemented from G4VSolid.

Definition at line 739 of file G4Polyhedra.cc.

742{
743 p->ComputeDimensions(*this,n,pRep);
744}
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const

◆ CopyStuff()

void G4Polyhedra::CopyStuff ( const G4Polyhedra source)
protected

Definition at line 412 of file G4Polyhedra.cc.

413{
414 //
415 // Simple stuff
416 //
417 numSide = source.numSide;
418 startPhi = source.startPhi;
419 endPhi = source.endPhi;
420 phiIsOpen = source.phiIsOpen;
421 numCorner = source.numCorner;
422 genericPgon= source.genericPgon;
423
424 //
425 // The corner array
426 //
428
430 * sourceCorn = source.corners;
431 do // Loop checking, 13.08.2015, G.Cosmo
432 {
433 *corn = *sourceCorn;
434 } while( ++sourceCorn, ++corn < corners+numCorner );
435
436 //
437 // Original parameters
438 //
439 if (source.original_parameters)
440 {
443 }
444
445 //
446 // Enclosing cylinder
447 //
449
450 //
451 // Surface elements
452 //
453 delete fElements;
454 fElements = nullptr;
455
456 //
457 // Polyhedron
458 //
459 fRebuildPolyhedron = false;
460 delete fpPolyhedron;
461 fpPolyhedron = nullptr;
462}
G4bool phiIsOpen
Definition: G4Polyhedra.hh:185
G4int numCorner
Definition: G4Polyhedra.hh:187
G4bool fRebuildPolyhedron

Referenced by G4Polyhedra(), and operator=().

◆ Create()

void G4Polyhedra::Create ( G4double  phiStart,
G4double  phiTotal,
G4int  numSide,
G4ReduciblePolygon rz 
)
protected

Definition at line 188 of file G4Polyhedra.cc.

192{
193 //
194 // Perform checks of rz values
195 //
196 if (rz->Amin() < 0.0)
197 {
198 std::ostringstream message;
199 message << "Illegal input parameters - " << GetName() << G4endl
200 << " All R values must be >= 0 !";
201 G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
202 FatalErrorInArgument, message);
203 }
204
205 G4double rzArea = rz->Area();
206 if (rzArea < -kCarTolerance)
207 {
208 rz->ReverseOrder();
209 }
210 else if (rzArea < kCarTolerance)
211 {
212 std::ostringstream message;
213 message << "Illegal input parameters - " << GetName() << G4endl
214 << " R/Z cross section is zero or near zero: " << rzArea;
215 G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
216 FatalErrorInArgument, message);
217 }
218
221 {
222 std::ostringstream message;
223 message << "Illegal input parameters - " << GetName() << G4endl
224 << " Too few unique R/Z values !";
225 G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
226 FatalErrorInArgument, message);
227 }
228
229 if (rz->CrossesItself( 1/kInfinity ))
230 {
231 std::ostringstream message;
232 message << "Illegal input parameters - " << GetName() << G4endl
233 << " R/Z segments cross !";
234 G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
235 FatalErrorInArgument, message);
236 }
237
238 numCorner = rz->NumVertices();
239
240
241 startPhi = phiStart;
242 while( startPhi < 0 ) // Loop checking, 13.08.2015, G.Cosmo
243 startPhi += twopi;
244 //
245 // Phi opening? Account for some possible roundoff, and interpret
246 // nonsense value as representing no phi opening
247 //
248 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-DBL_EPSILON)) )
249 {
250 phiIsOpen = false;
251 endPhi = phiStart+twopi;
252 }
253 else
254 {
255 phiIsOpen = true;
256
257 //
258 // Convert phi into our convention
259 //
260 endPhi = phiStart+phiTotal;
261 while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
262 endPhi += twopi;
263 }
264
265 //
266 // Save number sides
267 //
268 numSide = theNumSide;
269
270 //
271 // Allocate corner array.
272 //
274
275 //
276 // Copy corners
277 //
279
281 iterRZ.Begin();
282 do // Loop checking, 13.08.2015, G.Cosmo
283 {
284 next->r = iterRZ.GetA();
285 next->z = iterRZ.GetB();
286 } while( ++next, iterRZ.Next() );
287
288 //
289 // Allocate face pointer array
290 //
292 faces = new G4VCSGface*[numFace];
293
294 //
295 // Construct side faces
296 //
297 // To do so properly, we need to keep track of four successive RZ
298 // corners.
299 //
300 // But! Don't construct a face if both points are at zero radius!
301 //
302 G4PolyhedraSideRZ* corner = corners,
303 * prev = corners + numCorner-1,
304 * nextNext;
305 G4VCSGface** face = faces;
306 do // Loop checking, 13.08.2015, G.Cosmo
307 {
308 next = corner+1;
309 if (next >= corners+numCorner) next = corners;
310 nextNext = next+1;
311 if (nextNext >= corners+numCorner) nextNext = corners;
312
313 if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
314/*
315 // We must decide here if we can dare declare one of our faces
316 // as having a "valid" normal (i.e. allBehind = true). This
317 // is never possible if the face faces "inward" in r *unless*
318 // we have only one side
319 //
320 G4bool allBehind;
321 if ((corner->z > next->z) && (numSide > 1))
322 {
323 allBehind = false;
324 }
325 else
326 {
327 //
328 // Otherwise, it is only true if the line passing
329 // through the two points of the segment do not
330 // split the r/z cross section
331 //
332 allBehind = !rz->BisectedBy( corner->r, corner->z,
333 next->r, next->z, kCarTolerance );
334 }
335*/
336 *face++ = new G4PolyhedraSide( prev, corner, next, nextNext,
338 } while( prev=corner, corner=next, corner > corners );
339
340 if (phiIsOpen)
341 {
342 //
343 // Construct phi open edges
344 //
345 *face++ = new G4PolyPhiFace( rz, startPhi, phiTotal/numSide, endPhi );
346 *face++ = new G4PolyPhiFace( rz, endPhi, phiTotal/numSide, startPhi );
347 }
348
349 //
350 // We might have dropped a face or two: recalculate numFace
351 //
352 numFace = face-faces;
353
354 //
355 // Make enclosingCylinder
356 //
358 new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
359}
G4double Amin() const
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
G4VCSGface ** faces

Referenced by G4Polyhedra(), and Reset().

◆ CreatePolyhedron()

G4Polyhedron * G4Polyhedra::CreatePolyhedron ( ) const
virtual

Creates user defined polyhedron. This function allows to the user to define arbitrary polyhedron. The faces of the polyhedron should be either triangles or planar quadrilateral. Nodes of a face are defined by indexes pointing to the elements in the xyz array. Numeration of the elements in the array starts from 1 (like in fortran). The indexes can be positive or negative. Negative sign means that the corresponding edge is invisible. The normal of the face should be directed to exterior of the polyhedron.

Parameters
Nnodesnumber of nodes
Nfacesnumber of faces
xyznodes
faces_vecfaces (quadrilaterals or triangles)
Returns
status of the operation - is non-zero in case of problem

Implements G4VCSGfaceted.

Definition at line 1037 of file G4Polyhedra.cc.

1038{
1039 if (!genericPgon)
1040 {
1048 }
1049 else
1050 {
1051 // The following code prepares for:
1052 // HepPolyhedron::createPolyhedron(int Nnodes, int Nfaces,
1053 // const double xyz[][3],
1054 // const int faces_vec[][4])
1055 // Here is an extract from the header file HepPolyhedron.h:
1056 /**
1057 * Creates user defined polyhedron.
1058 * This function allows to the user to define arbitrary polyhedron.
1059 * The faces of the polyhedron should be either triangles or planar
1060 * quadrilateral. Nodes of a face are defined by indexes pointing to
1061 * the elements in the xyz array. Numeration of the elements in the
1062 * array starts from 1 (like in fortran). The indexes can be positive
1063 * or negative. Negative sign means that the corresponding edge is
1064 * invisible. The normal of the face should be directed to exterior
1065 * of the polyhedron.
1066 *
1067 * @param Nnodes number of nodes
1068 * @param Nfaces number of faces
1069 * @param xyz nodes
1070 * @param faces_vec faces (quadrilaterals or triangles)
1071 * @return status of the operation - is non-zero in case of problem
1072 */
1073 G4int nNodes;
1074 G4int nFaces;
1075 typedef G4double double3[3];
1076 double3* xyz;
1077 typedef G4int int4[4];
1078 int4* faces_vec;
1079 if (phiIsOpen)
1080 {
1081 // Triangulate open ends. Simple ear-chopping algorithm...
1082 // I'm not sure how robust this algorithm is (J.Allison).
1083 //
1084 std::vector<G4bool> chopped(numCorner, false);
1085 std::vector<G4int*> triQuads;
1086 G4int remaining = numCorner;
1087 G4int iStarter = 0;
1088 while (remaining >= 3) // Loop checking, 13.08.2015, G.Cosmo
1089 {
1090 // Find unchopped corners...
1091 //
1092 G4int A = -1, B = -1, C = -1;
1093 G4int iStepper = iStarter;
1094 do // Loop checking, 13.08.2015, G.Cosmo
1095 {
1096 if (A < 0) { A = iStepper; }
1097 else if (B < 0) { B = iStepper; }
1098 else if (C < 0) { C = iStepper; }
1099 do // Loop checking, 13.08.2015, G.Cosmo
1100 {
1101 if (++iStepper >= numCorner) iStepper = 0;
1102 }
1103 while (chopped[iStepper]);
1104 }
1105 while (C < 0 && iStepper != iStarter);
1106
1107 // Check triangle at B is pointing outward (an "ear").
1108 // Sign of z cross product determines...
1109
1110 G4double BAr = corners[A].r - corners[B].r;
1111 G4double BAz = corners[A].z - corners[B].z;
1112 G4double BCr = corners[C].r - corners[B].r;
1113 G4double BCz = corners[C].z - corners[B].z;
1114 if (BAr * BCz - BAz * BCr < kCarTolerance)
1115 {
1116 G4int* tq = new G4int[3];
1117 tq[0] = A + 1;
1118 tq[1] = B + 1;
1119 tq[2] = C + 1;
1120 triQuads.push_back(tq);
1121 chopped[B] = true;
1122 --remaining;
1123 }
1124 else
1125 {
1126 do // Loop checking, 13.08.2015, G.Cosmo
1127 {
1128 if (++iStarter >= numCorner) { iStarter = 0; }
1129 }
1130 while (chopped[iStarter]);
1131 }
1132 }
1133
1134 // Transfer to faces...
1135
1136 nNodes = (numSide + 1) * numCorner;
1137 nFaces = numSide * numCorner + 2 * triQuads.size();
1138 faces_vec = new int4[nFaces];
1139 G4int iface = 0;
1140 G4int addition = numCorner * numSide;
1141 G4int d = numCorner - 1;
1142 for (G4int iEnd = 0; iEnd < 2; ++iEnd)
1143 {
1144 for (size_t i = 0; i < triQuads.size(); ++i)
1145 {
1146 // Negative for soft/auxiliary/normally invisible edges...
1147 //
1148 G4int a, b, c;
1149 if (iEnd == 0)
1150 {
1151 a = triQuads[i][0];
1152 b = triQuads[i][1];
1153 c = triQuads[i][2];
1154 }
1155 else
1156 {
1157 a = triQuads[i][0] + addition;
1158 b = triQuads[i][2] + addition;
1159 c = triQuads[i][1] + addition;
1160 }
1161 G4int ab = std::abs(b - a);
1162 G4int bc = std::abs(c - b);
1163 G4int ca = std::abs(a - c);
1164 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
1165 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
1166 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
1167 faces_vec[iface][3] = 0;
1168 ++iface;
1169 }
1170 }
1171
1172 // Continue with sides...
1173
1174 xyz = new double3[nNodes];
1175 const G4double dPhi = (endPhi - startPhi) / numSide;
1176 G4double phi = startPhi;
1177 G4int ixyz = 0;
1178 for (G4int iSide = 0; iSide < numSide; ++iSide)
1179 {
1180 for (G4int iCorner = 0; iCorner < numCorner; ++iCorner)
1181 {
1182 xyz[ixyz][0] = corners[iCorner].r * std::cos(phi);
1183 xyz[ixyz][1] = corners[iCorner].r * std::sin(phi);
1184 xyz[ixyz][2] = corners[iCorner].z;
1185 if (iCorner < numCorner - 1)
1186 {
1187 faces_vec[iface][0] = ixyz + 1;
1188 faces_vec[iface][1] = ixyz + numCorner + 1;
1189 faces_vec[iface][2] = ixyz + numCorner + 2;
1190 faces_vec[iface][3] = ixyz + 2;
1191 }
1192 else
1193 {
1194 faces_vec[iface][0] = ixyz + 1;
1195 faces_vec[iface][1] = ixyz + numCorner + 1;
1196 faces_vec[iface][2] = ixyz + 2;
1197 faces_vec[iface][3] = ixyz - numCorner + 2;
1198 }
1199 ++iface;
1200 ++ixyz;
1201 }
1202 phi += dPhi;
1203 }
1204
1205 // Last corners...
1206
1207 for (G4int iCorner = 0; iCorner < numCorner; ++iCorner)
1208 {
1209 xyz[ixyz][0] = corners[iCorner].r * std::cos(phi);
1210 xyz[ixyz][1] = corners[iCorner].r * std::sin(phi);
1211 xyz[ixyz][2] = corners[iCorner].z;
1212 ++ixyz;
1213 }
1214 }
1215 else // !phiIsOpen - i.e., a complete 360 degrees.
1216 {
1217 nNodes = numSide * numCorner;
1218 nFaces = numSide * numCorner;;
1219 xyz = new double3[nNodes];
1220 faces_vec = new int4[nFaces];
1221 // const G4double dPhi = (endPhi - startPhi) / numSide;
1222 const G4double dPhi = twopi / numSide;
1223 // !phiIsOpen endPhi-startPhi = 360 degrees.
1224 G4double phi = startPhi;
1225 G4int ixyz = 0, iface = 0;
1226 for (G4int iSide = 0; iSide < numSide; ++iSide)
1227 {
1228 for (G4int iCorner = 0; iCorner < numCorner; ++iCorner)
1229 {
1230 xyz[ixyz][0] = corners[iCorner].r * std::cos(phi);
1231 xyz[ixyz][1] = corners[iCorner].r * std::sin(phi);
1232 xyz[ixyz][2] = corners[iCorner].z;
1233 if (iSide < numSide - 1)
1234 {
1235 if (iCorner < numCorner - 1)
1236 {
1237 faces_vec[iface][0] = ixyz + 1;
1238 faces_vec[iface][1] = ixyz + numCorner + 1;
1239 faces_vec[iface][2] = ixyz + numCorner + 2;
1240 faces_vec[iface][3] = ixyz + 2;
1241 }
1242 else
1243 {
1244 faces_vec[iface][0] = ixyz + 1;
1245 faces_vec[iface][1] = ixyz + numCorner + 1;
1246 faces_vec[iface][2] = ixyz + 2;
1247 faces_vec[iface][3] = ixyz - numCorner + 2;
1248 }
1249 }
1250 else // Last side joins ends...
1251 {
1252 if (iCorner < numCorner - 1)
1253 {
1254 faces_vec[iface][0] = ixyz + 1;
1255 faces_vec[iface][1] = ixyz + numCorner - nFaces + 1;
1256 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
1257 faces_vec[iface][3] = ixyz + 2;
1258 }
1259 else
1260 {
1261 faces_vec[iface][0] = ixyz + 1;
1262 faces_vec[iface][1] = ixyz - nFaces + numCorner + 1;
1263 faces_vec[iface][2] = ixyz - nFaces + 2;
1264 faces_vec[iface][3] = ixyz - numCorner + 2;
1265 }
1266 }
1267 ++ixyz;
1268 ++iface;
1269 }
1270 phi += dPhi;
1271 }
1272 }
1273 G4Polyhedron* polyhedron = new G4Polyhedron;
1274 G4int problem = polyhedron->createPolyhedron(nNodes,nFaces,xyz,faces_vec);
1275 delete [] faces_vec;
1276 delete [] xyz;
1277 if (problem)
1278 {
1279 std::ostringstream message;
1280 message << "Problem creating G4Polyhedron for: " << GetName();
1281 G4Exception("G4Polyhedra::CreatePolyhedron()", "GeomSolids1002",
1282 JustWarning, message);
1283 delete polyhedron;
1284 return nullptr;
1285 }
1286 else
1287 {
1288 return polyhedron;
1289 }
1290 }
1291}
double B(double temperature)
double C(double temp)
double A(double temperature)
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])

◆ DeleteStuff()

void G4Polyhedra::DeleteStuff ( )
protected

◆ DistanceToIn() [1/2]

G4double G4Polyhedra::DistanceToIn ( const G4ThreeVector p) const
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 548 of file G4Polyhedra.cc.

549{
551}
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const

◆ DistanceToIn() [2/2]

G4double G4Polyhedra::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 531 of file G4Polyhedra.cc.

533{
534 //
535 // Quick test
536 //
538 return kInfinity;
539
540 //
541 // Long answer
542 //
543 return G4VCSGfaceted::DistanceToIn( p, v );
544}
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const

◆ GetCorner()

◆ GetCosEndPhi()

G4double G4Polyhedra::GetCosEndPhi ( ) const
inline

◆ GetCosStartPhi()

G4double G4Polyhedra::GetCosStartPhi ( ) const
inline

Referenced by BoundingLimits(), and CalculateExtent().

◆ GetCubicVolume()

G4double G4Polyhedra::GetCubicVolume ( )
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 814 of file G4Polyhedra.cc.

815{
816 if (fCubicVolume == 0.)
817 {
818 G4double total = 0.;
819 G4int nrz = GetNumRZCorner();
820 G4PolyhedraSideRZ a = GetCorner(nrz - 1);
821 for (G4int i=0; i<nrz; ++i)
822 {
824 total += (b.r*b.r + b.r*a.r + a.r*a.r)*(b.z - a.z);
825 a = b;
826 }
827 fCubicVolume = std::abs(total)*
828 std::sin((GetEndPhi() - GetStartPhi())/GetNumSide())*GetNumSide()/6.;
829 }
830 return fCubicVolume;
831}
G4double fCubicVolume
G4double total(Particle const *const p1, Particle const *const p2)

◆ GetEndPhi()

◆ GetEntityType()

G4GeometryType G4Polyhedra::GetEntityType ( ) const
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 748 of file G4Polyhedra.cc.

749{
750 return G4String("G4Polyhedra");
751}

◆ GetNumRZCorner()

◆ GetNumSide()

◆ GetOriginalParameters()

◆ GetPointOnSurface()

G4ThreeVector G4Polyhedra::GetPointOnSurface ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 956 of file G4Polyhedra.cc.

957{
958 // Set surface elements
959 if (!fElements)
960 {
961 G4AutoLock l(&surface_elementsMutex);
963 l.unlock();
964 }
965
966 // Select surface element
968 selem = fElements->back();
969 G4double select = selem.area*G4QuickRand();
970 auto it = std::lower_bound(fElements->begin(), fElements->end(), select,
971 [](const G4Polyhedra::surface_element& x, G4double val)
972 -> G4bool { return x.area < val; });
973
974 // Generate random point
975 G4double x = 0, y = 0, z = 0;
976 G4double u = G4QuickRand();
977 G4double v = G4QuickRand();
978 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
979 G4int i0 = (*it).i0;
980 G4int i1 = (*it).i1;
981 G4int i2 = (*it).i2;
982 if (i2 < 0) // lateral surface
983 {
984 // sample point
985 G4int nside = GetNumSide();
986 G4double dphi = (GetEndPhi() - GetStartPhi())/nside;
987 G4double cosa = std::cos(dphi);
988 G4double sina = std::sin(dphi);
991 G4ThreeVector p0(a.r, 0, a.z);
992 G4ThreeVector p1(b.r, 0, b.z);
993 G4ThreeVector p2(b.r*cosa, b.r*sina, b.z);
994 if (i2 == -1) p1.set(a.r*cosa, a.r*sina, a.z);
995 p0 += (p1 - p0)*u + (p2 - p0)*v;
996 // find selected side and rotate point
997 G4double scurr = (*it).area;
998 G4double sprev = (it == fElements->begin()) ? 0. : (*(--it)).area;
999 G4int iside = nside*(select - sprev)/(scurr - sprev);
1000 if (iside == 0 && GetStartPhi() == 0.)
1001 {
1002 x = p0.x();
1003 y = p0.y();
1004 z = p0.z();
1005 }
1006 else
1007 {
1008 if (iside == nside) --iside; // iside must be less then nside
1009 G4double phi = iside*dphi + GetStartPhi();
1010 G4double cosphi = std::cos(phi);
1011 G4double sinphi = std::sin(phi);
1012 x = p0.x()*cosphi - p0.y()*sinphi;
1013 y = p0.x()*sinphi + p0.y()*cosphi;
1014 z = p0.z();
1015 }
1016 }
1017 else // phi cut
1018 {
1019 G4int nrz = GetNumRZCorner();
1020 G4double phi = (i0 < nrz) ? GetStartPhi() : GetEndPhi();
1021 if (i0 >= nrz) { i0 -= nrz; }
1025 G4double r = (p1.r - p0.r)*u + (p2.r - p0.r)*v + p0.r;
1026 x = r*std::cos(phi);
1027 y = r*std::sin(phi);
1028 z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p0.z;
1029 }
1030 return G4ThreeVector(x, y, z);
1031}
G4double G4QuickRand()
Definition: G4QuickRand.hh:34
CLHEP::Hep3Vector G4ThreeVector
void SetSurfaceElements() const
Definition: G4Polyhedra.cc:878

◆ GetSinEndPhi()

G4double G4Polyhedra::GetSinEndPhi ( ) const
inline

◆ GetSinStartPhi()

G4double G4Polyhedra::GetSinStartPhi ( ) const
inline

Referenced by BoundingLimits(), and CalculateExtent().

◆ GetStartPhi()

◆ GetSurfaceArea()

G4double G4Polyhedra::GetSurfaceArea ( )
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 837 of file G4Polyhedra.cc.

838{
839 if (fSurfaceArea == 0.)
840 {
841 G4double total = 0.;
842 G4int nrz = GetNumRZCorner();
843 if (IsOpen())
844 {
845 G4PolyhedraSideRZ a = GetCorner(nrz - 1);
846 for (G4int i=0; i<nrz; ++i)
847 {
849 total += a.r*b.z - a.z*b.r;
850 a = b;
851 }
852 total = std::abs(total);
853 }
855 G4double cosa = std::cos(alp);
856 G4double sina = std::sin(alp);
857 G4PolyhedraSideRZ a = GetCorner(nrz - 1);
858 for (G4int i=0; i<nrz; ++i)
859 {
861 G4ThreeVector p1(a.r, 0, a.z);
862 G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);
863 G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);
864 G4ThreeVector p4(b.r, 0, b.z);
865 total += GetNumSide()*(G4GeomTools::QuadAreaNormal(p1, p2, p3, p4)).mag();
866 a = b;
867 }
869 }
870 return fSurfaceArea;
871}
static G4ThreeVector QuadAreaNormal(const G4ThreeVector &A, const G4ThreeVector &B, const G4ThreeVector &C, const G4ThreeVector &D)
Definition: G4GeomTools.cc:609
G4double fSurfaceArea

◆ Inside()

EInside G4Polyhedra::Inside ( const G4ThreeVector p) const
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 513 of file G4Polyhedra.cc.

514{
515 //
516 // Quick test
517 //
519
520 //
521 // Long answer
522 //
523 return G4VCSGfaceted::Inside(p);
524}
G4bool MustBeOutside(const G4ThreeVector &p) const
virtual EInside Inside(const G4ThreeVector &p) const
@ kOutside
Definition: geomdefs.hh:68

◆ IsGeneric()

◆ IsOpen()

G4bool G4Polyhedra::IsOpen ( ) const
inline

◆ operator=()

G4Polyhedra & G4Polyhedra::operator= ( const G4Polyhedra source)

Definition at line 395 of file G4Polyhedra.cc.

396{
397 if (this == &source) return *this;
398
399 G4VCSGfaceted::operator=( source );
400
401 delete [] corners;
402 delete original_parameters;
403 delete enclosingCylinder;
404
405 CopyStuff( source );
406
407 return *this;
408}
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)

◆ Reset()

G4bool G4Polyhedra::Reset ( )

Definition at line 469 of file G4Polyhedra.cc.

470{
471 if (genericPgon)
472 {
473 std::ostringstream message;
474 message << "Solid " << GetName() << " built using generic construct."
475 << G4endl << "Not applicable to the generic construct !";
476 G4Exception("G4Polyhedra::Reset()", "GeomSolids1001",
477 JustWarning, message, "Parameters NOT resetted.");
478 return true;
479 }
480
481 //
482 // Clear old setup
483 //
485 delete [] corners;
486 delete enclosingCylinder;
487 delete fElements;
488 corners = nullptr;
489 fElements = nullptr;
490 enclosingCylinder = nullptr;
491
492 //
493 // Rebuild polyhedra
494 //
503 delete rz;
504
505 return false;
506}

Referenced by G4ParameterisationPolyhedraRho::ComputeDimensions(), G4ParameterisationPolyhedraPhi::ComputeDimensions(), and G4ParameterisationPolyhedraZ::ComputeDimensions().

◆ SetOriginalParameters() [1/2]

◆ SetOriginalParameters() [2/2]

void G4Polyhedra::SetOriginalParameters ( G4ReduciblePolygon rz)
protected

Definition at line 1295 of file G4Polyhedra.cc.

1296{
1297 G4int numPlanes = numCorner;
1298 G4bool isConvertible = true;
1299 G4double Zmax=rz->Bmax();
1300 rz->StartWithZMin();
1301
1302 // Prepare vectors for storage
1303 //
1304 std::vector<G4double> Z;
1305 std::vector<G4double> Rmin;
1306 std::vector<G4double> Rmax;
1307
1308 G4int countPlanes=1;
1309 G4int icurr=0;
1310 G4int icurl=0;
1311
1312 // first plane Z=Z[0]
1313 //
1314 Z.push_back(corners[0].z);
1315 G4double Zprev=Z[0];
1316 if (Zprev == corners[1].z)
1317 {
1318 Rmin.push_back(corners[0].r);
1319 Rmax.push_back (corners[1].r);icurr=1;
1320 }
1321 else if (Zprev == corners[numPlanes-1].z)
1322 {
1323 Rmin.push_back(corners[numPlanes-1].r);
1324 Rmax.push_back (corners[0].r);
1325 icurl=numPlanes-1;
1326 }
1327 else
1328 {
1329 Rmin.push_back(corners[0].r);
1330 Rmax.push_back (corners[0].r);
1331 }
1332
1333 // next planes until last
1334 //
1335 G4int inextr=0, inextl=0;
1336 for (G4int i=0; i < numPlanes-2; ++i)
1337 {
1338 inextr=1+icurr;
1339 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1340
1341 if((corners[inextr].z >= Zmax) & (corners[inextl].z >= Zmax)) { break; }
1342
1343 G4double Zleft = corners[inextl].z;
1344 G4double Zright = corners[inextr].z;
1345 if(Zright>Zleft)
1346 {
1347 Z.push_back(Zleft);
1348 countPlanes++;
1349 G4double difZr=corners[inextr].z - corners[icurr].z;
1350 G4double difZl=corners[inextl].z - corners[icurl].z;
1351
1352 if(std::fabs(difZl) < kCarTolerance)
1353 {
1354 if(std::fabs(difZr) < kCarTolerance)
1355 {
1356 Rmin.push_back(corners[inextl].r);
1357 Rmax.push_back(corners[icurr].r);
1358 }
1359 else
1360 {
1361 Rmin.push_back(corners[inextl].r);
1362 Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
1363 *(corners[inextr].r - corners[icurr].r));
1364 }
1365 }
1366 else if (difZl >= kCarTolerance)
1367 {
1368 if(std::fabs(difZr) < kCarTolerance)
1369 {
1370 Rmin.push_back(corners[icurl].r);
1371 Rmax.push_back(corners[icurr].r);
1372 }
1373 else
1374 {
1375 Rmin.push_back(corners[icurl].r);
1376 Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
1377 *(corners[inextr].r - corners[icurr].r));
1378 }
1379 }
1380 else
1381 {
1382 isConvertible=false; break;
1383 }
1384 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1385 }
1386 else if(std::fabs(Zright-Zleft)<kCarTolerance) // Zright=Zleft
1387 {
1388 Z.push_back(Zleft);
1389 ++countPlanes;
1390 ++icurr;
1391
1392 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1393
1394 Rmin.push_back(corners[inextl].r);
1395 Rmax.push_back (corners[inextr].r);
1396 }
1397 else // Zright<Zleft
1398 {
1399 Z.push_back(Zright);
1400 ++countPlanes;
1401
1402 G4double difZr=corners[inextr].z - corners[icurr].z;
1403 G4double difZl=corners[inextl].z - corners[icurl].z;
1404 if(std::fabs(difZr) < kCarTolerance)
1405 {
1406 if(std::fabs(difZl) < kCarTolerance)
1407 {
1408 Rmax.push_back(corners[inextr].r);
1409 Rmin.push_back(corners[icurr].r);
1410 }
1411 else
1412 {
1413 Rmin.push_back(corners[icurl].r + (Zright-corners[icurl].z)/difZl
1414 * (corners[inextl].r - corners[icurl].r));
1415 Rmax.push_back(corners[inextr].r);
1416 }
1417 ++icurr;
1418 } // plate
1419 else if (difZr >= kCarTolerance)
1420 {
1421 if(std::fabs(difZl) < kCarTolerance)
1422 {
1423 Rmax.push_back(corners[inextr].r);
1424 Rmin.push_back (corners[icurr].r);
1425 }
1426 else
1427 {
1428 Rmax.push_back(corners[inextr].r);
1429 Rmin.push_back (corners[icurl].r+(Zright-corners[icurl].z)/difZl
1430 * (corners[inextl].r - corners[icurl].r));
1431 }
1432 ++icurr;
1433 }
1434 else
1435 {
1436 isConvertible=false; break;
1437 }
1438 }
1439 } // end for loop
1440
1441 // last plane Z=Zmax
1442 //
1443 Z.push_back(Zmax);
1444 ++countPlanes;
1445 inextr=1+icurr;
1446 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1447
1448 Rmax.push_back(corners[inextr].r);
1449 Rmin.push_back(corners[inextl].r);
1450
1451 // Set original parameters Rmin,Rmax,Z
1452 //
1453 if(isConvertible)
1454 {
1457 original_parameters->Z_values = new G4double[countPlanes];
1458 original_parameters->Rmin = new G4double[countPlanes];
1459 original_parameters->Rmax = new G4double[countPlanes];
1460
1461 for(G4int j=0; j < countPlanes; ++j)
1462 {
1463 original_parameters->Z_values[j] = Z[j];
1464 original_parameters->Rmax[j] = Rmax[j];
1465 original_parameters->Rmin[j] = Rmin[j];
1466 }
1469 original_parameters->Num_z_planes = countPlanes;
1470
1471 }
1472 else // Set parameters(r,z) with Rmin==0 as convention
1473 {
1474#ifdef G4SPECSDEBUG
1475 std::ostringstream message;
1476 message << "Polyhedra " << GetName() << G4endl
1477 << "cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1478 G4Exception("G4Polyhedra::SetOriginalParameters()",
1479 "GeomSolids0002", JustWarning, message);
1480#endif
1483 original_parameters->Z_values = new G4double[numPlanes];
1484 original_parameters->Rmin = new G4double[numPlanes];
1485 original_parameters->Rmax = new G4double[numPlanes];
1486
1487 for(G4int j=0; j < numPlanes; ++j)
1488 {
1491 original_parameters->Rmin[j] = 0.0;
1492 }
1495 original_parameters->Num_z_planes = numPlanes;
1496 }
1497}
G4double Bmax() const

◆ SetSurfaceElements()

void G4Polyhedra::SetSurfaceElements ( ) const
protected

Definition at line 878 of file G4Polyhedra.cc.

879{
880 fElements = new std::vector<G4Polyhedra::surface_element>;
881 G4double total = 0.;
882 G4int nrz = GetNumRZCorner();
883
884 // set lateral surface elements
885 G4double dphi = (GetEndPhi() - GetStartPhi())/GetNumSide();
886 G4double cosa = std::cos(dphi);
887 G4double sina = std::sin(dphi);
888 G4int ia = nrz - 1;
889 for (G4int ib=0; ib<nrz; ++ib)
890 {
894 selem.i0 = ia;
895 selem.i1 = ib;
896 ia = ib;
897 if (a.r == 0. && b.r == 0.) continue;
898 G4ThreeVector p1(a.r, 0, a.z);
899 G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);
900 G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);
901 G4ThreeVector p4(b.r, 0, b.z);
902 if (a.r > 0.)
903 {
904 selem.i2 = -1;
905 total += GetNumSide()*(G4GeomTools::TriangleAreaNormal(p1, p2, p3)).mag();
906 selem.area = total;
907 fElements->push_back(selem);
908 }
909 if (b.r > 0.)
910 {
911 selem.i2 = -2;
912 total += GetNumSide()*(G4GeomTools::TriangleAreaNormal(p1, p3, p4)).mag();
913 selem.area = total;
914 fElements->push_back(selem);
915 }
916 }
917
918 // set elements for phi cuts
919 if (IsOpen())
920 {
921 G4TwoVectorList contourRZ;
922 std::vector<G4int> triangles;
923 for (G4int i=0; i<nrz; ++i)
924 {
925 G4PolyhedraSideRZ corner = GetCorner(i);
926 contourRZ.push_back(G4TwoVector(corner.r, corner.z));
927 }
928 G4GeomTools::TriangulatePolygon(contourRZ, triangles);
929 G4int ntria = triangles.size();
930 for (G4int i=0; i<ntria; i+=3)
931 {
933 selem.i0 = triangles[i];
934 selem.i1 = triangles[i+1];
935 selem.i2 = triangles[i+2];
936 G4PolyhedraSideRZ a = GetCorner(selem.i0);
937 G4PolyhedraSideRZ b = GetCorner(selem.i1);
938 G4PolyhedraSideRZ c = GetCorner(selem.i2);
939 G4double stria =
940 std::abs(G4GeomTools::TriangleArea(a.r, a.z, b.r, b.z, c.r, c.z));
941 total += stria;
942 selem.area = total;
943 fElements->push_back(selem); // start phi
944 total += stria;
945 selem.area = total;
946 selem.i0 += nrz;
947 fElements->push_back(selem); // end phi
948 }
949 }
950}
static G4double TriangleArea(G4double Ax, G4double Ay, G4double Bx, G4double By, G4double Cx, G4double Cy)
Definition: G4GeomTools.cc:41
static G4ThreeVector TriangleAreaNormal(const G4ThreeVector &A, const G4ThreeVector &B, const G4ThreeVector &C)
Definition: G4GeomTools.cc:598

Referenced by GetPointOnSurface().

◆ StreamInfo()

std::ostream & G4Polyhedra::StreamInfo ( std::ostream &  os) const
virtual

Reimplemented from G4VCSGfaceted.

Definition at line 762 of file G4Polyhedra.cc.

763{
764 G4int oldprc = os.precision(16);
765 os << "-----------------------------------------------------------\n"
766 << " *** Dump for solid - " << GetName() << " ***\n"
767 << " ===================================================\n"
768 << " Solid type: G4Polyhedra\n"
769 << " Parameters: \n"
770 << " starting phi angle : " << startPhi/degree << " degrees \n"
771 << " ending phi angle : " << endPhi/degree << " degrees \n"
772 << " number of sides : " << numSide << " \n";
773 G4int i=0;
774 if (!genericPgon)
775 {
777 os << " number of Z planes: " << numPlanes << "\n"
778 << " Z values: \n";
779 for (i=0; i<numPlanes; ++i)
780 {
781 os << " Z plane " << i << ": "
782 << original_parameters->Z_values[i] << "\n";
783 }
784 os << " Tangent distances to inner surface (Rmin): \n";
785 for (i=0; i<numPlanes; ++i)
786 {
787 os << " Z plane " << i << ": "
788 << original_parameters->Rmin[i] << "\n";
789 }
790 os << " Tangent distances to outer surface (Rmax): \n";
791 for (i=0; i<numPlanes; ++i)
792 {
793 os << " Z plane " << i << ": "
794 << original_parameters->Rmax[i] << "\n";
795 }
796 }
797 os << " number of RZ points: " << numCorner << "\n"
798 << " RZ values (corners): \n";
799 for (i=0; i<numCorner; ++i)
800 {
801 os << " "
802 << corners[i].r << ", " << corners[i].z << "\n";
803 }
804 os << "-----------------------------------------------------------\n";
805 os.precision(oldprc);
806
807 return os;
808}

Member Data Documentation

◆ corners

G4PolyhedraSideRZ* G4Polyhedra::corners = nullptr
protected

◆ enclosingCylinder

G4EnclosingCylinder* G4Polyhedra::enclosingCylinder = nullptr
protected

Definition at line 191 of file G4Polyhedra.hh.

Referenced by CopyStuff(), Create(), DistanceToIn(), Inside(), operator=(), Reset(), and ~G4Polyhedra().

◆ endPhi

G4double G4Polyhedra::endPhi
protected

◆ fElements

std::vector<surface_element>* G4Polyhedra::fElements = nullptr
mutableprotected

Definition at line 194 of file G4Polyhedra.hh.

Referenced by CopyStuff(), GetPointOnSurface(), Reset(), SetSurfaceElements(), and ~G4Polyhedra().

◆ genericPgon

G4bool G4Polyhedra::genericPgon = false
protected

Definition at line 186 of file G4Polyhedra.hh.

Referenced by CopyStuff(), CreatePolyhedron(), Reset(), and StreamInfo().

◆ numCorner

G4int G4Polyhedra::numCorner = 0
protected

◆ numSide

G4int G4Polyhedra::numSide = 0
protected

◆ original_parameters

G4PolyhedraHistorical* G4Polyhedra::original_parameters = nullptr
protected

◆ phiIsOpen

G4bool G4Polyhedra::phiIsOpen = false
protected

Definition at line 185 of file G4Polyhedra.hh.

Referenced by CopyStuff(), Create(), and CreatePolyhedron().

◆ startPhi

G4double G4Polyhedra::startPhi
protected

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