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.7 2007/11/02 13:48:43 japost 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() 45 { 51 { 46 G4ThreeVector Big3Vector( kInfinity, kInfini << 52 fNoActiveNavigators= 0; >> 53 G4ThreeVector Big3Vector( DBL_MAX, DBL_MAX, DBL_MAX ); 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= -DBL_MAX; >> 61 fMinStep= -DBL_MAX; >> 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] = -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= DBL_MAX, minStep= DBL_MAX; 87 << 88 fNoLimitingStep= -1; << 89 fIdNavLimiting= -1; // Reset for new ste << 90 97 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= DBL_MAX; 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 G4int navigatorNo=-1; >> 192 >> 193 if( navigatorId <= fNoActiveNavigators ) >> 194 { >> 195 navigatorNo= navigatorId; >> 196 } >> 197 else 185 { 198 { 186 std::ostringstream message; << 199 G4cerr << "ERROR - G4MultiNavigator::ObtainFinalStep()" 187 message << "Bad Navigator Id!" << G4endl << 200 << " Navigator Id = " << navigatorId 188 << " Navigator Id = " << n << 201 << " No Active = " << fNoActiveNavigators << " . " 189 << " No Active = " << fNoA << 202 << G4endl; 190 G4Exception("G4MultiNavigator::ObtainFina << 203 G4Exception("G4MultiNavigator::ObtainFinalStep()", "InvalidSetup", 191 FatalException, message); << 204 FatalException, "Bad Navigator Id" ); 192 } 205 } 193 206 194 // Prepare the information to return 207 // Prepare the information to return 195 // << 208 pNewSafety = fNewSafety[ navigatorNo ]; 196 pNewSafety = fNewSafety[ navigatorId ]; << 209 limitedStep = fLimitedStep[ navigatorNo ]; 197 limitedStep = fLimitedStep[ navigatorId ]; << 198 minStep= fMinStep; 210 minStep= fMinStep; 199 211 >> 212 // if( (minStep==kInfinity) || (fVerbose > 1) ){ 200 #ifdef G4DEBUG_NAVIGATION 213 #ifdef G4DEBUG_NAVIGATION 201 if( fVerbose > 1 ) << 214 if( fVerbose > 1 ){ 202 { << 215 G4cout << " G4MultiNavigator::ComputeStep returns " << fCurrentStepSize[ navigatorNo ] 203 G4cout << " G4MultiNavigator::ComputeStep << 216 << " for Navigator " << navigatorNo << " Limited step = " << limitedStep 204 << fCurrentStepSize[ navigatorId ] << 205 << " for Navigator " << navigatorI << 206 << " Limited step = " << limitedSt << 207 << " Safety(mm) = " << pNewSafety 217 << " Safety(mm) = " << pNewSafety / mm << G4endl; 208 } 218 } 209 #endif 219 #endif 210 220 211 return fCurrentStepSize[ navigatorId ]; << 221 return fCurrentStepSize[ navigatorNo ]; 212 } 222 } 213 223 214 // ------------------------------------------- 224 // ---------------------------------------------------------------------- 215 225 216 void G4MultiNavigator::PrepareNewTrack( const << 226 void G4MultiNavigator::PrepareNewTrack( const G4ThreeVector position, 217 const 227 const G4ThreeVector direction ) 218 { 228 { 219 #ifdef G4DEBUG_NAVIGATION 229 #ifdef G4DEBUG_NAVIGATION 220 if( fVerbose > 1 ) 230 if( fVerbose > 1 ) 221 { 231 { 222 G4cout << " Entered G4MultiNavigator::Prep 232 G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl; 223 } 233 } 224 #endif 234 #endif 225 235 226 G4MultiNavigator::PrepareNavigators(); 236 G4MultiNavigator::PrepareNavigators(); 227 237 228 LocateGlobalPointAndSetup( position, &direct 238 LocateGlobalPointAndSetup( position, &direction, false, false ); 229 // 239 // 230 // The first location for each Navigator mus 240 // The first location for each Navigator must be non-relative 231 // or else call ResetStackAndState() for eac 241 // or else call ResetStackAndState() for each Navigator 232 // Use direction to get correct side of boun 242 // Use direction to get correct side of boundary (ignore dir= false) 233 } 243 } 234 244 235 // ------------------------------------------- 245 // ---------------------------------------------------------------------- 236 246 237 void G4MultiNavigator::PrepareNavigators() 247 void G4MultiNavigator::PrepareNavigators() 238 { 248 { 239 // Key purposes: 249 // Key purposes: 240 // - Check and cache set of active navigat 250 // - Check and cache set of active navigators 241 // - Reset state for new track 251 // - Reset state for new track 242 252 243 #ifdef G4DEBUG_NAVIGATION 253 #ifdef G4DEBUG_NAVIGATION 244 if( fVerbose > 1 ) 254 if( fVerbose > 1 ) 245 { 255 { 246 G4cout << " Entered G4MultiNavigator::Prep 256 G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl; 247 } 257 } 248 #endif 258 #endif 249 259 250 // Message the transportation-manager to fin 260 // Message the transportation-manager to find active navigators 251 261 252 std::vector<G4Navigator*>::const_iterator pN << 262 std::vector<G4Navigator*>::iterator pNavigatorIter; 253 fNoActiveNavigators = (G4int)pTransportManag << 263 fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators(); 254 264 255 if( fNoActiveNavigators > fMaxNav ) 265 if( fNoActiveNavigators > fMaxNav ) 256 { 266 { 257 std::ostringstream message; << 267 G4cerr << "ERROR - G4MultiNavigator::PrepareNavigators()" 258 message << "Too many active Navigators / w << 268 << " Too many active Navigators (worlds): " 259 << " Active Navigators (wor << 269 << fNoActiveNavigators << G4endl 260 << fNoActiveNavigators << G4endl << 270 << " which is more than the number allowed: " 261 << " which is more than the << 271 << fMaxNav << " !" << G4endl; 262 << fMaxNav << " !"; << 272 G4Exception("G4MultiNavigator::PrepareNavigators()", "InvalidSetup", 263 G4Exception("G4MultiNavigator::PrepareNavi << 273 FatalException, "Too many active Navigators / worlds !"); 264 FatalException, message); << 265 } 274 } 266 275 267 pNavigatorIter= pTransportManager->GetActive << 276 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 268 for( auto num=0; num< fNoActiveNavigators; + << 277 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 269 { 278 { 270 fpNavigator[num] = *pNavigatorIter; << 279 fpNavigator[num] = *pNavigatorIter; 271 fLimitTruth[num] = false; 280 fLimitTruth[num] = false; 272 fLimitedStep[num] = kDoNot; 281 fLimitedStep[num] = kDoNot; 273 fCurrentStepSize[num] = 0.0; 282 fCurrentStepSize[num] = 0.0; 274 fLocatedVolume[num] = nullptr; << 283 fLocatedVolume[num] = 0; 275 } 284 } 276 fWasLimitedByGeometry = false; 285 fWasLimitedByGeometry = false; 277 286 278 // Check the world volume of the mass naviga 287 // Check the world volume of the mass navigator 279 // in case a call to SetWorldVolume() change 288 // in case a call to SetWorldVolume() changed it 280 289 281 G4VPhysicalVolume* massWorld = GetWorldVolum 290 G4VPhysicalVolume* massWorld = GetWorldVolume(); 282 291 283 if( (massWorld != fLastMassWorld) && (massWo << 292 if( (massWorld != fLastMassWorld) && (massWorld!=0) ) 284 { 293 { 285 // Pass along change to Mass Navigator 294 // Pass along change to Mass Navigator 286 fpNavigator[0] -> SetWorldVolume( massWor 295 fpNavigator[0] -> SetWorldVolume( massWorld ); 287 296 288 #ifdef G4DEBUG_NAVIGATION 297 #ifdef G4DEBUG_NAVIGATION 289 if( fVerbose > 0 ) 298 if( fVerbose > 0 ) 290 { 299 { 291 G4cout << " G4MultiNavigator::PrepareNa 300 G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume " 292 << " for mass geometry to " << m 301 << " for mass geometry to " << massWorld->GetName() << G4endl; 293 } 302 } 294 #endif 303 #endif 295 304 296 fLastMassWorld = massWorld; 305 fLastMassWorld = massWorld; 297 } 306 } 298 } 307 } 299 308 300 // ------------------------------------------- 309 // ---------------------------------------------------------------------- 301 310 302 G4VPhysicalVolume* 311 G4VPhysicalVolume* 303 G4MultiNavigator::LocateGlobalPointAndSetup(co 312 G4MultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position, 304 co 313 const G4ThreeVector* pDirection, 305 co 314 const G4bool pRelativeSearch, 306 co 315 const G4bool ignoreDirection ) 307 { 316 { 308 // Locate the point in each geometry 317 // Locate the point in each geometry 309 318 310 G4ThreeVector direction(0.0, 0.0, 0.0); 319 G4ThreeVector direction(0.0, 0.0, 0.0); 311 G4bool relative = pRelativeSearch; 320 G4bool relative = pRelativeSearch; 312 auto pNavIter = pTransportManager->GetActive << 321 std::vector<G4Navigator*>::iterator pNavIter >> 322 = pTransportManager->GetActiveNavigatorsIterator(); 313 323 314 if( pDirection != nullptr ) { direction = *p << 324 if( pDirection ) { direction = *pDirection; } 315 325 316 #ifdef G4DEBUG_NAVIGATION 326 #ifdef G4DEBUG_NAVIGATION 317 if( fVerbose > 2 ) 327 if( fVerbose > 2 ) 318 { 328 { 319 G4cout << " Entered G4MultiNavigator::Loca 329 G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() " 320 << G4endl; 330 << G4endl; 321 G4cout << " Locating at position: " << p 331 G4cout << " Locating at position: " << position 322 << ", with direction: " << directio 332 << ", with direction: " << direction << G4endl 323 << " Relative: " << relative 333 << " Relative: " << relative 324 << ", ignore direction: " << ignore 334 << ", ignore direction: " << ignoreDirection << G4endl; 325 G4cout << " Number of active navigators: 335 G4cout << " Number of active navigators: " << fNoActiveNavigators 326 << G4endl; 336 << G4endl; 327 } 337 } 328 #endif 338 #endif 329 339 330 for ( auto num=0; num< fNoActiveNavigators ; << 340 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 331 { 341 { 332 if( fWasLimitedByGeometry && fLimitTruth[ 342 if( fWasLimitedByGeometry && fLimitTruth[num] ) 333 { 343 { 334 (*pNavIter)->SetGeometricallyLimitedSt 344 (*pNavIter)->SetGeometricallyLimitedStep(); 335 } 345 } 336 346 337 G4VPhysicalVolume *pLocated 347 G4VPhysicalVolume *pLocated 338 = (*pNavIter)->LocateGlobalPointAndSetu 348 = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction, 339 349 relative, ignoreDirection ); 340 // Set the state related to the location 350 // Set the state related to the location 341 // 351 // 342 fLocatedVolume[num] = pLocated; 352 fLocatedVolume[num] = pLocated; 343 353 344 // Clear state related to the step 354 // Clear state related to the step 345 // 355 // 346 fLimitedStep[num] = kDoNot; 356 fLimitedStep[num] = kDoNot; 347 fCurrentStepSize[num] = 0.0; 357 fCurrentStepSize[num] = 0.0; 348 fLimitTruth[ num ] = false; // Always c 358 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator) 349 359 350 #ifdef G4DEBUG_NAVIGATION 360 #ifdef G4DEBUG_NAVIGATION 351 if( fVerbose > 2 ) 361 if( fVerbose > 2 ) 352 { 362 { 353 G4cout << " Located in world: " << num 363 G4cout << " Located in world: " << num << ", at: " << position << G4endl 354 << " Used geomLimStp: " << fLimi 364 << " Used geomLimStp: " << fLimitTruth[num] 355 << ", found in volume: " << pLoc 365 << ", found in volume: " << pLocated << G4endl; 356 G4cout << " Name = '" ; 366 G4cout << " Name = '" ; 357 if( pLocated ) 367 if( pLocated ) 358 { 368 { 359 G4cout << pLocated->GetName() << "'"; 369 G4cout << pLocated->GetName() << "'"; 360 G4cout << " - CopyNo= " << pLocated-> 370 G4cout << " - CopyNo= " << pLocated->GetCopyNo(); 361 } 371 } 362 else 372 else 363 { 373 { 364 G4cout << "Null' Id: Not-Set "; 374 G4cout << "Null' Id: Not-Set "; 365 } 375 } 366 G4cout << G4endl; 376 G4cout << G4endl; 367 } 377 } 368 #endif 378 #endif 369 } 379 } 370 380 371 fWasLimitedByGeometry = false; // Clear on 381 fWasLimitedByGeometry = false; // Clear on locating 372 G4VPhysicalVolume* volMassLocated = fLocated << 382 G4VPhysicalVolume* volMassLocated= fLocatedVolume[0]; 373 383 374 return volMassLocated; 384 return volMassLocated; 375 } 385 } 376 386 377 // ------------------------------------------- 387 // ---------------------------------------------------------------------- 378 388 379 void 389 void 380 G4MultiNavigator::LocateGlobalPointWithinVolum 390 G4MultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position) 381 { 391 { 382 // Relocate the point in each geometry 392 // Relocate the point in each geometry 383 393 384 auto pNavIter = pTransportManager->GetActive << 394 std::vector<G4Navigator*>::iterator pNavIter >> 395 = pTransportManager->GetActiveNavigatorsIterator(); 385 396 386 #ifdef G4DEBUG_NAVIGATION 397 #ifdef G4DEBUG_NAVIGATION 387 if( fVerbose > 2 ) 398 if( fVerbose > 2 ) 388 { 399 { 389 G4cout << " Entered G4MultiNavigator::ReLo 400 G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl 390 << " Re-locating at position: " << 401 << " Re-locating at position: " << position << G4endl; 391 } 402 } 392 #endif 403 #endif 393 404 394 for ( auto num=0; num< fNoActiveNavigators ; << 405 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 395 { 406 { 396 // ... none limited the step 407 // ... none limited the step 397 408 398 (*pNavIter)->LocateGlobalPointWithinVolum 409 (*pNavIter)->LocateGlobalPointWithinVolume( position ); 399 410 400 // Clear state related to the step 411 // Clear state related to the step 401 // 412 // 402 fLimitedStep[num] = kDoNot; 413 fLimitedStep[num] = kDoNot; 403 fCurrentStepSize[num] = 0.0; 414 fCurrentStepSize[num] = 0.0; 404 415 405 fLimitTruth[ num ] = false; // Always c 416 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator) 406 } 417 } 407 fWasLimitedByGeometry = false; // Clear on 418 fWasLimitedByGeometry = false; // Clear on locating 408 fLastLocatedPosition = position; 419 fLastLocatedPosition = position; 409 } 420 } 410 421 411 // ------------------------------------------- 422 // ---------------------------------------------------------------------- 412 423 413 G4double G4MultiNavigator::ComputeSafety( cons 424 G4double G4MultiNavigator::ComputeSafety( const G4ThreeVector& position, 414 cons << 425 G4double maxDistance) 415 cons << 416 { 426 { 417 // Recompute safety for the relevant point 427 // Recompute safety for the relevant point 418 428 419 G4double minSafety = kInfinity, safety = k << 429 G4double minSafety = DBL_MAX, safety = DBL_MAX; 420 430 421 std::vector<G4Navigator*>::iterator pNavig 431 std::vector<G4Navigator*>::iterator pNavigatorIter; 422 pNavigatorIter= pTransportManager-> GetAct 432 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 423 433 424 for( auto num=0; num< fNoActiveNavigators; << 434 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 425 { 435 { 426 safety = (*pNavigatorIter)->ComputeSafe << 436 safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance ); 427 if( safety < minSafety ) { minSafety = 437 if( safety < minSafety ) { minSafety = safety; } 428 } 438 } 429 439 430 fSafetyLocation = position; 440 fSafetyLocation = position; 431 fMinSafety_atSafLocation = minSafety; 441 fMinSafety_atSafLocation = minSafety; 432 442 433 #ifdef G4DEBUG_NAVIGATION 443 #ifdef G4DEBUG_NAVIGATION 434 if( fVerbose > 1 ) 444 if( fVerbose > 1 ) 435 { 445 { 436 G4cout << " G4MultiNavigator::ComputeSaf 446 G4cout << " G4MultiNavigator::ComputeSafety - returns: " 437 << minSafety << ", at location: " 447 << minSafety << ", at location: " << position << G4endl; 438 } 448 } 439 #endif 449 #endif 440 return minSafety; 450 return minSafety; 441 } 451 } 442 452 443 // ------------------------------------------- 453 // ----------------------------------------------------------------------- 444 454 445 G4TouchableHandle G4MultiNavigator::CreateTouc << 455 G4TouchableHistoryHandle >> 456 G4MultiNavigator::CreateTouchableHistoryHandle() const 446 { 457 { 447 G4Exception( "G4MultiNavigator::CreateToucha 458 G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()", 448 "GeomNav0001", FatalException, << 459 "215-TouchableFromWrongNavigator", FatalException, 449 "Getting a touchable from G4Mul 460 "Getting a touchable from G4MultiNavigator is not defined."); 450 461 451 G4TouchableHistory* touchHist; 462 G4TouchableHistory* touchHist; 452 touchHist= fpNavigator[0] -> CreateTouchable 463 touchHist= fpNavigator[0] -> CreateTouchableHistory(); 453 464 454 G4VPhysicalVolume* locatedVolume= fLocatedVo 465 G4VPhysicalVolume* locatedVolume= fLocatedVolume[0]; 455 if( locatedVolume == nullptr ) << 466 if( locatedVolume == 0 ) 456 { 467 { 457 // Workaround to ensure that the touchable 468 // Workaround to ensure that the touchable is fixed !! // TODO: fix 458 // 469 // 459 touchHist->UpdateYourself( locatedVolume, 470 touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() ); 460 } 471 } 461 472 462 return {touchHist}; << 473 return G4TouchableHistoryHandle(touchHist); 463 } 474 } 464 475 465 // ------------------------------------------- 476 // ----------------------------------------------------------------------- 466 477 467 void G4MultiNavigator::WhichLimited() 478 void G4MultiNavigator::WhichLimited() 468 { 479 { 469 // Flag which processes limited the step 480 // Flag which processes limited the step 470 481 471 G4int last=-1; 482 G4int last=-1; 472 const G4int IdTransport= 0; // Id of Mass N 483 const G4int IdTransport= 0; // Id of Mass Navigator !! 473 G4int noLimited=0; 484 G4int noLimited=0; 474 ELimited shared= kSharedOther; 485 ELimited shared= kSharedOther; 475 486 476 #ifdef G4DEBUG_NAVIGATION 487 #ifdef G4DEBUG_NAVIGATION 477 if( fVerbose > 2 ) 488 if( fVerbose > 2 ) 478 { 489 { 479 G4cout << " Entered G4MultiNavigator::Whic 490 G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl; 480 } 491 } 481 #endif 492 #endif 482 493 483 // Assume that [IdTransport] is Mass / Trans 494 // Assume that [IdTransport] is Mass / Transport 484 // 495 // 485 G4bool transportLimited = (fCurrentStepSize[ 496 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep) 486 && ( fMinStep!= kInfi 497 && ( fMinStep!= kInfinity); 487 if( transportLimited ) 498 if( transportLimited ) 488 { 499 { 489 shared = kSharedTransport; << 500 shared= kSharedTransport; 490 } 501 } 491 502 492 for ( auto num = 0; num < fNoActiveNavigator << 503 for ( register int num= 0; num < fNoActiveNavigators; num++ ) 493 { 504 { 494 G4bool limitedStep; 505 G4bool limitedStep; 495 506 496 G4double step = fCurrentStepSize[num]; << 507 G4double step= fCurrentStepSize[num]; 497 508 498 limitedStep = ( step == fMinStep ) && ( st 509 limitedStep = ( step == fMinStep ) && ( step != kInfinity); 499 510 500 fLimitTruth[ num ] = limitedStep; 511 fLimitTruth[ num ] = limitedStep; 501 if( limitedStep ) 512 if( limitedStep ) 502 { 513 { 503 ++noLimited; << 514 noLimited++; 504 fLimitedStep[num] = shared; 515 fLimitedStep[num] = shared; 505 last= num; 516 last= num; 506 } 517 } 507 else 518 else 508 { 519 { 509 fLimitedStep[num] = kDoNot; 520 fLimitedStep[num] = kDoNot; 510 } 521 } 511 } 522 } 512 if( (last > -1) && (noLimited == 1 ) ) 523 if( (last > -1) && (noLimited == 1 ) ) 513 { 524 { 514 fLimitedStep[ last ] = kUnique; << 525 fLimitedStep[ last ] = kUnique; 515 fIdNavLimiting = last; << 516 } 526 } 517 << 518 fNoLimitingStep = noLimited; << 519 << 520 return; << 521 } 527 } 522 528 523 // ------------------------------------------- 529 // ----------------------------------------------------------------------- 524 530 525 void 531 void 526 G4MultiNavigator::PrintLimited() 532 G4MultiNavigator::PrintLimited() 527 { 533 { 528 // Report results -- for checking 534 // Report results -- for checking 529 535 530 static const G4String StrDoNot("DoNot"), Str << 536 static G4String StrDoNot("DoNot"), StrUnique("Unique"), 531 StrUndefined("Undefined"), 537 StrUndefined("Undefined"), 532 StrSharedTransport("SharedTr 538 StrSharedTransport("SharedTransport"), 533 StrSharedOther("SharedOther" 539 StrSharedOther("SharedOther"); 534 G4cout << "### G4MultiNavigator::PrintLimite 540 G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl; 535 G4cout << " Minimum step (true): " << fTr 541 G4cout << " Minimum step (true): " << fTrueMinStep 536 << ", reported min: " << fMinStep << 542 << ", reported min: " << fMinStep << G4endl; 537 543 538 #ifdef G4DEBUG_NAVIGATION 544 #ifdef G4DEBUG_NAVIGATION 539 if(fVerbose>=2) 545 if(fVerbose>=2) 540 { 546 { 541 G4cout << std::setw(5) << " NavId" << " " 547 G4cout << std::setw(5) << " NavId" << " " 542 << std::setw(12) << " step-size " < 548 << std::setw(12) << " step-size " << " " 543 << std::setw(12) << " raw-size " < 549 << std::setw(12) << " raw-size " << " " 544 << std::setw(12) << " pre-safety " 550 << std::setw(12) << " pre-safety " << " " 545 << std::setw(15) << " Limited / fla 551 << std::setw(15) << " Limited / flag" << " " 546 << std::setw(15) << " World " << 552 << std::setw(15) << " World " << " " 547 << G4endl; 553 << G4endl; 548 } 554 } 549 #endif 555 #endif 550 556 551 for ( auto num = 0; num < fNoActiveNavigator << 557 for ( register int num= 0; num < fNoActiveNavigators; num++ ) 552 { 558 { 553 G4double rawStep = fCurrentStepSize[num]; 559 G4double rawStep = fCurrentStepSize[num]; 554 G4double stepLen = fCurrentStepSize[num]; 560 G4double stepLen = fCurrentStepSize[num]; 555 if( stepLen > fTrueMinStep ) 561 if( stepLen > fTrueMinStep ) 556 { 562 { 557 stepLen = fTrueMinStep; // did not l 563 stepLen = fTrueMinStep; // did not limit (went as far as asked) 558 } 564 } 559 G4long oldPrec = G4cout.precision(9); << 565 G4int oldPrec= G4cout.precision(9); 560 566 561 G4cout << std::setw(5) << num << " " 567 G4cout << std::setw(5) << num << " " 562 << std::setw(12) << stepLen << " " 568 << std::setw(12) << stepLen << " " 563 << std::setw(12) << rawStep << " " 569 << std::setw(12) << rawStep << " " 564 << std::setw(12) << fNewSafety[num] 570 << std::setw(12) << fNewSafety[num] << " " 565 << std::setw(5) << (fLimitTruth[num 571 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " "; 566 G4String limitedStr; 572 G4String limitedStr; 567 switch ( fLimitedStep[num] ) 573 switch ( fLimitedStep[num] ) 568 { 574 { 569 case kDoNot : limitedStr = StrD << 575 case kDoNot : limitedStr= StrDoNot; break; 570 case kUnique : limitedStr = StrU 576 case kUnique : limitedStr = StrUnique; break; 571 case kSharedTransport: limitedStr = StrS << 577 case kSharedTransport: limitedStr= StrSharedTransport; break; 572 case kSharedOther : limitedStr = StrS 578 case kSharedOther : limitedStr = StrSharedOther; break; 573 default : limitedStr = StrU 579 default : limitedStr = StrUndefined; break; 574 } 580 } 575 G4cout << " " << std::setw(15) << limitedS 581 G4cout << " " << std::setw(15) << limitedStr << " "; 576 G4cout.precision(oldPrec); 582 G4cout.precision(oldPrec); 577 583 578 G4Navigator *pNav = fpNavigator[ num ]; << 584 G4Navigator *pNav= fpNavigator[ num ]; 579 G4String WorldName( "Not-Set" ); 585 G4String WorldName( "Not-Set" ); 580 if (pNav != nullptr) << 586 if (pNav) 581 { 587 { 582 G4VPhysicalVolume *pWorld = pNav->GetWo << 588 G4VPhysicalVolume *pWorld= pNav->GetWorldVolume(); 583 if( pWorld != nullptr ) << 589 if( pWorld ) 584 { 590 { 585 WorldName = pWorld->GetName(); 591 WorldName = pWorld->GetName(); 586 } 592 } 587 } 593 } 588 G4cout << " " << WorldName ; 594 G4cout << " " << WorldName ; 589 G4cout << G4endl; 595 G4cout << G4endl; 590 } 596 } 591 } 597 } 592 598 593 599 594 // ------------------------------------------- 600 // ----------------------------------------------------------------------- 595 601 596 void G4MultiNavigator::ResetState() 602 void G4MultiNavigator::ResetState() 597 { 603 { 598 fWasLimitedByGeometry = false; << 604 fWasLimitedByGeometry= false; 599 605 600 G4Exception("G4MultiNavigator::ResetState() << 606 G4Exception("G4MultiNavigator::ResetState()", "217-NotImplemented", 601 FatalException, 607 FatalException, 602 "Cannot reset state for navigat << 608 "Cannot call ResetState() for navigators of G4MultiNavigator."); 603 /* << 609 604 std::vector<G4Navigator*>::iterator pNaviga 610 std::vector<G4Navigator*>::iterator pNavigatorIter; 605 pNavigatorIter = pTransportManager->GetActi << 611 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator(); 606 for( auto num = 0; num< fNoActiveNavigators << 612 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 607 { 613 { 608 // (*pNavigatorIter)->ResetState(); / 614 // (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!! 609 } << 615 } 610 */ << 611 } 616 } 612 617 613 // ------------------------------------------- 618 // ----------------------------------------------------------------------- 614 619 615 void G4MultiNavigator::SetupHierarchy() 620 void G4MultiNavigator::SetupHierarchy() 616 { 621 { 617 G4Exception( "G4MultiNavigator::SetupHierarc 622 G4Exception( "G4MultiNavigator::SetupHierarchy()", 618 "GeomNav0001", FatalException, << 623 "217-NotImplemented", FatalException, 619 "Cannot setup hierarchy for nav << 624 "Cannot call SetupHierarchy() for navigators of G4MultiNavigator."); 620 } 625 } 621 626 622 // ------------------------------------------- 627 // ----------------------------------------------------------------------- 623 628 624 void G4MultiNavigator::CheckMassWorld() 629 void G4MultiNavigator::CheckMassWorld() 625 { 630 { 626 G4VPhysicalVolume* navTrackWorld = << 631 G4VPhysicalVolume* navTrackWorld= 627 pTransportManager->GetNavigatorForTrackin 632 pTransportManager->GetNavigatorForTracking()->GetWorldVolume(); 628 633 629 if( navTrackWorld != fLastMassWorld ) 634 if( navTrackWorld != fLastMassWorld ) 630 { 635 { 631 G4Exception( "G4MultiNavigator::CheckMas 636 G4Exception( "G4MultiNavigator::CheckMassWorld()", 632 "GeomNav0003", FatalExcepti << 637 "220-InvalidSetup", FatalException, 633 "Mass world pointer has bee 638 "Mass world pointer has been changed." ); 634 } 639 } 635 } 640 } 636 641 637 // ------------------------------------------- 642 // ----------------------------------------------------------------------- 638 643 639 G4VPhysicalVolume* 644 G4VPhysicalVolume* 640 G4MultiNavigator::ResetHierarchyAndLocate(cons << 645 G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point, 641 cons << 646 const G4ThreeVector &direction, 642 cons << 647 const G4TouchableHistory &MassHistory) 643 { 648 { 644 // Reset geometry for all -- and use the to 649 // Reset geometry for all -- and use the touchable for the mass history 645 650 646 G4VPhysicalVolume* massVolume = nullptr; << 651 G4VPhysicalVolume* massVolume=0; 647 G4Navigator* pMassNavigator = fpNavigator[0 << 652 G4Navigator* pMassNavigator= fpNavigator[0]; 648 653 649 if( pMassNavigator != nullptr ) << 654 if( pMassNavigator ) 650 { 655 { 651 massVolume= pMassNavigator->ResetHierarc 656 massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction, 652 657 MassHistory); 653 } 658 } 654 else 659 else 655 { 660 { 656 G4Exception("G4MultiNavigator::ResetHier 661 G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()", 657 "GeomNav0002", FatalExceptio << 662 "218-TooEarlyToReset", FatalException, 658 "Cannot reset hierarchy befo 663 "Cannot reset hierarchy before navigators are initialised."); 659 } 664 } 660 665 661 auto pNavIter= pTransportManager->GetActive << 666 std::vector<G4Navigator*>::iterator pNavIter= >> 667 pTransportManager->GetActiveNavigatorsIterator(); 662 668 663 for ( auto num = 0; num < fNoActiveNavigato << 669 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num ) 664 { 670 { 665 G4bool relativeSearch, ignoreDirection; 671 G4bool relativeSearch, ignoreDirection; 666 672 667 (*pNavIter)-> LocateGlobalPointAndSetup( 673 (*pNavIter)-> LocateGlobalPointAndSetup( point, 668 674 &direction, 669 675 relativeSearch=false, 670 676 ignoreDirection=false); 671 } 677 } 672 return massVolume; 678 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 } 679 } 828 680