|
||||
File indexing completed on 2025-01-18 09:58:32
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 // 0027 // Original author: Paul Kent, July 95/96 0028 // 0029 /// \brief { Class description: 0030 /// 0031 /// G4ITNavigator1 is a duplicate version of G4Navigator started from Geant4.9.5 0032 /// initially written by Paul Kent and colleagues. 0033 /// The only difference resides in the way the information is saved and managed 0034 /// 0035 /// A class for use by the tracking management, able to obtain/calculate 0036 /// dynamic tracking time information such as the distance to the next volume, 0037 /// or to find the physical volume containing a given point in the world 0038 /// reference system. The navigator maintains a transformation history and 0039 /// other information to optimise the tracking time performance.} 0040 // 0041 // Contact : Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) 0042 // 0043 // WARNING : This class is released as a prototype. 0044 // It might strongly evolve or even disapear in the next releases. 0045 // 0046 // We would be very happy hearing from you, send us your feedback! :) 0047 // 0048 // History: 0049 // - Created. Paul Kent, Jul 95/96 0050 // - Zero step protections J.A. / G.C., Nov 2004 0051 // - Added check mode G. Cosmo, Mar 2004 0052 // - Made Navigator Abstract G. Cosmo, Nov 2003 0053 // - G4ITNavigator1 created M.K., Nov 2012 0054 // ********************************************************************* 0055 0056 #ifndef G4ITNAVIGATOR_HH 0057 #define G4ITNAVIGATOR_HH 0058 0059 #include "geomdefs.hh" 0060 0061 #include "G4ThreeVector.hh" 0062 #include "G4AffineTransform.hh" 0063 #include "G4RotationMatrix.hh" 0064 0065 #include "G4LogicalVolume.hh" // Used in inline methods 0066 #include "G4TouchableHandle.hh" // " " 0067 0068 #include "G4NavigationHistory.hh" 0069 #include "G4NormalNavigation.hh" 0070 #include "G4VoxelNavigation.hh" 0071 #include "G4ParameterisedNavigation.hh" 0072 #include "G4ReplicaNavigation.hh" 0073 #include "G4RegularNavigation.hh" 0074 0075 #include <iostream> 0076 0077 class G4VPhysicalVolume; 0078 0079 0080 struct G4ITNavigatorState_Lock1 0081 { 0082 virtual ~G4ITNavigatorState_Lock1()= default; 0083 protected: 0084 G4ITNavigatorState_Lock1(){} 0085 }; 0086 0087 class G4ITNavigator1 0088 { 0089 public: 0090 static const G4int fMaxNav = 8; // rename to kMaxNoNav ?? 0091 0092 public: // with description 0093 0094 friend std::ostream& operator << (std::ostream &os, const G4ITNavigator1 &n); 0095 0096 G4ITNavigator1(); 0097 // Constructor - initialisers and setup. 0098 0099 virtual ~G4ITNavigator1(); 0100 // Destructor. No actions. 0101 0102 G4ITNavigator1(const G4ITNavigator1&) = delete; 0103 G4ITNavigator1& operator=(const G4ITNavigator1&) = delete; 0104 0105 // !> 0106 G4ITNavigatorState_Lock1* GetNavigatorState(); 0107 void SetNavigatorState(G4ITNavigatorState_Lock1*); 0108 void NewNavigatorState(); 0109 // <! 0110 0111 virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, 0112 const G4ThreeVector &pDirection, 0113 const G4double pCurrentProposedStepLength, 0114 G4double &pNewSafety); 0115 // Calculate the distance to the next boundary intersected 0116 // along the specified NORMALISED vector direction and 0117 // from the specified point in the global coordinate 0118 // system. LocateGlobalPointAndSetup or LocateGlobalPointWithinVolume 0119 // must have been called with the same global point prior to this call. 0120 // The isotropic distance to the nearest boundary is also 0121 // calculated (usually an underestimate). The current 0122 // proposed Step length is used to avoid intersection 0123 // calculations: if it can be determined that the nearest 0124 // boundary is >pCurrentProposedStepLength away, kInfinity 0125 // is returned together with the computed isotropic safety 0126 // distance. Geometry must be closed. 0127 0128 G4double CheckNextStep(const G4ThreeVector &pGlobalPoint, 0129 const G4ThreeVector &pDirection, 0130 const G4double pCurrentProposedStepLength, 0131 G4double &pNewSafety); 0132 // Same as above, but do not disturb the state of the Navigator. 0133 0134 virtual 0135 G4VPhysicalVolume* ResetHierarchyAndLocate(const G4ThreeVector &point, 0136 const G4ThreeVector &direction, 0137 const G4TouchableHistory &h); 0138 0139 // Resets the geometrical hierarchy and search for the volumes deepest 0140 // in the hierarchy containing the point in the global coordinate space. 0141 // The direction is used to check if a volume is entered. 0142 // The search begin is the geometrical hierarchy at the location of the 0143 // last located point, or the endpoint of the previous Step if 0144 // SetGeometricallyLimitedStep() has been called immediately before. 0145 // 0146 // Important Note: In order to call this the geometry MUST be closed. 0147 0148 virtual 0149 G4VPhysicalVolume* LocateGlobalPointAndSetup(const G4ThreeVector& point, 0150 const G4ThreeVector* direction=nullptr, 0151 const G4bool pRelativeSearch=true, 0152 const G4bool ignoreDirection=true); 0153 // Search the geometrical hierarchy for the volumes deepest in the hierarchy 0154 // containing the point in the global coordinate space. Two main cases are: 0155 // i) If pRelativeSearch=false it makes use of no previous/state 0156 // information. Returns the physical volume containing the point, 0157 // with all previous mothers correctly set up. 0158 // ii) If pRelativeSearch is set to true, the search begin is the 0159 // geometrical hierarchy at the location of the last located point, 0160 // or the endpoint of the previous Step if SetGeometricallyLimitedStep() 0161 // has been called immediately before. 0162 // The direction is used (to check if a volume is entered) if either 0163 // - the argument ignoreDirection is false, or 0164 // - the Navigator has determined that it is on an edge shared by two or 0165 // more volumes. (This is state information.) 0166 // 0167 // Important Note: In order to call this the geometry MUST be closed. 0168 0169 virtual 0170 void LocateGlobalPointWithinVolume(const G4ThreeVector& position); 0171 // Notify the Navigator that a track has moved to the new Global point 0172 // 'position', that is known to be within the current safety. 0173 // No check is performed to ensure that it is within the volume. 0174 // This method can be called instead of LocateGlobalPointAndSetup ONLY if 0175 // the caller is certain that the new global point (position) is inside the 0176 // same volume as the previous position. Usually this can be guaranteed 0177 // only if the point is within safety. 0178 0179 inline void LocateGlobalPointAndUpdateTouchableHandle( 0180 const G4ThreeVector& position, 0181 const G4ThreeVector& direction, 0182 G4TouchableHandle& oldTouchableToUpdate, 0183 const G4bool RelativeSearch = true); 0184 // First, search the geometrical hierarchy like the above method 0185 // LocateGlobalPointAndSetup(). Then use the volume found and its 0186 // navigation history to update the touchable. 0187 0188 inline void LocateGlobalPointAndUpdateTouchable( 0189 const G4ThreeVector& position, 0190 const G4ThreeVector& direction, 0191 G4VTouchable* touchableToUpdate, 0192 const G4bool RelativeSearch = true); 0193 // First, search the geometrical hierarchy like the above method 0194 // LocateGlobalPointAndSetup(). Then use the volume found and its 0195 // navigation history to update the touchable. 0196 0197 inline void LocateGlobalPointAndUpdateTouchable( 0198 const G4ThreeVector& position, 0199 G4VTouchable* touchableToUpdate, 0200 const G4bool RelativeSearch = true); 0201 // Same as the method above but missing direction. 0202 0203 inline void SetGeometricallyLimitedStep(); 0204 // Inform the navigator that the previous Step calculated 0205 // by the geometry was taken in its entirety. 0206 0207 virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, 0208 const G4double pProposedMaxLength = DBL_MAX, 0209 const G4bool keepState = true); 0210 // Calculate the isotropic distance to the nearest boundary from the 0211 // specified point in the global coordinate system. 0212 // The globalpoint utilised must be within the current volume. 0213 // The value returned is usually an underestimate. 0214 // The proposed maximum length is used to avoid volume safety 0215 // calculations. The geometry must be closed. 0216 // To ensure minimum side effects from the call, keepState 0217 // must be true. 0218 0219 inline G4VPhysicalVolume* GetWorldVolume() const; 0220 // Return the current world (`topmost') volume. 0221 0222 inline void SetWorldVolume(G4VPhysicalVolume* pWorld); 0223 // Set the world (`topmost') volume. This must be positioned at 0224 // origin (0,0,0) and unrotated. 0225 0226 inline G4TouchableHistory* CreateTouchableHistory() const; 0227 inline G4TouchableHistory* CreateTouchableHistory(const G4NavigationHistory*) const; 0228 // `Touchable' creation methods: caller has deletion responsibility. 0229 0230 virtual G4TouchableHandle CreateTouchableHistoryHandle() const; 0231 // Returns a reference counted handle to a touchable history. 0232 0233 virtual G4ThreeVector GetLocalExitNormal(G4bool* valid); 0234 virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector& point, 0235 G4bool* valid); 0236 virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector& point, 0237 G4bool* valid); 0238 // Return Exit Surface Normal and validity too. 0239 // Can only be called if the Navigator's last Step has crossed a 0240 // volume geometrical boundary. 0241 // It returns the Normal to the surface pointing out of the volume that 0242 // was left behind and/or into the volume that was entered. 0243 // Convention: 0244 // The *local* normal is in the coordinate system of the *final* volume. 0245 // Restriction: 0246 // Normals are not available for replica volumes (returns valid= false) 0247 // These methods takes full care about how to calculate this normal, 0248 // but if the surfaces are not convex it will return valid=false. 0249 0250 inline G4int GetVerboseLevel() const; 0251 inline void SetVerboseLevel(G4int level); 0252 // Get/Set Verbose(ness) level. 0253 // [if level>0 && G4VERBOSE, printout can occur] 0254 0255 inline G4bool IsActive() const; 0256 // Verify if the navigator is active. 0257 inline void Activate(G4bool flag); 0258 // Activate/inactivate the navigator. 0259 0260 inline G4bool EnteredDaughterVolume() const; 0261 // The purpose of this function is to inform the caller if the track is 0262 // entering a daughter volume while exiting from the current volume. 0263 // This method returns 0264 // - True only in case 1) above, that is when the Step has caused 0265 // the track to arrive at a boundary of a daughter. 0266 // - False in cases 2), 3) and 4), i.e. in all other cases. 0267 // This function is not guaranteed to work if SetGeometricallyLimitedStep() 0268 // was not called when it should have been called. 0269 inline G4bool ExitedMotherVolume() const; 0270 // Verify if the step has exited the mother volume. 0271 0272 inline void CheckMode(G4bool mode); 0273 // Run navigation in "check-mode", therefore using additional 0274 // verifications and more strict correctness conditions. 0275 // Is effective only with G4VERBOSE set. 0276 inline G4bool IsCheckModeActive() const; 0277 inline void SetPushVerbosity(G4bool mode); 0278 // Set/unset verbosity for pushed tracks (default is true). 0279 0280 void PrintState() const; 0281 // Print the internal state of the Navigator (for debugging). 0282 // The level of detail is according to the verbosity. 0283 0284 inline const G4AffineTransform& GetGlobalToLocalTransform() const; 0285 inline const G4AffineTransform GetLocalToGlobalTransform() const; 0286 // Obtain the transformations Global/Local (and inverse). 0287 // Clients of these methods must copy the data if they need to keep it. 0288 0289 G4AffineTransform GetMotherToDaughterTransform(G4VPhysicalVolume* dVolume, 0290 G4int dReplicaNo, 0291 EVolume dVolumeType ); 0292 // Obtain mother to daughter transformation 0293 0294 inline void ResetStackAndState(); 0295 // Reset stack and minimum or navigator state machine necessary for reset 0296 // as needed by LocalGlobalPointAndSetup. 0297 // [Does not perform clears, resizes, or reset fLastLocatedPointLocal] 0298 0299 inline G4int SeverityOfZeroStepping( G4int* noZeroSteps ) const; 0300 // Report on severity of error and number of zero steps, 0301 // in case Navigator is stuck and is returning zero steps. 0302 // Values: 1 (small problem), 5 (correcting), 0303 // 9 (ready to abandon), 10 (abandoned) 0304 0305 void SetSavedState(); 0306 // ( fValidExitNormal, fExitNormal, fExiting, fEntering, 0307 // fBlockedPhysicalVolume, fBlockedReplicaNo, fLastStepWasZero); 0308 void RestoreSavedState(); 0309 // Copy aspects of the state, to enable a non-state changing 0310 // call to ComputeStep 0311 0312 inline G4ThreeVector GetCurrentLocalCoordinate() const; 0313 // Return the local coordinate of the point in the reference system 0314 // of its containing volume that was found by LocalGlobalPointAndSetup. 0315 // The local coordinate of the last located track. 0316 0317 inline G4ThreeVector NetTranslation() const; 0318 inline G4RotationMatrix NetRotation() const; 0319 // Compute+return the local->global translation/rotation of current volume. 0320 0321 inline void EnableBestSafety( G4bool value= false ); 0322 // Enable best-possible evaluation of isotropic safety 0323 0324 virtual void ResetState(); 0325 // Utility method to reset the navigator state machine. 0326 0327 protected: // with description 0328 0329 inline G4ThreeVector ComputeLocalPoint(const G4ThreeVector& rGlobPoint) const; 0330 // Return position vector in local coordinate system, given a position 0331 // vector in world coordinate system. 0332 0333 inline G4ThreeVector ComputeLocalAxis(const G4ThreeVector& pVec) const; 0334 // Return the local direction of the specified vector in the reference 0335 // system of the volume that was found by LocalGlobalPointAndSetup. 0336 // The Local Coordinates of point in world coordinate system. 0337 0338 inline EVolume VolumeType(const G4VPhysicalVolume *pVol) const; 0339 // Characterise `type' of volume - normal/replicated/parameterised. 0340 0341 inline EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const; 0342 // Characterise daughter of logical volume. 0343 0344 inline G4int GetDaughtersRegularStructureId(const G4LogicalVolume *pLog) const; 0345 // Get regular structure ID of first daughter 0346 0347 virtual void SetupHierarchy(); 0348 // Renavigate & reset hierarchy described by current history 0349 // o Reset volumes 0350 // o Recompute transforms and/or solids of replicated/parameterised 0351 // volumes. 0352 0353 private: 0354 0355 void ComputeStepLog(const G4ThreeVector& pGlobalpoint, 0356 G4double moveLenSq) const; 0357 // Log and checks for steps larger than the tolerance 0358 0359 protected: // without description 0360 0361 G4double kCarTolerance; 0362 // Geometrical tolerance for surface thickness of shapes. 0363 0364 // 0365 // BEGIN State information 0366 // 0367 0368 G4NavigationHistory fHistory; 0369 // Transformation and history of the current path 0370 // through the geometrical hierarchy. 0371 0372 G4bool fEnteredDaughter; 0373 // A memory of whether in this Step a daughter volume is entered 0374 // (set in Compute & Locate). 0375 // After Compute: it expects to enter a daughter 0376 // After Locate: it has entered a daughter 0377 0378 G4bool fExitedMother; 0379 // A similar memory whether the Step exited current "mother" volume 0380 // completely, not entering daughter. 0381 0382 G4bool fWasLimitedByGeometry{false}; 0383 // Set true if last Step was limited by geometry. 0384 0385 G4ThreeVector fStepEndPoint; 0386 // Endpoint of last ComputeStep 0387 // can be used for optimisation (e.g. when computing safety). 0388 G4ThreeVector fLastStepEndPointLocal; 0389 // Position of the end-point of the last call to ComputeStep 0390 // in last Local coordinates. 0391 0392 G4int fVerbose{0}; 0393 // Verbose(ness) level [if > 0, printout can occur]. 0394 0395 private: 0396 0397 G4bool fActive; 0398 // States if the navigator is activated or not. 0399 0400 G4bool fLastTriedStepComputation; 0401 // Whether ComputeStep was called since the last call to a Locate method 0402 // Uses: - distinguish parts of state which differ before/after calls 0403 // to ComputeStep or one of the Locate methods; 0404 // - avoid two consecutive calls to compute-step (illegal). 0405 0406 G4bool fEntering,fExiting; 0407 // Entering/Exiting volumes blocking/setup 0408 // o If exiting 0409 // volume ptr & replica number (set & used by Locate..()) 0410 // used for blocking on redescent of geometry 0411 // o If entering 0412 // volume ptr & replica number (set by ComputeStep(),used by 0413 // Locate..()) of volume for `automatic' entry 0414 0415 G4VPhysicalVolume *fBlockedPhysicalVolume; 0416 G4int fBlockedReplicaNo; 0417 0418 G4ThreeVector fLastLocatedPointLocal; 0419 // Position of the last located point relative to its containing volume. 0420 G4bool fLocatedOutsideWorld; 0421 // Whether the last call to Locate methods left the world 0422 0423 G4bool fValidExitNormal; // Set true if have leaving volume normal 0424 G4ThreeVector fExitNormal; // Leaving volume normal, in the 0425 // volume containing the exited 0426 // volume's coordinate system 0427 G4ThreeVector fGrandMotherExitNormal; // Leaving volume normal, in its 0428 // own coordinate system 0429 G4bool fChangedGrandMotherRefFrame; // Whether frame is changed 0430 0431 G4ThreeVector fExitNormalGlobalFrame; // Leaving volume normal, in the 0432 // global coordinate system 0433 G4bool fCalculatedExitNormal; // Has it been computed since 0434 // the last call to ComputeStep 0435 // Covers both Global and GrandMother 0436 0437 // Count zero steps - as one or two can occur due to changing momentum at 0438 // a boundary or at an edge common between volumes 0439 // - several are likely a problem in the geometry 0440 // description or in the navigation 0441 // 0442 G4bool fLastStepWasZero; 0443 // Whether the last ComputeStep moved Zero. Used to check for edges. 0444 0445 G4bool fLocatedOnEdge; 0446 // Whether the Navigator has detected an edge 0447 G4int fNumberZeroSteps; 0448 // Number of preceding moves that were Zero. Reset to 0 after finite step 0449 G4int fActionThreshold_NoZeroSteps; 0450 // After this many failed/zero steps, act (push etc) 0451 G4int fAbandonThreshold_NoZeroSteps; 0452 // After this many failed/zero steps, abandon track 0453 0454 G4ThreeVector fPreviousSftOrigin; 0455 G4double fPreviousSafety; 0456 // Memory of last safety origin & value. Used in ComputeStep to ensure 0457 // that origin of current Step is in the same volume as the point of the 0458 // last relocation 0459 0460 // 0461 // END State information 0462 // 0463 0464 // Save key state information (NOT the navigation history stack) 0465 // 0466 struct G4SaveNavigatorState : public G4ITNavigatorState_Lock1 0467 { 0468 G4SaveNavigatorState(); 0469 ~G4SaveNavigatorState() override= default; 0470 G4ThreeVector sExitNormal; 0471 G4bool sValidExitNormal; 0472 G4bool sEntering, sExiting; 0473 G4VPhysicalVolume* spBlockedPhysicalVolume; 0474 G4int sBlockedReplicaNo; 0475 G4int sLastStepWasZero; 0476 0477 // !> 0478 G4bool sLocatedOnEdge; 0479 G4bool sWasLimitedByGeometry; 0480 G4bool sPushed; 0481 G4int sNumberZeroSteps; 0482 // <! 0483 0484 // Potentially relevant 0485 // 0486 G4bool sLocatedOutsideWorld; 0487 G4ThreeVector sLastLocatedPointLocal; 0488 G4bool sEnteredDaughter, sExitedMother; 0489 G4ThreeVector sPreviousSftOrigin; 0490 G4double sPreviousSafety; 0491 } ; 0492 0493 G4SaveNavigatorState* fpSaveState; 0494 0495 0496 // Tracking Invariants 0497 // 0498 G4VPhysicalVolume *fTopPhysical{nullptr}; 0499 // A link to the topmost physical volume in the detector. 0500 // Must be positioned at the origin and unrotated. 0501 0502 // Utility information 0503 // 0504 G4bool fCheck{false}; 0505 // Check-mode flag [if true, more strict checks are performed]. 0506 G4bool fPushed{false}, fWarnPush{true}; 0507 // Push flags [if true, means a stuck particle has been pushed]. 0508 0509 // Helpers/Utility classes 0510 // 0511 G4NormalNavigation fnormalNav; 0512 G4VoxelNavigation fvoxelNav; 0513 G4ParameterisedNavigation fparamNav; 0514 G4ReplicaNavigation freplicaNav; 0515 G4RegularNavigation fregularNav; 0516 G4VoxelSafety *fpVoxelSafety; 0517 }; 0518 0519 #include "G4ITNavigator1.icc" 0520 0521 #endif 0522 0523 0524 // NOTES: 0525 // 0526 // The following methods provide detailed information when a Step has 0527 // arrived at a geometrical boundary. They distinguish between the different 0528 // causes that can result in the track leaving its current volume. 0529 // 0530 // Four cases are possible: 0531 // 0532 // 1) The particle has reached a boundary of a daughter of the current volume: 0533 // (this could cause the relocation to enter the daughter itself 0534 // or a potential granddaughter or further descendant) 0535 // 0536 // 2) The particle has reached a boundary of the current 0537 // volume, exiting into a mother (regardless the level 0538 // at which it is located in the tree): 0539 // 0540 // 3) The particle has reached a boundary of the current 0541 // volume, exiting into a volume which is not in its 0542 // parental hierarchy: 0543 // 0544 // 4) The particle is not on a boundary between volumes: 0545 // the function returns an exception, and the caller is 0546 // reccomended to compare the G4touchables associated 0547 // to the preStepPoint and postStepPoint to handle this case. 0548 // 0549 // G4bool EnteredDaughterVolume() 0550 // G4bool IsExitNormalValid() 0551 // G4ThreeVector GetLocalExitNormal() 0552 // 0553 // The expected usefulness of these methods is to allow the caller to 0554 // determine how to compute the surface normal at the volume boundary. The two 0555 // possibilities are to obtain the normal from: 0556 // 0557 // i) the solid associated with the volume of the initial point of the Step. 0558 // This is valid for cases 2 and 3. 0559 // (Note that the initial point is generally the PreStepPoint of a Step). 0560 // or 0561 // 0562 // ii) the solid of the final point, ie of the volume after the relocation. 0563 // This is valid for case 1. 0564 // (Note that the final point is generally the PreStepPoint of a Step). 0565 // 0566 // This way the caller can always get a valid normal, pointing outside 0567 // the solid for which it is computed, that can be used at his own 0568 // discretion.
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |