Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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[])
 
 ~G4Polyhedra () override
 
EInside Inside (const G4ThreeVector &p) const override
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const override
 
G4double DistanceToIn (const G4ThreeVector &p) const override
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const override
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
 
void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep) override
 
G4GeometryType GetEntityType () const override
 
G4bool IsFaceted () const override
 
G4VSolidClone () const override
 
G4double GetCubicVolume () override
 
G4double GetSurfaceArea () override
 
G4ThreeVector GetPointOnSurface () const override
 
std::ostream & StreamInfo (std::ostream &os) const override
 
G4PolyhedronCreatePolyhedron () const override
 
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)
 
 ~G4VCSGfaceted () override
 
 G4VCSGfaceted (const G4VCSGfaceted &source)
 
G4VCSGfacetedoperator= (const G4VCSGfaceted &source)
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
 
EInside Inside (const G4ThreeVector &p) const override
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const override
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const override
 
G4double DistanceToIn (const G4ThreeVector &p) const override
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const override
 
G4double DistanceToOut (const G4ThreeVector &p) const override
 
G4GeometryType GetEntityType () const override
 
std::ostream & StreamInfo (std::ostream &os) const override
 
void DescribeYourselfTo (G4VGraphicsScene &scene) const override
 
G4VisExtent GetExtent () const override
 
G4PolyhedronGetPolyhedron () const override
 
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)
 
G4double GetCubicVolume () override
 
G4double GetSurfaceArea () override
 
 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 G4int GetNumOfConstituents () const
 
void DumpInfo () 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 //
101 original_parameters = new G4PolyhedraHistorical;
102
103 original_parameters->numSide = theNumSide;
104 original_parameters->Start_angle = phiStart;
105 original_parameters->Opening_angle = phiTotal;
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 //
140 auto rz = new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
141 rz->ScaleA( 1/convertRad );
142
143 //
144 // Do the real work
145 //
146 Create( phiStart, phiTotal, theNumSide, rz );
147
148 delete rz;
149}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4PolyhedraHistorical * original_parameters
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
G4VCSGfaceted(const G4String &name)
G4String GetName() const
void DumpInfo() const
#define DBL_EPSILON
Definition templates.hh:66

Referenced by Clone(), CopyStuff(), G4Polyhedra(), operator=(), and SetOriginalParameters().

◆ 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 153 of file G4Polyhedra.cc.

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

◆ ~G4Polyhedra()

G4Polyhedra::~G4Polyhedra ( )
override

Definition at line 364 of file G4Polyhedra.cc.

365{
366 delete [] corners;
367 delete original_parameters;
368 delete enclosingCylinder;
369 delete fElements;
370 delete fpPolyhedron;
371 corners = nullptr;
372 original_parameters = nullptr;
373 enclosingCylinder = nullptr;
374 fElements = nullptr;
375 fpPolyhedron = nullptr;
376}
G4PolyhedraSideRZ * corners
std::vector< surface_element > * fElements
G4EnclosingCylinder * enclosingCylinder
G4Polyhedron * fpPolyhedron

◆ G4Polyhedra() [3/4]

G4Polyhedra::G4Polyhedra ( __void__ & a)

Definition at line 357 of file G4Polyhedra.cc.

358 : G4VCSGfaceted(a), startPhi(0.), endPhi(0.)
359{
360}
G4double endPhi
G4double startPhi

◆ G4Polyhedra() [4/4]

G4Polyhedra::G4Polyhedra ( const G4Polyhedra & source)

Definition at line 380 of file G4Polyhedra.cc.

381 : G4VCSGfaceted( source )
382{
383 CopyStuff( source );
384}
void CopyStuff(const G4Polyhedra &source)

Member Function Documentation

◆ BoundingLimits()

void G4Polyhedra::BoundingLimits ( G4ThreeVector & pMin,
G4ThreeVector & pMax ) const
overridevirtual

Reimplemented from G4VSolid.

Definition at line 547 of file G4Polyhedra.cc.

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

Implements G4VSolid.

