Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 09:09:25

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 // G4MultiNavigator
0027 //
0028 // Class description:
0029 //
0030 // Utility class for polling the navigators of several geometries to
0031 // identify the next boundary. 
0032 
0033 // Author: John Apostolakis (CERN), November 2006
0034 // --------------------------------------------------------------------
0035 #ifndef G4MULTINAVIGATOR_HH
0036 #define G4MULTINAVIGATOR_HH 1
0037 
0038 #include <iostream>
0039 
0040 #include "geomdefs.hh"
0041 #include "G4ThreeVector.hh"
0042 #include "G4Navigator.hh"
0043 
0044 #include "G4TouchableHandle.hh"
0045 
0046 #include "G4NavigationHistory.hh"
0047 
0048 enum  ELimited { kDoNot,kUnique,kSharedTransport,kSharedOther,kUndefLimited };
0049 
0050 class G4TransportationManager;
0051 class G4VPhysicalVolume;
0052 
0053 /**
0054  * @brief G4MultiNavigator is a utility class for polling the navigators
0055  * of several geometries to identify the next boundary.
0056  */
0057 
0058 class G4MultiNavigator : public G4Navigator
0059 {
0060   public:
0061 
0062     friend std::ostream& operator << (std::ostream& os, const G4Navigator& n);
0063 
0064     /**
0065      * Constructor and default Destructor.
0066      */
0067     G4MultiNavigator();
0068     ~G4MultiNavigator() override = default;
0069 
0070     /**
0071      * Computes the distance to the next boundary of any geometry.
0072      *  @param[in] pGlobalPoint The point in global coordinates system.
0073      *  @param[in] pDirection The normalised vector direction.
0074      *  @param[in] pCurrentProposedStepLength Current proposed step length.
0075      *  @param[in,out] newSafety New safety.
0076      *  @returns Length from current point to next boundary surface along
0077      *           @p pDirection.
0078      */
0079     G4double ComputeStep( const G4ThreeVector& pGlobalPoint,
0080                           const G4ThreeVector& pDirection,
0081                           const G4double       pCurrentProposedStepLength,
0082                                 G4double&      pNewSafety ) override;
0083 
0084     /**
0085      * Gets values for a single geometry.
0086      *  @param[in] navigatorId The navigator identifier.
0087      *  @param[in,out] pnewSafety New safety for this geometry.
0088      *  @param[in,out] minStepLast The last minimum step returned.
0089      *  @param[in,out] limitedStep The step characterisation returned.
0090      *  @returns The step size for the geometry associated to 'navigatorId'.
0091      */
0092     G4double ObtainFinalStep( G4int        navigatorId, 
0093                               G4double&    pNewSafety,     // for this geom 
0094                               G4double&    minStepLast,
0095                               ELimited&    limitedStep ); 
0096 
0097     /**
0098      * Finds which geometries are registered for this particles, and keeps info.
0099      */
0100     void PrepareNavigators(); 
0101 
0102     /**
0103      * Prepares Navigators and locates.
0104      *  @param[in] position The position point in global coordinates system.
0105      *  @param[in] direction The normalised vector direction.
0106      */
0107     void PrepareNewTrack( const G4ThreeVector& position, 
0108                           const G4ThreeVector direction ); 
0109 
0110     /**
0111      * Resets the geometrical hierarchy for all geometries.
0112      * Use the touchable history for the first (mass) geometry.
0113      *  @note In order to call this the geometries MUST be closed.
0114      *  @param[in] point The  point in global coordinates system.
0115      *  @param[in] direction The normalised vector direction.
0116      *  @param[in] h The touchable history to be used for initialisation.
0117      *  @returns The pointer to the volume in the first (mass) geometry.
0118      */
0119     G4VPhysicalVolume* ResetHierarchyAndLocate( const G4ThreeVector& point,
0120                                      const G4ThreeVector& direction,
0121                                      const G4TouchableHistory& h ) override;
0122 
0123     /**
0124      * Locates the point in all geometries.
0125      * Maintains a vector of other volumes, to be returned separately.
0126      *  @note In order to call this the geometry MUST be closed.
0127      *  @param[in] point The point in global coordinates system.
0128      *  @param[in] direction The normalised vector direction.
0129      *  @param[in] pRelativeSearch Flag to specify where search starts from.
0130      *  @param[in] ignoreDirection Flag to specify if to use direction or not.
0131      *  @returns The volume in the first (mass) geometry.
0132      */
0133     G4VPhysicalVolume* LocateGlobalPointAndSetup( const G4ThreeVector& point,
0134                                       const G4ThreeVector* direction = nullptr,
0135                                       const G4bool pRelativeSearch = true,
0136                                       const G4bool ignoreDirection = true) override;
0137 
0138     /**
0139      * Relocates in all geometries for point that has not changed volume,
0140      * i.e. is within safety in all geometries or its distance is less that 
0141      * along the direction of a computed step.
0142      *  @param[in] position The position point in global coordinates system.
0143      */
0144     void LocateGlobalPointWithinVolume( const G4ThreeVector& position ) override; 
0145 
0146     /**
0147      * Calculates the isotropic distance to the nearest boundary in any
0148      * geometry from the specified point in the global coordinates system.
0149      *  @note The geometry must be closed.
0150      *  @param[in] globalpoint The point in global coordinates system.
0151      *             The point must be within the current volume.
0152      *  @param[in] pProposedMaxLength The proposed maximum length is used
0153      *             to avoid volume safety calculations.
0154      *  @param[in] keepState Flag to instruct keeping the state (default false)
0155      *             to ensure minimum side effects from the call.
0156      *  @returns Length from current point to closest boundary surface.
0157      *           The value returned is usually an underestimate.  
0158      */
0159     G4double ComputeSafety( const G4ThreeVector& globalpoint,
0160                             const G4double pProposedMaxLength = DBL_MAX,
0161                             const G4bool keepState = false ) override;
0162 
0163     /**
0164      * Returns a reference counted handle to a touchable history.
0165      */
0166     G4TouchableHandle CreateTouchableHistoryHandle() const override;
0167 
0168     /**
0169      * Obtains the Normal vector to a surface (in local coordinates)
0170      * pointing out of previous volume and into current volume
0171      * Convention: the *local* normal is in the coordinate system of the
0172      * *final* volume. The method takes full care about how to calculate
0173      * this normal, but if the surfaces are not convex it will return
0174      * valid=false.
0175      *  @param[in,out] obtained Flag indicating if normal is valid.
0176      *  @returns A Exit Surface Normal vector and validity too.
0177      */
0178     G4ThreeVector GetLocalExitNormal( G4bool* obtained ) override;
0179 
0180     /**
0181      * Obtains the Normal vector to a surface (in local coordinates)
0182      * pointing out of previous volume and into current volume, and
0183      * checks the current point against expected 'local' value.
0184      * Convention: the *local* normal is in the coordinate system of the
0185      * *final* volume. The method takes full care about how to calculate
0186      * this normal, but if the surfaces are not convex it will return
0187      * valid=false.
0188      *  @param[in] point Point in global coordinates system to compare to.
0189      *  @param[in,out] obtained Flag indicating if normal is valid.
0190      *  @returns A Exit Surface Normal vector and validity too.
0191      */
0192     G4ThreeVector GetLocalExitNormalAndCheck( const G4ThreeVector& point,
0193                                               G4bool* obtained ) override;
0194 
0195     /**
0196      * Obtains the Normal vector to a surface (in global coordinates)
0197      * pointing out of previous volume and into current volume
0198      * The method takes full care about how to calculate the normal,
0199      * but if the surfaces are not convex it will return valid=false.
0200      *  @param[in] point Point in global coordinates system to compare to.
0201      *  @param[in,out] obtained Flag indicating if normal is valid.
0202      *  @returns A Exit Surface Normal vector and validity too.
0203      */
0204     G4ThreeVector GetGlobalExitNormal( const G4ThreeVector& point,
0205                                              G4bool* obtained ) override;
0206 
0207     /**
0208      * Returns a pointer to a navigator, given its index.
0209      */
0210     inline G4Navigator* GetNavigator( G4int n ) const;
0211 
0212   protected:
0213 
0214     /**
0215      * Utility method to reset the navigator state machine.
0216      */
0217     void ResetState() override;
0218 
0219     /**
0220      * Renavigates & resets hierarchy described by the current history,
0221      * i.e. resets volumes and recomputes transforms and/or solids of
0222      * replicated/parameterised volumes.
0223      */
0224     void SetupHierarchy() override;
0225 
0226     /**
0227      * Flags which processes limited the step.
0228      */
0229     void WhichLimited(); 
0230 
0231     /**
0232      * Auxiliary, debugging printing.
0233      */
0234     void PrintLimited();
0235 
0236     /**
0237      * Checks if mass world pointed has been changed => issues and exception.
0238      */
0239     void CheckMassWorld(); 
0240 
0241   private:
0242 
0243     // STATE Information 
0244 
0245     G4int fNoActiveNavigators = 0; 
0246     static const G4int fMaxNav = 16;
0247     G4VPhysicalVolume* fLastMassWorld = nullptr; 
0248 
0249     /** Global state (retained during stepping for one track). */
0250     G4Navigator* fpNavigator[fMaxNav];
0251 
0252     // State after a step computation 
0253     //
0254     ELimited fLimitedStep[fMaxNav];
0255     G4bool   fLimitTruth[fMaxNav];
0256     G4double fCurrentStepSize[fMaxNav]; 
0257     G4double fNewSafety[ fMaxNav ]; // Safety for starting point
0258     G4int    fNoLimitingStep = -1;  // How many geometries limited the step
0259     G4int    fIdNavLimiting = -1;   // Id of Navigator limiting step
0260 
0261     // Lowest values - determine step length, and safety
0262     //
0263     G4double fMinStep = -kInfinity;     // As reported by Navigators
0264     G4double fMinSafety = -kInfinity;
0265     G4double fTrueMinStep = -kInfinity; // Corrected if fMinStep>=proposed
0266 
0267     // State after calling 'locate'
0268     //
0269     G4VPhysicalVolume* fLocatedVolume[fMaxNav];
0270     G4ThreeVector      fLastLocatedPosition; 
0271 
0272     // Cache of safety information
0273     //
0274     G4ThreeVector fSafetyLocation; // point where ComputeSafety() is called
0275     G4double fMinSafety_atSafLocation = -1.0; // - corresponding value of safety
0276     G4ThreeVector fPreStepLocation; // point where last ComputeStep() called
0277     G4double fMinSafety_PreStepPt = -1.0; // - corresponding value of safety
0278 
0279     G4TransportationManager* pTransportManager; // Cache for frequent use
0280 };
0281 
0282 // --------------------------------------------------------------------
0283 // Inline methods
0284 // --------------------------------------------------------------------
0285 
0286 inline G4Navigator* G4MultiNavigator::GetNavigator( G4int n ) const
0287 { 
0288   if( (n>fNoActiveNavigators) || (n<0) ) { n=0; }
0289   return fpNavigator[n]; 
0290 }
0291 
0292 #endif