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