Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-15 08:21:12

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4PolyhedraSide
0027 //
0028 // Class description:
0029 //
0030 // Class implementing a face that represents one segmented side of a polyhedra:
0031 //
0032 //   G4PolyhedraSide( const G4PolyhedraSideRZ* prevRZ,
0033 //                    const G4PolyhedraSideRZ* tail,
0034 //                    const G4PolyhedraSideRZ* head,
0035 //                    const G4PolyhedraSideRZ* nextRZ,
0036 //                          G4int numSide,
0037 //                          G4double phiStart, G4double phiTotal, 
0038 //                          G4bool phiIsOpen, G4bool isAllBehind=false )
0039 //
0040 // Values for r1,z1 and r2,z2 should be specified in clockwise order in (r,z).
0041 
0042 // Author: David C. Williams (UCSC), 1998 - Created
0043 // --------------------------------------------------------------------
0044 #ifndef G4POLYHEDRASIDE_HH
0045 #define G4POLYHEDRASIDE_HH
0046 
0047 #include "G4VCSGface.hh"
0048 
0049 class G4IntersectingCone;
0050 
0051 struct G4PolyhedraSideRZ
0052 {
0053   G4double r, z;  // start of vector
0054 };
0055 
0056 // ----------------------------------------------------------------------------
0057 // MT-specific utility code 
0058 
0059 #include "G4GeomSplitter.hh"
0060 
0061 // The class G4PhSideData is introduced to encapsulate the
0062 // fields of the class G4PolyhedraSide that may not be read-only.
0063 //
0064 class G4PhSideData
0065 {
0066   public:
0067 
0068     void initialize()
0069     {
0070       fPhix = 0.; fPhiy = 0.; fPhiz = 0.; fPhik = 0.;
0071     }
0072 
0073     G4double fPhix=0., fPhiy=0., fPhiz=0., fPhik=0.;   // Cached values for phi
0074 };
0075 
0076 // The type G4PhSideManager is introduced to encapsulate the methods used
0077 // by both the master thread and worker threads to allocate memory space
0078 // for the fields encapsulated by the class G4PhSideData.
0079 //
0080 using G4PhSideManager = G4GeomSplitter<G4PhSideData>;
0081 
0082 //
0083 // ----------------------------------------------------------------------------
0084 
0085 /**
0086  * @brief G4PolyhedraSide is a utility class implementing a face that
0087  * represents one segmented side of a polyhedra.
0088  */
0089 
0090 class G4PolyhedraSide : public G4VCSGface
0091 {
0092 
0093   public:
0094 
0095     /**
0096      * Constructor for the segmented side of a polyhedra.
0097      *  @param[in] prevRZ Pointer to previous r,Z section.
0098      *  @param[in] tail Pointer to r,Z tail of section.
0099      *  @param[in] head Pointer to r,Z head of section.
0100      *  @param[in] nextRZ Pointer to next r,Z section.
0101      *  @param[in] numSide The number od sides.
0102      *  @param[in] phiStart Initial Phi starting angle.
0103      *  @param[in] phiTotal Total Phi angle.
0104      *  @param[in] phiIsOpen Flag indicating if it is a Phi section.
0105      *  @param[in] isAllBehind Indicating if entire surface is behind normal.
0106      */
0107     G4PolyhedraSide( const G4PolyhedraSideRZ* prevRZ,
0108                      const G4PolyhedraSideRZ* tail,
0109                      const G4PolyhedraSideRZ* head,
0110                      const G4PolyhedraSideRZ* nextRZ,
0111                            G4int numSide,
0112                            G4double phiStart, G4double phiTotal, 
0113                            G4bool phiIsOpen, G4bool isAllBehind = false );
0114 
0115     /**
0116      * Destructor.
0117      */
0118     ~G4PolyhedraSide() override;
0119   
0120     /**
0121      * Copy constructor and assignment operator.
0122      */
0123     G4PolyhedraSide( const G4PolyhedraSide& source );
0124     G4PolyhedraSide& operator=( const G4PolyhedraSide& source );
0125   
0126     /**
0127      * Determines the distance along a line to the face.
0128      *  @param[in] p Position.
0129      *  @param[in] v Direction (assumed to be a unit vector).
0130      *  @param[in] outgoing Flag true, to consider only inside surfaces;
0131      *             false, to consider only outside surfaces.
0132      *  @param[in] surfTolerance Minimum distance from the surface.
0133      *  @param[out] distance Distance to intersection.
0134      *  @param[out] distFromSurface Distance from surface (along surface normal),
0135      *              < 0 if the point is in front of the surface.
0136      *  @param[out] normal Normal of surface at intersection point.
0137      *  @param[out] allBehind Flag, true, if entire surface is behind normal.
0138      *  @returns true if there is an intersection, false otherwise.
0139      */
0140     G4bool Intersect( const G4ThreeVector& p, const G4ThreeVector& v,  
0141                             G4bool outgoing, G4double surfTolerance,
0142                             G4double& distance, G4double& distFromSurface,
0143                             G4ThreeVector& normal, G4bool& allBehind ) override;
0144 
0145     /**
0146      * Determines the distance of a point from either the inside or outside
0147      * surfaces of the face.
0148      *  @param[in] p Position.
0149      *  @param[in] outgoing Flag, true, to consider only inside surfaces
0150      *             or false, to consider only outside surfaces.
0151      *  @returns The distance to the closest surface satisfying requirements
0152      *           or kInfinity if no such surface exists.
0153      */
0154     G4double Distance( const G4ThreeVector& p, G4bool outgoing ) override;
0155   
0156     /**
0157      * Determines whether a point is inside, outside, or on the surface of
0158      * the face.
0159      *  @param[in] p Position.
0160      *  @param[in] tolerance Tolerance defining the bounds of the "kSurface",
0161      *             nominally equal to kCarTolerance/2.
0162      *  @param[out] bestDistance Distance to the closest surface (in or out).
0163      *  @returns kInside if the point is closest to the inside surface;
0164      *           kOutside if the point is closest to the outside surface;
0165      *           kSurface if the point is withing tolerance of the surface.
0166      */
0167     EInside Inside( const G4ThreeVector &p, G4double tolerance, 
0168                           G4double *bestDistance ) override;
0169   
0170     /**
0171      * Returns the normal of surface closest to the point.
0172      *  @param[in] p Position.
0173      *  @param[out] bestDistance Distance to the closest surface (in or out).
0174      *  @returns The normal of the surface nearest the point.
0175      */
0176     G4ThreeVector Normal( const G4ThreeVector& p,
0177                                 G4double* bestDistance ) override;
0178 
0179     /**
0180      * Returns the face extent along the axis.
0181      *  @param[in] axis Unit vector defining the direction.
0182      *  @returns The largest point along the given axis of the face's extent.
0183      */
0184     G4double Extent( const G4ThreeVector axis ) override;
0185   
0186     /**
0187      * Calculates the extent of the face for the voxel navigator.
0188      *  @param[in] axis The axis in which to check the shapes 3D extent against.
0189      *  @param[in] voxelLimit Limits along x, y, and/or z axes.
0190      *  @param[in] tranform A coordinate transformation on which to apply to
0191      *             the shape before testing.
0192      *  @param[out] extentList The list of (voxel) extents along the axis.
0193      */
0194     void CalculateExtent( const EAxis axis, 
0195                           const G4VoxelLimits &voxelLimit,
0196                           const G4AffineTransform& tranform,
0197                                 G4SolidExtentList& extentList ) override;
0198 
0199     /**
0200      * Method invoked by the copy constructor or the assignment operator.
0201      * Its purpose is to return a pointer to a duplicate copy of the face.
0202      */
0203     inline G4VCSGface* Clone() override { return new G4PolyhedraSide( *this ); }
0204 
0205     /**
0206      * Returning an estimation of the face surface area, in internal units.
0207      */
0208     G4double SurfaceArea() override;
0209 
0210     /**
0211      * Fake default constructor for usage restricted to direct object
0212      * persistency for clients requiring preallocation of memory for
0213      * persistifiable objects.
0214      */
0215     G4PolyhedraSide(__void__&);
0216 
0217     /**
0218      * Returns the instance ID.
0219      */
0220     inline G4int GetInstanceID() const  { return instanceID; }
0221 
0222     /**
0223      * Returns the private data instance manager.
0224      */
0225     static const G4PhSideManager& GetSubInstanceManager();
0226 
0227   private:
0228 
0229     /**
0230      * Internal data structures.
0231      */
0232     struct sG4PolyhedraSideVec;         // Secret recipe for allowing
0233     friend struct sG4PolyhedraSideVec;  // protected nested structures
0234 
0235     using G4PolyhedraSideEdge = struct sG4PolyhedraSideEdge
0236     {
0237       G4ThreeVector  normal;       // Unit normal to this edge
0238       G4ThreeVector  corner[2];    // The two corners of this phi edge
0239       G4ThreeVector  cornNorm[2];  // The normals of these corners
0240     };
0241   
0242     using G4PolyhedraSideVec = struct sG4PolyhedraSideVec
0243     {
0244       G4ThreeVector  normal,   // Normal (point out of the shape)
0245                      center,   // Point in center of side
0246                      surfPhi,  // Unit vector on surface pointing along phi
0247                      surfRZ;   // Unit vector on surface pointing along R/Z
0248       G4PolyhedraSideEdge* edges[2];  // The phi boundary edges to this side 
0249                                       //     [0]=low phi [1]=high phi
0250       G4ThreeVector edgeNorm[2];      // RZ edge normals [i] at {r[i],z[i]}
0251     };
0252 
0253     /**
0254      * Calculates the surface area of a triangle. 
0255      * At the same time a random point in the triangle is given.
0256      */
0257     G4double SurfaceTriangle( const G4ThreeVector& p1,
0258                               const G4ThreeVector& p2,
0259                               const G4ThreeVector& p3,
0260                                     G4ThreeVector* p4 );
0261 
0262     /**
0263      * Returns a random point located and uniformly distributed on the face.
0264      */
0265     G4ThreeVector GetPointOnFace() override;  
0266 
0267     /**
0268      * Auxiliary method for GetPointOnSurface().
0269      */
0270     G4ThreeVector GetPointOnPlane( const G4ThreeVector& p0, const G4ThreeVector& p1, 
0271                                    const G4ThreeVector& p2, const G4ThreeVector& p3,
0272                                    G4double* Area );
0273 
0274     /**
0275      * Decides if a line correctly intersects one side plane of a segment.
0276      * It is assumed that the correct side has been chosen, and thus only 
0277      * the Z bounds (of the entire segment) are checked.
0278      *  @param[in] p The point to check.
0279      *  @param[in] v The direction.
0280      *  @param[in] vec Description record of the side plane.
0281      *  @param[in] normSign Sign (+/- 1) to apply to normal.
0282      *  @param[in] surfTolerance Surface tolerance (generally > 0, see below).
0283      *  @param[out] distance Distance along v to intersection.
0284      *  @param[out] distFromSurface Distance from surface normal.
0285      *  @returns true is the line is intersecting, false otherwise.
0286      */
0287     G4bool IntersectSidePlane( const G4ThreeVector& p, const G4ThreeVector& v,
0288                                const G4PolyhedraSideVec& vec,
0289                                      G4double normSign, 
0290                                      G4double surfTolerance,
0291                                      G4double& distance,
0292                                      G4double& distFromSurface );
0293 
0294     /**
0295      * Calculates which phi segments a line intersects in three dimensions.
0296      * No check is made as to whether the intersections are within the Z bounds
0297      * of the segment.
0298      */
0299     G4int LineHitsSegments( const G4ThreeVector& p,
0300                             const G4ThreeVector& v,
0301                                   G4int* i1, G4int* i2 );
0302 
0303     /**
0304      * Decides which phi segment an angle belongs to, counting from zero.
0305      * A returned value of -1 indicates that the phi value is outside the
0306      * shape (only possible if phiTotal < 360 degrees).
0307      */
0308     G4int PhiSegment( G4double phi );
0309 
0310     /**
0311      * Decides which phi segment is closest in phi to the point.
0312      * The result is the same as PhiSegment() if there is no phi opening.
0313      */
0314     G4int ClosestPhiSegment( G4double phi );
0315   
0316     /**
0317      * Calculates Phi for a given 3-vector (point 'p'), if not already cached
0318      * for the same point, in the attempt to avoid consecutive computation of
0319      * the same quantity.
0320      */
0321     G4double GetPhi( const G4ThreeVector& p );
0322 
0323     /**
0324      * Computes the total distance from the side.
0325      *  @param[in] p The point to check.
0326      *  @param[in] vec The vector set of this side.
0327      *  @param[out] normDist The returned distance normal to the side or edge,
0328      *              as appropriate, signed.
0329      *  @returns The total distance from the side.
0330      */
0331     G4double DistanceToOneSide( const G4ThreeVector& p,
0332                                 const G4PolyhedraSideVec& vec,
0333                                       G4double* normDist );
0334 
0335     /**
0336      * Calculates the distance of a point from the segmented surface, including
0337      * the effect of any phi segmentation.
0338      * Adds distance from side edges, if necessary, to the total distance,
0339      * and updates 'normDist' appropriate depending on edge normals.
0340      *  @param[in] p The point to check.
0341      *  @param[in] opposite If true, check the opposite hemisphere (see below).
0342      *  @param[out] normDist The returned normal distance.
0343      *  @returns The distance from the segmented plane.
0344      */
0345     G4double DistanceAway( const G4ThreeVector& p,
0346                            const G4PolyhedraSideVec& vec,
0347                                  G4double* normDist );
0348              
0349     /**
0350      * Copies parameters from other object; used in copy constructor and
0351      * assignment operator.
0352      */
0353     void CopyStuff( const G4PolyhedraSide& source );
0354 
0355   private:
0356 
0357     G4int numSide = 0;    // Number sides
0358     G4double r[2], z[2];  // r, z parameters, in specified order
0359     G4double startPhi,    // Start phi (0 to 2pi), if phiIsOpen
0360              deltaPhi,    // Delta phi (0 to 2pi), if phiIsOpen
0361              endPhi;      // End phi (>startPhi), if phiIsOpen
0362     G4bool phiIsOpen = false; // True if there is a phi slice
0363     G4bool allBehind = false; // True if the entire solid is "behind" this face
0364   
0365     G4IntersectingCone* cone = nullptr; // Our intersecting cone
0366   
0367     G4PolyhedraSideVec* vecs = nullptr; // Vector set for each facet of our face
0368     G4PolyhedraSideEdge* edges = nullptr; // The edges belong to vecs
0369     G4double    lenRZ,      // RZ length of each side
0370                 lenPhi[2];  // Phi dimensions of each side
0371     G4double    edgeNorm;   // Normal in RZ/Phi space to each side
0372 
0373     G4double kCarTolerance;      // Geometrical surface thickness
0374     G4double fSurfaceArea = 0.0; // Surface Area 
0375 
0376     G4int instanceID;
0377       // This field is used as instance ID.
0378     G4GEOM_DLL static G4PhSideManager subInstanceManager;
0379       // This field helps to use the class G4PhSideManager introduced above.
0380 };
0381 
0382 #endif