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 // $Id: G4MultiNavigator.cc,v 1.11 2010-09-06 09:49:15 gcosmo Exp $ >> 28 // GEANT4 tag $ Name: $ 25 // 29 // 26 // class G4MultiNavigator Implementation << 30 // class G4PathFinder Implementation 27 // 31 // 28 // Author: John Apostolakis, November 2006 32 // Author: John Apostolakis, November 2006 29 // ------------------------------------------- 33 // -------------------------------------------------------------------- 30 34 31 #include <iomanip> << 32 << 33 #include "G4MultiNavigator.hh" 35 #include "G4MultiNavigator.hh" 34 36 35 class G4FieldManager; 37 class G4FieldManager; 36 38 37 #include "G4SystemOfUnits.hh" << 38 #include "G4Navigator.hh" 39 #include "G4Navigator.hh" 39 #include "G4PropagatorInField.hh" 40 #include "G4PropagatorInField.hh" 40 #include "G4TransportationManager.hh" 41 #include "G4TransportationManager.hh" 41 42 42 // ------------------------------------------- << 43 #include <iomanip> 43 44 44 G4MultiNavigator::G4MultiNavigator() << 45 // ******************************************************************** >> 46 // Constructor >> 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(register int 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 << 74 // ------------------------------------------- << 75 84 76 G4MultiNavigator::~G4MultiNavigator() = defaul << 85 fNoLimitingStep= -1; >> 86 fIdNavLimiting= -1; >> 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( register int 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( register int 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 ( register int 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 ( register int 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( register int 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 ( register int 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; << 516 } 531 } 517 532 518 fNoLimitingStep = noLimited; << 533 fNoLimitingStep= noLimited; 519 534 520 return; 535 return; 521 } 536 } 522 537 523 // ------------------------------------------- 538 // ----------------------------------------------------------------------- 524 539 525 void 540 void 526 G4MultiNavigator::PrintLimited() 541 G4MultiNavigator::PrintLimited() 527 { 542 { 528 // Report results -- for checking 543 // Report results -- for checking 529 544 530 static const G4String StrDoNot("DoNot"), Str << 545 static G4String StrDoNot("DoNot"), StrUnique("Unique"), 531 StrUndefined("Undefined"), 546 StrUndefined("Undefined"), 532 StrSharedTransport("SharedTr 547 StrSharedTransport("SharedTransport"), 533 StrSharedOther("SharedOther" 548 StrSharedOther("SharedOther"); 534 G4cout << "### G4MultiNavigator::PrintLimite 549 G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl; 535 G4cout << " Minimum step (true): " << fTr 550 G4cout << " Minimum step (true): " << fTrueMinStep 536 << ", reported min: " << fMinStep << 551 << ", reported min: " << fMinStep << G4endl; 537 552 538 #ifdef G4DEBUG_NAVIGATION 553 #ifdef G4DEBUG_NAVIGATION 539 if(fVerbose>=2) 554 if(fVerbose>=2) 540 { 555 { 541 G4cout << std::setw(5) << " NavId" << " " 556 G4cout << std::setw(5) << " NavId" << " " 542 << std::setw(12) << " step-size " < 557 << std::setw(12) << " step-size " << " " 543 << std::setw(12) << " raw-size " < 558 << std::setw(12) << " raw-size " << " " 544 << std::setw(12) << " pre-safety " 559 << std::setw(12) << " pre-safety " << " " 545 << std::setw(15) << " Limited / fla 560 << std::setw(15) << " Limited / flag" << " " 546 << std::setw(15) << " World " << 561 << std::setw(15) << " World " << " " 547 << G4endl; 562 << G4endl; 548 } 563 } 549 #endif 564 #endif 550 565 551 for ( auto num = 0; num < fNoActiveNavigator << 566 for ( register int num= 0; num < fNoActiveNavigators; num++ ) 552 { 567 { 553 G4double rawStep = fCurrentStepSize[num]; 568 G4double rawStep = fCurrentStepSize[num]; 554 G4double stepLen = fCurrentStepSize[num]; 569 G4double stepLen = fCurrentStepSize[num]; 555 if( stepLen > fTrueMinStep ) 570 if( stepLen > fTrueMinStep ) 556 { 571 { 557 stepLen = fTrueMinStep; // did not l 572 stepLen = fTrueMinStep; // did not limit (went as far as asked) 558 } 573 } 559 G4long oldPrec = G4cout.precision(9); << 574 G4int oldPrec= G4cout.precision(9); 560 575 561 G4cout << std::setw(5) << num << " " 576 G4cout << std::setw(5) << num << " " 562 << std::setw(12) << stepLen << " " 577 << std::setw(12) << stepLen << " " 563 << std::setw(12) << rawStep << " " 578 << std::setw(12) << rawStep << " " 564 << std::setw(12) << fNewSafety[num] 579 << std::setw(12) << fNewSafety[num] << " " 565 << std::setw(5) << (fLimitTruth[num 580 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " "; 566 G4String limitedStr; 581 G4String limitedStr; 567 switch ( fLimitedStep[num] ) 582 switch ( fLimitedStep[num] ) 568 { 583 { 569 case kDoNot : limitedStr = StrD << 584 case kDoNot : limitedStr= StrDoNot; break; 570 case kUnique : limitedStr = StrU 585 case kUnique : limitedStr = StrUnique; break; 571 case kSharedTransport: limitedStr = StrS << 586 case kSharedTransport: limitedStr= StrSharedTransport; break; 572 case kSharedOther : limitedStr = StrS 587 case kSharedOther : limitedStr = StrSharedOther; break; 573 default : limitedStr = StrU 588 default : limitedStr = StrUndefined; break; 574 } 589 } 575 G4cout << " " << std::setw(15) << limitedS 590 G4cout << " " << std::setw(15) << limitedStr << " "; 576 G4cout.precision(oldPrec); 591 G4cout.precision(oldPrec); 577 592 578 G4Navigator *pNav = fpNavigator[ num ]; << 593 G4Navigator *pNav= fpNavigator[ num ]; 579 G4String WorldName( "Not-Set" ); 594 G4String WorldName( "Not-Set" ); 580 if (pNav != nullptr) << 595 if (pNav) 581 { 596 { 582 G4VPhysicalVolume *pWorld = pNav->GetWo << 597 G4VPhysicalVolume *pWorld= pNav->GetWorldVolume(); 583 if( pWorld != nullptr ) << 598 if( pWorld ) 584 { 599 { 585 WorldName = pWorld->GetName(); 600 WorldName = pWorld->GetName(); 586 } 601 } 587 } 602 } 588 G4cout << " " << WorldName ; 603 G4cout << " " << WorldName ; 589 G4cout << G4endl; 604 G4cout << G4endl; 590 } 605 } 591 } 606 } 592 607 593 608 594 // ------------------------------------------- 609 // ----------------------------------------------------------------------- 595 610 596 void G4MultiNavigator::ResetState() 611 void G4MultiNavigator::ResetState() 597 { 612 { 598 fWasLimitedByGeometry = false; << 613 fWasLimitedByGeometry= false; 599 614 600 G4Exception("G4MultiNavigator::ResetState() 615 G4Exception("G4MultiNavigator::ResetState()", "GeomNav0001", 601 FatalException, 616 FatalException, 602 "Cannot reset state for navigat 617 "Cannot reset state for navigators of G4MultiNavigator."); 603 /* << 618 604 std::vector<G4Navigator*>::iterator pNaviga 619 std::vector<G4Navigator*>::iterator pNavigatorIter; 605 pNavigatorIter = pTransportManager->GetActi << 620 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 606 for( auto num = 0; num< fNoActiveNavigators << 621 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 607 { 622 { 608 // (*pNavigatorIter)->ResetState(); / 623 // (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!! 609 } << 624 } 610 */ << 611 } 625 } 612 626 613 // ------------------------------------------- 627 // ----------------------------------------------------------------------- 614 628 615 void G4MultiNavigator::SetupHierarchy() 629 void G4MultiNavigator::SetupHierarchy() 616 { 630 { 617 G4Exception( "G4MultiNavigator::SetupHierarc 631 G4Exception( "G4MultiNavigator::SetupHierarchy()", 618 "GeomNav0001", FatalException, 632 "GeomNav0001", FatalException, 619 "Cannot setup hierarchy for nav 633 "Cannot setup hierarchy for navigators of G4MultiNavigator."); 620 } 634 } 621 635 622 // ------------------------------------------- 636 // ----------------------------------------------------------------------- 623 637 624 void G4MultiNavigator::CheckMassWorld() 638 void G4MultiNavigator::CheckMassWorld() 625 { 639 { 626 G4VPhysicalVolume* navTrackWorld = << 640 G4VPhysicalVolume* navTrackWorld= 627 pTransportManager->GetNavigatorForTrackin 641 pTransportManager->GetNavigatorForTracking()->GetWorldVolume(); 628 642 629 if( navTrackWorld != fLastMassWorld ) 643 if( navTrackWorld != fLastMassWorld ) 630 { 644 { 631 G4Exception( "G4MultiNavigator::CheckMas 645 G4Exception( "G4MultiNavigator::CheckMassWorld()", 632 "GeomNav0003", FatalExcepti 646 "GeomNav0003", FatalException, 633 "Mass world pointer has bee 647 "Mass world pointer has been changed." ); 634 } 648 } 635 } 649 } 636 650 637 // ------------------------------------------- 651 // ----------------------------------------------------------------------- 638 652 639 G4VPhysicalVolume* 653 G4VPhysicalVolume* 640 G4MultiNavigator::ResetHierarchyAndLocate(cons << 654 G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point, 641 cons << 655 const G4ThreeVector &direction, 642 cons << 656 const G4TouchableHistory &MassHistory) 643 { 657 { 644 // Reset geometry for all -- and use the to 658 // Reset geometry for all -- and use the touchable for the mass history 645 659 646 G4VPhysicalVolume* massVolume = nullptr; << 660 G4VPhysicalVolume* massVolume=0; 647 G4Navigator* pMassNavigator = fpNavigator[0 << 661 G4Navigator* pMassNavigator= fpNavigator[0]; 648 662 649 if( pMassNavigator != nullptr ) << 663 if( pMassNavigator ) 650 { 664 { 651 massVolume= pMassNavigator->ResetHierarc 665 massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction, 652 666 MassHistory); 653 } 667 } 654 else 668 else 655 { 669 { 656 G4Exception("G4MultiNavigator::ResetHier 670 G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()", 657 "GeomNav0002", FatalExceptio 671 "GeomNav0002", FatalException, 658 "Cannot reset hierarchy befo 672 "Cannot reset hierarchy before navigators are initialised."); 659 } 673 } 660 674 661 auto pNavIter= pTransportManager->GetActive << 675 std::vector<G4Navigator*>::iterator pNavIter= >> 676 pTransportManager->GetActiveNavigatorsIterator(); 662 677 663 for ( auto num = 0; num < fNoActiveNavigato << 678 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 664 { 679 { 665 G4bool relativeSearch, ignoreDirection; 680 G4bool relativeSearch, ignoreDirection; 666 681 667 (*pNavIter)-> LocateGlobalPointAndSetup( 682 (*pNavIter)-> LocateGlobalPointAndSetup( point, 668 683 &direction, 669 684 relativeSearch=false, 670 685 ignoreDirection=false); 671 } 686 } 672 return massVolume; 687 return massVolume; 673 } 688 } 674 689 675 // ------------------------------------------- << 690 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo ------------------------------------- 676 691 677 G4ThreeVector 692 G4ThreeVector 678 G4MultiNavigator::GetGlobalExitNormal(const G4 << 693 G4MultiNavigator::GetGlobalExitNormal(const G4ThreeVector &argPoint, 679 G4bool* << 694 G4bool* argpObtained) // const 680 { 695 { 681 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0) 696 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0); 682 G4bool isObtained = false; << 697 G4bool isObtained= false; 683 // These default values will be used if fNoL 698 // These default values will be used if fNoLimitingStep== 0 684 G4int firstNavigatorId = -1; << 699 G4int firstNavigatorId= -1; 685 G4bool oneObtained = false; << 700 G4bool oneObtained= false; 686 701 687 if( fNoLimitingStep == 1 ) << 702 if( fNoLimitingStep==1 ) 688 { 703 { 689 // Only message the Navigator which limite 704 // Only message the Navigator which limited the step! 690 normalGlobalCrd = fpNavigator[ fIdNavLimit << 705 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetGlobalExitNormal( argPoint, &isObtained); 691 ->GetGlobalExitNormal( arg << 706 *argpObtained= isObtained; 692 *argpObtained = isObtained; << 693 } 707 } 694 else 708 else 695 { 709 { 696 if( fNoLimitingStep > 1 ) 710 if( fNoLimitingStep > 1 ) 697 { 711 { 698 auto pNavIter= pTransportManager->GetAct << 712 std::vector<G4Navigator*>::iterator pNavIter= >> 713 pTransportManager->GetActiveNavigatorsIterator(); 699 714 700 for ( auto num = 0; num < fNoActiveNavig << 715 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 701 { 716 { 702 G4ThreeVector oneNormal; 717 G4ThreeVector oneNormal; 703 if( fLimitTruth[ num ] ) // Did this << 718 if( fLimitedStep[ num ] ) 704 { 719 { 705 G4ThreeVector newNormal = << 720 G4ThreeVector newNormal= (*pNavIter)-> GetGlobalExitNormal( argPoint, &oneObtained ); 706 (*pNavIter)->GetGlobalExitNormal( << 707 if( oneObtained ) 721 if( oneObtained ) 708 { 722 { 709 // Keep first one - only if it is 723 // Keep first one - only if it is valid (ie not null) 710 if( !isObtained && (newNormal.mag2 724 if( !isObtained && (newNormal.mag2() != 0.0) ) 711 { 725 { 712 normalGlobalCrd = newNormal; << 726 normalGlobalCrd= newNormal; 713 isObtained = oneObtained; << 727 isObtained = oneObtained; 714 firstNavigatorId = num; << 728 firstNavigatorId= num; 715 } << 729 }else{ 716 else << 717 { << 718 // Check for clash 730 // Check for clash 719 G4double dotNewPrevious = newNor << 731 G4double dotNewPrevious= newNormal.dot( normalGlobalCrd ); 720 G4double productMagSq = normalGl << 732 G4double productMagSq= normalGlobalCrd.mag2() * newNormal.mag2(); 721 if( productMagSq > 0.0 ) 733 if( productMagSq > 0.0 ) 722 { 734 { 723 G4double productMag = std::sqr << 735 G4double productMag= std::sqrt( productMagSq ); 724 dotNewPrevious /= productMag; 736 dotNewPrevious /= productMag; // Normalise 725 if( dotNewPrevious < (1 - perT 737 if( dotNewPrevious < (1 - perThousand) ) 726 { 738 { 727 *argpObtained = false; << 739 if( dotNewPrevious <= 0.0 ) 728 << 729 if( fVerbose > 2 ) // dotN << 730 { 740 { 731 std::ostringstream message 741 std::ostringstream message; 732 message << "Clash of Norma << 742 message << "Clash of Normal from different Navigators!" << G4endl 733 << G4endl << 743 << " Previous Navigator Id = " << firstNavigatorId << G4endl 734 << " Previo << 744 << " Current Navigator Id = " << num << G4endl; 735 << firstNavigatorI << 745 message << " Dot product of 2 normals = " << dotNewPrevious << G4endl; 736 << " Curren << 746 message << " Normal (previous) = " << normalGlobalCrd << G4endl; 737 << num << G4endl; << 738 message << " Dot product << 739 << dotNewPrevious << 740 message << " Normal << 741 << normalGlobalCrd << 742 message << " Normal 747 message << " Normal (current) = " << newNormal << G4endl; 743 G4Exception("G4MultiNaviga << 748 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 744 "GeomNav0002", << 749 FatalException, message); 745 } 750 } 746 } 751 } 747 else 752 else 748 { 753 { 749 // Close agreement - Do not 754 // Close agreement - Do not change 750 } 755 } 751 } 756 } 752 } 757 } 753 } 758 } 754 } 759 } 755 } // end for over the Navigators 760 } // end for over the Navigators 756 761 757 // Report if no Normal was obtained 762 // Report if no Normal was obtained 758 if( !oneObtained ) 763 if( !oneObtained ) 759 { 764 { 760 std::ostringstream message; 765 std::ostringstream message; 761 message << "No Normal obtained despite 766 message << "No Normal obtained despite having " << fNoLimitingStep 762 << " candidate Navigators limi 767 << " candidate Navigators limiting the step!" << G4endl; 763 G4Exception("G4MultiNavigator::GetGlob 768 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 764 JustWarning, message); 769 JustWarning, message); 765 } 770 } 766 771 767 } // end if ( fNoLimiting > 1 ) 772 } // end if ( fNoLimiting > 1 ) 768 } // end else 773 } // end else 769 774 770 *argpObtained = isObtained; << 775 *argpObtained= isObtained; 771 return normalGlobalCrd; 776 return normalGlobalCrd; 772 } 777 } 773 778 774 // ------------------------------------------- << 779 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo ------------------------------------- 775 780 776 G4ThreeVector 781 G4ThreeVector 777 G4MultiNavigator::GetLocalExitNormal(G4bool* a 782 G4MultiNavigator::GetLocalExitNormal(G4bool* argpObtained) 778 { 783 { 779 // If it is the mass navigator, then expect 784 // If it is the mass navigator, then expect 780 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0) 785 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0); 781 G4bool isObtained = false; << 786 G4bool isObtained= false; 782 // These default values will be used if fNoL 787 // These default values will be used if fNoLimitingStep== 0 783 788 784 if( fNoLimitingStep == 1 ) << 789 if( fNoLimitingStep==1 ) 785 { 790 { 786 // Only message the Navigator which limite 791 // Only message the Navigator which limited the step! 787 normalGlobalCrd = fpNavigator[ fIdNavLimit << 792 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetLocalExitNormal( &isObtained); 788 ->GetLocalExitNormal( &isO << 793 *argpObtained= isObtained; 789 *argpObtained = isObtained; << 794 790 << 795 G4int static numberWarnings= 0; 791 static G4ThreadLocal G4int numberWarnings << 796 G4int noWarningsStart= 10, noModuloWarnings=100; 792 G4int noWarningsStart = 10, noModuloWarnin << 797 numberWarnings++; 793 ++numberWarnings; << 798 if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) ) 794 if( (numberWarnings < noWarningsStart ) << 795 || (numberWarnings%noModuloWarnings == 0) << 796 { 799 { 797 std::ostringstream message; << 800 std::ostringstream message; 798 message << "Cannot obtain normal in loca << 801 message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl; 799 << "coordinate systems." << G4en << 802 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 800 G4Exception("G4MultiNavigator::GetGlobal << 803 JustWarning, message); 801 JustWarning, message); << 802 } 804 } 803 } 805 } 804 else 806 else 805 { 807 { 806 if( fNoLimitingStep > 1 ) 808 if( fNoLimitingStep > 1 ) 807 { 809 { 808 std::ostringstream message; << 810 // Does not make sense - cannot obtain *local* normal in several coordinate systems 809 message << "Cannot obtain normal in loca << 811 std::ostringstream message; 810 << "coordinate systems." << G4en << 812 message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl; 811 G4Exception("G4MultiNavigator::GetGlobal << 813 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002", 812 FatalException, message); << 814 FatalException, message); 813 } 815 } 814 } 816 } 815 817 816 *argpObtained = isObtained; << 818 *argpObtained= isObtained; 817 return normalGlobalCrd; 819 return normalGlobalCrd; 818 } 820 } 819 821 820 // ------------------------------------------- << 822 >> 823 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo ------------------------------------- 821 824 822 G4ThreeVector 825 G4ThreeVector 823 G4MultiNavigator::GetLocalExitNormalAndCheck(c << 826 G4MultiNavigator::GetLocalExitNormalAndCheck(const G4ThreeVector &, // point, 824 827 G4bool* obtained) 825 { 828 { 826 return G4MultiNavigator::GetLocalExitNormal( << 829 return G4MultiNavigator::GetLocalExitNormal( obtained); 827 } 830 } 828 831