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