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