Definition at line 615 of file G4Polyhedra.cc.

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

◆ Clone()

G4VSolid * G4Polyhedra::Clone ( ) const
overridevirtual

Reimplemented from G4VSolid.

Definition at line 754 of file G4Polyhedra.cc.

755{
756 return new G4Polyhedra(*this);
757}
G4Polyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])

◆ ComputeDimensions()

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

Reimplemented from G4VSolid.

Definition at line 731 of file G4Polyhedra.cc.

734{
735 p->ComputeDimensions(*this,n,pRep);
736}
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const

◆ CopyStuff()

void G4Polyhedra::CopyStuff ( const G4Polyhedra & source)
protected

Definition at line 405 of file G4Polyhedra.cc.

406{
407 //
408 // Simple stuff
409 //
410 numSide = source.numSide;
411 startPhi = source.startPhi;
412 endPhi = source.endPhi;
413 phiIsOpen = source.phiIsOpen;
414 numCorner = source.numCorner;
415 genericPgon= source.genericPgon;
416
417 //
418 // The corner array
419 //
420 corners = new G4PolyhedraSideRZ[numCorner];
421
422 G4PolyhedraSideRZ* corn = corners,
423 * sourceCorn = source.corners;
424 do // Loop checking, 13.08.2015, G.Cosmo
425 {
426 *corn = *sourceCorn;
427 } while( ++sourceCorn, ++corn < corners+numCorner );
428
429 //
430 // Original parameters
431 //
432 if (source.original_parameters != nullptr)
433 {
435 new G4PolyhedraHistorical( *source.original_parameters );
436 }
437
438 //
439 // Enclosing cylinder
440 //
441 enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
442
443 //
444 // Surface elements
445 //
446 delete fElements;
447 fElements = nullptr;
448
449 //
450 // Polyhedron
451 //
452 fRebuildPolyhedron = false;
453 delete fpPolyhedron;
454 fpPolyhedron = nullptr;
455}
G4bool phiIsOpen
G4bool fRebuildPolyhedron

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

◆ Create()

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

Definition at line 187 of file G4Polyhedra.cc.

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

Referenced by G4Polyhedra(), G4Polyhedra(), and Reset().

◆ CreatePolyhedron()

G4Polyhedron * G4Polyhedra::CreatePolyhedron ( ) const
overridevirtual

Implements G4VCSGfaceted.

Definition at line 1036 of file G4Polyhedra.cc.

1037{
1038 std::vector<G4TwoVector> rz(numCorner);
1039 for (G4int i = 0; i < numCorner; ++i)
1040 rz[i].set(corners[i].r, corners[i].z);
1041 return new G4PolyhedronPgon(startPhi, endPhi - startPhi, numSide, rz);
1042}

◆ DeleteStuff()

void G4Polyhedra::DeleteStuff ( )
protected

◆ DistanceToIn() [1/2]

G4double G4Polyhedra::DistanceToIn ( const G4ThreeVector & p) const
overridevirtual

Implements G4VSolid.

Definition at line 540 of file G4Polyhedra.cc.

541{
543}
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override

◆ DistanceToIn() [2/2]

G4double G4Polyhedra::DistanceToIn ( const G4ThreeVector & p,
const G4ThreeVector & v ) const
overridevirtual

Implements G4VSolid.

Definition at line 523 of file G4Polyhedra.cc.

525{
526 //
527 // Quick test
528 //
529 if (enclosingCylinder->ShouldMiss(p,v))
530 return kInfinity;
531
532 //
533 // Long answer
534 //
535 return G4VCSGfaceted::DistanceToIn( p, v );
536}

◆ GetCorner()

◆ GetCosEndPhi()

G4double G4Polyhedra::GetCosEndPhi ( ) const
inline

◆ GetCosStartPhi()

G4double G4Polyhedra::GetCosStartPhi ( ) const
inline

Referenced by BoundingLimits(), and CalculateExtent().

◆ GetCubicVolume()

G4double G4Polyhedra::GetCubicVolume ( )
overridevirtual

Reimplemented from G4VSolid.

