Back to home page

EIC code displayed by LXR

 
 

    


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

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 // G4Navigator
0027 //
0028 // Class description:
0029 //
0030 // A class for use by the tracking management, able to obtain/calculate
0031 // dynamic tracking time information such as the distance to the next volume,
0032 // or to find the physical volume containing a given point in the world
0033 // reference system. The navigator maintains a transformation history and
0034 // other information to optimise the tracking time performance.
0035 
0036 // Original author: Paul Kent (CERN), July 1995-1996
0037 //
0038 // - Made Navigator Abstract                   G. Cosmo,      Nov  2003
0039 // - Added check mode                          G. Cosmo,      Mar  2004
0040 // - Zero step protections                     J.A. / G.C.,   Nov  2004
0041 // --------------------------------------------------------------------
0042 #ifndef G4NAVIGATOR_HH
0043 #define G4NAVIGATOR_HH 1
0044 
0045 #include "geomdefs.hh"
0046 
0047 #include "G4ThreeVector.hh"
0048 #include "G4AffineTransform.hh"
0049 #include "G4RotationMatrix.hh"
0050 
0051 #include "G4LogicalVolume.hh"             // Used in inline methods
0052 #include "G4TouchableHandle.hh"           //    "         "
0053 
0054 #include "G4NavigationHistory.hh"
0055 #include "G4NormalNavigation.hh"
0056 #include "G4VoxelNavigation.hh"
0057 #include "G4ParameterisedNavigation.hh"
0058 #include "G4ReplicaNavigation.hh"
0059 #include "G4RegularNavigation.hh"
0060 #include "G4VExternalNavigation.hh"
0061 
0062 #include <iostream>
0063 
0064 class G4VPhysicalVolume;
0065 class G4SafetyCalculator;
0066 
0067 /**
0068  * @brief G4Navigator is a class for use by the tracking management, able to
0069  * obtain/calculate dynamic tracking time information such as the distance to
0070  * the next volume, or to find the physical volume containing a given point in
0071  * the world reference system. The navigator maintains a transformation history
0072  * and other information to optimise the tracking time performance.
0073  */
0074 
0075 class G4Navigator
0076 {
0077   public:
0078 
0079     friend std::ostream& operator << (std::ostream &os, const G4Navigator &n);
0080 
0081     /**
0082      * Constructor - initialisers and setup.
0083      */
0084     G4Navigator();
0085 
0086     /**
0087      * Copy constructor & assignment operator not allowed.
0088      */
0089     G4Navigator(const G4Navigator&) = delete;
0090     G4Navigator& operator=(const G4Navigator&) = delete;
0091 
0092     /**
0093      * Destructor.
0094      */
0095     virtual ~G4Navigator();
0096 
0097     /**
0098      * Calculates the distance to the next boundary intersected along the
0099      * specified NORMALISED vector direction and from the specified point in
0100      * the global coordinate system.
0101      * LocateGlobalPointAndSetup() or LocateGlobalPointWithinVolume() must
0102      * have been called with the same global point prior to this call.
0103      * The isotropic distance to the nearest boundary is also calculated
0104      * (usually an underestimate). The current proposed Step length is used
0105      * to avoid intersection calculations: if it can be determined that the
0106      * nearest boundary is >pCurrentProposedStepLength away, kInfinity
0107      * is returned together with the computed isotropic safety distance.
0108      *  @note Geometry must be closed.
0109      *  @param[in] pGlobalPoint The point in global coordinates system.
0110      *  @param[in] pDirection The normalised vector direction.
0111      *  @param[in] pCurrentProposedStepLength Current proposed step length.
0112      *  @param[in,out] newSafety New safety.
0113      *  @returns Length from current point to next boundary surface along
0114      *           @p pDirection.
0115      */
0116     virtual G4double ComputeStep(const G4ThreeVector& pGlobalPoint,
0117                                  const G4ThreeVector& pDirection,
0118                                  const G4double pCurrentProposedStepLength,
0119                                        G4double& pNewSafety);
0120 
0121     /**
0122      * Same as ComputeStep() above, but does not affect/modify the state
0123      * of the Navigator.
0124      */
0125     G4double CheckNextStep(const G4ThreeVector& pGlobalPoint,
0126                            const G4ThreeVector& pDirection,
0127                            const G4double pCurrentProposedStepLength,
0128                                  G4double& pNewSafety); 
0129 
0130     /**
0131      * Resets the geometrical hierarchy and searches for the volumes deepest
0132      * in the hierarchy containing the point in the global coordinates space.
0133      * The direction is used to check if a volume is entered.
0134      * The search begin is the geometrical hierarchy at the location of the
0135      * last located point, or the endpoint of the previous Step if
0136      * SetGeometricallyLimitedStep() has been called immediately before.
0137      *  @note: In order to call this the geometry MUST be closed.
0138      *  @param[in] point The point in global coordinates system.
0139      *  @param[in] direction The normalised vector direction.
0140      *  @param[in] h The touchable history to be used for initialisation.
0141      *  @returns The pointer to the physical volume where point is located.
0142      */
0143     virtual
0144     G4VPhysicalVolume* ResetHierarchyAndLocate(const G4ThreeVector& point,
0145                                                const G4ThreeVector& direction,
0146                                                const G4TouchableHistory& h);
0147 
0148     /**
0149      * Searches the geometrical hierarchy for the volumes deepest in hierarchy
0150      * containing the point in the global coordinate space. Two main cases
0151      * are:
0152      *  i) If pRelativeSearch=false it makes use of no previous/state
0153      *     information. Returns the physical volume containing the point, 
0154      *     with all previous mothers correctly set up.
0155      * ii) If pRelativeSearch is set to true, the search begin is the
0156      *     geometrical hierarchy at the location of the last located point,
0157      *     or the endpoint of previous Step if SetGeometricallyLimitedStep()
0158      *     has been called immediately before.
0159      * The direction is used (to check if a volume is entered) if either
0160      *   - the argument ignoreDirection is false, or
0161      *   - the Navigator has determined that it is on an edge shared by two
0162      *     or more volumes (this is state information).
0163      *  @note In order to call this the geometry MUST be closed.
0164      *  @param[in] point The point in global coordinates system.
0165      *  @param[in] direction The normalised vector direction.
0166      *  @param[in] pRelativeSearch Flag to specify where search starts from.
0167      *  @param[in] ignoreDirection Flag to specify if to use direction or not.
0168      *  @returns The pointer to the physical volume where point is located.
0169      */
0170     virtual
0171     G4VPhysicalVolume* LocateGlobalPointAndSetup(const G4ThreeVector& point,
0172                                        const G4ThreeVector* direction = nullptr,
0173                                        const G4bool pRelativeSearch = true,
0174                                        const G4bool ignoreDirection = true);
0175 
0176     /**
0177      * Notifies the Navigator that a track has moved to the new Global point
0178      * 'position', that is known to be within the current safety.
0179      * No check is performed to ensure that it is within  the volume. 
0180      * This method can be called instead of LocateGlobalPointAndSetup() ONLY
0181      * if the caller is certain that the new global point (position) is inside
0182      * the same volume as the previous position. Usually this can be guaranteed
0183      * only if the point is within safety.
0184      *  @param[in] position The position point in global coordinates system.
0185      */
0186     virtual
0187     void LocateGlobalPointWithinVolume(const G4ThreeVector& position);
0188 
0189     /**
0190      * It first searches the geometrical hierarchy like the above method
0191      * LocateGlobalPointAndSetup(), then it uses the volume found and its
0192      * navigation history to update the touchable handle.
0193      *  @param[in] position The point in global coordinates system.
0194      *  @param[in] direction The normalised vector direction.
0195      *  @param[in,out] oldTouchableToUpdate Touchable handle to update.
0196      *  @param[in] RelativeSearch Flag to specify where search starts from.
0197      */
0198     inline void LocateGlobalPointAndUpdateTouchableHandle(
0199                   const G4ThreeVector&       position,
0200                   const G4ThreeVector&       direction,
0201                         G4TouchableHandle&   oldTouchableToUpdate,
0202                   const G4bool               RelativeSearch = true);
0203     /**
0204      * Same as the method above LocateGlobalPointAndUpdateTouchableHandle(),
0205      * except that a pointer to G4VTouchable is used for updating the touchable.
0206      */
0207     inline void LocateGlobalPointAndUpdateTouchable(
0208                   const G4ThreeVector&       position,
0209                   const G4ThreeVector&       direction,
0210                         G4VTouchable*        touchableToUpdate,
0211                   const G4bool               RelativeSearch = true);
0212 
0213     /**
0214      * Same as the method above LocateGlobalPointAndUpdateTouchable(),
0215      * except that direction is not specified.
0216      */
0217     inline void LocateGlobalPointAndUpdateTouchable(
0218                   const G4ThreeVector&       position,
0219                         G4VTouchable*        touchableToUpdate,
0220                   const G4bool               RelativeSearch = true);
0221 
0222     /**
0223      * Informs the navigator that the previous Step calculated by the
0224      * geometry was taken in its entirety.
0225      */
0226     inline void SetGeometricallyLimitedStep();
0227 
0228     /**
0229      * Calculates the isotropic distance to the nearest boundary from the
0230      * specified point in the global coordinate system. 
0231      *  @note The geometry must be closed.
0232      *  @param[in] globalpoint The point in global coordinates system.
0233      *             The point must be within the current volume.
0234      *  @param[in] pProposedMaxLength The proposed maximum length is used
0235      *             to avoid volume safety calculations.
0236      *  @param[in] keepState Flag to instruct keeping the state (default true)
0237      *             to ensure minimum side effects from the call.
0238      *  @returns Length from current point to closest boundary surface.
0239      *           The value returned is usually an underestimate.  
0240      */
0241     virtual G4double ComputeSafety(const G4ThreeVector& globalpoint,
0242                                    const G4double pProposedMaxLength = DBL_MAX,
0243                                    const G4bool keepState = true);
0244 
0245     /**
0246      * Returns the current  world (topmost) volume.
0247      */
0248     inline G4VPhysicalVolume* GetWorldVolume() const;
0249 
0250     /**
0251      * Sets the world (topmost) volume. This must be positioned at the
0252      * origin (0,0,0) and unrotated.
0253      */
0254     inline void SetWorldVolume(G4VPhysicalVolume* pWorld);
0255 
0256     /**
0257      * Touchable creation method.
0258      *  @note Caller has deletion responsibility.
0259      *  @returns A pointer to the allocated touchable history.
0260      */
0261     inline G4TouchableHistory* CreateTouchableHistory() const;
0262 
0263     /**
0264      * Touchable creation method, given a history.
0265      *  @note Caller has deletion responsibility.
0266      *  @param[in] h Pointer to a navigation history to copy from.
0267      *  @returns A pointer to the allocated touchable history.
0268      */
0269     inline G4TouchableHistory* CreateTouchableHistory(const G4NavigationHistory* h) const;
0270 
0271     /**
0272      * Returns a reference counted handle to a touchable history.
0273      */
0274     virtual G4TouchableHandle CreateTouchableHistoryHandle() const;
0275 
0276     /**
0277      * Obtains the Normal vector to a surface (in local coordinates)
0278      * pointing out of previous volume and into current volume
0279      * Convention: the *local* normal is in the coordinate system of the
0280      * *final* volume. The method takes full care about how to calculate
0281      * this normal, but if the surfaces are not convex it will return
0282      * valid=false.
0283      *  @note Can only be called if the Navigator's last Step has crossed a
0284      *        volume geometrical boundary.
0285      *  @note Normals are not available for replica volumes (i.e. valid=false).
0286      *  @param[in,out] valid Flag indicating if normal is valid.
0287      *  @returns A Exit Surface Normal vector and validity too.
0288      */
0289     virtual G4ThreeVector GetLocalExitNormal(G4bool* valid);
0290 
0291     /**
0292      * Obtains the Normal vector to a surface (in local coordinates)
0293      * pointing out of previous volume and into current volume, and
0294      * checks the current point against expected 'local' value.
0295      * Convention: the *local* normal is in the coordinate system of the
0296      * *final* volume. The method takes full care about how to calculate
0297      * this normal, but if the surfaces are not convex it will return
0298      * valid=false.
0299      *  @note Can only be called if the Navigator's last Step has crossed a
0300      *        volume geometrical boundary.
0301      *  @note Normals are not available for replica volumes (i.e. valid=false).
0302      *  @param[in] point Point in global coordinates system to compare to.
0303      *  @param[in,out] valid Flag indicating if normal is valid.
0304      *  @returns A Exit Surface Normal vector and validity too.
0305      */
0306     virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector& point,
0307                                                            G4bool* valid);
0308     /**
0309      * Obtains the Normal vector to a surface (in global coordinates)
0310      * pointing out of previous volume and into current volume
0311      * The method takes full care about how to calculate the normal,
0312      * but if the surfaces are not convex it will return valid=false.
0313      *  @note Can only be called if the Navigator's last Step has crossed a
0314      *        volume geometrical boundary.
0315      *  @note Normals are not available for replica volumes (i.e. valid=false).
0316      *  @param[in] point Point in global coordinates system to compare to.
0317      *  @param[in,out] valid Flag indicating if normal is valid.
0318      *  @returns A Exit Surface Normal vector and validity too.
0319      */
0320     virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector& point,
0321                                                     G4bool* valid);
0322 
0323     /**
0324      * Verbosity control.
0325      *  @note If level>0 && G4VERBOSE, printout can occur.
0326      */
0327     inline G4int GetVerboseLevel() const;
0328     inline void  SetVerboseLevel(G4int level);
0329 
0330     /**
0331      * Verify if the navigator is active.
0332      */
0333     inline G4bool IsActive() const;
0334 
0335     /**
0336      * Activate/inactivate the navigator.
0337      */
0338     inline void  Activate(G4bool flag);
0339 
0340     /**
0341      * The purpose of this function is to inform the caller if the track is
0342      * entering a daughter volume while exiting from the current volume.
0343      *  @note It is not guaranteed to work if SetGeometricallyLimitedStep()
0344      *        was not called when it should have been called.
0345      *  @returns True only in case when the Step has caused the track to arrive
0346      *           at a boundary of a daughter. False, in all other cases.
0347      */
0348     inline G4bool EnteredDaughterVolume() const;
0349 
0350     /**
0351      * Verify if the step has exited the mother volume.
0352      */
0353     inline G4bool ExitedMotherVolume() const;
0354 
0355     /**
0356      * Run navigation in "check-mode", therefore using additional verifications
0357      * and more strict correctness conditions.
0358      *  @note Is effective only with G4VERBOSE set.
0359      */
0360     inline void CheckMode(G4bool mode);
0361 
0362     /**
0363      * Set/unset verbosity for pushed tracks (default is true).
0364      */
0365     inline G4bool IsCheckModeActive() const;
0366     inline void SetPushVerbosity(G4bool mode);
0367 
0368     /**
0369      * Prints the internal state of the Navigator (for debugging).
0370      * The level of detail is according to the verbosity.
0371      */
0372     void PrintState() const;
0373 
0374     /**
0375      * Obtains the transformations Global/Local (and inverse).
0376      *  @note Clients of these methods must copy the data
0377      *        if they need to keep it.
0378      */
0379     inline const G4AffineTransform& GetGlobalToLocalTransform() const;
0380     inline const G4AffineTransform  GetLocalToGlobalTransform() const;
0381 
0382     /**
0383      * Obtains mother to daughter transformation.
0384      */
0385     G4AffineTransform GetMotherToDaughterTransform(G4VPhysicalVolume* dVolume, 
0386                                                    G4int dReplicaNo,
0387                                                    EVolume dVolumeType );
0388 
0389     /**
0390      * Resets stack and minimum or navigator state machine necessary for reset
0391      * as needed by LocalGlobalPointAndSetup().
0392      *  @note Does not perform clears, resizes, or reset fLastLocatedPointLocal.
0393      */
0394     inline void ResetStackAndState();
0395 
0396     /**
0397      * Reports on severity of error and number of zero steps,
0398      * in case Navigator is stuck and is returning zero steps.
0399      * Values: 1 (small problem),  5 (correcting), 
0400      *         9 (ready to abandon), 10 (abandoned)
0401      *  @param[in,out] noZeroSteps Returns the number of zero steps in case
0402      *                 pointer is not null.
0403      *  @returns The error severity.
0404      */
0405     inline G4int SeverityOfZeroStepping( G4int* noZeroSteps ) const; 
0406 
0407     /**
0408      * Returns the local coordinate of the point in the reference system
0409      * of its containing volume that was found by LocalGlobalPointAndSetup().
0410      * The local coordinate of the last located track.
0411      */
0412     inline G4ThreeVector GetCurrentLocalCoordinate() const;
0413 
0414     /**
0415      * Computes and returns the local->global translation/rotation
0416      * of current volume.
0417      */
0418     inline G4ThreeVector NetTranslation() const;
0419     inline G4RotationMatrix NetRotation() const;
0420 
0421     /**
0422      * Enables best-possible evaluation of isotropic safety.
0423      */
0424     inline void EnableBestSafety( G4bool value = false );
0425 
0426     /**
0427      * Accessor & modifier for custom external navigation.
0428      */
0429     inline G4VExternalNavigation* GetExternalNavigation() const;
0430     void SetExternalNavigation(G4VExternalNavigation* externalNav);
0431    
0432     /**
0433      * Gets/sets alternative navigator for voxel volumes.
0434      */
0435     inline G4VoxelNavigation& GetVoxelNavigator();
0436     void SetVoxelNavigation(G4VoxelNavigation* voxelNav);
0437 
0438     /**
0439      * Cloning feature for use in MT applications to clone the navigator,
0440      * including external sub-navigator.
0441      *  @note Client has responsibility for ownership of the returned
0442      *        allocated pointer.
0443      *  @returns A pointer to the cloned navigator object.
0444      */
0445     inline G4Navigator* Clone() const;
0446 
0447     /**
0448      * Gets endpoint of last step.
0449      */
0450     inline G4ThreeVector GetLastStepEndPoint() const;
0451 
0452     /**
0453      * Derived navigators which rely on LocateGlobalPointAndSetup() need to
0454      * inform size of step, to maintain logic about arriving on boundary
0455      * for challenging cases.
0456      * Required in order to cope with multiple trials at boundaries
0457      * => Locate with use direction rather than simple, fast logic.
0458      */
0459     void InformLastStep(G4double lastStep,
0460                         G4bool entersDaughtVol,
0461                         G4bool exitsMotherVol );
0462 
0463   protected:
0464 
0465     /**
0466      * Saves the state: fValidExitNormal, fExitNormal, fExiting, fEntering,
0467      * fBlockedPhysicalVolume, fBlockedReplicaNo, fLastStepWasZero,
0468      * fLastLocatedPointLocal, fLocatedOutsideWorld, fEnteredDaughter,
0469      * fExitedMother, fPreviousSftOrigin, fPreviousSafety.
0470      */
0471     void SetSavedState();
0472 
0473     /**
0474      * Copy aspects of the state, to enable a non-state changing
0475      * call to ComputeStep().
0476      */
0477     void RestoreSavedState();
0478   
0479     /**
0480      * Utility method to reset the navigator state machine.
0481      */
0482     virtual void ResetState();
0483 
0484     /**
0485      * Returns position vector in local coordinate system, given a position
0486      * vector in world coordinate system.
0487      */
0488     inline G4ThreeVector ComputeLocalPoint(const G4ThreeVector& rGlobP) const;
0489 
0490     /**
0491      * Returns the local direction of the specified vector in the reference
0492      * system of the volume that was found by LocalGlobalPointAndSetup().
0493      * The Local Coordinates of point in world coordinate system.
0494      */
0495     inline G4ThreeVector ComputeLocalAxis(const G4ThreeVector& pVec) const;
0496 
0497     /**
0498      * Characterises the type of volume - normal/replicated/parameterised.
0499      */
0500     inline EVolume VolumeType(const G4VPhysicalVolume *pVol) const;
0501 
0502     /**
0503      * Characterises the daughters of given logical volume.
0504      */
0505     inline EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const;
0506 
0507     /**
0508      * Gets regular structure ID of first daughter.
0509      */
0510     inline G4int GetDaughtersRegularStructureId(const G4LogicalVolume *pLv) const;
0511 
0512     /**
0513      * Renavigates & resets hierarchy described by the current history:
0514      * Resets volumes and recomputes transforms and/or solids of
0515      * replicated/parameterised volumes.
0516      */
0517     virtual void SetupHierarchy();
0518 
0519     /**
0520      * Utility method to trigger overlaps check on a volume with reported
0521      * overlaps ordered by relevance. Used in ComputeStep() when loopings
0522      * with zero step are detected.
0523      */
0524     G4bool CheckOverlapsIterative(G4VPhysicalVolume* vol);
0525 
0526   private:
0527 
0528     /**
0529      * Logs and checks for steps larger than the tolerance.
0530      */
0531     void ComputeStepLog(const G4ThreeVector& pGlobalpoint,
0532                               G4double moveLenSq) const;
0533 
0534   protected:
0535 
0536     G4double kCarTolerance, fMinStep, fSqTol;  // Cached tolerances.
0537 
0538     // BEGIN State information ------------------------------------------------
0539     //
0540 
0541     /** Transformation and history of the current path
0542         through the geometrical hierarchy. */
0543     G4NavigationHistory fHistory;
0544 
0545     /** Endpoint of last ComputeStep().
0546         Can be used for optimisation (e.g. when computing safety). */
0547     G4ThreeVector fStepEndPoint;
0548 
0549     /** Position of the end-point of the last call to ComputeStep()
0550         in last local coordinates. */
0551     G4ThreeVector fLastStepEndPointLocal; 
0552 
0553     /** Verbosity level  [if > 0, printout can occur]. */
0554     G4int fVerbose = 0;
0555    
0556     /** A memory of whether in this Step a daughter volume is entered 
0557         (set in Compute & Locate).
0558         After Compute: it expects to enter a daughter
0559         After Locate:  it has entered a daughter. */
0560     G4bool fEnteredDaughter;
0561 
0562     /** A similar memory whether the Step exited current "mother" volume
0563         completely, not entering daughter. */
0564     G4bool fExitedMother;
0565 
0566     /** Set true if last Step was limited by geometry. */
0567     G4bool fWasLimitedByGeometry = false;
0568 
0569   private:
0570 
0571     /** Position of the last located point relative to its containing volume.
0572         This is coupled with the Boolean member 'fLocatedOutsideWorld'. */
0573     G4ThreeVector fLastLocatedPointLocal;
0574 
0575     /** Leaving volume normal, in the volume containing the exited
0576         volume's coordinate system.
0577         This is closely coupled with 'fValidExitNormal', which signals whether
0578         we have a (valid) normal for volume we're leaving. */
0579     G4ThreeVector fExitNormal;
0580    
0581     /** Leaving volume normal, in its own coordinate system. */
0582     G4ThreeVector fGrandMotherExitNormal;
0583 
0584     /** Leaving volume normal, in the global coordinate system. */
0585     G4ThreeVector fExitNormalGlobalFrame;
0586 
0587     /** Memory of last safety origin & value. Used in ComputeStep() to ensure
0588         that origin of current Step is in the same volume as the point of the
0589         last relocation. */
0590     G4ThreeVector fPreviousSftOrigin;
0591     G4double fPreviousSafety; 
0592 
0593     /** Memory of the mother volume during previous step.
0594         Intended use: inform user in case of stuck track. */
0595     G4VPhysicalVolume* fLastMotherPhys = nullptr;
0596    
0597     /** Identifies the volume and copy / replica number that is blocked
0598         (after exiting -- because the exit direction is along the exit normal)
0599         or a candidate for entry (after compute step). */
0600     G4VPhysicalVolume* fBlockedPhysicalVolume;
0601     G4int fBlockedReplicaNo;
0602    
0603     /** Count zero steps, as one or two can occur due to changing momentum at
0604         a boundary or at an edge common between volumes; several zero steps
0605         are likely a problem in the geometry description or in the navigation.
0606         Number of preceding moves that were Zero.
0607         Reset to 0 after finite step. */
0608     G4int fNumberZeroSteps;
0609 
0610     /** After this many failed/zero steps, act (push etc). */
0611     G4int fActionThreshold_NoZeroSteps = 10;  
0612 
0613     /** After this many failed/zero steps, abandon track. */
0614     G4int fAbandonThreshold_NoZeroSteps = 25; 
0615 
0616     /** States if the navigator is activated or not. */
0617     G4bool fActive = false;
0618 
0619     /** Whether ComputeStep() was called since the last call to a Locate().
0620         Uses: distinguish parts of state which differ before/after calls
0621         to ComputeStep() or one of the Locate() methods; avoid two consecutive
0622         calls to compute-step (illegal). */
0623     G4bool fLastTriedStepComputation = false; 
0624 
0625     /** Entering/Exiting volumes blocking/setup.
0626         o If exiting, volume ptr & replica number (set & used by Locate..())
0627           used for blocking on redescent of geometry;
0628         o If entering, volume ptr & replica number (set by ComputeStep(),
0629           used by Locate..()) of volume for 'automatic' entry. */
0630     G4bool fEntering, fExiting;
0631    
0632     /** Set true if have leaving volume normal. */
0633     G4bool fValidExitNormal;
0634 
0635     /** Whether the last ComputeStep moved Zero. Used to check for edges. */
0636     G4bool fLastStepWasZero;
0637 
0638     /** Whether the Navigator has detected an edge. */
0639     G4bool fLocatedOnEdge;       
0640 
0641     /** Whether the last call to Locate methods left the world. */
0642     G4bool fLocatedOutsideWorld;
0643    
0644     /** Whether frame is changed. */
0645     G4bool  fChangedGrandMotherRefFrame;
0646 
0647     /** Has it been computed since the last call to ComputeStep().
0648         Covers both Global and GrandMother. */
0649     G4bool  fCalculatedExitNormal;
0650 
0651     //
0652     // END State information --------------------------------------------------
0653 
0654     // Optional State information (created/used as needed)
0655     // 
0656    
0657     // Save key state information (NOT the navigation history stack)
0658     //
0659     struct G4SaveNavigatorState
0660     { 
0661        G4ThreeVector sExitNormal;  
0662        G4bool sValidExitNormal;    
0663        G4bool sEntering, sExiting;
0664        G4VPhysicalVolume* spBlockedPhysicalVolume;
0665        G4int sBlockedReplicaNo;  
0666        G4int sLastStepWasZero; 
0667        G4bool sWasLimitedByGeometry;
0668 
0669        //  Potentially relevant
0670        //
0671        G4bool sLocatedOutsideWorld;
0672        G4ThreeVector sLastLocatedPointLocal; 
0673        G4bool sEnteredDaughter, sExitedMother;
0674        G4ThreeVector sPreviousSftOrigin;
0675        G4double sPreviousSafety; 
0676     } fSaveState; 
0677 
0678     // ========================================================================
0679     // BEGIN -- Tracking Invariants
0680 
0681     /** A link to the topmost physical volume in the detector.
0682         Must be positioned at the origin and unrotated. */
0683     G4VPhysicalVolume* fTopPhysical = nullptr;
0684 
0685     // Helpers/Utility classes
0686 
0687     G4NormalNavigation fnormalNav;
0688     G4VoxelNavigation* fpvoxelNav;
0689     G4ParameterisedNavigation fparamNav;
0690     G4ReplicaNavigation freplicaNav;
0691     G4RegularNavigation fregularNav;
0692     G4VExternalNavigation* fpExternalNav = nullptr;
0693     G4VoxelSafety* fpVoxelSafety;
0694     G4SafetyCalculator* fpSafetyCalculator = nullptr;
0695 
0696     // Utility information
0697 
0698     /** Check-mode flag  [if true, more strict checks are performed]. */
0699     G4bool fCheck = false;
0700 
0701     /** Push flags  [if true, means a stuck particle has been pushed]. */
0702     G4bool fPushed = false, fWarnPush = true;
0703 
0704     // End -- Tracking Invariants
0705     // ========================================================================
0706 };
0707 
0708 #include "G4Navigator.icc"
0709 
0710 #endif
0711 
0712 
0713 // NOTES:
0714 //
0715 // The following methods provide detailed information when a Step has
0716 // arrived at a geometrical boundary.  They distinguish between the different
0717 // causes that can result in the track leaving its current volume.
0718 //
0719 // Four cases are possible:
0720 //
0721 // 1) The particle has reached a boundary of a daughter of the current volume:
0722 //     (this could cause the relocation to enter the daughter itself
0723 //     or a potential granddaughter or further descendant)
0724 //     
0725 // 2) The particle has reached a boundary of the current
0726 //     volume, exiting into a mother (regardless the level
0727 //     at which it is located in the tree):
0728 //
0729 // 3) The particle has reached a boundary of the current
0730 //     volume, exiting into a volume which is not in its
0731 //     parental hierarchy:
0732 //
0733 // 4) The particle is not on a boundary between volumes:
0734 //     the function returns an exception, and the caller is
0735 //     reccomended to compare the G4touchables associated
0736 //     to the preStepPoint and postStepPoint to handle this case.
0737 //
0738 //   G4bool        EnteredDaughterVolume()
0739 //   G4bool        IsExitNormalValid()
0740 //   G4ThreeVector GetLocalExitNormal()
0741 //
0742 // The expected usefulness of these methods is to allow the caller to
0743 // determine how to compute the surface normal at the volume boundary. The two
0744 // possibilities are to obtain the normal from:
0745 //
0746 //   i) the solid associated with the volume of the initial point of the Step.
0747 //      This is valid for cases 2 and 3.  
0748 //      (Note that the initial point is generally the PreStepPoint of a Step).
0749 //   or
0750 // 
0751 //  ii) the solid of the final point, ie of the volume after the relocation.
0752 //      This is valid for case 1.
0753 //      (Note that the final point is generally the PreStepPoint of a Step).
0754 //
0755 // This way the caller can always get a valid normal, pointing outside
0756 // the solid for which it is computed, that can be used at his own
0757 // discretion.