////////////////////////////////////////////////////////////////////////////////////////// /// \class RAT::SphericalSubregionList /// /// \brief Breaks up a spherically symmetric volume into small regions that can be accessed/checked for intersections. /// /// \author Aksel Hallin aksel.hallin@ualberta.ca /// /// Revision History: \n /// 2014-07-02 Aksel Hallin /// ///\detail This class is used to segment a G4VSolid that is built around a spherical shell into smaller units. Only /// features within a given segment need to be checked for intersection, interiorness, etc. /// 10000 is reasonably optimized as the default number of segments into which we break up the solid- this makes for roughly 30*30 cm /// square regions. /// ///////////////////////////////////////////////////////////////////////////////////////// #ifndef __RAT_SphericalSubregionList__ #define __RAT_SphericalSubregionList__ class SphericalSubregion; #include #include const int kNPhi=100; const int kNCosTheta=100; const int kNRegions=kNPhi*kNCosTheta; // number of regions into which we subdivide the surface of SNO class SphericalSubregionList:public G4VSolid{ public: /// Default constructor. Does nothing enum Mode {kPhysicalInner, kPhysicalOuter, kAbstract}; enum NextMode {kToIn, kToOut}; SphericalSubregionList(const G4String &aTitle); // The class declaration needs to be split to be able to read values form the database void InitializeSubregion(G4double anInnerRadius, G4double anOuterRadius, G4double maxSphereRadius, Mode aMod); /// Adds multiple regions to the fRegions array. Checks each region using SphericalSubregion::OverlapsRegion to add pointers to these /// subregions at the appropriate places. void AddRegions(std::listalist); /// Finds the distances to the intersections of a line starting at aPosition with aDirection with the set of concentric spheres defined by fRadii. /// @param[in] aPosition The starting position of the track /// @param[in] aDirection The direction of the track ( a unit vector) /// @param[in] radii A list of radii of spheres for which intersections will be calculated /// @param[in] list A list that will be filled with positive distances corresponding to intersections with the spheres void CalculateSphericalPoints(const G4ThreeVector &aPosition, const G4ThreeVector &aDirection,const G4double radii[2] ,std::list &list)const; /// Finds the distances to the intersections of a line starting at aPosition with aDirection with a sphere. /// @param[in] aPosition The starting position of the track /// @param[in] aDirection The direction of the track ( a unit vector) /// @param[in] aRadius The radius of the sphere for which intersections will be calculated /// @param[out] d The calculated intersections. /// @returns The number of intersections. static G4int CalculateSphereIntersection(const G4ThreeVector &aPosition, const G4ThreeVector &aDirection, const G4double aRadius, G4double d[2]); /// Finds the region index in which a given point lies /// @param[in]p The point for which we are finding the region. /// @return The region index G4int Region(const G4ThreeVector &p)const{ double ct = p.cosTheta(); double pp = p.phi(); return Region(ct, pp); } /// Finds the region index in which a given point lies /// @param[in]aCosTheta /// @param[in] aPhi /// @return The region index G4int Region(G4double aCosTheta, G4double aPhi)const; /// Finds the region index in which a given point lies /// @param[in]p The point for which we are finding the region. /// @param[out] ict The index of the region along the cos-theta direction /// @param[out] ipp The index of the region along the phi direction /// @return The region index G4int Region(G4ThreeVector &p, G4int &ict, G4int &ipp)const; /// Finds the spherical coordinate angle ranges that correspond to a given region. /// @param[in] anIndex The region that is being asked for /// @param[out] aThetaMin the minimum theta corresponding to the region /// @param[out] aThetaMax the maximum theta corresponding to the region /// @param[out] aPhiMin the minimum phi corresponding to the region /// @param[out] aPhimMax the minimum phi corresponding to the region void RegionExtent(G4int anIndex, G4double &aThetaMin, G4double &aThetaMax,G4double &aPhiMin, G4double &aPhiMax)const; /// Adds aRegion to the list of regions to check for index i. void AddRegion(G4int i, SphericalSubregion *aRegion); /// Goes through each region and removes any duplicate Subregions from the internal list void PruneList(); /// Implements G4VSolid::EInside /// @param[in] p The point /// @return kInside, kSurface, or kOutside virtual EInside Inside(const G4ThreeVector &p)const; G4ThreeVector SurfaceNormal(const G4ThreeVector &p)const { G4bool isValid; return SurfaceNormal(p, isValid); } virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p, G4bool &isValid)const; /// Finds the distance to the next intersection by looking up the reference position=p+referenceDistance*n. It goes through the relevent /// list of subregions, to see if there are any intersections at a value less than the proposedDistance. /// @param[in]p The starting point /// @param[in]v The direction of the path of the particle /// @returns Distance to the intersection, or the proposed distance if no intersection is found. G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v)const; /// Routine that is used by both DistanceToIn and DistanceToOut to calculate next intersection /// Finds the distance to the next intersection by looking up the reference position=p+referenceDistance*n. It goes through the relevent /// list of subregions, to see if there are any intersections at a value less than the proposedDistance. /// @param[in]p The starting point /// @param[in]v The direction of the path of the particle /// @returns Distance to the intersection, or the proposed distance if no intersection is found. virtual G4double DistanceToNext(const G4ThreeVector &p, const G4ThreeVector &v, NextMode aNextMode)const; G4double DistanceToIn(const G4ThreeVector &p)const ; /// Implements the G4VSolid method G4double DistanceToOut(const G4ThreeVector& p,const G4ThreeVector& v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0)const; /// Implements the G4VSolid method G4double DistanceToOut(const G4ThreeVector &p)const; protected: G4double fInnerRadius; ///< The reference radius G4double fOuterRadius; ///< G4double fPhysicalRadius; ///< The radius of the physical boundary G4double fNeckRadius; ///< The cylindrical radius of the "hole" for the neck. G4double fMaxSphereRadius; /// The maximum spherical radius of the volume, accounting for neck protrusions G4double fSphereMaxZ; Mode fMode; ///< enumeration telling which of inner or outer is the physical radius G4double fThreshold; ///< Geant4 tolerance for determining whether a point is on the surface or in the bulk. std::listfRegions[kNRegions]; ///< A list of Subregions to check. }; #endif