Definition at line 813 of file G4Polyhedra.cc.

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

◆ GetEndPhi()

◆ GetEntityType()

G4GeometryType G4Polyhedra::GetEntityType ( ) const
overridevirtual

Implements G4VSolid.

Definition at line 740 of file G4Polyhedra.cc.

741{
742 return {"G4Polyhedra"};
743}

◆ GetNumRZCorner()

◆ GetNumSide()

◆ GetOriginalParameters()

◆ GetPointOnSurface()

G4ThreeVector G4Polyhedra::GetPointOnSurface ( ) const
overridevirtual

Reimplemented from G4VSolid.

Definition at line 955 of file G4Polyhedra.cc.

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

◆ GetSinEndPhi()

G4double G4Polyhedra::GetSinEndPhi ( ) const
inline

◆ GetSinStartPhi()

G4double G4Polyhedra::GetSinStartPhi ( ) const
inline

Referenced by BoundingLimits(), and CalculateExtent().

◆ GetStartPhi()

◆ GetSurfaceArea()

G4double G4Polyhedra::GetSurfaceArea ( )
overridevirtual

Reimplemented from G4VSolid.

Definition at line 836 of file G4Polyhedra.cc.

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

◆ Inside()

EInside G4Polyhedra::Inside ( const G4ThreeVector & p) const
overridevirtual

Implements G4VSolid.

Definition at line 505 of file G4Polyhedra.cc.

506{
507 //
508 // Quick test
509 //
510 if (enclosingCylinder->MustBeOutside(p)) return kOutside;
511
512 //
513 // Long answer
514 //
515 return G4VCSGfaceted::Inside(p);
516}
EInside Inside(const G4ThreeVector &p) const override
@ kOutside
Definition geomdefs.hh:68

◆ IsFaceted()

G4bool G4Polyhedra::IsFaceted ( ) const
overridevirtual

Reimplemented from G4VSolid.

Definition at line 747 of file G4Polyhedra.cc.

748{
749 return true;
750}

◆ IsGeneric()

G4bool G4Polyhedra::IsGeneric ( ) const
inline

◆ IsOpen()

G4bool G4Polyhedra::IsOpen ( ) const
inline

◆ operator=()

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

Definition at line 388 of file G4Polyhedra.cc.

389{
390 if (this == &source) return *this;
391
392 G4VCSGfaceted::operator=( source );
393
394 delete [] corners;
395 delete original_parameters;
396 delete enclosingCylinder;
397
398 CopyStuff( source );
399
400 return *this;
401}
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)

◆ Reset()

G4bool G4Polyhedra::Reset ( )

Definition at line 462 of file G4Polyhedra.cc.

463{
464 if (genericPgon)
465 {
466 std::ostringstream message;
467 message << "Solid " << GetName() << " built using generic construct."
468 << G4endl << "Not applicable to the generic construct !";
469 G4Exception("G4Polyhedra::Reset()", "GeomSolids1001",
470 JustWarning, message, "Parameters NOT resetted.");
471 return true;
472 }
473
474 //
475 // Clear old setup
476 //
478 delete [] corners;
479 delete enclosingCylinder;
480 delete fElements;
481 corners = nullptr;
482 fElements = nullptr;
483 enclosingCylinder = nullptr;
484
485 //
486 // Rebuild polyhedra
487 //
488 auto rz = new G4ReduciblePolygon( original_parameters->Rmin,
490 original_parameters->Z_values,
491 original_parameters->Num_z_planes );
492 Create( original_parameters->Start_angle,
493 original_parameters->Opening_angle,
494 original_parameters->numSide, rz );
495 delete rz;
496
497 return false;
498}

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

◆ SetOriginalParameters() [1/2]

◆ SetOriginalParameters() [2/2]

void G4Polyhedra::SetOriginalParameters ( G4ReduciblePolygon * rz)
protected

Definition at line 1046 of file G4Polyhedra.cc.

