00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 // 00027 // $Id$ 00028 // 00029 // 00030 // class G4MultiNavigator 00031 // 00032 // Class description: 00033 // 00034 // Utility class for polling the navigators of several geometries to 00035 // identify the next boundary. 00036 00037 // History: 00038 // - Created. John Apostolakis, November 2006 00039 // ********************************************************************* 00040 00041 #ifndef G4MULTINAVIGATOR_HH 00042 #define G4MULTINAVIGATOR_HH 00043 00044 #include <iostream> 00045 00046 #include "geomdefs.hh" 00047 #include "G4ThreeVector.hh" 00048 #include "G4Navigator.hh" 00049 00050 #include "G4TouchableHistoryHandle.hh" 00051 00052 #include "G4NavigationHistory.hh" 00053 00054 enum ELimited { kDoNot,kUnique,kSharedTransport,kSharedOther,kUndefLimited }; 00055 00056 class G4TransportationManager; 00057 class G4VPhysicalVolume; 00058 00059 class G4MultiNavigator : public G4Navigator 00060 { 00061 public: // with description 00062 00063 friend std::ostream& operator << (std::ostream &os, const G4Navigator &n); 00064 00065 G4MultiNavigator(); 00066 // Constructor - initialisers and setup. 00067 00068 ~G4MultiNavigator(); 00069 // Destructor. No actions. 00070 00071 G4double ComputeStep(const G4ThreeVector &pGlobalPoint, 00072 const G4ThreeVector &pDirection, 00073 const G4double pCurrentProposedStepLength, 00074 G4double &pNewSafety); 00075 // Return the distance to the next boundary of any geometry 00076 00077 G4double ObtainFinalStep( G4int navigatorId, 00078 G4double &pNewSafety, // for this geom 00079 G4double &minStepLast, 00080 ELimited &limitedStep); 00081 // Get values for a single geometry 00082 00083 void PrepareNavigators(); 00084 // Find which geometries are registered for this particles, and keep info 00085 void PrepareNewTrack( const G4ThreeVector position, 00086 const G4ThreeVector direction ); 00087 // Prepare Navigators and locate 00088 00089 G4VPhysicalVolume* ResetHierarchyAndLocate(const G4ThreeVector &point, 00090 const G4ThreeVector &direction, 00091 const G4TouchableHistory &h); 00092 // Reset the geometrical hierarchy for all geometries. 00093 // Use the touchable history for the first (mass) geometry. 00094 // Return the volume in the first (mass) geometry. 00095 // 00096 // Important Note: In order to call this the geometries MUST be closed. 00097 00098 G4VPhysicalVolume* LocateGlobalPointAndSetup(const G4ThreeVector& point, 00099 const G4ThreeVector* direction=0, 00100 const G4bool pRelativeSearch=true, 00101 const G4bool ignoreDirection=true); 00102 // Locate in all geometries. 00103 // Return the volume in the first (mass) geometry 00104 // Maintain vector of other volumes, to be returned separately 00105 // 00106 // Important Note: In order to call this the geometry MUST be closed. 00107 00108 void LocateGlobalPointWithinVolume(const G4ThreeVector& position); 00109 // Relocate in all geometries for point that has not changed volume 00110 // (ie is within safety in all geometries or is distance less that 00111 // along the direction of a computed step. 00112 00113 G4double ComputeSafety(const G4ThreeVector &globalpoint, 00114 const G4double pProposedMaxLength = DBL_MAX, 00115 const G4bool keepState = false); 00116 // Calculate the isotropic distance to the nearest boundary 00117 // in any geometry from the specified point in the global coordinate 00118 // system. The geometry must be closed. 00119 00120 G4TouchableHistoryHandle CreateTouchableHistoryHandle() const; 00121 // Returns a reference counted handle to a touchable history. 00122 00123 virtual G4ThreeVector GetLocalExitNormal(G4bool* obtained); // const 00124 virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &CurrentE_Point, 00125 G4bool* obtained); // const 00126 virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &CurrentE_Point, 00127 G4bool* obtained); // const 00128 // Return Exit Surface Normal and validity too. 00129 // Can only be called if the Navigator's last Step either 00130 // - has just crossed a volume geometrical boundary and relocated, or 00131 // - has arrived at a boundary in a ComputeStep 00132 // It returns the Normal to the surface pointing out of the volume that 00133 // was left behind and/or into the volume that was entered. 00134 // Convention:x 00135 // The *local* normal is in the coordinate system of the *final* volume. 00136 // Restriction: 00137 // Normals are not available for replica volumes (returns obtained= false) 00138 00139 public: // without description 00140 00141 G4Navigator* GetNavigator(G4int n) const 00142 { 00143 if( (n>fNoActiveNavigators)||(n<0)){ n=0; } 00144 return fpNavigator[n]; 00145 } 00146 00147 protected: // with description 00148 00149 void ResetState(); 00150 // Utility method to reset the navigator state machine. 00151 00152 void SetupHierarchy(); 00153 // Renavigate & reset hierarchy described by current history 00154 // o Reset volumes 00155 // o Recompute transforms and/or solids of replicated/parameterised 00156 // volumes. 00157 00158 void WhichLimited(); // Flag which processes limited the step 00159 void PrintLimited(); // Auxiliary, debugging printing 00160 void CheckMassWorld(); 00161 00162 private: 00163 00164 // STATE Information 00165 00166 G4int fNoActiveNavigators; 00167 static const G4int fMaxNav = 8; // rename to kMaxNoNav ?? 00168 G4VPhysicalVolume* fLastMassWorld; 00169 00170 // Global state (retained during stepping for one track 00171 G4Navigator* fpNavigator[fMaxNav]; // G4Navigator** fpNavigator; 00172 00173 // State after a step computation 00174 ELimited fLimitedStep[fMaxNav]; 00175 G4bool fLimitTruth[fMaxNav]; 00176 G4double fCurrentStepSize[fMaxNav]; 00177 G4double fNewSafety[ fMaxNav ]; // Safety for starting point 00178 G4int fNoLimitingStep; // How many geometries limited the step 00179 G4int fIdNavLimiting; // Id of Navigator limiting step (if only one limits) 00180 00181 // Lowest values - determine step length, and safety 00182 G4double fMinStep; // As reported by Navigators. Can be kInfinity 00183 G4double fMinSafety; 00184 G4double fTrueMinStep; // Corrected in case fMinStep >= proposed 00185 00186 // State after calling 'locate' 00187 G4VPhysicalVolume* fLocatedVolume[fMaxNav]; 00188 G4ThreeVector fLastLocatedPosition; 00189 00190 // cache of safety information 00191 G4ThreeVector fSafetyLocation; // point where ComputeSafety is called 00192 G4double fMinSafety_atSafLocation; // /\ corresponding value of safety 00193 G4ThreeVector fPreStepLocation; // point where last ComputeStep called 00194 G4double fMinSafety_PreStepPt; // /\ corresponding value of safety 00195 00196 G4TransportationManager* pTransportManager; // Cache for frequent use 00197 }; 00198 00199 #endif