// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // // // class G4ITMultiNavigator // // Class description: // // Utility class for polling the navigators of several geometries to // identify the next boundary. /// \brief { Class description: /// /// G4ITMultiNavigator is a duplicate version of G4MultiNavigator /// /// Utility class for polling the navigators of several geometries to /// identify the next boundary. /// /// } // History: // - Created. John Apostolakis, November 2006 // ********************************************************************* #ifndef G4ITMULTINAVIGATOR_HH #define G4ITMULTINAVIGATOR_HH #include #include "geomdefs.hh" #include "G4ThreeVector.hh" #include "G4ITNavigator.hh" #include "G4TouchableHandle.hh" #include "G4NavigationHistory.hh" #include "G4TrackState.hh" #include "G4MultiNavigator.hh" namespace G4ITMN { enum ELimited { kDoNot, kUnique, kSharedTransport, kSharedOther, kUndefLimited }; } class G4ITTransportationManager; class G4VPhysicalVolume; class G4ITMultiNavigator; // Global state (retained during stepping for one track template<> class G4TrackState : public G4TrackState { public: ~G4TrackState() override = default; G4TrackState() { G4ThreeVector Big3Vector(kInfinity, kInfinity, kInfinity); fLastLocatedPosition = Big3Vector; fSafetyLocation = Big3Vector; fPreStepLocation = Big3Vector; fMinSafety_PreStepPt = -1.0; fMinSafety_atSafLocation = -1.0; fMinSafety = -kInfinity; fTrueMinStep = fMinStep = -kInfinity; for (G4int num = 0; num < G4ITNavigator::fMaxNav; ++num) { fLimitTruth[num] = false; fLimitedStep[num] = kUndefLimited; fCurrentStepSize[num] = fNewSafety[num] = -1.0; fLocatedVolume[num] = nullptr; } fNoLimitingStep = -1; // How many geometries limited the step fIdNavLimiting = -1; // Id of Navigator limiting step (if only one limits) fWasLimitedByGeometry = false; } ; protected: friend class G4ITMultiNavigator; // State after a step computation ELimited fLimitedStep[G4ITNavigator::fMaxNav]; G4bool fLimitTruth[G4ITNavigator::fMaxNav]; G4double fCurrentStepSize[G4ITNavigator::fMaxNav]; G4double fNewSafety[G4ITNavigator::fMaxNav]; // Safety for starting point G4int fNoLimitingStep; // How many geometries limited the step G4int fIdNavLimiting; // Id of Navigator limiting step (if only one limits) G4bool fWasLimitedByGeometry; // Lowest values - determine step length, and safety G4double fMinStep; // As reported by Navigators. Can be kInfinity G4double fMinSafety; G4double fTrueMinStep; // Corrected in case fMinStep >= proposed // State after calling 'locate' G4VPhysicalVolume* fLocatedVolume[G4ITNavigator::fMaxNav]; G4ThreeVector fLastLocatedPosition; // cache of safety information G4ThreeVector fSafetyLocation; // point where ComputeSafety is called G4double fMinSafety_atSafLocation; // /\ corresponding value of safety G4ThreeVector fPreStepLocation; // point where last ComputeStep called G4double fMinSafety_PreStepPt; // /\ corresponding value of safety }; class G4ITMultiNavigator : public G4ITNavigator, public G4TrackStateDependent { public: // with description friend std::ostream& operator <<(std::ostream &os, const G4ITNavigator &n); G4ITMultiNavigator(); // Constructor - initialisers and setup. ~G4ITMultiNavigator() override; // Destructor. No actions. G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety) override; // Return the distance to the next boundary of any geometry G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, // for this geom G4double &minStepLast, ELimited &limitedStep); // Get values for a single geometry void PrepareNavigators(); // Find which geometries are registered for this particles, and keep info void PrepareNewTrack(const G4ThreeVector position, const G4ThreeVector direction); // Prepare Navigators and locate G4VPhysicalVolume* ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h) override; // Reset the geometrical hierarchy for all geometries. // Use the touchable history for the first (mass) geometry. // Return the volume in the first (mass) geometry. // // Important Note: In order to call this the geometries MUST be closed. G4VPhysicalVolume* LocateGlobalPointAndSetup(const G4ThreeVector& point, const G4ThreeVector* direction = nullptr, const G4bool pRelativeSearch = true, const G4bool ignoreDirection = true) override; // Locate in all geometries. // Return the volume in the first (mass) geometry // Maintain vector of other volumes, to be returned separately // // Important Note: In order to call this the geometry MUST be closed. void LocateGlobalPointWithinVolume(const G4ThreeVector& position) override; // Relocate in all geometries for point that has not changed volume // (ie is within safety in all geometries or is distance less that // along the direction of a computed step. G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength = DBL_MAX, const G4bool keepState = false) override; // Calculate the isotropic distance to the nearest boundary // in any geometry from the specified point in the global coordinate // system. The geometry must be closed. G4TouchableHandle CreateTouchableHistoryHandle() const override; // Returns a reference counted handle to a touchable history. G4ThreeVector GetLocalExitNormal(G4bool* obtained) override;// const G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &CurrentE_Point, G4bool* obtained) override;// const G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &CurrentE_Point, G4bool* obtained) override;// const // Return Exit Surface Normal and validity too. // Can only be called if the Navigator's last Step either // - has just crossed a volume geometrical boundary and relocated, or // - has arrived at a boundary in a ComputeStep // It returns the Normal to the surface pointing out of the volume that // was left behind and/or into the volume that was entered. // Convention:x // The *local* normal is in the coordinate system of the *final* volume. // Restriction: // Normals are not available for replica volumes (returns obtained= false) public:// without description G4ITNavigator* GetNavigator(G4int n) const { if( (n>fNoActiveNavigators)||(n<0)) { n=0;} return fpNavigator[n]; } protected: // with description void ResetState() override; // Utility method to reset the navigator state machine. void SetupHierarchy() override; // Renavigate & reset hierarchy described by current history // o Reset volumes // o Recompute transforms and/or solids of replicated/parameterised // volumes. void WhichLimited();// Flag which processes limited the step void PrintLimited();// Auxiliary, debugging printing void CheckMassWorld(); private: G4int fNoActiveNavigators; G4VPhysicalVolume* fLastMassWorld{nullptr}; G4ITNavigator* fpNavigator[fMaxNav];// G4ITNavigator** fpNavigator; G4ITTransportationManager* pTransportManager;// Cache for frequent use }; #endif