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 // 26 // 27 // GEANT4 tag $ Name: $ 27 // GEANT4 tag $ Name: $ 28 // 28 // 29 // class G4PathFinder Implementation 29 // class G4PathFinder Implementation 30 // 30 // 31 // Author: John Apostolakis, November 2006 31 // Author: John Apostolakis, November 2006 32 // ------------------------------------------- 32 // -------------------------------------------------------------------- 33 33 34 #include <iomanip> 34 #include <iomanip> 35 35 36 #include "G4ITMultiNavigator.hh" 36 #include "G4ITMultiNavigator.hh" 37 37 38 class G4FieldManager; 38 class G4FieldManager; 39 39 40 #include "G4SystemOfUnits.hh" 40 #include "G4SystemOfUnits.hh" 41 #include "G4ITNavigator.hh" 41 #include "G4ITNavigator.hh" 42 #include "G4PropagatorInField.hh" 42 #include "G4PropagatorInField.hh" 43 #include "G4ITTransportationManager.hh" 43 #include "G4ITTransportationManager.hh" 44 44 45 #define State(X) fpTrackState->X 45 #define State(X) fpTrackState->X 46 #define fLimitedStep State(fLimitedStep) 46 #define fLimitedStep State(fLimitedStep) 47 #define fLimitTruth State(fLimitTruth) 47 #define fLimitTruth State(fLimitTruth) 48 #define fCurrentStepSize State(fCurrentStepSiz 48 #define fCurrentStepSize State(fCurrentStepSize) 49 #define fNewSafety State(fNewSafety) 49 #define fNewSafety State(fNewSafety) 50 #define fNoLimitingStep State(fNoLimitingStep) 50 #define fNoLimitingStep State(fNoLimitingStep) 51 #define fIdNavLimiting State(fIdNavLimiting) 51 #define fIdNavLimiting State(fIdNavLimiting) 52 #define fMinStep State(fMinStep) 52 #define fMinStep State(fMinStep) 53 #define fMinSafety State(fMinSafety) 53 #define fMinSafety State(fMinSafety) 54 #define fTrueMinStep State(fTrueMinStep) 54 #define fTrueMinStep State(fTrueMinStep) 55 #define fLocatedVolume State(fLocatedVolume) 55 #define fLocatedVolume State(fLocatedVolume) 56 #define fLastLocatedPosition State(fLastLocate 56 #define fLastLocatedPosition State(fLastLocatedPosition) 57 #define fSafetyLocation State(fSafetyLocation) 57 #define fSafetyLocation State(fSafetyLocation) 58 #define fMinSafety_atSafLocation State(fMinSaf 58 #define fMinSafety_atSafLocation State(fMinSafety_atSafLocation) 59 #define fPreStepLocation State(fPreStepLocatio 59 #define fPreStepLocation State(fPreStepLocation) 60 #define fMinSafety_PreStepPt State(fMinSafety_ 60 #define fMinSafety_PreStepPt State(fMinSafety_PreStepPt) 61 #define fWasLimitedByGeometry State(fWasLimite 61 #define fWasLimitedByGeometry State(fWasLimitedByGeometry) 62 62 63 // ******************************************* 63 // ******************************************************************** 64 // Constructor 64 // Constructor 65 // ******************************************* 65 // ******************************************************************** 66 // 66 // 67 G4ITMultiNavigator::G4ITMultiNavigator() 67 G4ITMultiNavigator::G4ITMultiNavigator() 68 { 68 { 69 fNoActiveNavigators= 0; 69 fNoActiveNavigators= 0; 70 70 71 for(auto & num : fpNavigator) 71 for(auto & num : fpNavigator) 72 { 72 { 73 num = nullptr; 73 num = nullptr; 74 } 74 } 75 75 76 pTransportManager= G4ITTransportationManager 76 pTransportManager= G4ITTransportationManager::GetTransportationManager(); 77 77 78 G4ITNavigator* massNav= pTransportManager->G 78 G4ITNavigator* massNav= pTransportManager->GetNavigatorForTracking(); 79 if( massNav != nullptr ) 79 if( massNav != nullptr ) 80 { 80 { 81 G4VPhysicalVolume* pWorld= massNav->GetWor 81 G4VPhysicalVolume* pWorld= massNav->GetWorldVolume(); 82 if( pWorld != nullptr ) 82 if( pWorld != nullptr ) 83 { 83 { 84 SetWorldVolume( pWorld ); 84 SetWorldVolume( pWorld ); 85 fLastMassWorld = pWorld; 85 fLastMassWorld = pWorld; 86 } 86 } 87 } 87 } 88 } 88 } 89 89 90 G4ITMultiNavigator::~G4ITMultiNavigator() 90 G4ITMultiNavigator::~G4ITMultiNavigator() 91 = default; 91 = default; 92 92 93 G4double G4ITMultiNavigator::ComputeStep(const 93 G4double G4ITMultiNavigator::ComputeStep(const G4ThreeVector &pGlobalPoint, 94 const G 94 const G4ThreeVector &pDirection, 95 const G 95 const G4double proposedStepLength, 96 G 96 G4double &pNewSafety) 97 { 97 { 98 G4double safety= 0.0, step=0.0; 98 G4double safety= 0.0, step=0.0; 99 G4double minSafety= kInfinity, minStep= kInf 99 G4double minSafety= kInfinity, minStep= kInfinity; 100 100 101 fNoLimitingStep= -1; 101 fNoLimitingStep= -1; 102 fIdNavLimiting= -1; // Reset for new ste 102 fIdNavLimiting= -1; // Reset for new step 103 103 104 #ifdef G4DEBUG_NAVIGATION 104 #ifdef G4DEBUG_NAVIGATION 105 if( fVerbose > 2 ) 105 if( fVerbose > 2 ) 106 { 106 { 107 G4cout << " G4ITMultiNavigator::ComputeSte 107 G4cout << " G4ITMultiNavigator::ComputeStep : entered " << G4endl; 108 G4cout << " Input position= " << pGlobal 108 G4cout << " Input position= " << pGlobalPoint 109 << " direction= " << pDirect 109 << " direction= " << pDirection << G4endl; 110 G4cout << " Requested step= " << propose 110 G4cout << " Requested step= " << proposedStepLength << G4endl; 111 } 111 } 112 #endif 112 #endif 113 113 114 std::vector<G4ITNavigator*>::iterator pNavig 114 std::vector<G4ITNavigator*>::iterator pNavigatorIter; 115 115 116 pNavigatorIter= pTransportManager-> GetActiv 116 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 117 117 118 G4ThreeVector initialPosition = pGlobalPoint 118 G4ThreeVector initialPosition = pGlobalPoint; 119 G4ThreeVector initialDirection= pDirection; 119 G4ThreeVector initialDirection= pDirection; 120 120 121 for( G4int num=0; num< fNoActiveNavigators; 121 for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 122 { 122 { 123 safety= kInfinity; 123 safety= kInfinity; 124 124 125 step= (*pNavigatorIter)->ComputeStep( ini 125 step= (*pNavigatorIter)->ComputeStep( initialPosition, 126 ini 126 initialDirection, 127 pro 127 proposedStepLength, 128 saf 128 safety ); 129 if( safety < minSafety ){ minSafety = saf 129 if( safety < minSafety ){ minSafety = safety; } 130 if( step < minStep ) { minStep= step; 130 if( step < minStep ) { minStep= step; } 131 131 132 fCurrentStepSize[num] = step; 132 fCurrentStepSize[num] = step; 133 fNewSafety[num]= safety; 133 fNewSafety[num]= safety; 134 // This is currently the safety from the 134 // This is currently the safety from the last sub-step 135 135 136 #ifdef G4DEBUG_NAVIGATION 136 #ifdef G4DEBUG_NAVIGATION 137 if( fVerbose > 2 ) 137 if( fVerbose > 2 ) 138 { 138 { 139 G4cout << "G4ITMultiNavigator::ComputeS 139 G4cout << "G4ITMultiNavigator::ComputeStep : Navigator [" 140 << num << "] -- step size " << s 140 << num << "] -- step size " << step 141 << " safety= " << safety << G4en 141 << " safety= " << safety << G4endl; 142 } 142 } 143 #endif 143 #endif 144 } 144 } 145 145 146 // Save safety value, related position 146 // Save safety value, related position 147 // 147 // 148 fPreStepLocation = initialPosition; 148 fPreStepLocation = initialPosition; 149 fMinSafety_PreStepPt = minSafety; 149 fMinSafety_PreStepPt = minSafety; 150 fMinStep = minStep; 150 fMinStep = minStep; 151 151 152 if( fMinStep == kInfinity ) 152 if( fMinStep == kInfinity ) 153 { 153 { 154 fTrueMinStep = proposedStepLength; // 154 fTrueMinStep = proposedStepLength; // Use this below for endpoint !! 155 } 155 } 156 else 156 else 157 { 157 { 158 fTrueMinStep = minStep; 158 fTrueMinStep = minStep; 159 } 159 } 160 160 161 #ifdef G4DEBUG_NAVIGATION 161 #ifdef G4DEBUG_NAVIGATION 162 if( fVerbose > 1 ) 162 if( fVerbose > 1 ) 163 { 163 { 164 G4ThreeVector endPosition = initialPositio 164 G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection; 165 165 166 G4int oldPrec = G4cout.precision(8); 166 G4int oldPrec = G4cout.precision(8); 167 G4cout << "G4ITMultiNavigator::ComputeStep 167 G4cout << "G4ITMultiNavigator::ComputeStep : " 168 << " initialPosition = " << initial 168 << " initialPosition = " << initialPosition 169 << " and endPosition = " << endPosi 169 << " and endPosition = " << endPosition << G4endl; 170 G4cout.precision( oldPrec ); 170 G4cout.precision( oldPrec ); 171 } 171 } 172 #endif 172 #endif 173 173 174 pNewSafety = minSafety; 174 pNewSafety = minSafety; 175 175 176 this->WhichLimited(); 176 this->WhichLimited(); 177 177 178 #ifdef G4DEBUG_NAVIGATION 178 #ifdef G4DEBUG_NAVIGATION 179 if( fVerbose > 2 ) 179 if( fVerbose > 2 ) 180 { 180 { 181 G4cout << " G4ITMultiNavigator::ComputeSte 181 G4cout << " G4ITMultiNavigator::ComputeStep : exits returning " 182 << minStep << G4endl; 182 << minStep << G4endl; 183 } 183 } 184 #endif 184 #endif 185 185 186 return minStep; // must return kInfinity if 186 return minStep; // must return kInfinity if do not limit step 187 } 187 } 188 188 189 // ------------------------------------------- 189 // ---------------------------------------------------------------------- 190 190 191 G4double 191 G4double 192 G4ITMultiNavigator::ObtainFinalStep( G4int 192 G4ITMultiNavigator::ObtainFinalStep( G4int navigatorId, 193 G4double &p 193 G4double &pNewSafety, // for this geometry 194 G4double &m 194 G4double &minStep, 195 ELimited &l 195 ELimited &limitedStep) 196 { 196 { 197 if( navigatorId > fNoActiveNavigators ) 197 if( navigatorId > fNoActiveNavigators ) 198 { 198 { 199 std::ostringstream message; 199 std::ostringstream message; 200 message << "Bad Navigator Id!" << G4endl 200 message << "Bad Navigator Id!" << G4endl 201 << " Navigator Id = " << n 201 << " Navigator Id = " << navigatorId 202 << " No Active = " << fNoA 202 << " No Active = " << fNoActiveNavigators << "."; 203 G4Exception("G4ITMultiNavigator::ObtainFi 203 G4Exception("G4ITMultiNavigator::ObtainFinalStep()", "GeomNav0002", 204 FatalException, message); 204 FatalException, message); 205 } 205 } 206 206 207 // Prepare the information to return 207 // Prepare the information to return 208 // 208 // 209 pNewSafety = fNewSafety[ navigatorId ]; 209 pNewSafety = fNewSafety[ navigatorId ]; 210 limitedStep = fLimitedStep[ navigatorId ]; 210 limitedStep = fLimitedStep[ navigatorId ]; 211 minStep= fMinStep; 211 minStep= fMinStep; 212 212 213 #ifdef G4DEBUG_NAVIGATION 213 #ifdef G4DEBUG_NAVIGATION 214 if( fVerbose > 1 ) 214 if( fVerbose > 1 ) 215 { 215 { 216 G4cout << " G4ITMultiNavigator::ComputeSt 216 G4cout << " G4ITMultiNavigator::ComputeStep returns " 217 << fCurrentStepSize[ navigatorId ] 217 << fCurrentStepSize[ navigatorId ] 218 << " for Navigator " << navigatorI 218 << " for Navigator " << navigatorId 219 << " Limited step = " << limitedSt 219 << " Limited step = " << limitedStep 220 << " Safety(mm) = " << pNewSafety 220 << " Safety(mm) = " << pNewSafety / mm << G4endl; 221 } 221 } 222 #endif 222 #endif 223 223 224 return fCurrentStepSize[ navigatorId ]; 224 return fCurrentStepSize[ navigatorId ]; 225 } 225 } 226 226 227 // ------------------------------------------- 227 // ---------------------------------------------------------------------- 228 228 229 void G4ITMultiNavigator::PrepareNewTrack( cons 229 void G4ITMultiNavigator::PrepareNewTrack( const G4ThreeVector position, 230 const 230 const G4ThreeVector direction ) 231 { 231 { 232 #ifdef G4DEBUG_NAVIGATION 232 #ifdef G4DEBUG_NAVIGATION 233 if( fVerbose > 1 ) 233 if( fVerbose > 1 ) 234 { 234 { 235 G4cout << " Entered G4ITMultiNavigator::Pr 235 G4cout << " Entered G4ITMultiNavigator::PrepareNewTrack() " << G4endl; 236 } 236 } 237 #endif 237 #endif 238 238 239 G4ITMultiNavigator::PrepareNavigators(); 239 G4ITMultiNavigator::PrepareNavigators(); 240 240 241 LocateGlobalPointAndSetup( position, &direct 241 LocateGlobalPointAndSetup( position, &direction, false, false ); 242 // 242 // 243 // The first location for each Navigator mus 243 // The first location for each Navigator must be non-relative 244 // or else call ResetStackAndState() for eac 244 // or else call ResetStackAndState() for each Navigator 245 // Use direction to get correct side of boun 245 // Use direction to get correct side of boundary (ignore dir= false) 246 } 246 } 247 247 248 // ------------------------------------------- 248 // ---------------------------------------------------------------------- 249 249 250 void G4ITMultiNavigator::PrepareNavigators() 250 void G4ITMultiNavigator::PrepareNavigators() 251 { 251 { 252 // Key purposes: 252 // Key purposes: 253 // - Check and cache set of active navigat 253 // - Check and cache set of active navigators 254 // - Reset state for new track 254 // - Reset state for new track 255 255 256 #ifdef G4DEBUG_NAVIGATION 256 #ifdef G4DEBUG_NAVIGATION 257 if( fVerbose > 1 ) 257 if( fVerbose > 1 ) 258 { 258 { 259 G4cout << " Entered G4ITMultiNavigator::Pr 259 G4cout << " Entered G4ITMultiNavigator::PrepareNavigators() " << G4endl; 260 } 260 } 261 #endif 261 #endif 262 262 263 // Message the transportation-manager to fin 263 // Message the transportation-manager to find active navigators 264 264 265 std::vector<G4ITNavigator*>::iterator pNavig 265 std::vector<G4ITNavigator*>::iterator pNavigatorIter; 266 fNoActiveNavigators = (G4int)pTransportManag 266 fNoActiveNavigators = (G4int)pTransportManager-> GetNoActiveNavigators(); 267 267 268 if( fNoActiveNavigators > fMaxNav ) 268 if( fNoActiveNavigators > fMaxNav ) 269 { 269 { 270 std::ostringstream message; 270 std::ostringstream message; 271 message << "Too many active Navigators / w 271 message << "Too many active Navigators / worlds !" << G4endl 272 << " Active Navigators (wor 272 << " Active Navigators (worlds): " 273 << fNoActiveNavigators << G4endl 273 << fNoActiveNavigators << G4endl 274 << " which is more than the 274 << " which is more than the number allowed: " 275 << fMaxNav << " !"; 275 << fMaxNav << " !"; 276 G4Exception("G4ITMultiNavigator::PrepareNa 276 G4Exception("G4ITMultiNavigator::PrepareNavigators()", "GeomNav0002", 277 FatalException, message); 277 FatalException, message); 278 } 278 } 279 279 280 pNavigatorIter= pTransportManager-> GetActiv 280 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 281 for( G4int num=0; num< fNoActiveNavigators; 281 for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 282 { 282 { 283 fpNavigator[num] = *pNavigatorIter; 283 fpNavigator[num] = *pNavigatorIter; 284 fLimitTruth[num] = false; 284 fLimitTruth[num] = false; 285 fLimitedStep[num] = kDoNot; 285 fLimitedStep[num] = kDoNot; 286 fCurrentStepSize[num] = 0.0; 286 fCurrentStepSize[num] = 0.0; 287 fLocatedVolume[num] = nullptr; 287 fLocatedVolume[num] = nullptr; 288 } 288 } 289 fWasLimitedByGeometry = false; 289 fWasLimitedByGeometry = false; 290 290 291 // Check the world volume of the mass naviga 291 // Check the world volume of the mass navigator 292 // in case a call to SetWorldVolume() change 292 // in case a call to SetWorldVolume() changed it 293 293 294 G4VPhysicalVolume* massWorld = GetWorldVolum 294 G4VPhysicalVolume* massWorld = GetWorldVolume(); 295 295 296 if( (massWorld != fLastMassWorld) && (massWo 296 if( (massWorld != fLastMassWorld) && (massWorld!=nullptr) ) 297 { 297 { 298 // Pass along change to Mass Navigator 298 // Pass along change to Mass Navigator 299 fpNavigator[0] -> SetWorldVolume( massWor 299 fpNavigator[0] -> SetWorldVolume( massWorld ); 300 300 301 #ifdef G4DEBUG_NAVIGATION 301 #ifdef G4DEBUG_NAVIGATION 302 if( fVerbose > 0 ) 302 if( fVerbose > 0 ) 303 { 303 { 304 G4cout << " G4ITMultiNavigator::Prepare 304 G4cout << " G4ITMultiNavigator::PrepareNavigators() changed world volume " 305 << " for mass geometry to " << m 305 << " for mass geometry to " << massWorld->GetName() << G4endl; 306 } 306 } 307 #endif 307 #endif 308 308 309 fLastMassWorld = massWorld; 309 fLastMassWorld = massWorld; 310 } 310 } 311 } 311 } 312 312 313 // ------------------------------------------- 313 // ---------------------------------------------------------------------- 314 314 315 G4VPhysicalVolume* 315 G4VPhysicalVolume* 316 G4ITMultiNavigator::LocateGlobalPointAndSetup( 316 G4ITMultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position, 317 co 317 const G4ThreeVector* pDirection, 318 co 318 const G4bool pRelativeSearch, 319 co 319 const G4bool ignoreDirection ) 320 { 320 { 321 // Locate the point in each geometry 321 // Locate the point in each geometry 322 322 323 G4ThreeVector direction(0.0, 0.0, 0.0); 323 G4ThreeVector direction(0.0, 0.0, 0.0); 324 G4bool relative = pRelativeSearch; 324 G4bool relative = pRelativeSearch; 325 auto pNavIter 325 auto pNavIter 326 = pTransportManager->GetActiveNavigatorsIt 326 = pTransportManager->GetActiveNavigatorsIterator(); 327 327 328 if( pDirection != nullptr ) { direction = *p 328 if( pDirection != nullptr ) { direction = *pDirection; } 329 329 330 #ifdef G4DEBUG_NAVIGATION 330 #ifdef G4DEBUG_NAVIGATION 331 if( fVerbose > 2 ) 331 if( fVerbose > 2 ) 332 { 332 { 333 G4cout << " Entered G4ITMultiNavigator::Lo 333 G4cout << " Entered G4ITMultiNavigator::LocateGlobalPointAndSetup() " 334 << G4endl; 334 << G4endl; 335 G4cout << " Locating at position: " << p 335 G4cout << " Locating at position: " << position 336 << ", with direction: " << directio 336 << ", with direction: " << direction << G4endl 337 << " Relative: " << relative 337 << " Relative: " << relative 338 << ", ignore direction: " << ignore 338 << ", ignore direction: " << ignoreDirection << G4endl; 339 G4cout << " Number of active navigators: 339 G4cout << " Number of active navigators: " << fNoActiveNavigators 340 << G4endl; 340 << G4endl; 341 } 341 } 342 #endif 342 #endif 343 343 344 for ( G4int num=0; num< fNoActiveNavigators 344 for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 345 { 345 { 346 if( fWasLimitedByGeometry && fLimitTruth[ 346 if( fWasLimitedByGeometry && fLimitTruth[num] ) 347 { 347 { 348 (*pNavIter)->SetGeometricallyLimitedSt 348 (*pNavIter)->SetGeometricallyLimitedStep(); 349 } 349 } 350 350 351 G4VPhysicalVolume *pLocated 351 G4VPhysicalVolume *pLocated 352 = (*pNavIter)->LocateGlobalPointAndSetu 352 = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction, 353 353 relative, ignoreDirection ); 354 // Set the state related to the location 354 // Set the state related to the location 355 // 355 // 356 fLocatedVolume[num] = pLocated; 356 fLocatedVolume[num] = pLocated; 357 357 358 // Clear state related to the step 358 // Clear state related to the step 359 // 359 // 360 fLimitedStep[num] = kDoNot; 360 fLimitedStep[num] = kDoNot; 361 fCurrentStepSize[num] = 0.0; 361 fCurrentStepSize[num] = 0.0; 362 fLimitTruth[ num ] = false; // Always c 362 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator) 363 363 364 #ifdef G4DEBUG_NAVIGATION 364 #ifdef G4DEBUG_NAVIGATION 365 if( fVerbose > 2 ) 365 if( fVerbose > 2 ) 366 { 366 { 367 G4cout << " Located in world: " << num 367 G4cout << " Located in world: " << num << ", at: " << position << G4endl 368 << " Used geomLimStp: " << fLimi 368 << " Used geomLimStp: " << fLimitTruth[num] 369 << ", found in volume: " << pLoc 369 << ", found in volume: " << pLocated << G4endl; 370 G4cout << " Name = '" ; 370 G4cout << " Name = '" ; 371 if( pLocated ) 371 if( pLocated ) 372 { 372 { 373 G4cout << pLocated->GetName() << "'"; 373 G4cout << pLocated->GetName() << "'"; 374 G4cout << " - CopyNo= " << pLocated-> 374 G4cout << " - CopyNo= " << pLocated->GetCopyNo(); 375 } 375 } 376 else 376 else 377 { 377 { 378 G4cout << "Null' Id: Not-Set "; 378 G4cout << "Null' Id: Not-Set "; 379 } 379 } 380 G4cout << G4endl; 380 G4cout << G4endl; 381 } 381 } 382 #endif 382 #endif 383 } 383 } 384 384 385 fWasLimitedByGeometry = false; // Clear on 385 fWasLimitedByGeometry = false; // Clear on locating 386 G4VPhysicalVolume* volMassLocated= fLocatedV 386 G4VPhysicalVolume* volMassLocated= fLocatedVolume[0]; 387 387 388 return volMassLocated; 388 return volMassLocated; 389 } 389 } 390 390 391 // ------------------------------------------- 391 // ---------------------------------------------------------------------- 392 392 393 void 393 void 394 G4ITMultiNavigator::LocateGlobalPointWithinVol 394 G4ITMultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position) 395 { 395 { 396 // Relocate the point in each geometry 396 // Relocate the point in each geometry 397 397 398 auto pNavIter 398 auto pNavIter 399 = pTransportManager->GetActiveNavigatorsIt 399 = pTransportManager->GetActiveNavigatorsIterator(); 400 400 401 #ifdef G4DEBUG_NAVIGATION 401 #ifdef G4DEBUG_NAVIGATION 402 if( fVerbose > 2 ) 402 if( fVerbose > 2 ) 403 { 403 { 404 G4cout << " Entered G4ITMultiNavigator::Re 404 G4cout << " Entered G4ITMultiNavigator::ReLocate() " << G4endl 405 << " Re-locating at position: " << 405 << " Re-locating at position: " << position << G4endl; 406 } 406 } 407 #endif 407 #endif 408 408 409 for ( G4int num=0; num< fNoActiveNavigators 409 for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 410 { 410 { 411 // ... none limited the step 411 // ... none limited the step 412 412 413 (*pNavIter)->LocateGlobalPointWithinVolum 413 (*pNavIter)->LocateGlobalPointWithinVolume( position ); 414 414 415 // Clear state related to the step 415 // Clear state related to the step 416 // 416 // 417 fLimitedStep[num] = kDoNot; 417 fLimitedStep[num] = kDoNot; 418 fCurrentStepSize[num] = 0.0; 418 fCurrentStepSize[num] = 0.0; 419 419 420 fLimitTruth[ num ] = false; // Always c 420 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator) 421 } 421 } 422 fWasLimitedByGeometry = false; // Clear on 422 fWasLimitedByGeometry = false; // Clear on locating 423 fLastLocatedPosition = position; 423 fLastLocatedPosition = position; 424 } 424 } 425 425 426 // ------------------------------------------- 426 // ---------------------------------------------------------------------- 427 427 428 G4double G4ITMultiNavigator::ComputeSafety( co 428 G4double G4ITMultiNavigator::ComputeSafety( const G4ThreeVector& position, 429 cons 429 const G4double maxDistance, 430 cons 430 const G4bool state) 431 { 431 { 432 // Recompute safety for the relevant point 432 // Recompute safety for the relevant point 433 433 434 G4double minSafety = kInfinity, safety = k 434 G4double minSafety = kInfinity, safety = kInfinity; 435 435 436 std::vector<G4ITNavigator*>::iterator pNav 436 std::vector<G4ITNavigator*>::iterator pNavigatorIter; 437 pNavigatorIter= pTransportManager-> GetAct 437 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 438 438 439 for( G4int num=0; num< fNoActiveNavigators 439 for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 440 { 440 { 441 safety = (*pNavigatorIter)->ComputeSafe 441 safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state); 442 if( safety < minSafety ) { minSafety = 442 if( safety < minSafety ) { minSafety = safety; } 443 } 443 } 444 444 445 fSafetyLocation = position; 445 fSafetyLocation = position; 446 fMinSafety_atSafLocation = minSafety; 446 fMinSafety_atSafLocation = minSafety; 447 447 448 #ifdef G4DEBUG_NAVIGATION 448 #ifdef G4DEBUG_NAVIGATION 449 if( fVerbose > 1 ) 449 if( fVerbose > 1 ) 450 { 450 { 451 G4cout << " G4ITMultiNavigator::ComputeS 451 G4cout << " G4ITMultiNavigator::ComputeSafety - returns: " 452 << minSafety << ", at location: " 452 << minSafety << ", at location: " << position << G4endl; 453 } 453 } 454 #endif 454 #endif 455 return minSafety; 455 return minSafety; 456 } 456 } 457 457 458 // ------------------------------------------- 458 // ----------------------------------------------------------------------- 459 459 460 G4TouchableHandle G4ITMultiNavigator::CreateT 460 G4TouchableHandle G4ITMultiNavigator::CreateTouchableHistoryHandle() const 461 { 461 { 462 G4Exception( "G4ITMultiNavigator::CreateTouc 462 G4Exception( "G4ITMultiNavigator::CreateTouchableHistoryHandle()", 463 "GeomNav0001", FatalException, 463 "GeomNav0001", FatalException, 464 "Getting a touchable from G4ITM 464 "Getting a touchable from G4ITMultiNavigator is not defined."); 465 465 466 G4TouchableHistory* touchHist; 466 G4TouchableHistory* touchHist; 467 touchHist= fpNavigator[0] -> CreateTouchable 467 touchHist= fpNavigator[0] -> CreateTouchableHistory(); 468 468 469 G4VPhysicalVolume* locatedVolume= fLocatedVo 469 G4VPhysicalVolume* locatedVolume= fLocatedVolume[0]; 470 if( locatedVolume == nullptr ) 470 if( locatedVolume == nullptr ) 471 { 471 { 472 // Workaround to ensure that the touchable 472 // Workaround to ensure that the touchable is fixed !! // TODO: fix 473 // 473 // 474 touchHist->UpdateYourself( locatedVolume, 474 touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() ); 475 } 475 } 476 476 477 return G4TouchableHandle(touchHist); 477 return G4TouchableHandle(touchHist); 478 } 478 } 479 479 480 // ------------------------------------------- 480 // ----------------------------------------------------------------------- 481 481 482 void G4ITMultiNavigator::WhichLimited() 482 void G4ITMultiNavigator::WhichLimited() 483 { 483 { 484 // Flag which processes limited the step 484 // Flag which processes limited the step 485 485 486 G4int last=-1; 486 G4int last=-1; 487 const G4int IdTransport= 0; // Id of Mass N 487 const G4int IdTransport= 0; // Id of Mass Navigator !! 488 G4int noLimited=0; 488 G4int noLimited=0; 489 ELimited shared= kSharedOther; 489 ELimited shared= kSharedOther; 490 490 491 #ifdef G4DEBUG_NAVIGATION 491 #ifdef G4DEBUG_NAVIGATION 492 if( fVerbose > 2 ) 492 if( fVerbose > 2 ) 493 { 493 { 494 G4cout << " Entered G4ITMultiNavigator::Wh 494 G4cout << " Entered G4ITMultiNavigator::WhichLimited() " << G4endl; 495 } 495 } 496 #endif 496 #endif 497 497 498 // Assume that [IdTransport] is Mass / Trans 498 // Assume that [IdTransport] is Mass / Transport 499 // 499 // 500 G4bool transportLimited = (fCurrentStepSize[ 500 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep) 501 && ( fMinStep!= kInfi 501 && ( fMinStep!= kInfinity); 502 if( transportLimited ) 502 if( transportLimited ) 503 { 503 { 504 shared= kSharedTransport; 504 shared= kSharedTransport; 505 } 505 } 506 506 507 for ( G4int num= 0; num < fNoActiveNavigator 507 for ( G4int num= 0; num < fNoActiveNavigators; num++ ) 508 { 508 { 509 G4bool limitedStep; 509 G4bool limitedStep; 510 510 511 G4double step= fCurrentStepSize[num]; 511 G4double step= fCurrentStepSize[num]; 512 512 513 limitedStep = ( step == fMinStep ) && ( st 513 limitedStep = ( step == fMinStep ) && ( step != kInfinity); 514 514 515 fLimitTruth[ num ] = limitedStep; 515 fLimitTruth[ num ] = limitedStep; 516 if( limitedStep ) 516 if( limitedStep ) 517 { 517 { 518 noLimited++; 518 noLimited++; 519 fLimitedStep[num] = shared; 519 fLimitedStep[num] = shared; 520 last= num; 520 last= num; 521 } 521 } 522 else 522 else 523 { 523 { 524 fLimitedStep[num] = kDoNot; 524 fLimitedStep[num] = kDoNot; 525 } 525 } 526 } 526 } 527 if( (last > -1) && (noLimited == 1 ) ) 527 if( (last > -1) && (noLimited == 1 ) ) 528 { 528 { 529 fLimitedStep[ last ] = kUnique; 529 fLimitedStep[ last ] = kUnique; 530 } 530 } 531 531 532 fNoLimitingStep= noLimited; 532 fNoLimitingStep= noLimited; 533 533 534 return; 534 return; 535 } 535 } 536 536 537 // ------------------------------------------- 537 // ----------------------------------------------------------------------- 538 538 539 void 539 void 540 G4ITMultiNavigator::PrintLimited() 540 G4ITMultiNavigator::PrintLimited() 541 { 541 { 542 // Report results -- for checking 542 // Report results -- for checking 543 543 544 static const G4String StrDoNot("DoNot"), Str 544 static const G4String StrDoNot("DoNot"), StrUnique("Unique"), 545 StrUndefined("Undefined"), 545 StrUndefined("Undefined"), 546 StrSharedTransport("SharedTr 546 StrSharedTransport("SharedTransport"), 547 StrSharedOther("SharedOther" 547 StrSharedOther("SharedOther"); 548 G4cout << "### G4ITMultiNavigator::PrintLimi 548 G4cout << "### G4ITMultiNavigator::PrintLimited() reports: " << G4endl; 549 G4cout << " Minimum step (true): " << fTr 549 G4cout << " Minimum step (true): " << fTrueMinStep 550 << ", reported min: " << fMinStep << 550 << ", reported min: " << fMinStep << G4endl; 551 551 552 #ifdef G4DEBUG_NAVIGATION 552 #ifdef G4DEBUG_NAVIGATION 553 if(fVerbose>=2) 553 if(fVerbose>=2) 554 { 554 { 555 G4cout << std::setw(5) << " NavId" << " " 555 G4cout << std::setw(5) << " NavId" << " " 556 << std::setw(12) << " step-size " < 556 << std::setw(12) << " step-size " << " " 557 << std::setw(12) << " raw-size " < 557 << std::setw(12) << " raw-size " << " " 558 << std::setw(12) << " pre-safety " 558 << std::setw(12) << " pre-safety " << " " 559 << std::setw(15) << " Limited / fla 559 << std::setw(15) << " Limited / flag" << " " 560 << std::setw(15) << " World " << 560 << std::setw(15) << " World " << " " 561 << G4endl; 561 << G4endl; 562 } 562 } 563 #endif 563 #endif 564 564 565 for ( G4int num= 0; num < fNoActiveNavigator 565 for ( G4int num= 0; num < fNoActiveNavigators; num++ ) 566 { 566 { 567 G4double rawStep = fCurrentStepSize[num]; 567 G4double rawStep = fCurrentStepSize[num]; 568 G4double stepLen = fCurrentStepSize[num]; 568 G4double stepLen = fCurrentStepSize[num]; 569 if( stepLen > fTrueMinStep ) 569 if( stepLen > fTrueMinStep ) 570 { 570 { 571 stepLen = fTrueMinStep; // did not l 571 stepLen = fTrueMinStep; // did not limit (went as far as asked) 572 } 572 } 573 G4long oldPrec= G4cout.precision(9); 573 G4long oldPrec= G4cout.precision(9); 574 574 575 G4cout << std::setw(5) << num << " " 575 G4cout << std::setw(5) << num << " " 576 << std::setw(12) << stepLen << " " 576 << std::setw(12) << stepLen << " " 577 << std::setw(12) << rawStep << " " 577 << std::setw(12) << rawStep << " " 578 << std::setw(12) << fNewSafety[num] 578 << std::setw(12) << fNewSafety[num] << " " 579 << std::setw(5) << (fLimitTruth[num 579 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " "; 580 G4String limitedStr; 580 G4String limitedStr; 581 switch ( fLimitedStep[num] ) 581 switch ( fLimitedStep[num] ) 582 { 582 { 583 case kDoNot : limitedStr= StrDo 583 case kDoNot : limitedStr= StrDoNot; break; 584 case kUnique : limitedStr = StrU 584 case kUnique : limitedStr = StrUnique; break; 585 case kSharedTransport: limitedStr= StrSh 585 case kSharedTransport: limitedStr= StrSharedTransport; break; 586 case kSharedOther : limitedStr = StrS 586 case kSharedOther : limitedStr = StrSharedOther; break; 587 default : limitedStr = StrU 587 default : limitedStr = StrUndefined; break; 588 } 588 } 589 G4cout << " " << std::setw(15) << limitedS 589 G4cout << " " << std::setw(15) << limitedStr << " "; 590 G4cout.precision(oldPrec); 590 G4cout.precision(oldPrec); 591 591 592 G4ITNavigator *pNav= fpNavigator[ num ]; 592 G4ITNavigator *pNav= fpNavigator[ num ]; 593 G4String WorldName( "Not-Set" ); 593 G4String WorldName( "Not-Set" ); 594 if (pNav != nullptr) 594 if (pNav != nullptr) 595 { 595 { 596 G4VPhysicalVolume *pWorld= pNav->GetWor 596 G4VPhysicalVolume *pWorld= pNav->GetWorldVolume(); 597 if( pWorld != nullptr ) 597 if( pWorld != nullptr ) 598 { 598 { 599 WorldName = pWorld->GetName(); 599 WorldName = pWorld->GetName(); 600 } 600 } 601 } 601 } 602 G4cout << " " << WorldName ; 602 G4cout << " " << WorldName ; 603 G4cout << G4endl; 603 G4cout << G4endl; 604 } 604 } 605 } 605 } 606 606 607 607 608 // ------------------------------------------- 608 // ----------------------------------------------------------------------- 609 609 610 void G4ITMultiNavigator::ResetState() 610 void G4ITMultiNavigator::ResetState() 611 { 611 { 612 fWasLimitedByGeometry= false; 612 fWasLimitedByGeometry= false; 613 613 614 G4Exception("G4ITMultiNavigator::ResetState 614 G4Exception("G4ITMultiNavigator::ResetState()", "GeomNav0001", 615 FatalException, 615 FatalException, 616 "Cannot reset state for navigat 616 "Cannot reset state for navigators of G4ITMultiNavigator."); 617 617 618 std::vector<G4ITNavigator*>::iterator pNavi 618 std::vector<G4ITNavigator*>::iterator pNavigatorIter; 619 pNavigatorIter= pTransportManager-> GetActi 619 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 620 for( G4int num=0; num< fNoActiveNavigators; 620 for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 621 { 621 { 622 // (*pNavigatorIter)->ResetState(); / 622 // (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!! 623 } 623 } 624 } 624 } 625 625 626 // ------------------------------------------- 626 // ----------------------------------------------------------------------- 627 627 628 void G4ITMultiNavigator::SetupHierarchy() 628 void G4ITMultiNavigator::SetupHierarchy() 629 { 629 { 630 G4Exception( "G4ITMultiNavigator::SetupHiera 630 G4Exception( "G4ITMultiNavigator::SetupHierarchy()", 631 "GeomNav0001", FatalException, 631 "GeomNav0001", FatalException, 632 "Cannot setup hierarchy for nav 632 "Cannot setup hierarchy for navigators of G4ITMultiNavigator."); 633 } 633 } 634 634 635 // ------------------------------------------- 635 // ----------------------------------------------------------------------- 636 636 637 void G4ITMultiNavigator::CheckMassWorld() 637 void G4ITMultiNavigator::CheckMassWorld() 638 { 638 { 639 G4VPhysicalVolume* navTrackWorld= 639 G4VPhysicalVolume* navTrackWorld= 640 pTransportManager->GetNavigatorForTrackin 640 pTransportManager->GetNavigatorForTracking()->GetWorldVolume(); 641 641 642 if( navTrackWorld != fLastMassWorld ) 642 if( navTrackWorld != fLastMassWorld ) 643 { 643 { 644 G4Exception( "G4ITMultiNavigator::CheckM 644 G4Exception( "G4ITMultiNavigator::CheckMassWorld()", 645 "GeomNav0003", FatalExcepti 645 "GeomNav0003", FatalException, 646 "Mass world pointer has bee 646 "Mass world pointer has been changed." ); 647 } 647 } 648 } 648 } 649 649 650 // ------------------------------------------- 650 // ----------------------------------------------------------------------- 651 651 652 G4VPhysicalVolume* 652 G4VPhysicalVolume* 653 G4ITMultiNavigator::ResetHierarchyAndLocate(co 653 G4ITMultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point, 654 cons 654 const G4ThreeVector &direction, 655 cons 655 const G4TouchableHistory &MassHistory) 656 { 656 { 657 // Reset geometry for all -- and use the to 657 // Reset geometry for all -- and use the touchable for the mass history 658 658 659 G4VPhysicalVolume* massVolume=nullptr; 659 G4VPhysicalVolume* massVolume=nullptr; 660 G4ITNavigator* pMassNavigator= fpNavigator[ 660 G4ITNavigator* pMassNavigator= fpNavigator[0]; 661 661 662 if( pMassNavigator != nullptr ) 662 if( pMassNavigator != nullptr ) 663 { 663 { 664 massVolume= pMassNavigator->ResetHierarc 664 massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction, 665 665 MassHistory); 666 } 666 } 667 else 667 else 668 { 668 { 669 G4Exception("G4ITMultiNavigator::ResetHi 669 G4Exception("G4ITMultiNavigator::ResetHierarchyAndLocate()", 670 "GeomNav0002", FatalExceptio 670 "GeomNav0002", FatalException, 671 "Cannot reset hierarchy befo 671 "Cannot reset hierarchy before navigators are initialised."); 672 } 672 } 673 673 674 auto pNavIter= 674 auto pNavIter= 675 pTransportManager->GetActiveNavigatorsI 675 pTransportManager->GetActiveNavigatorsIterator(); 676 676 677 for ( G4int num=0; num< fNoActiveNavigators 677 for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 678 { 678 { 679 G4bool relativeSearch, ignoreDirection; 679 G4bool relativeSearch, ignoreDirection; 680 680 681 (*pNavIter)-> LocateGlobalPointAndSetup( 681 (*pNavIter)-> LocateGlobalPointAndSetup( point, 682 682 &direction, 683 683 relativeSearch=false, 684 684 ignoreDirection=false); 685 } 685 } 686 return massVolume; 686 return massVolume; 687 } 687 } 688 688 689 // ----------------- ooooooOOOOOOOOOOOOOOOooo 689 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo ------------------------------------- 690 690 691 G4ThreeVector 691 G4ThreeVector 692 G4ITMultiNavigator::GetGlobalExitNormal(const 692 G4ITMultiNavigator::GetGlobalExitNormal(const G4ThreeVector &argPoint, 693 G4bool* 693 G4bool* argpObtained) // obtained valid 694 { 694 { 695 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0) 695 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0); 696 G4bool isObtained= false; 696 G4bool isObtained= false; 697 // These default values will be used if fNoL 697 // These default values will be used if fNoLimitingStep== 0 698 G4int firstNavigatorId= -1; 698 G4int firstNavigatorId= -1; 699 G4bool oneObtained= false; 699 G4bool oneObtained= false; 700 700 701 if( fNoLimitingStep==1 ) 701 if( fNoLimitingStep==1 ) 702 { 702 { 703 // Only message the Navigator which limite 703 // Only message the Navigator which limited the step! 704 normalGlobalCrd= fpNavigator[ fIdNavLimiti 704 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetGlobalExitNormal( argPoint, &isObtained); 705 *argpObtained= isObtained; 705 *argpObtained= isObtained; 706 } 706 } 707 else 707 else 708 { 708 { 709 if( fNoLimitingStep > 1 ) 709 if( fNoLimitingStep > 1 ) 710 { 710 { 711 auto pNavIter= 711 auto pNavIter= 712 pTransportManager->GetActiveNavigators 712 pTransportManager->GetActiveNavigatorsIterator(); 713 713 714 for ( G4int num=0; num< fNoActiveNavigat 714 for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 715 { 715 { 716 G4ThreeVector oneNormal; 716 G4ThreeVector oneNormal; 717 if( fLimitTruth[ num ] ) // Did this 717 if( fLimitTruth[ num ] ) // Did this geometry limit the step ? 718 { 718 { 719 G4ThreeVector newNormal= (*pNavIter) 719 G4ThreeVector newNormal= (*pNavIter)-> GetGlobalExitNormal( argPoint, &oneObtained ); 720 if( oneObtained ) 720 if( oneObtained ) 721 { 721 { 722 // Keep first one - only if it is 722 // Keep first one - only if it is valid (ie not null) 723 if( !isObtained && (newNormal.mag2 723 if( !isObtained && (newNormal.mag2() != 0.0) ) 724 { 724 { 725 normalGlobalCrd= newNormal; 725 normalGlobalCrd= newNormal; 726 isObtained = oneObtained; 726 isObtained = oneObtained; 727 firstNavigatorId= num; 727 firstNavigatorId= num; 728 }else{ 728 }else{ 729 // Check for clash 729 // Check for clash 730 G4double dotNewPrevious= newNorm 730 G4double dotNewPrevious= newNormal.dot( normalGlobalCrd ); 731 G4double productMagSq= normalGlo 731 G4double productMagSq= normalGlobalCrd.mag2() * newNormal.mag2(); 732 if( productMagSq > 0.0 ) 732 if( productMagSq > 0.0 ) 733 { 733 { 734 G4double productMag= std::sqrt 734 G4double productMag= std::sqrt( productMagSq ); 735 dotNewPrevious /= productMag; 735 dotNewPrevious /= productMag; // Normalise 736 if( dotNewPrevious < (1 - perT 736 if( dotNewPrevious < (1 - perThousand) ) 737 { 737 { 738 *argpObtained= false; 738 *argpObtained= false; 739 739 740 if( fVerbose > 2 ) // dotN 740 if( fVerbose > 2 ) // dotNewPrevious <= 0.0 ) 741 { 741 { 742 std::ostringstream message 742 std::ostringstream message; 743 message << "Clash of Norma 743 message << "Clash of Normal from different Navigators!" << G4endl 744 << " Previo 744 << " Previous Navigator Id = " << firstNavigatorId << G4endl 745 << " Curren 745 << " Current Navigator Id = " << num << G4endl; 746 message << " Dot product 746 message << " Dot product of 2 normals = " << dotNewPrevious << G4endl; 747 message << " Normal 747 message << " Normal (previous) = " << normalGlobalCrd << G4endl; 748 message << " Normal 748 message << " Normal (current) = " << newNormal << G4endl; 749 G4Exception("G4ITMultiNavi 749 G4Exception("G4ITMultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 750 JustWarning, m 750 JustWarning, message); 751 } 751 } 752 } 752 } 753 else 753 else 754 { 754 { 755 // Close agreement - Do not 755 // Close agreement - Do not change 756 } 756 } 757 } 757 } 758 } 758 } 759 } 759 } 760 } 760 } 761 } // end for over the Navigators 761 } // end for over the Navigators 762 762 763 // Report if no Normal was obtained 763 // Report if no Normal was obtained 764 if( !oneObtained ) 764 if( !oneObtained ) 765 { 765 { 766 std::ostringstream message; 766 std::ostringstream message; 767 message << "No Normal obtained despite 767 message << "No Normal obtained despite having " << fNoLimitingStep 768 << " candidate Navigators limi 768 << " candidate Navigators limiting the step!" << G4endl; 769 G4Exception("G4ITMultiNavigator::GetGl 769 G4Exception("G4ITMultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 770 JustWarning, message); 770 JustWarning, message); 771 } 771 } 772 772 773 } // end if ( fNoLimiting > 1 ) 773 } // end if ( fNoLimiting > 1 ) 774 } // end else 774 } // end else 775 775 776 *argpObtained= isObtained; 776 *argpObtained= isObtained; 777 return normalGlobalCrd; 777 return normalGlobalCrd; 778 } 778 } 779 779 780 // ----------------- ooooooOOOOOOOOOOOOOOOooo 780 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo ------------------------------------- 781 781 782 G4ThreeVector 782 G4ThreeVector 783 G4ITMultiNavigator::GetLocalExitNormal(G4bool* 783 G4ITMultiNavigator::GetLocalExitNormal(G4bool* argpObtained) 784 { 784 { 785 // If it is the mass navigator, then expect 785 // If it is the mass navigator, then expect 786 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0) 786 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0); 787 G4bool isObtained= false; 787 G4bool isObtained= false; 788 // These default values will be used if fNoL 788 // These default values will be used if fNoLimitingStep== 0 789 789 790 if( fNoLimitingStep==1 ) 790 if( fNoLimitingStep==1 ) 791 { 791 { 792 // Only message the Navigator which limite 792 // Only message the Navigator which limited the step! 793 normalGlobalCrd= fpNavigator[ fIdNavLimiti 793 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetLocalExitNormal( &isObtained); 794 *argpObtained= isObtained; 794 *argpObtained= isObtained; 795 795 796 static G4ThreadLocal G4int numberWarnings= 796 static G4ThreadLocal G4int numberWarnings= 0; 797 G4int noWarningsStart= 10, noModuloWarning 797 G4int noWarningsStart= 10, noModuloWarnings=100; 798 numberWarnings++; 798 numberWarnings++; 799 if( (numberWarnings < noWarningsStart ) || 799 if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) ) 800 { 800 { 801 std::ostringstream message; 801 std::ostringstream message; 802 message << "Cannot obtain normal in local 802 message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl; 803 G4Exception("G4ITMultiNavigator::GetGlobal 803 G4Exception("G4ITMultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 804 JustWarning, message); 804 JustWarning, message); 805 } 805 } 806 } 806 } 807 else 807 else 808 { 808 { 809 if( fNoLimitingStep > 1 ) 809 if( fNoLimitingStep > 1 ) 810 { 810 { 811 // Does not make sense - cannot obtain 811 // Does not make sense - cannot obtain *local* normal in several coordinate systems 812 std::ostringstream message; 812 std::ostringstream message; 813 message << "Cannot obtain normal in lo 813 message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl; 814 G4Exception("G4ITMultiNavigator::GetGl 814 G4Exception("G4ITMultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 815 FatalException, message); 815 FatalException, message); 816 } 816 } 817 } 817 } 818 818 819 *argpObtained= isObtained; 819 *argpObtained= isObtained; 820 return normalGlobalCrd; 820 return normalGlobalCrd; 821 } 821 } 822 822 823 823 824 // ----------------- ooooooOOOOOOOOOOOOOOOooo 824 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo ------------------------------------- 825 825 826 G4ThreeVector 826 G4ThreeVector 827 G4ITMultiNavigator::GetLocalExitNormalAndCheck 827 G4ITMultiNavigator::GetLocalExitNormalAndCheck(const G4ThreeVector &, // point, 828 828 G4bool* obtained) 829 { 829 { 830 return G4ITMultiNavigator::GetLocalExitNorma 830 return G4ITMultiNavigator::GetLocalExitNormal( obtained); 831 } 831 } 832 832