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