1047{
1048 G4int numPlanes = numCorner;
1049 G4bool isConvertible = true;
1050 G4double Zmax=rz->Bmax();
1051 rz->StartWithZMin();
1052
1053 // Prepare vectors for storage
1054 //
1055 std::vector<G4double> Z;
1056 std::vector<G4double> Rmin;
1057 std::vector<G4double> Rmax;
1058
1059 G4int countPlanes=1;
1060 G4int icurr=0;
1061 G4int icurl=0;
1062
1063 // first plane Z=Z[0]
1064 //
1065 Z.push_back(corners[0].z);
1066 G4double Zprev=Z[0];
1067 if (Zprev == corners[1].z)
1068 {
1069 Rmin.push_back(corners[0].r);
1070 Rmax.push_back (corners[1].r);icurr=1;
1071 }
1072 else if (Zprev == corners[numPlanes-1].z)
1073 {
1074 Rmin.push_back(corners[numPlanes-1].r);
1075 Rmax.push_back (corners[0].r);
1076 icurl=numPlanes-1;
1077 }
1078 else
1079 {
1080 Rmin.push_back(corners[0].r);
1081 Rmax.push_back (corners[0].r);
1082 }
1083
1084 // next planes until last
1085 //
1086 G4int inextr=0, inextl=0;
1087 for (G4int i=0; i < numPlanes-2; ++i)
1088 {
1089 inextr=1+icurr;
1090 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1091
1092 if((corners[inextr].z >= Zmax) & (corners[inextl].z >= Zmax)) { break; }
1093
1094 G4double Zleft = corners[inextl].z;
1095 G4double Zright = corners[inextr].z;
1096 if(Zright>Zleft)
1097 {
1098 Z.push_back(Zleft);
1099 countPlanes++;
1100 G4double difZr=corners[inextr].z - corners[icurr].z;
1101 G4double difZl=corners[inextl].z - corners[icurl].z;
1102
1103 if(std::fabs(difZl) < kCarTolerance)
1104 {
1105 if(std::fabs(difZr) < kCarTolerance)
1106 {
1107 Rmin.push_back(corners[inextl].r);
1108 Rmax.push_back(corners[icurr].r);
1109 }
1110 else
1111 {
1112 Rmin.push_back(corners[inextl].r);
1113 Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
1114 *(corners[inextr].r - corners[icurr].r));
1115 }
1116 }
1117 else if (difZl >= kCarTolerance)
1118 {
1119 if(std::fabs(difZr) < kCarTolerance)
1120 {
1121 Rmin.push_back(corners[icurl].r);
1122 Rmax.push_back(corners[icurr].r);
1123 }
1124 else
1125 {
1126 Rmin.push_back(corners[icurl].r);
1127 Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
1128 *(corners[inextr].r - corners[icurr].r));
1129 }
1130 }
1131 else
1132 {
1133 isConvertible=false; break;
1134 }
1135 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1136 }
1137 else if(std::fabs(Zright-Zleft)<kCarTolerance) // Zright=Zleft
1138 {
1139 Z.push_back(Zleft);
1140 ++countPlanes;
1141 ++icurr;
1142
1143 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1144
1145 Rmin.push_back(corners[inextl].r);
1146 Rmax.push_back (corners[inextr].r);
1147 }
1148 else // Zright<Zleft
1149 {
1150 Z.push_back(Zright);
1151 ++countPlanes;
1152
1153 G4double difZr=corners[inextr].z - corners[icurr].z;
1154 G4double difZl=corners[inextl].z - corners[icurl].z;
1155 if(std::fabs(difZr) < kCarTolerance)
1156 {
1157 if(std::fabs(difZl) < kCarTolerance)
1158 {
1159 Rmax.push_back(corners[inextr].r);
1160 Rmin.push_back(corners[icurr].r);
1161 }
1162 else
1163 {
1164 Rmin.push_back(corners[icurl].r + (Zright-corners[icurl].z)/difZl
1165 * (corners[inextl].r - corners[icurl].r));
1166 Rmax.push_back(corners[inextr].r);
1167 }
1168 ++icurr;
1169 } // plate
1170 else if (difZr >= kCarTolerance)
1171 {
1172 if(std::fabs(difZl) < kCarTolerance)
1173 {
1174 Rmax.push_back(corners[inextr].r);
1175 Rmin.push_back (corners[icurr].r);
1176 }
1177 else
1178 {
1179 Rmax.push_back(corners[inextr].r);
1180 Rmin.push_back (corners[icurl].r+(Zright-corners[icurl].z)/difZl
1181 * (corners[inextl].r - corners[icurl].r));
1182 }
1183 ++icurr;
1184 }
1185 else
1186 {
1187 isConvertible=false; break;
1188 }
1189 }
1190 } // end for loop
1191
1192 // last plane Z=Zmax
1193 //
1194 Z.push_back(Zmax);
1195 ++countPlanes;
1196 inextr=1+icurr;
1197 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1198
1199 Rmax.push_back(corners[inextr].r);
1200 Rmin.push_back(corners[inextl].r);
1201
1202 // Set original parameters Rmin,Rmax,Z
1203 //
1204 if(isConvertible)
1205 {
1206 original_parameters = new G4PolyhedraHistorical;
1207 original_parameters->numSide = numSide;
1208 original_parameters->Z_values = new G4double[countPlanes];
1209 original_parameters->Rmin = new G4double[countPlanes];
1210 original_parameters->Rmax = new G4double[countPlanes];
1211
1212 for(G4int j=0; j < countPlanes; ++j)
1213 {
1214 original_parameters->Z_values[j] = Z[j];
1215 original_parameters->Rmax[j] = Rmax[j];
1216 original_parameters->Rmin[j] = Rmin[j];
1217 }
1218 original_parameters->Start_angle = startPhi;
1219 original_parameters->Opening_angle = endPhi-startPhi;
1220 original_parameters->Num_z_planes = countPlanes;
1221
1222 }
1223 else // Set parameters(r,z) with Rmin==0 as convention
1224 {
1225#ifdef G4SPECSDEBUG
1226 std::ostringstream message;
1227 message << "Polyhedra " << GetName() << G4endl
1228 << "cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1229 G4Exception("G4Polyhedra::SetOriginalParameters()",
1230 "GeomSolids0002", JustWarning, message);
1231#endif
1232 original_parameters = new G4PolyhedraHistorical;
1233 original_parameters->numSide = numSide;
1234 original_parameters->Z_values = new G4double[numPlanes];
1235 original_parameters->Rmin = new G4double[numPlanes];
1236 original_parameters->Rmax = new G4double[numPlanes];
1237
1238 for(G4int j=0; j < numPlanes; ++j)
1239 {
1240 original_parameters->Z_values[j] = corners[j].z;
1241 original_parameters->Rmax[j] = corners[j].r;
1242 original_parameters->Rmin[j] = 0.0;
1243 }
1244 original_parameters->Start_angle = startPhi;
1245 original_parameters->Opening_angle = endPhi-startPhi;
1246 original_parameters->Num_z_planes = numPlanes;
1247 }
1248}
G4double Bmax() const

◆ SetSurfaceElements()

void G4Polyhedra::SetSurfaceElements ( ) const
protected

Definition at line 877 of file G4Polyhedra.cc.

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

Referenced by GetPointOnSurface().

◆ StreamInfo()

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

Implements G4VSolid.

Definition at line 761 of file G4Polyhedra.cc.

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

Member Data Documentation

◆ corners

G4PolyhedraSideRZ* G4Polyhedra::corners = nullptr
protected

◆ enclosingCylinder

G4EnclosingCylinder* G4Polyhedra::enclosingCylinder = nullptr
protected

Definition at line 189 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 192 of file G4Polyhedra.hh.

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

◆ genericPgon

G4bool G4Polyhedra::genericPgon = false
protected

Definition at line 184 of file G4Polyhedra.hh.

Referenced by CopyStuff(), G4Polyhedra(), 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 183 of file G4Polyhedra.hh.

Referenced by CopyStuff(), and Create().

◆ startPhi

G4double G4Polyhedra::startPhi
protected

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