Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // GEANT4 tag $ Name: $ 27 // 28 // class G4ITSafetyHelper Implementation 29 // 30 // Original author: John Apostolakis, 2006 31 // 32 // -------------------------------------------------------------------- 33 34 #include "G4ITSafetyHelper.hh" 35 #include "G4ITPathFinder.hh" 36 #include "G4ITTransportationManager.hh" 37 #include "G4ITNavigator.hh" 38 #include "G4PathFinder.hh" 39 #include "globals.hh" 40 41 G4ITSafetyHelper::G4ITSafetyHelper() 42 { 43 fpPathFinder = nullptr; // Cannot initialise this yet - a loop results 44 45 // Initialization of the Navigator pointer is postponed, and must 46 // be undertaken by another class calling InitialiseHelper() 47 // 48 fpMassNavigator = nullptr; 49 fMassNavigatorId = -1; 50 } 51 52 void G4ITSafetyHelper::InitialiseNavigator() 53 { 54 fpPathFinder = G4PathFinder::GetInstance(); 55 56 G4ITTransportationManager* pTransportMgr = 57 G4ITTransportationManager::GetTransportationManager(); 58 59 fpMassNavigator = pTransportMgr->GetNavigatorForTracking(); 60 61 if(fpMassNavigator == nullptr) abort(); 62 63 // Check 64 // 65 G4VPhysicalVolume* worldPV = fpMassNavigator->GetWorldVolume(); 66 if (worldPV == nullptr) 67 { 68 G4Exception("G4ITSafetyHelper::InitialiseNavigator", 69 "InvalidNavigatorWorld", FatalException, 70 "Found that existing tracking Navigator has NULL world"); 71 } 72 73 // fMassNavigatorId = pTransportMgr->ActivateNavigator( fpMassNavigator ); 74 } 75 76 void G4ITSafetyHelper::InitialiseHelper() 77 { 78 NewTrackState(); 79 if (fFirstCall) 80 { 81 InitialiseNavigator(); 82 } 83 fFirstCall = false; 84 } 85 86 G4ITSafetyHelper::~G4ITSafetyHelper() 87 = default; 88 89 G4double G4ITSafetyHelper::CheckNextStep(const G4ThreeVector &position, 90 const G4ThreeVector &direction, 91 const G4double currentMaxStep, 92 G4double& newSafety) 93 { 94 // Distance in the Mass geometry 95 // 96 G4double linstep = fpMassNavigator->CheckNextStep(position, direction, 97 currentMaxStep, newSafety); 98 fpTrackState->fLastSafetyPosition = position; 99 fpTrackState->fLastSafety = newSafety; 100 101 // TODO: Can replace this with a call to PathFinder 102 // giving id of Mass Geometry --> this avoid doing the work twice 103 104 return linstep; 105 } 106 107 G4double G4ITSafetyHelper::ComputeSafety(const G4ThreeVector& position, 108 G4double maxLength) 109 { 110 G4double newSafety; 111 112 // Only recompute (calling Navigator/PathFinder) if 'position' 113 // is *not* the safety location and has moved 'significantly' 114 // 115 G4double moveLengthSq = (position - fpTrackState->fLastSafetyPosition).mag2(); 116 if ((moveLengthSq > 0.0)) 117 { 118 if (!fUseParallelGeometries) 119 { 120 // Safety for mass geometry 121 newSafety = fpMassNavigator->ComputeSafety(position, maxLength, true); 122 } 123 else 124 { 125 // Safety for all geometries 126 newSafety = fpPathFinder->ComputeSafety(position); 127 } 128 129 // We can only store a 'true' safety - one that was not restricted by maxLength 130 if (newSafety < maxLength) 131 { 132 fpTrackState->fLastSafety = newSafety; 133 fpTrackState->fLastSafetyPosition = position; 134 } 135 } 136 else 137 { 138 // return last value if position is not (significantly) changed 139 // 140 // G4double moveLength = 0; 141 // if( moveLengthSq > 0.0 ) { moveLength= std::sqrt(moveLengthSq); } 142 newSafety = fpTrackState->fLastSafety; // -moveLength; 143 } 144 return newSafety; 145 } 146 147 void G4ITSafetyHelper::ReLocateWithinVolume(const G4ThreeVector &newPosition) 148 { 149 #ifdef G4VERBOSE 150 if (fVerbose > 0) 151 { 152 // There is an opportunity - and need - to check whether the proposed move is safe 153 G4ThreeVector moveVec = newPosition - fpTrackState->fLastSafetyPosition; 154 if (moveVec.mag2() > sqr(fpTrackState->fLastSafety)) 155 { 156 // A problem exists - we are proposing to move outside 'Safety Sphere' 157 G4ExceptionDescription ed; 158 ed << " Safety Sphere: Radius = " << fpTrackState->fLastSafety; 159 ed << " Center = " << fpTrackState->fLastSafetyPosition << G4endl; 160 ed << " New Location : Move = " << moveVec.mag2(); 161 ed << " Position = " << newPosition << G4endl; 162 G4Exception("G4ITSafetyHelper::ReLocateWithinVolume", "GeomNav999", 163 JustWarning, 164 "Unsafe Move> Asked to relocate beyond 'Safety sphere'."); 165 } 166 } 167 #endif 168 169 if (!fUseParallelGeometries) 170 { 171 fpMassNavigator->LocateGlobalPointWithinVolume(newPosition); 172 } 173 else 174 { 175 fpPathFinder->ReLocate(newPosition); 176 } 177 } 178 179 void G4ITSafetyHelper::Locate(const G4ThreeVector& newPosition, 180 const G4ThreeVector& newDirection) 181 { 182 if (!fUseParallelGeometries) 183 { 184 fpMassNavigator->LocateGlobalPointAndSetup(newPosition, &newDirection, true, 185 false); 186 } 187 else 188 { 189 fpPathFinder->Locate(newPosition, newDirection); 190 } 191 } 192