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