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