00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <iomanip>
00036
00037 #include "G4MultiNavigator.hh"
00038
00039 class G4FieldManager;
00040
00041 #include "G4SystemOfUnits.hh"
00042 #include "G4Navigator.hh"
00043 #include "G4PropagatorInField.hh"
00044 #include "G4TransportationManager.hh"
00045
00046
00047
00048
00049
00050 G4MultiNavigator::G4MultiNavigator()
00051 : G4Navigator(), fLastMassWorld(0)
00052 {
00053 fNoActiveNavigators= 0;
00054 G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity );
00055 fLastLocatedPosition = Big3Vector;
00056 fSafetyLocation = Big3Vector;
00057 fPreStepLocation = Big3Vector;
00058
00059 fMinSafety_PreStepPt= -1.0;
00060 fMinSafety_atSafLocation= -1.0;
00061 fMinSafety= -kInfinity;
00062 fTrueMinStep= fMinStep= -kInfinity;
00063
00064 for(register int num=0; num< fMaxNav; ++num )
00065 {
00066 fpNavigator[num] = 0;
00067 fLimitTruth[num] = false;
00068 fLimitedStep[num] = kUndefLimited;
00069 fCurrentStepSize[num] = fNewSafety[num] = -1.0;
00070 fLocatedVolume[num] = 0;
00071 }
00072
00073 pTransportManager= G4TransportationManager::GetTransportationManager();
00074
00075 G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
00076 if( massNav )
00077 {
00078 G4VPhysicalVolume* pWorld= massNav->GetWorldVolume();
00079 if( pWorld )
00080 {
00081 SetWorldVolume( pWorld );
00082 fLastMassWorld = pWorld;
00083 }
00084 }
00085
00086 fNoLimitingStep= -1;
00087 fIdNavLimiting= -1;
00088 }
00089
00090 G4MultiNavigator::~G4MultiNavigator()
00091 {
00092 }
00093
00094 G4double G4MultiNavigator::ComputeStep(const G4ThreeVector &pGlobalPoint,
00095 const G4ThreeVector &pDirection,
00096 const G4double proposedStepLength,
00097 G4double &pNewSafety)
00098 {
00099 G4double safety= 0.0, step=0.0;
00100 G4double minSafety= kInfinity, minStep= kInfinity;
00101
00102 fNoLimitingStep= -1;
00103 fIdNavLimiting= -1;
00104
00105 #ifdef G4DEBUG_NAVIGATION
00106 if( fVerbose > 2 )
00107 {
00108 G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
00109 G4cout << " Input position= " << pGlobalPoint
00110 << " direction= " << pDirection << G4endl;
00111 G4cout << " Requested step= " << proposedStepLength << G4endl;
00112 }
00113 #endif
00114
00115 std::vector<G4Navigator*>::iterator pNavigatorIter;
00116
00117 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00118
00119 G4ThreeVector initialPosition = pGlobalPoint;
00120 G4ThreeVector initialDirection= pDirection;
00121
00122 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00123 {
00124 safety= kInfinity;
00125
00126 step= (*pNavigatorIter)->ComputeStep( initialPosition,
00127 initialDirection,
00128 proposedStepLength,
00129 safety );
00130 if( safety < minSafety ){ minSafety = safety; }
00131 if( step < minStep ) { minStep= step; }
00132
00133 fCurrentStepSize[num] = step;
00134 fNewSafety[num]= safety;
00135
00136
00137 #ifdef G4DEBUG_NAVIGATION
00138 if( fVerbose > 2 )
00139 {
00140 G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
00141 << num << "] -- step size " << step
00142 << " safety= " << safety << G4endl;
00143 }
00144 #endif
00145 }
00146
00147
00148
00149 fPreStepLocation = initialPosition;
00150 fMinSafety_PreStepPt = minSafety;
00151 fMinStep = minStep;
00152
00153 if( fMinStep == kInfinity )
00154 {
00155 fTrueMinStep = proposedStepLength;
00156 }
00157 else
00158 {
00159 fTrueMinStep = minStep;
00160 }
00161
00162 #ifdef G4DEBUG_NAVIGATION
00163 if( fVerbose > 1 )
00164 {
00165 G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
00166
00167 G4int oldPrec = G4cout.precision(8);
00168 G4cout << "G4MultiNavigator::ComputeStep : "
00169 << " initialPosition = " << initialPosition
00170 << " and endPosition = " << endPosition << G4endl;
00171 G4cout.precision( oldPrec );
00172 }
00173 #endif
00174
00175 pNewSafety = minSafety;
00176
00177 this->WhichLimited();
00178
00179 #ifdef G4DEBUG_NAVIGATION
00180 if( fVerbose > 2 )
00181 {
00182 G4cout << " G4MultiNavigator::ComputeStep : exits returning "
00183 << minStep << G4endl;
00184 }
00185 #endif
00186
00187 return minStep;
00188 }
00189
00190
00191
00192 G4double
00193 G4MultiNavigator::ObtainFinalStep( G4int navigatorId,
00194 G4double &pNewSafety,
00195 G4double &minStep,
00196 ELimited &limitedStep)
00197 {
00198 if( navigatorId > fNoActiveNavigators )
00199 {
00200 std::ostringstream message;
00201 message << "Bad Navigator Id!" << G4endl
00202 << " Navigator Id = " << navigatorId
00203 << " No Active = " << fNoActiveNavigators << ".";
00204 G4Exception("G4MultiNavigator::ObtainFinalStep()", "GeomNav0002",
00205 FatalException, message);
00206 }
00207
00208
00209
00210 pNewSafety = fNewSafety[ navigatorId ];
00211 limitedStep = fLimitedStep[ navigatorId ];
00212 minStep= fMinStep;
00213
00214 #ifdef G4DEBUG_NAVIGATION
00215 if( fVerbose > 1 )
00216 {
00217 G4cout << " G4MultiNavigator::ComputeStep returns "
00218 << fCurrentStepSize[ navigatorId ]
00219 << " for Navigator " << navigatorId
00220 << " Limited step = " << limitedStep
00221 << " Safety(mm) = " << pNewSafety / mm << G4endl;
00222 }
00223 #endif
00224
00225 return fCurrentStepSize[ navigatorId ];
00226 }
00227
00228
00229
00230 void G4MultiNavigator::PrepareNewTrack( const G4ThreeVector position,
00231 const G4ThreeVector direction )
00232 {
00233 #ifdef G4DEBUG_NAVIGATION
00234 if( fVerbose > 1 )
00235 {
00236 G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
00237 }
00238 #endif
00239
00240 G4MultiNavigator::PrepareNavigators();
00241
00242 LocateGlobalPointAndSetup( position, &direction, false, false );
00243
00244
00245
00246
00247 }
00248
00249
00250
00251 void G4MultiNavigator::PrepareNavigators()
00252 {
00253
00254
00255
00256
00257 #ifdef G4DEBUG_NAVIGATION
00258 if( fVerbose > 1 )
00259 {
00260 G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
00261 }
00262 #endif
00263
00264
00265
00266 std::vector<G4Navigator*>::iterator pNavigatorIter;
00267 fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators();
00268
00269 if( fNoActiveNavigators > fMaxNav )
00270 {
00271 std::ostringstream message;
00272 message << "Too many active Navigators / worlds !" << G4endl
00273 << " Active Navigators (worlds): "
00274 << fNoActiveNavigators << G4endl
00275 << " which is more than the number allowed: "
00276 << fMaxNav << " !";
00277 G4Exception("G4MultiNavigator::PrepareNavigators()", "GeomNav0002",
00278 FatalException, message);
00279 }
00280
00281 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00282 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00283 {
00284 fpNavigator[num] = *pNavigatorIter;
00285 fLimitTruth[num] = false;
00286 fLimitedStep[num] = kDoNot;
00287 fCurrentStepSize[num] = 0.0;
00288 fLocatedVolume[num] = 0;
00289 }
00290 fWasLimitedByGeometry = false;
00291
00292
00293
00294
00295 G4VPhysicalVolume* massWorld = GetWorldVolume();
00296
00297 if( (massWorld != fLastMassWorld) && (massWorld!=0) )
00298 {
00299
00300 fpNavigator[0] -> SetWorldVolume( massWorld );
00301
00302 #ifdef G4DEBUG_NAVIGATION
00303 if( fVerbose > 0 )
00304 {
00305 G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume "
00306 << " for mass geometry to " << massWorld->GetName() << G4endl;
00307 }
00308 #endif
00309
00310 fLastMassWorld = massWorld;
00311 }
00312 }
00313
00314
00315
00316 G4VPhysicalVolume*
00317 G4MultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position,
00318 const G4ThreeVector* pDirection,
00319 const G4bool pRelativeSearch,
00320 const G4bool ignoreDirection )
00321 {
00322
00323
00324 G4ThreeVector direction(0.0, 0.0, 0.0);
00325 G4bool relative = pRelativeSearch;
00326 std::vector<G4Navigator*>::iterator pNavIter
00327 = pTransportManager->GetActiveNavigatorsIterator();
00328
00329 if( pDirection ) { direction = *pDirection; }
00330
00331 #ifdef G4DEBUG_NAVIGATION
00332 if( fVerbose > 2 )
00333 {
00334 G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
00335 << G4endl;
00336 G4cout << " Locating at position: " << position
00337 << ", with direction: " << direction << G4endl
00338 << " Relative: " << relative
00339 << ", ignore direction: " << ignoreDirection << G4endl;
00340 G4cout << " Number of active navigators: " << fNoActiveNavigators
00341 << G4endl;
00342 }
00343 #endif
00344
00345 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00346 {
00347 if( fWasLimitedByGeometry && fLimitTruth[num] )
00348 {
00349 (*pNavIter)->SetGeometricallyLimitedStep();
00350 }
00351
00352 G4VPhysicalVolume *pLocated
00353 = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
00354 relative, ignoreDirection );
00355
00356
00357 fLocatedVolume[num] = pLocated;
00358
00359
00360
00361 fLimitedStep[num] = kDoNot;
00362 fCurrentStepSize[num] = 0.0;
00363 fLimitTruth[ num ] = false;
00364
00365 #ifdef G4DEBUG_NAVIGATION
00366 if( fVerbose > 2 )
00367 {
00368 G4cout << " Located in world: " << num << ", at: " << position << G4endl
00369 << " Used geomLimStp: " << fLimitTruth[num]
00370 << ", found in volume: " << pLocated << G4endl;
00371 G4cout << " Name = '" ;
00372 if( pLocated )
00373 {
00374 G4cout << pLocated->GetName() << "'";
00375 G4cout << " - CopyNo= " << pLocated->GetCopyNo();
00376 }
00377 else
00378 {
00379 G4cout << "Null' Id: Not-Set ";
00380 }
00381 G4cout << G4endl;
00382 }
00383 #endif
00384 }
00385
00386 fWasLimitedByGeometry = false;
00387 G4VPhysicalVolume* volMassLocated= fLocatedVolume[0];
00388
00389 return volMassLocated;
00390 }
00391
00392
00393
00394 void
00395 G4MultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position)
00396 {
00397
00398
00399 std::vector<G4Navigator*>::iterator pNavIter
00400 = pTransportManager->GetActiveNavigatorsIterator();
00401
00402 #ifdef G4DEBUG_NAVIGATION
00403 if( fVerbose > 2 )
00404 {
00405 G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
00406 << " Re-locating at position: " << position << G4endl;
00407 }
00408 #endif
00409
00410 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00411 {
00412
00413
00414 (*pNavIter)->LocateGlobalPointWithinVolume( position );
00415
00416
00417
00418 fLimitedStep[num] = kDoNot;
00419 fCurrentStepSize[num] = 0.0;
00420
00421 fLimitTruth[ num ] = false;
00422 }
00423 fWasLimitedByGeometry = false;
00424 fLastLocatedPosition = position;
00425 }
00426
00427
00428
00429 G4double G4MultiNavigator::ComputeSafety( const G4ThreeVector& position,
00430 const G4double maxDistance,
00431 const G4bool state)
00432 {
00433
00434
00435 G4double minSafety = kInfinity, safety = kInfinity;
00436
00437 std::vector<G4Navigator*>::iterator pNavigatorIter;
00438 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00439
00440 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00441 {
00442 safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
00443 if( safety < minSafety ) { minSafety = safety; }
00444 }
00445
00446 fSafetyLocation = position;
00447 fMinSafety_atSafLocation = minSafety;
00448
00449 #ifdef G4DEBUG_NAVIGATION
00450 if( fVerbose > 1 )
00451 {
00452 G4cout << " G4MultiNavigator::ComputeSafety - returns: "
00453 << minSafety << ", at location: " << position << G4endl;
00454 }
00455 #endif
00456 return minSafety;
00457 }
00458
00459
00460
00461 G4TouchableHistoryHandle
00462 G4MultiNavigator::CreateTouchableHistoryHandle() const
00463 {
00464 G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()",
00465 "GeomNav0001", FatalException,
00466 "Getting a touchable from G4MultiNavigator is not defined.");
00467
00468 G4TouchableHistory* touchHist;
00469 touchHist= fpNavigator[0] -> CreateTouchableHistory();
00470
00471 G4VPhysicalVolume* locatedVolume= fLocatedVolume[0];
00472 if( locatedVolume == 0 )
00473 {
00474
00475
00476 touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
00477 }
00478
00479 return G4TouchableHistoryHandle(touchHist);
00480 }
00481
00482
00483
00484 void G4MultiNavigator::WhichLimited()
00485 {
00486
00487
00488 G4int last=-1;
00489 const G4int IdTransport= 0;
00490 G4int noLimited=0;
00491 ELimited shared= kSharedOther;
00492
00493 #ifdef G4DEBUG_NAVIGATION
00494 if( fVerbose > 2 )
00495 {
00496 G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
00497 }
00498 #endif
00499
00500
00501
00502 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
00503 && ( fMinStep!= kInfinity);
00504 if( transportLimited )
00505 {
00506 shared= kSharedTransport;
00507 }
00508
00509 for ( register int num= 0; num < fNoActiveNavigators; num++ )
00510 {
00511 G4bool limitedStep;
00512
00513 G4double step= fCurrentStepSize[num];
00514
00515 limitedStep = ( step == fMinStep ) && ( step != kInfinity);
00516
00517 fLimitTruth[ num ] = limitedStep;
00518 if( limitedStep )
00519 {
00520 noLimited++;
00521 fLimitedStep[num] = shared;
00522 last= num;
00523 }
00524 else
00525 {
00526 fLimitedStep[num] = kDoNot;
00527 }
00528 }
00529 if( (last > -1) && (noLimited == 1 ) )
00530 {
00531 fLimitedStep[ last ] = kUnique;
00532 }
00533
00534 fNoLimitingStep= noLimited;
00535
00536 return;
00537 }
00538
00539
00540
00541 void
00542 G4MultiNavigator::PrintLimited()
00543 {
00544
00545
00546 static G4String StrDoNot("DoNot"), StrUnique("Unique"),
00547 StrUndefined("Undefined"),
00548 StrSharedTransport("SharedTransport"),
00549 StrSharedOther("SharedOther");
00550 G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
00551 G4cout << " Minimum step (true): " << fTrueMinStep
00552 << ", reported min: " << fMinStep << G4endl;
00553
00554 #ifdef G4DEBUG_NAVIGATION
00555 if(fVerbose>=2)
00556 {
00557 G4cout << std::setw(5) << " NavId" << " "
00558 << std::setw(12) << " step-size " << " "
00559 << std::setw(12) << " raw-size " << " "
00560 << std::setw(12) << " pre-safety " << " "
00561 << std::setw(15) << " Limited / flag" << " "
00562 << std::setw(15) << " World " << " "
00563 << G4endl;
00564 }
00565 #endif
00566
00567 for ( register int num= 0; num < fNoActiveNavigators; num++ )
00568 {
00569 G4double rawStep = fCurrentStepSize[num];
00570 G4double stepLen = fCurrentStepSize[num];
00571 if( stepLen > fTrueMinStep )
00572 {
00573 stepLen = fTrueMinStep;
00574 }
00575 G4int oldPrec= G4cout.precision(9);
00576
00577 G4cout << std::setw(5) << num << " "
00578 << std::setw(12) << stepLen << " "
00579 << std::setw(12) << rawStep << " "
00580 << std::setw(12) << fNewSafety[num] << " "
00581 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
00582 G4String limitedStr;
00583 switch ( fLimitedStep[num] )
00584 {
00585 case kDoNot : limitedStr= StrDoNot; break;
00586 case kUnique : limitedStr = StrUnique; break;
00587 case kSharedTransport: limitedStr= StrSharedTransport; break;
00588 case kSharedOther : limitedStr = StrSharedOther; break;
00589 default : limitedStr = StrUndefined; break;
00590 }
00591 G4cout << " " << std::setw(15) << limitedStr << " ";
00592 G4cout.precision(oldPrec);
00593
00594 G4Navigator *pNav= fpNavigator[ num ];
00595 G4String WorldName( "Not-Set" );
00596 if (pNav)
00597 {
00598 G4VPhysicalVolume *pWorld= pNav->GetWorldVolume();
00599 if( pWorld )
00600 {
00601 WorldName = pWorld->GetName();
00602 }
00603 }
00604 G4cout << " " << WorldName ;
00605 G4cout << G4endl;
00606 }
00607 }
00608
00609
00610
00611
00612 void G4MultiNavigator::ResetState()
00613 {
00614 fWasLimitedByGeometry= false;
00615
00616 G4Exception("G4MultiNavigator::ResetState()", "GeomNav0001",
00617 FatalException,
00618 "Cannot reset state for navigators of G4MultiNavigator.");
00619
00620 std::vector<G4Navigator*>::iterator pNavigatorIter;
00621 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00622 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00623 {
00624
00625 }
00626 }
00627
00628
00629
00630 void G4MultiNavigator::SetupHierarchy()
00631 {
00632 G4Exception( "G4MultiNavigator::SetupHierarchy()",
00633 "GeomNav0001", FatalException,
00634 "Cannot setup hierarchy for navigators of G4MultiNavigator.");
00635 }
00636
00637
00638
00639 void G4MultiNavigator::CheckMassWorld()
00640 {
00641 G4VPhysicalVolume* navTrackWorld=
00642 pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
00643
00644 if( navTrackWorld != fLastMassWorld )
00645 {
00646 G4Exception( "G4MultiNavigator::CheckMassWorld()",
00647 "GeomNav0003", FatalException,
00648 "Mass world pointer has been changed." );
00649 }
00650 }
00651
00652
00653
00654 G4VPhysicalVolume*
00655 G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point,
00656 const G4ThreeVector &direction,
00657 const G4TouchableHistory &MassHistory)
00658 {
00659
00660
00661 G4VPhysicalVolume* massVolume=0;
00662 G4Navigator* pMassNavigator= fpNavigator[0];
00663
00664 if( pMassNavigator )
00665 {
00666 massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
00667 MassHistory);
00668 }
00669 else
00670 {
00671 G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
00672 "GeomNav0002", FatalException,
00673 "Cannot reset hierarchy before navigators are initialised.");
00674 }
00675
00676 std::vector<G4Navigator*>::iterator pNavIter=
00677 pTransportManager->GetActiveNavigatorsIterator();
00678
00679 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00680 {
00681 G4bool relativeSearch, ignoreDirection;
00682
00683 (*pNavIter)-> LocateGlobalPointAndSetup( point,
00684 &direction,
00685 relativeSearch=false,
00686 ignoreDirection=false);
00687 }
00688 return massVolume;
00689 }
00690
00691
00692
00693 G4ThreeVector
00694 G4MultiNavigator::GetGlobalExitNormal(const G4ThreeVector &argPoint,
00695 G4bool* argpObtained)
00696 {
00697 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
00698 G4bool isObtained= false;
00699
00700 G4int firstNavigatorId= -1;
00701 G4bool oneObtained= false;
00702
00703 if( fNoLimitingStep==1 )
00704 {
00705
00706 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetGlobalExitNormal( argPoint, &isObtained);
00707 *argpObtained= isObtained;
00708 }
00709 else
00710 {
00711 if( fNoLimitingStep > 1 )
00712 {
00713 std::vector<G4Navigator*>::iterator pNavIter=
00714 pTransportManager->GetActiveNavigatorsIterator();
00715
00716 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00717 {
00718 G4ThreeVector oneNormal;
00719 if( fLimitedStep[ num ] )
00720 {
00721 G4ThreeVector newNormal= (*pNavIter)-> GetGlobalExitNormal( argPoint, &oneObtained );
00722 if( oneObtained )
00723 {
00724
00725 if( !isObtained && (newNormal.mag2() != 0.0) )
00726 {
00727 normalGlobalCrd= newNormal;
00728 isObtained = oneObtained;
00729 firstNavigatorId= num;
00730 }else{
00731
00732 G4double dotNewPrevious= newNormal.dot( normalGlobalCrd );
00733 G4double productMagSq= normalGlobalCrd.mag2() * newNormal.mag2();
00734 if( productMagSq > 0.0 )
00735 {
00736 G4double productMag= std::sqrt( productMagSq );
00737 dotNewPrevious /= productMag;
00738 if( dotNewPrevious < (1 - perThousand) )
00739 {
00740 *argpObtained= false;
00741
00742 if( fVerbose > 2 )
00743 {
00744 std::ostringstream message;
00745 message << "Clash of Normal from different Navigators!" << G4endl
00746 << " Previous Navigator Id = " << firstNavigatorId << G4endl
00747 << " Current Navigator Id = " << num << G4endl;
00748 message << " Dot product of 2 normals = " << dotNewPrevious << G4endl;
00749 message << " Normal (previous) = " << normalGlobalCrd << G4endl;
00750 message << " Normal (current) = " << newNormal << G4endl;
00751 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00752 JustWarning, message);
00753 }
00754 }
00755 else
00756 {
00757
00758 }
00759 }
00760 }
00761 }
00762 }
00763 }
00764
00765
00766 if( !oneObtained )
00767 {
00768 std::ostringstream message;
00769 message << "No Normal obtained despite having " << fNoLimitingStep
00770 << " candidate Navigators limiting the step!" << G4endl;
00771 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00772 JustWarning, message);
00773 }
00774
00775 }
00776 }
00777
00778 *argpObtained= isObtained;
00779 return normalGlobalCrd;
00780 }
00781
00782
00783
00784 G4ThreeVector
00785 G4MultiNavigator::GetLocalExitNormal(G4bool* argpObtained)
00786 {
00787
00788 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
00789 G4bool isObtained= false;
00790
00791
00792 if( fNoLimitingStep==1 )
00793 {
00794
00795 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetLocalExitNormal( &isObtained);
00796 *argpObtained= isObtained;
00797
00798 G4int static numberWarnings= 0;
00799 G4int noWarningsStart= 10, noModuloWarnings=100;
00800 numberWarnings++;
00801 if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) )
00802 {
00803 std::ostringstream message;
00804 message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
00805 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00806 JustWarning, message);
00807 }
00808 }
00809 else
00810 {
00811 if( fNoLimitingStep > 1 )
00812 {
00813
00814 std::ostringstream message;
00815 message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
00816 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00817 FatalException, message);
00818 }
00819 }
00820
00821 *argpObtained= isObtained;
00822 return normalGlobalCrd;
00823 }
00824
00825
00826
00827
00828 G4ThreeVector
00829 G4MultiNavigator::GetLocalExitNormalAndCheck(const G4ThreeVector &,
00830 G4bool* obtained)
00831 {
00832 return G4MultiNavigator::GetLocalExitNormal( obtained);
00833 }