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