G4PathFinder Class Reference

#include <G4PathFinder.hh>


Public Member Functions

G4double ComputeStep (const G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4int navigatorId, G4int stepNo, G4double &pNewSafety, ELimited &limitedStep, G4FieldTrack &EndState, G4VPhysicalVolume *currentVolume)
void Locate (const G4ThreeVector &position, const G4ThreeVector &direction, G4bool relativeSearch=true)
void ReLocate (const G4ThreeVector &position)
void PrepareNewTrack (const G4ThreeVector &position, const G4ThreeVector &direction, G4VPhysicalVolume *massStartVol=0)
G4TouchableHandle CreateTouchableHandle (G4int navId) const
G4VPhysicalVolumeGetLocatedVolume (G4int navId) const
void SetChargeMomentumMass (G4double charge, G4double momentum, G4double pMass)
G4bool IsParticleLooping () const
G4double GetCurrentSafety () const
G4double GetMinimumStep () const
unsigned int GetNumberGeometriesLimitingStep () const
G4double ComputeSafety (const G4ThreeVector &globalPoint)
G4double ObtainSafety (G4int navId, G4ThreeVector &globalCenterPoint)
void EnableParallelNavigation (G4bool enableChoice=true)
G4int SetVerboseLevel (G4int lev=-1)
G4int GetMaxLoopCount () const
void SetMaxLoopCount (G4int new_max)
void MovePoint ()
G4double LastPreSafety (G4int navId, G4ThreeVector &globalCenterPoint, G4double &minSafety)
void PushPostSafetyToPreSafety ()
G4StringLimitedString (ELimited lim)

Static Public Member Functions

static G4PathFinderGetInstance ()

Protected Member Functions

G4double DoNextLinearStep (const G4FieldTrack &FieldTrack, G4double proposedStepLength)
G4double DoNextCurvedStep (const G4FieldTrack &FieldTrack, G4double proposedStepLength, G4VPhysicalVolume *pCurrentPhysVolume)
void WhichLimited ()
void PrintLimited ()
G4bool UseSafetyForOptimization (G4bool)
void ReportMove (const G4ThreeVector &OldV, const G4ThreeVector &NewV, const G4String &Quantity) const
 G4PathFinder ()
 ~G4PathFinder ()
G4NavigatorGetNavigator (G4int n) const


Detailed Description

Definition at line 61 of file G4PathFinder.hh.


Constructor & Destructor Documentation

G4PathFinder::G4PathFinder (  )  [protected]

Definition at line 70 of file G4PathFinder.cc.

References G4GeometryTolerance::GetInstance(), G4TransportationManager::GetPropagatorInField(), G4GeometryTolerance::GetSurfaceTolerance(), G4TransportationManager::GetTransportationManager(), and kUndefLimited.

00071   : fEndState( G4ThreeVector(), G4ThreeVector(), 0., 0., 0., 0., 0.),
00072     fFieldExertedForce(false),
00073     fRelocatedPoint(true),
00074     fLastStepNo(-1), fCurrentStepNo(-1),
00075     fVerboseLevel(0)
00076 {
00077    fpMultiNavigator= new G4MultiNavigator(); 
00078 
00079    fpTransportManager= G4TransportationManager::GetTransportationManager();
00080    fpFieldPropagator = fpTransportManager->GetPropagatorInField();
00081 
00082    kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00083 
00084    fNoActiveNavigators= 0; 
00085    G4ThreeVector  Big3Vector( kInfinity, kInfinity, kInfinity );
00086    fLastLocatedPosition= Big3Vector;
00087    fSafetyLocation= Big3Vector; 
00088    fPreSafetyLocation= Big3Vector;
00089    fPreStepLocation= Big3Vector;
00090 
00091    fPreSafetyMinValue=  -1.0; 
00092    fMinSafety_PreStepPt= -1.0; 
00093    fMinSafety_atSafLocation= -1.0; 
00094    fMinStep=   -1.0;
00095    fTrueMinStep= -1.0;
00096    fPreStepCenterRenewed= false;
00097    fNewTrack= false; 
00098    fNoGeometriesLimiting= 0; 
00099 
00100    for( register int num=0; num< fMaxNav; ++num )
00101    {
00102       fpNavigator[num] =  0;   
00103       fLimitTruth[num] = false;
00104       fLimitedStep[num] = kUndefLimited;
00105       fCurrentStepSize[num] = -1.0; 
00106       fLocatedVolume[num] = 0;
00107       fPreSafetyValues[num]= -1.0; 
00108       fCurrentPreStepSafety[num] = -1.0;
00109       fNewSafetyComputed[num]= -1.0; 
00110    }
00111 }

G4PathFinder::~G4PathFinder (  )  [protected]

Definition at line 116 of file G4PathFinder.cc.

00117 {
00118    delete fpMultiNavigator; 
00119 }


Member Function Documentation

G4double G4PathFinder::ComputeSafety ( const G4ThreeVector globalPoint  ) 

Definition at line 732 of file G4PathFinder.cc.

References G4cout, G4endl, and G4TransportationManager::GetActiveNavigatorsIterator().

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength(), G4SafetyHelper::ComputeSafety(), DoNextCurvedStep(), and ReLocate().

00733 {
00734     // Recompute safety for the relevant point
00735 
00736    G4double minSafety= kInfinity; 
00737   
00738    std::vector<G4Navigator*>::iterator pNavigatorIter;
00739    pNavigatorIter= fpTransportManager->GetActiveNavigatorsIterator();
00740 
00741    for( register G4int num=0; num<fNoActiveNavigators; ++pNavigatorIter,++num )
00742    {
00743       G4double safety = (*pNavigatorIter)->ComputeSafety( position,true );
00744       if( safety < minSafety ) { minSafety = safety; } 
00745       fNewSafetyComputed[num]= safety;
00746    } 
00747 
00748    fSafetyLocation= position;
00749    fMinSafety_atSafLocation = minSafety;
00750 
00751 #ifdef G4DEBUG_PATHFINDER
00752    if( fVerboseLevel > 1 )
00753    { 
00754      G4cout << " G4PathFinder::ComputeSafety - returns " 
00755             << minSafety << " at location " << position << G4endl;
00756    }
00757 #endif
00758    return minSafety; 
00759 }

G4double G4PathFinder::ComputeStep ( const G4FieldTrack pFieldTrack,
G4double  pCurrentProposedStepLength,
G4int  navigatorId,
G4int  stepNo,
G4double pNewSafety,
ELimited limitedStep,
G4FieldTrack EndState,
G4VPhysicalVolume currentVolume 
)

Definition at line 151 of file G4PathFinder.cc.

References DoNextCurvedStep(), DoNextLinearStep(), FatalException, G4PropagatorInField::FindAndSetFieldManager(), G4cout, G4endl, G4Exception(), G4FieldTrack::GetCharge(), G4FieldManager::GetDetectorField(), G4FieldTrack::GetMomentumDirection(), G4FieldTrack::GetPosition(), Locate(), and MovePoint().

Referenced by G4WeightWindowProcess::AlongStepGetPhysicalInteractionLength(), G4WeightCutOffProcess::AlongStepGetPhysicalInteractionLength(), G4ParallelWorldScoringProcess::AlongStepGetPhysicalInteractionLength(), G4ParallelWorldProcess::AlongStepGetPhysicalInteractionLength(), G4ImportanceProcess::AlongStepGetPhysicalInteractionLength(), G4FastSimulationManagerProcess::AlongStepGetPhysicalInteractionLength(), and G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

00159 {
00160   G4double  possibleStep= -1.0; 
00161 
00162 #ifdef G4DEBUG_PATHFINDER
00163   if( fVerboseLevel > 2 )
00164   { 
00165     G4cout << " -------------------------" <<  G4endl;
00166     G4cout << " G4PathFinder::ComputeStep - entered " << G4endl;
00167     G4cout << "   - stepNo = "  << std::setw(4) << stepNo  << " "
00168            << " navigatorId = " << std::setw(2) << navigatorNo  << " "
00169            << " proposed step len = " << proposedStepLength << " " << G4endl;
00170     G4cout << " PF::ComputeStep requested step " 
00171            << " from " << InitialFieldTrack.GetPosition()
00172            << " dir  " << InitialFieldTrack.GetMomentumDirection() << G4endl;
00173   }
00174 #endif
00175 #ifdef G4VERBOSE
00176   if( navigatorNo >= fNoActiveNavigators )
00177   {
00178     std::ostringstream message;
00179     message << "Bad Navigator ID !" << G4endl
00180             << "        Requested Navigator ID = " << navigatorNo << G4endl
00181             << "        Number of active navigators = " << fNoActiveNavigators;
00182     G4Exception("G4PathFinder::ComputeStep()", "GeomNav0002",
00183                 FatalException, message); 
00184   }
00185 #endif
00186 
00187   if( fNewTrack || (stepNo != fLastStepNo)  )
00188   {
00189     // This is a new track or a new step, so we must make the step
00190     // ( else we can simply retrieve its results for this Navigator Id )    
00191 
00192     G4FieldTrack currentState= InitialFieldTrack;
00193 
00194     fCurrentStepNo = stepNo; 
00195 
00196     // Check whether a process shifted the position 
00197     // since the last step -- by physics processes
00198     //
00199     G4ThreeVector newPosition = InitialFieldTrack.GetPosition();   
00200     G4ThreeVector moveVector= newPosition - fLastLocatedPosition; 
00201     G4double moveLenSq= moveVector.mag2(); 
00202     if( moveLenSq > kCarTolerance * kCarTolerance )
00203     { 
00204        G4ThreeVector newDirection = InitialFieldTrack.GetMomentumDirection();   
00205 #ifdef G4DEBUG_PATHFINDER
00206        if( fVerboseLevel > 2 )
00207        { 
00208           G4double moveLen= std::sqrt( moveLenSq ); 
00209           G4cout << " G4PathFinder::ComputeStep : Point moved since last step " 
00210                  << " -- at step # = " << stepNo << G4endl
00211                  << " by " << moveLen  << " to " << newPosition << G4endl;      
00212        } 
00213 #endif
00214        MovePoint();  // Unintentional changed -- ????
00215 
00216        // Relocate to cope with this move -- else could abort !?
00217        //
00218        Locate( newPosition, newDirection ); 
00219     }
00220 
00221     // Check whether the particle have an (EM) field force exerting upon it
00222     //
00223     G4double particleCharge=  currentState.GetCharge(); 
00224 
00225     G4FieldManager* fieldMgr=0;
00226     G4bool          fieldExertsForce = false ;
00227     if( (particleCharge != 0.0) )
00228     {
00229         fieldMgr= fpFieldPropagator->FindAndSetFieldManager( currentVolume );
00230 
00231         // Protect for case where field manager has no field (= field is zero)
00232         //
00233         fieldExertsForce = (fieldMgr != 0) 
00234                         && (fieldMgr->GetDetectorField() != 0);
00235     }
00236     fFieldExertedForce = fieldExertsForce;  // Store for use in later calls
00237                                             // referring to this 'step'.
00238 
00239     fNoGeometriesLimiting= -1;  // At start of track, no process limited step
00240     if( fieldExertsForce )
00241     {
00242        DoNextCurvedStep( currentState, proposedStepLength, currentVolume ); 
00243        //--------------
00244     }else{
00245        DoNextLinearStep( currentState, proposedStepLength ); 
00246        //--------------
00247     }
00248     fLastStepNo= stepNo; 
00249 
00250 #ifdef  G4DEBUG_PATHFINDER
00251     if ( (fNoGeometriesLimiting < 0)
00252       || (fNoGeometriesLimiting > fNoActiveNavigators) )
00253     {
00254       std::ostringstream message;
00255       message << "Number of geometries limiting the step not set." << G4endl
00256               << "        Number of geometries limiting step = "
00257               << fNoGeometriesLimiting;
00258       G4Exception("G4PathFinder::ComputeStep()", 
00259                   "GeomNav0002", FatalException, message); 
00260     }
00261 #endif
00262   }
00263 #ifdef G4DEBUG_PATHFINDER      
00264   else
00265   {
00266      if( proposedStepLength < fTrueMinStep )  // For 2nd+ geometry 
00267      { 
00268        std::ostringstream message;
00269        message << "Problem in step size request." << G4endl
00270                << "        Error can be caused by incorrect process ordering."
00271                << "        Being requested to make a step which is shorter"
00272                << " than the minimum Step " << G4endl
00273                << "        already computed for any Navigator/geometry during"
00274                << " this tracking-step: " << G4endl
00275                << "        This can happen due to an error in process ordering."
00276                << G4endl
00277                << "        Check that all physics processes are registered"
00278                << G4endl
00279                << "        before all processes with a navigator/geometry."
00280                << G4endl
00281                << "        If using pre-packaged physics list and/or"
00282                << G4endl
00283                << "        functionality, please report this error."
00284                << G4endl << G4endl
00285                << "        Additional information for problem: "  << G4endl
00286                << "        Steps request/proposed = " << proposedStepLength
00287                << G4endl
00288                << "        MinimumStep (true) = " << fTrueMinStep
00289                << G4endl
00290                << "        MinimumStep (navraw)  = " << fMinStep
00291                << G4endl
00292                << "        Navigator raw return value" << G4endl
00293                << "        Requested step now = " << proposedStepLength
00294                << G4endl
00295                << "        Difference min-req = "
00296                << fTrueMinStep-proposedStepLength << G4endl
00297                << "     -- Step info> stepNo= " << stepNo
00298                << " last= " << fLastStepNo 
00299                << " newTr= " << fNewTrack << G4endl;
00300         G4Exception("G4PathFinder::ComputeStep()", 
00301                     "GeomNav0003", FatalException, message);
00302      }
00303      else
00304      { 
00305         // This is neither a new track nor a new step -- just another 
00306         // client accessing information for the current track, step 
00307         // We will simply retrieve the results of the synchronous
00308         // stepping for this Navigator Id below.
00309         //
00310         if( fVerboseLevel > 1 )
00311         { 
00312            G4cout << " G4P::CS -> Not calling DoNextLinearStep: " 
00313                   << " stepNo= " << stepNo << " last= " << fLastStepNo 
00314                   << " new= " << fNewTrack << " Step already done" << G4endl; 
00315         }
00316      } 
00317   }
00318 #endif
00319 
00320   fNewTrack= false; 
00321 
00322   // Prepare the information to return
00323 
00324   pNewSafety  = fCurrentPreStepSafety[ navigatorNo ]; 
00325   limitedStep = fLimitedStep[ navigatorNo ];
00326   fRelocatedPoint= false;
00327 
00328   possibleStep= std::min(proposedStepLength, fCurrentStepSize[ navigatorNo ]);
00329   EndState = fEndState;  //  now corrected for smaller step, if needed
00330 
00331 #ifdef G4DEBUG_PATHFINDER
00332   if( fVerboseLevel > 0 )
00333   { 
00334     G4cout << " G4PathFinder::ComputeStep returns "
00335            << fCurrentStepSize[ navigatorNo ]
00336            << " for Navigator " << navigatorNo 
00337            << " Limited step = " << limitedStep 
00338            << " Safety(mm) = " << pNewSafety / mm 
00339            << G4endl; 
00340   }
00341 #endif
00342 
00343   return possibleStep;
00344 }

G4TouchableHandle G4PathFinder::CreateTouchableHandle ( G4int  navId  )  const

Definition at line 765 of file G4PathFinder.cc.

References G4cout, G4endl, G4TouchableHistory::GetHistory(), G4VPhysicalVolume::GetName(), GetNavigator(), and G4TouchableHistory::UpdateYourself().

Referenced by G4WeightWindowProcess::PostStepDoIt(), G4WeightCutOffProcess::PostStepDoIt(), G4ParallelWorldScoringProcess::PostStepDoIt(), G4ParallelWorldProcess::PostStepDoIt(), G4ImportanceProcess::PostStepDoIt(), G4CoupledTransportation::PostStepDoIt(), G4WeightWindowProcess::StartTracking(), G4WeightCutOffProcess::StartTracking(), G4ParallelWorldScoringProcess::StartTracking(), G4ParallelWorldProcess::StartTracking(), and G4ImportanceProcess::StartTracking().

00766 {
00767 #ifdef G4DEBUG_PATHFINDER
00768   if( fVerboseLevel > 2 )
00769   {
00770     G4cout << "G4PathFinder::CreateTouchableHandle : navId = "
00771            << navId << " -- " << GetNavigator(navId) << G4endl;
00772   }
00773 #endif
00774 
00775   G4TouchableHistory* touchHist;
00776   touchHist= GetNavigator(navId) -> CreateTouchableHistory(); 
00777 
00778   G4VPhysicalVolume* locatedVolume= fLocatedVolume[navId]; 
00779   if( locatedVolume == 0 )
00780   {
00781      // Workaround to ensure that the touchable is fixed !! // TODO: fix
00782 
00783      touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
00784   }
00785  
00786 #ifdef G4DEBUG_PATHFINDER
00787   if( fVerboseLevel > 2 )
00788   {   
00789     G4String VolumeName("None"); 
00790     if( locatedVolume ) { VolumeName= locatedVolume->GetName(); }
00791     G4cout << " Touchable History created at address " << touchHist
00792            << "  volume = " << locatedVolume << " name= " << VolumeName
00793            << G4endl;
00794   }
00795 #endif
00796 
00797   return G4TouchableHandle(touchHist); 
00798 }

G4double G4PathFinder::DoNextCurvedStep ( const G4FieldTrack FieldTrack,
G4double  proposedStepLength,
G4VPhysicalVolume pCurrentPhysVolume 
) [protected]

Definition at line 1137 of file G4PathFinder.cc.

References ComputeSafety(), G4PropagatorInField::ComputeStep(), FatalException, G4cout, G4endl, G4Exception(), G4FieldTrack::GetPosition(), kDoNot, LimitedString(), G4MultiNavigator::ObtainFinalStep(), and PrintLimited().

Referenced by ComputeStep().

01140 {
01141   const G4double toleratedRelativeError= 1.0e-10; 
01142   G4double minStep= kInfinity, newSafety=0.0;
01143   G4int numNav; 
01144   G4FieldTrack  fieldTrack= initialState;
01145   G4ThreeVector startPoint= initialState.GetPosition(); 
01146 
01147 #ifdef G4DEBUG_PATHFINDER
01148   G4int prc= G4cout.precision(9);
01149   if( fVerboseLevel > 2 )
01150   {
01151     G4cout << " G4PathFinder::DoNextCurvedStep ****** " << G4endl;
01152     G4cout << " Initial value of field track is " << fieldTrack 
01153            << " and proposed step= " << proposedStepLength  << G4endl;
01154   }
01155 #endif
01156 
01157   fPreStepCenterRenewed= true; // Always update PreSafety with PreStep point
01158 
01159   if( fNoActiveNavigators > 1 )
01160   { 
01161      // Calculate the safety values before making the step
01162 
01163      G4double minSafety= kInfinity, safety; 
01164      for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
01165      {
01166         safety= fpNavigator[numNav]->ComputeSafety( startPoint, false );
01167         fPreSafetyValues[numNav]= safety; 
01168         fCurrentPreStepSafety[numNav]= safety; 
01169         minSafety = std::min( safety, minSafety ); 
01170      }
01171 
01172      // Save safety value, related position
01173 
01174      fPreSafetyLocation=  startPoint;   
01175      fPreSafetyMinValue=  minSafety;
01176      fPreStepLocation=    startPoint;
01177      fMinSafety_PreStepPt= minSafety;
01178   }
01179 
01180   // Allow Propagator In Field to do the hard work, calling G4MultiNavigator
01181   //
01182   minStep=  fpFieldPropagator->ComputeStep( fieldTrack,
01183                                             proposedStepLength,
01184                                             newSafety, 
01185                                             pCurrentPhysicalVolume );
01186 
01187   // fieldTrack now contains the endpoint information
01188   //
01189   fEndState= fieldTrack; 
01190   fMinStep=   minStep; 
01191   fTrueMinStep = std::min( minStep, proposedStepLength );
01192 
01193   if( fNoActiveNavigators== 1 )
01194   { 
01195      // Update the 'PreSafety' sphere - as any ComputeStep was called 
01196      // (must be done anyway in field)
01197 
01198      fPreSafetyValues[0]=   newSafety;
01199      fPreSafetyLocation= startPoint;   
01200      fPreSafetyMinValue= newSafety;
01201 
01202      // Update the current 'PreStep' point's values - mandatory
01203      //
01204      fCurrentPreStepSafety[0]= newSafety; 
01205      fPreStepLocation=  startPoint;
01206      fMinSafety_PreStepPt= newSafety;
01207   }
01208 
01209 #ifdef G4DEBUG_PATHFINDER
01210   if( fVerboseLevel > 2 )
01211   {
01212     G4cout << "G4PathFinder::DoNextCurvedStep : " << G4endl
01213            << " initialState = " << initialState << G4endl
01214            << " and endState = " << fEndState << G4endl;
01215     G4cout << "G4PathFinder::DoNextCurvedStep : " 
01216            << " minStep = " << minStep 
01217            << " proposedStepLength " << proposedStepLength 
01218            << " safety = " << newSafety << G4endl;
01219   }
01220 #endif
01221   G4double currentStepSize;   // = 0.0; 
01222   if( minStep < proposedStepLength ) // if == , then a boundary found at end ??
01223   {   
01224     // Recover the remaining information from MultiNavigator
01225     // especially regarding which Navigator limited the step
01226 
01227     G4int noLimited= 0;  //   No geometries limiting step
01228     for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
01229     {
01230       G4double finalStep, lastPreSafety=0.0, minStepLast;
01231       ELimited didLimit; 
01232       G4bool limited; 
01233 
01234       finalStep=  fpMultiNavigator->ObtainFinalStep( numNav, lastPreSafety, 
01235                                                      minStepLast, didLimit );
01236 
01237       // Calculate the step for this geometry, using the 
01238       // final step (the only one which can differ.)
01239 
01240       currentStepSize = fTrueMinStep;  
01241       G4double diffStep= 0.0; 
01242       if( (minStepLast != kInfinity) )
01243       { 
01244         diffStep = (finalStep-minStepLast);
01245         if ( std::abs(diffStep) <= toleratedRelativeError * finalStep ) 
01246         {
01247           diffStep = 0.0;
01248         }
01249         currentStepSize += diffStep; 
01250       }
01251       fCurrentStepSize[numNav] = currentStepSize;  
01252       
01253       // TODO: could refine the way to obtain safeties for > 1 geometries
01254       //     - for pre step safety
01255       //        notify MultiNavigator about new set of sub-steps
01256       //        allow it to return this value in ObtainFinalStep 
01257       //        instead of lastPreSafety (or as well?)
01258       //     - for final step start (available)
01259       //        get final Step start from MultiNavigator
01260       //        and corresponding safety values
01261       // and/or ALSO calculate ComputeSafety at endpoint
01262       //     endSafety= fpNavigator[numNav]->ComputeSafety( endPoint ); 
01263 
01264       fLimitedStep[numNav] = didLimit; 
01265       fLimitTruth[numNav] = limited = (didLimit != kDoNot ); 
01266       if( limited ) { noLimited++; }
01267 
01268 #ifdef G4DEBUG_PATHFINDER
01269       G4bool StepError= (currentStepSize < 0) 
01270                    || ( (minStepLast != kInfinity) && (diffStep < 0) ) ; 
01271       if( StepError || (fVerboseLevel > 2) )
01272       {
01273         G4String  limitedString=  LimitedString( fLimitedStep[numNav] ); 
01274         
01275         G4cout << " G4PathFinder::ComputeStep. Geometry " << numNav
01276                << "  step= " << fCurrentStepSize[numNav] 
01277                << " from final-step= " << finalStep 
01278                << " fTrueMinStep= " << fTrueMinStep 
01279                << " minStepLast= "  << minStepLast 
01280                << "  limited = " << (fLimitTruth[numNav] ? "YES" : " NO")
01281                << " ";
01282         G4cout << "  status = " << limitedString << " #= " << didLimit
01283                << G4endl;
01284         
01285         if( StepError )
01286         { 
01287           std::ostringstream message;
01288           message << "Incorrect calculation of step size for one navigator"
01289                   << G4endl
01290                   << "        currentStepSize = " << currentStepSize 
01291                   << ", diffStep= " << diffStep << G4endl
01292                   << "ERROR in computing step size for this navigator.";
01293           G4Exception("G4PathFinder::DoNextCurvedStep",
01294                       "GeomNav0003", FatalException, message);
01295         }
01296       }
01297 #endif
01298     } // for num Navigators
01299 
01300     fNoGeometriesLimiting= noLimited;  // Save # processes limiting step
01301   } 
01302   else if ( (minStep == proposedStepLength)  
01303             || (minStep == kInfinity)  
01304             || ( std::abs(minStep-proposedStepLength)
01305                < toleratedRelativeError * proposedStepLength ) )
01306   { 
01307     // In case the step was not limited, use default responses
01308     //  --> all Navigators 
01309     // Also avoid problems in case of PathFinder using safety to optimise
01310     //  - it is possible that the Navigators were not called
01311     //    if the safety was already satisfactory.
01312     //    (In that case calling ObtainFinalStep gives invalid results.)
01313 
01314     currentStepSize= minStep;
01315     for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
01316     {
01317       fCurrentStepSize[numNav] = minStep; 
01318       // Safety for endpoint ??  // Can eventuall improve it -- see TODO above
01319       fLimitedStep[numNav] = kDoNot; 
01320       fLimitTruth[numNav] = false; 
01321     }
01322     fNoGeometriesLimiting= 0;  // Save # processes limiting step
01323   } 
01324   else    //  (minStep > proposedStepLength) and not (minStep == kInfinity)
01325   {
01326     std::ostringstream message;
01327     message << "Incorrect calculation of step size for one navigator." << G4endl
01328             << "        currentStepSize = " << minStep << " is larger than "
01329             << " proposed StepSize = " << proposedStepLength << ".";
01330     G4Exception("G4PathFinder::DoNextCurvedStep()",
01331                 "GeomNav0003", FatalException, message); 
01332   }
01333 
01334 #ifdef G4DEBUG_PATHFINDER
01335   if( fVerboseLevel > 2 )
01336   {
01337     G4cout << " Exiting G4PathFinder::DoNextCurvedStep " << G4endl;
01338     PrintLimited(); 
01339   }
01340   G4cout.precision(prc); 
01341 #endif
01342 
01343   return minStep; 
01344 }

G4double G4PathFinder::DoNextLinearStep ( const G4FieldTrack FieldTrack,
G4double  proposedStepLength 
) [protected]

Definition at line 801 of file G4PathFinder.cc.

References G4cout, G4endl, G4FieldTrack::GetMomentumDirection(), G4FieldTrack::GetPosition(), kDoNot, kUnique, G4FieldTrack::SetPosition(), G4FieldTrack::SetProperTimeOfFlight(), sqr(), and WhichLimited().

Referenced by ComputeStep().

00803 {
00804   std::vector<G4Navigator*>::iterator pNavigatorIter;
00805   G4double safety= 0.0, step=0.0;
00806   G4double minSafety= kInfinity, minStep;
00807 
00808   const G4int IdTransport= 0;  // Id of Mass Navigator !!
00809   register G4int num=0; 
00810 
00811 #ifdef G4DEBUG_PATHFINDER
00812   if( fVerboseLevel > 2 )
00813   {
00814     G4cout << " G4PathFinder::DoNextLinearStep : entered " << G4endl;
00815     G4cout << "   Input field track= " << initialState << G4endl;
00816     G4cout << "   Requested step= " << proposedStepLength << G4endl;
00817   }
00818 #endif
00819 
00820   G4ThreeVector initialPosition= initialState.GetPosition(); 
00821   G4ThreeVector initialDirection= initialState.GetMomentumDirection();
00822   
00823   G4ThreeVector OriginShift = initialPosition - fPreSafetyLocation;
00824   G4double      MagSqShift  = OriginShift.mag2() ;
00825   G4double      MagShift;  // Only given value if it larger than minimum safety
00826 
00827   // Potential optimisation using Maximum Value of safety!
00828   // if( MagSqShift >= sqr(fPreSafetyMaxValue ) ){ 
00829   //   MagShift= kInfinity;   // Not a useful value -- all will not use/ignore
00830   // else
00831   //  MagShift= std::sqrt(MagSqShift) ;
00832 
00833   MagShift= std::sqrt(MagSqShift) ;
00834 
00835 #ifdef G4PATHFINDER_OPTIMISATION
00836 
00837   G4double fullSafety;  // For all geometries, for prestep point
00838 
00839   if( MagSqShift >= sqr(fPreSafetyMinValue ) )
00840   {
00841      fullSafety = 0.0 ;     
00842   }
00843   else
00844   {
00845      fullSafety = fPreSafetyMinValue - MagShift;
00846   }
00847   if( proposedStepLength < fullSafety ) 
00848   {
00849      // Move is smaller than all safeties
00850      //  -> so we do not have to move the safety center
00851 
00852      fPreStepCenterRenewed= false;
00853 
00854      for( num=0; num< fNoActiveNavigators; ++num )
00855      {
00856         fCurrentStepSize[num]= kInfinity; 
00857         safety = std::max( 0.0,  fPreSafetyValues[num] - MagShift); 
00858         minSafety= std::min( safety, minSafety ); 
00859         fCurrentPreStepSafety[num]= safety; 
00860      }
00861      minStep= kInfinity;
00862 
00863 #ifdef G4DEBUG_PATHFINDER
00864      if( fVerboseLevel > 2 )
00865      {
00866        G4cout << "G4PathFinder::DoNextLinearStep : Quick Stepping. " << G4endl
00867                << " proposedStepLength " <<  proposedStepLength
00868                << " < (full) safety = " << fullSafety 
00869                << " at " << initialPosition 
00870                << G4endl;
00871      }
00872 #endif
00873   }
00874   else
00875 #endif   // End of G4PATHFINDER_OPTIMISATION 1
00876   {
00877      // Move is larger than at least one of the safeties
00878      //  -> so we must move the safety center!
00879 
00880      fPreStepCenterRenewed= true;
00881      pNavigatorIter= fpTransportManager-> GetActiveNavigatorsIterator();
00882 
00883      minStep= kInfinity;  // Not proposedStepLength; 
00884 
00885      for( num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num ) 
00886      {
00887         safety = std::max( 0.0,  fPreSafetyValues[num] - MagShift); 
00888 
00889 #ifdef G4PATHFINDER_OPTIMISATION
00890         if( proposedStepLength <= safety )  // Should be just < safety ?
00891         {
00892            // The Step is guaranteed to be taken
00893 
00894            step= kInfinity;    //  ComputeStep Would return this
00895 
00896 #ifdef G4DEBUG_PATHFINDER
00897            G4cout.precision(8); 
00898            G4cout << "PathFinder::ComputeStep> small proposed step = "
00899                   << proposedStepLength
00900                   << " <=  safety = " << safety << " for nav " << num 
00901                   << " Step fully taken. " << G4endl;
00902 #endif
00903         }
00904         else
00905 #endif   // End of G4PATHFINDER_OPTIMISATION 2
00906         {
00907 #ifdef G4DEBUG_PATHFINDER
00908            G4double previousSafety= safety; 
00909 #endif
00910            step= (*pNavigatorIter)->ComputeStep( initialPosition, 
00911                                                  initialDirection,
00912                                                  proposedStepLength,
00913                                                  safety ); 
00914            minStep  = std::min( step,  minStep);
00915 
00916            //  TODO: consider whether/how to reduce the proposed step 
00917            //        to the latest minStep value - to reduce calculations
00918 
00919 #ifdef G4DEBUG_PATHFINDER
00920            if( fVerboseLevel > 0)
00921            {
00922              G4cout.precision(8); 
00923              G4cout << "PathFinder::ComputeStep> long  proposed step = "
00924                     << proposedStepLength
00925                     << "  >  safety = " << previousSafety
00926                     << " for nav " << num 
00927                     << " .  New safety = " << safety << " step= " << step
00928                     << G4endl;      
00929            } 
00930 #endif
00931         }
00932         fCurrentStepSize[num] = step; 
00933 
00934         // Save safety value, must be done for all geometries "together"
00935         // (even if not recomputed using call to ComputeStep)
00936         // since they share the fPreSafetyLocation
00937 
00938         fPreSafetyValues[num]= safety; 
00939         fCurrentPreStepSafety[num]= safety; 
00940 
00941         minSafety= std::min( safety, minSafety ); 
00942            
00943 #ifdef G4DEBUG_PATHFINDER
00944         if( fVerboseLevel > 2 )
00945         {
00946           G4cout << "G4PathFinder::DoNextLinearStep : Navigator ["
00947                  << num << "] -- step size " << step << G4endl;
00948         }
00949 #endif
00950      }
00951 
00952      // Only change these when safety is recalculated
00953      // it is good/relevant only for safety calculations
00954 
00955      fPreSafetyLocation=  initialPosition; 
00956      fPreSafetyMinValue=  minSafety;
00957   } // end of else for  if( proposedStepLength <= fullSafety)
00958 
00959   // For use in Relocation, need PreStep point location, min-safety
00960   //
00961   fPreStepLocation= initialPosition; 
00962   fMinSafety_PreStepPt= minSafety; 
00963 
00964   fMinStep=   minStep; 
00965 
00966   if( fMinStep == kInfinity )
00967   {
00968      minStep = proposedStepLength;   //  Use this below for endpoint !!
00969   }
00970   fTrueMinStep = minStep;
00971 
00972   // Set the EndState
00973 
00974   G4ThreeVector endPosition;
00975 
00976   fEndState= initialState; 
00977   endPosition= initialPosition + minStep * initialDirection ; 
00978 
00979 #ifdef G4DEBUG_PATHFINDER
00980   if( fVerboseLevel > 1 )
00981   {
00982     G4cout << "G4PathFinder::DoNextLinearStep : "
00983            << " initialPosition = " << initialPosition 
00984            << " and endPosition = " << endPosition<< G4endl;
00985   }
00986 #endif
00987 
00988   fEndState.SetPosition( endPosition ); 
00989   fEndState.SetProperTimeOfFlight( -1.000 );   // Not defined YET
00990 
00991   if( fNoActiveNavigators == 1 )
00992   { 
00993      G4bool transportLimited = (fMinStep!= kInfinity); 
00994      fLimitTruth[IdTransport] = transportLimited; 
00995      fLimitedStep[IdTransport] = transportLimited ? kUnique : kDoNot;
00996 
00997      // Set fNoGeometriesLimiting - as WhichLimited does
00998      fNoGeometriesLimiting = transportLimited ? 1 : 0;  
00999   }
01000   else
01001   {
01002      WhichLimited(); 
01003   }
01004 
01005 #ifdef G4DEBUG_PATHFINDER
01006   if( fVerboseLevel > 2 )
01007   {
01008     G4cout << " G4PathFinder::DoNextLinearStep : exits returning "
01009            << minStep << G4endl;
01010     G4cout << "   Endpoint values = " << fEndState << G4endl;
01011     G4cout << G4endl;
01012   }
01013 #endif
01014 
01015   return minStep;
01016 }

void G4PathFinder::EnableParallelNavigation ( G4bool  enableChoice = true  ) 

Definition at line 124 of file G4PathFinder.cc.

References G4SafetyHelper::EnableParallelNavigation(), G4TransportationManager::GetNavigatorForTracking(), G4TransportationManager::GetSafetyHelper(), and G4PropagatorInField::SetNavigatorForPropagating().

Referenced by PrepareNewTrack().

00125 {
00126    G4Navigator *navigatorForPropagation=0, *massNavigator=0;
00127 
00128    massNavigator= fpTransportManager->GetNavigatorForTracking(); 
00129    if( enableChoice )
00130    {
00131       navigatorForPropagation= fpMultiNavigator;
00132 
00133       // Enable SafetyHelper to use PF
00134       //
00135       fpTransportManager->GetSafetyHelper()->EnableParallelNavigation(true);
00136    }
00137    else
00138    {
00139       navigatorForPropagation= massNavigator;
00140        
00141       // Disable SafetyHelper to use PF
00142       //
00143       fpTransportManager->GetSafetyHelper()->EnableParallelNavigation(false);
00144    }
00145    fpFieldPropagator->SetNavigatorForPropagating(navigatorForPropagation);
00146 }

G4double G4PathFinder::GetCurrentSafety (  )  const [inline]

Definition at line 298 of file G4PathFinder.hh.

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

00299 {
00300   return fMinSafety_PreStepPt;
00301 }

G4PathFinder * G4PathFinder::GetInstance (  )  [static]

Definition at line 57 of file G4PathFinder.cc.

Referenced by G4CoupledTransportation::G4CoupledTransportation(), G4FastSimulationManagerProcess::G4FastSimulationManagerProcess(), G4ImportanceProcess::G4ImportanceProcess(), G4ParallelWorldProcess::G4ParallelWorldProcess(), G4ParallelWorldScoringProcess::G4ParallelWorldScoringProcess(), G4WeightCutOffProcess::G4WeightCutOffProcess(), G4WeightWindowProcess::G4WeightWindowProcess(), and G4SafetyHelper::InitialiseNavigator().

00058 {
00059    static G4PathFinder theInstance; 
00060    if( ! fpPathFinder )
00061    {
00062      fpPathFinder = &theInstance; 
00063    }
00064    return fpPathFinder;
00065 }

G4VPhysicalVolume * G4PathFinder::GetLocatedVolume ( G4int  navId  )  const [inline]

Definition at line 275 of file G4PathFinder.hh.

Referenced by G4FastSimulationManagerProcess::AtRestGetPhysicalInteractionLength(), and G4FastSimulationManagerProcess::PostStepGetPhysicalInteractionLength().

00276 {
00277   G4VPhysicalVolume* vol=0;  
00278   if( (navId < fMaxNav) && (navId >=0) ) { vol= fLocatedVolume[navId]; }
00279   return vol; 
00280 }

G4int G4PathFinder::GetMaxLoopCount (  )  const [inline]

G4double G4PathFinder::GetMinimumStep (  )  const [inline]

Definition at line 287 of file G4PathFinder.hh.

00288 { 
00289   return fMinStep; 
00290 } 

G4Navigator * G4PathFinder::GetNavigator ( G4int  n  )  const [inline, protected]

Definition at line 308 of file G4PathFinder.hh.

Referenced by CreateTouchableHandle(), and PrintLimited().

00309 { 
00310   if( (n>fNoActiveNavigators)||(n<0)) { n=0; }
00311   return fpNavigator[n];
00312 }

unsigned int G4PathFinder::GetNumberGeometriesLimitingStep (  )  const [inline]

Definition at line 292 of file G4PathFinder.hh.

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

00293 {
00294   unsigned int noGeometries=fNoGeometriesLimiting;
00295   return noGeometries; 
00296 }

G4bool G4PathFinder::IsParticleLooping (  )  const [inline]

G4double G4PathFinder::LastPreSafety ( G4int  navId,
G4ThreeVector globalCenterPoint,
G4double minSafety 
) [inline]

Definition at line 321 of file G4PathFinder.hh.

00324 {
00325   globalCenterPoint= fPreSafetyLocation;
00326   minSafety=         fPreSafetyMinValue;
00327   //  navId = std::min( navId, fMaxNav-1 ); 
00328   return  fPreSafetyValues[ navId ];
00329 }

G4String & G4PathFinder::LimitedString ( ELimited  lim  ) 

Definition at line 1346 of file G4PathFinder.cc.

References kDoNot, kSharedOther, kSharedTransport, and kUnique.

Referenced by DoNextCurvedStep(), and PrintLimited().

01347 {
01348   static G4String StrDoNot("DoNot"),
01349                   StrUnique("Unique"),
01350                   StrUndefined("Undefined"),
01351                   StrSharedTransport("SharedTransport"),  
01352                   StrSharedOther("SharedOther");
01353 
01354   G4String* limitedStr;
01355   switch ( lim )
01356   {
01357      case kDoNot:  limitedStr= &StrDoNot; break;
01358      case kUnique: limitedStr = &StrUnique; break; 
01359      case kSharedTransport:  limitedStr= &StrSharedTransport; break; 
01360      case kSharedOther: limitedStr = &StrSharedOther; break;
01361      default: limitedStr = &StrUndefined; break;
01362   }
01363   return *limitedStr;
01364 }

void G4PathFinder::Locate ( const G4ThreeVector position,
const G4ThreeVector direction,
G4bool  relativeSearch = true 
)

Definition at line 458 of file G4PathFinder.cc.

References G4cout, G4endl, G4TransportationManager::GetActiveNavigatorsIterator(), G4FieldTrack::GetPosition(), kDoNot, and ReportMove().

Referenced by ComputeStep(), G4SafetyHelper::Locate(), G4CoupledTransportation::PostStepDoIt(), and PrepareNewTrack().

00461 {
00462   // Locate the point in each geometry
00463 
00464   std::vector<G4Navigator*>::iterator pNavIter=
00465      fpTransportManager->GetActiveNavigatorsIterator(); 
00466 
00467   G4ThreeVector lastEndPosition= fEndState.GetPosition(); 
00468   G4ThreeVector moveVec = (position - lastEndPosition );
00469   G4double      moveLenSq= moveVec.mag2();
00470   if( (!fNewTrack) && (!fRelocatedPoint)
00471    && ( moveLenSq> kCarTolerance*kCarTolerance ) )
00472   {
00473      ReportMove( position, lastEndPosition, "Position" ); 
00474   }
00475   fLastLocatedPosition= position; 
00476 
00477 #ifdef G4DEBUG_PATHFINDER
00478   if( fVerboseLevel > 2 )
00479   {
00480     G4cout << G4endl; 
00481     G4cout << " G4PathFinder::Locate : entered " << G4endl;
00482     G4cout << " --------------------   -------" <<  G4endl;
00483     G4cout << "   Locating at position " << position
00484            << "  with direction " << direction 
00485            << "  relative= " << relative << G4endl;
00486     if ( (fVerboseLevel > 1) || ( moveLenSq > 0.0) )
00487     { 
00488        G4cout << "  lastEndPosition = " << lastEndPosition
00489               << "  moveVec = " << moveVec
00490               << "  newTr = " << fNewTrack 
00491               << "  relocated = " << fRelocatedPoint << G4endl;
00492     }
00493 
00494     G4cout << " Located at " << position ; 
00495     if( fNoActiveNavigators > 1 )  { G4cout << G4endl; }
00496   }
00497 #endif
00498 
00499   for ( register G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00500   {
00501      //  ... who limited the step ....
00502 
00503      if( fLimitTruth[num] ) { (*pNavIter)->SetGeometricallyLimitedStep(); }
00504 
00505      G4VPhysicalVolume *pLocated= 
00506      (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
00507                                              relative,  
00508                                              false);   
00509      // Set the state related to the location
00510      //
00511      fLocatedVolume[num] = pLocated; 
00512 
00513      // Clear state related to the step
00514      //
00515      fLimitedStep[num]   = kDoNot; 
00516      fCurrentStepSize[num] = 0.0;      
00517     
00518 #ifdef G4DEBUG_PATHFINDER
00519      if( fVerboseLevel > 2 )
00520      {
00521        G4cout << " - In world " << num << " geomLimStep= " << fLimitTruth[num]
00522               << "  gives volume= " << pLocated ; 
00523        if( pLocated )
00524        { 
00525          G4cout << "  name = '" << pLocated->GetName() << "'"; 
00526          G4cout << " - CopyNo= " << pLocated->GetCopyNo(); 
00527        } 
00528        G4cout  << G4endl; 
00529      }
00530 #endif
00531   }
00532 
00533   fRelocatedPoint= false;
00534 }

void G4PathFinder::MovePoint (  )  [inline]

Definition at line 303 of file G4PathFinder.hh.

Referenced by ComputeStep(), and PrepareNewTrack().

00304 {
00305   fRelocatedPoint= true;
00306 }

G4double G4PathFinder::ObtainSafety ( G4int  navId,
G4ThreeVector globalCenterPoint 
) [inline]

Definition at line 314 of file G4PathFinder.hh.

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

00315 {
00316   globalCenterPoint= fSafetyLocation; 
00317   //  navId = std::min( navId, fMaxNav-1 ); 
00318   return  fNewSafetyComputed[ navId ];
00319 }

void G4PathFinder::PrepareNewTrack ( const G4ThreeVector position,
const G4ThreeVector direction,
G4VPhysicalVolume massStartVol = 0 
)

Definition at line 349 of file G4PathFinder.cc.

References EnableParallelNavigation(), FatalException, G4endl, G4Exception(), G4TransportationManager::GetActiveNavigatorsIterator(), G4TransportationManager::GetSafetyHelper(), G4SafetyHelper::InitialiseHelper(), kDoNot, Locate(), MovePoint(), and G4MultiNavigator::PrepareNavigators().

Referenced by G4WeightWindowProcess::StartTracking(), G4WeightCutOffProcess::StartTracking(), G4ParallelWorldScoringProcess::StartTracking(), G4ParallelWorldProcess::StartTracking(), G4ImportanceProcess::StartTracking(), G4FastSimulationManagerProcess::StartTracking(), and G4CoupledTransportation::StartTracking().

00352 {
00353   // Key purposes:
00354   //   - Check and cache set of active navigators
00355   //   - Reset state for new track
00356 
00357   G4int num=0; 
00358 
00359   EnableParallelNavigation(true); 
00360     // Switch PropagatorInField to use MultiNavigator
00361 
00362   fpTransportManager->GetSafetyHelper()->InitialiseHelper(); 
00363     // Reinitialise state of safety helper -- avoid problems with overlaps
00364 
00365   fNewTrack= true; 
00366   this->MovePoint();   // Signal further that the last status is wiped
00367 
00368   // Message the G4NavigatorPanel / Dispatcher to find active navigators
00369   //
00370   std::vector<G4Navigator*>::iterator pNavigatorIter; 
00371 
00372   fNoActiveNavigators=  fpTransportManager-> GetNoActiveNavigators();
00373   if( fNoActiveNavigators > fMaxNav )
00374   {
00375     std::ostringstream message;
00376     message << "Too many active Navigators / worlds." << G4endl
00377             << "        Transportation Manager has "
00378             << fNoActiveNavigators << " active navigators." << G4endl
00379             << "        This is more than the number allowed = "
00380             << fMaxNav << " !";
00381     G4Exception("G4PathFinder::PrepareNewTrack()", "GeomNav0002",  
00382                 FatalException, message); 
00383   }
00384 
00385   fpMultiNavigator->PrepareNavigators(); 
00386   //------------------------------------
00387 
00388   pNavigatorIter= fpTransportManager->GetActiveNavigatorsIterator();
00389   for( num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00390   {
00391      // Keep information in C-array ... for creating touchables - at least
00392 
00393      fpNavigator[num] =  *pNavigatorIter;   
00394      fLimitTruth[num] = false;
00395      fLimitedStep[num] = kDoNot;
00396      fCurrentStepSize[num] = 0.0; 
00397      fLocatedVolume[num] = 0; 
00398   }
00399   fNoGeometriesLimiting= 0;  // At start of track, no process limited step
00400 
00401   // In case of one geometry, the tracking will have done the locating!!
00402 
00403   if( fNoActiveNavigators > 1 )
00404   {
00405      Locate( position, direction, false );   
00406   }
00407   else
00408   {
00409      // Update state -- depending on the tracking's call to Mass Navigator
00410 
00411      fLastLocatedPosition= position; 
00412      fLocatedVolume[0]= massStartVol; // This information must be given
00413                                       // by transportation
00414      fLimitedStep[0]   = kDoNot; 
00415      fCurrentStepSize[0] = 0.0;
00416   }
00417 
00418   // Reset Safety Information -- as in case of overlaps this can cause
00419   // inconsistencies ...
00420   //
00421   fMinSafety_PreStepPt= fPreSafetyMinValue= fMinSafety_atSafLocation= 0.0; 
00422  
00423   for( num=0; num< fNoActiveNavigators; ++num )
00424   {
00425      fPreSafetyValues[num]= 0.0; 
00426      fNewSafetyComputed[num]= 0.0; 
00427      fCurrentPreStepSafety[num] = 0.0;
00428   }
00429 
00430   // The first location for each Navigator must be non-relative
00431   // or else call ResetStackAndState() for each Navigator
00432 
00433   fRelocatedPoint= false; 
00434 }

void G4PathFinder::PrintLimited (  )  [protected]

Definition at line 1076 of file G4PathFinder.cc.

References G4cout, G4endl, G4VPhysicalVolume::GetName(), GetNavigator(), G4Navigator::GetWorldVolume(), and LimitedString().

Referenced by DoNextCurvedStep(), and WhichLimited().

01077 {
01078   // Report results -- for checking   
01079 
01080   G4cout << "G4PathFinder::PrintLimited reports: " ; 
01081   G4cout << "  Minimum step (true)= " << fTrueMinStep 
01082          << "  reported min = " << fMinStep 
01083          << G4endl; 
01084   if(  (fCurrentStepNo <= 2) || (fVerboseLevel>=2) )
01085   {
01086     G4cout << std::setw(5) << " Step#"  << " "
01087            << std::setw(5) << " NavId"  << " "
01088            << std::setw(12) << " step-size " << " "
01089            << std::setw(12) << " raw-size "  << " "
01090            << std::setw(12) << " pre-safety " << " " 
01091            << std::setw(15) << " Limited / flag"  << " "
01092            << std::setw(15) << "  World "  << " "
01093            << G4endl;  
01094   }
01095   G4int num;
01096   for ( num= 0; num < fNoActiveNavigators; num++ )
01097   { 
01098     G4double rawStep = fCurrentStepSize[num]; 
01099     G4double stepLen = fCurrentStepSize[num]; 
01100     if( stepLen > fTrueMinStep )
01101     { 
01102       stepLen = fTrueMinStep;     // did not limit (went as far as asked)
01103     }
01104     G4int oldPrec= G4cout.precision(9); 
01105 
01106     G4cout << std::setw(5) << fCurrentStepNo  << " " 
01107            << std::setw(5) << num  << " "
01108            << std::setw(12) << stepLen << " "
01109            << std::setw(12) << rawStep << " "
01110            << std::setw(12) << fCurrentPreStepSafety[num] << " "
01111            << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
01112     G4String limitedStr= LimitedString(fLimitedStep[num]); 
01113     G4cout << " " << std::setw(15) << limitedStr << " ";  
01114     G4cout.precision(oldPrec); 
01115 
01116     G4Navigator *pNav= GetNavigator( num ); 
01117     G4String  WorldName( "Not-Set" ); 
01118     if (pNav)
01119     {
01120        G4VPhysicalVolume *pWorld= pNav->GetWorldVolume(); 
01121        if( pWorld )
01122        {
01123            WorldName = pWorld->GetName(); 
01124        }
01125     }
01126     G4cout << " " << WorldName ; 
01127     G4cout << G4endl;
01128   }
01129 
01130   if( fVerboseLevel > 4 )
01131   {
01132     G4cout << " G4PathFinder::PrintLimited - exiting. " << G4endl;
01133   }
01134 }

void G4PathFinder::PushPostSafetyToPreSafety (  ) 

Definition at line 1366 of file G4PathFinder.cc.

01367 {
01368   fPreSafetyLocation= fSafetyLocation;
01369   fPreSafetyMinValue= fMinSafety_atSafLocation;
01370   for( register G4int nav=0; nav < fNoActiveNavigators; ++nav )
01371   {
01372      fPreSafetyValues[nav]= fNewSafetyComputed[nav];
01373   }
01374 }

void G4PathFinder::ReLocate ( const G4ThreeVector position  ) 

Definition at line 536 of file G4PathFinder.cc.

References ComputeSafety(), FatalException, G4cout, G4endl, G4Exception(), G4TransportationManager::GetActiveNavigatorsIterator(), G4GeometryTolerance::GetInstance(), G4FieldTrack::GetPosition(), G4GeometryTolerance::GetRadialTolerance(), kDoNot, and ReportMove().

Referenced by G4CoupledTransportation::PostStepDoIt(), and G4SafetyHelper::ReLocateWithinVolume().

00537 {
00538   // Locate the point in each geometry
00539 
00540   std::vector<G4Navigator*>::iterator pNavIter=
00541     fpTransportManager->GetActiveNavigatorsIterator(); 
00542 
00543 #ifdef G4DEBUG_PATHFINDER
00544 
00545   // Check that this relocation does not violate safety
00546   //   - at endpoint (computed from start point) AND
00547   //   - at last safety location  (likely just called)
00548 
00549   G4ThreeVector lastEndPosition= fEndState.GetPosition();
00550 
00551   // Calculate end-point safety ...
00552   //
00553   G4double      DistanceStartEnd= (lastEndPosition - fPreStepLocation).mag();
00554   G4double      endPointSafety_raw = fMinSafety_PreStepPt - DistanceStartEnd; 
00555   G4double      endPointSafety_Est1 = std::max( 0.0, endPointSafety_raw ); 
00556 
00557   // ... and check move from endpoint against this endpoint safety
00558   //
00559   G4ThreeVector moveVecEndPos  = position - lastEndPosition;
00560   G4double      moveLenEndPosSq = moveVecEndPos.mag2(); 
00561 
00562   // Check that move from endpoint of last step is within safety
00563   // -- or check against last location or relocation ?? 
00564   //
00565   G4ThreeVector moveVecSafety=  position - fSafetyLocation; 
00566   G4double      moveLenSafSq=   moveVecSafety.mag2();
00567 
00568   G4double distCheckEnd_sq= ( moveLenEndPosSq - endPointSafety_Est1 
00569                                                *endPointSafety_Est1 ); 
00570   G4double distCheckSaf_sq=   ( moveLenSafSq -  fMinSafety_atSafLocation
00571                                                *fMinSafety_atSafLocation ); 
00572 
00573   G4bool longMoveEnd = distCheckEnd_sq > 0.0; 
00574   G4bool longMoveSaf = distCheckSaf_sq > 0.0; 
00575 
00576   G4double revisedSafety= 0.0;
00577 
00578   if( (!fNewTrack) && ( longMoveEnd && longMoveSaf ) )
00579   {  
00580      // Recompute ComputeSafety for end position
00581      //
00582      revisedSafety= ComputeSafety(lastEndPosition); 
00583 
00584      const G4double kRadTolerance =
00585        G4GeometryTolerance::GetInstance()->GetRadialTolerance();
00586      const G4double cErrorTolerance=1e-12;   
00587        // Maximum relative error from roundoff of arithmetic 
00588 
00589      G4double  distCheckRevisedEnd= moveLenEndPosSq-revisedSafety*revisedSafety;
00590 
00591      G4bool  longMoveRevisedEnd=  ( distCheckRevisedEnd > 0. ) ; 
00592 
00593      G4double  moveMinusSafety= 0.0; 
00594      G4double  moveLenEndPosition= std::sqrt( moveLenEndPosSq );
00595      moveMinusSafety = moveLenEndPosition - revisedSafety; 
00596 
00597      if ( longMoveRevisedEnd && (moveMinusSafety > 0.0 )
00598        && ( revisedSafety > 0.0 ) )
00599      {
00600         // Take into account possibility of roundoff error causing
00601         // this apparent move further than safety
00602 
00603         if( fVerboseLevel > 0 )
00604         {
00605            G4cout << " G4PF:Relocate> Ratio to revised safety is " 
00606                   << std::fabs(moveMinusSafety)/revisedSafety << G4endl;
00607         }
00608 
00609         G4double  absMoveMinusSafety= std::fabs(moveMinusSafety);
00610         G4bool smallRatio= absMoveMinusSafety < kRadTolerance * revisedSafety ; 
00611         G4double maxCoordPos = std::max( 
00612                                       std::max( std::fabs(position.x()), 
00613                                                 std::fabs(position.y())), 
00614                                       std::fabs(position.z()) );
00615         G4bool smallValue= absMoveMinusSafety < cErrorTolerance * maxCoordPos;
00616         if( ! (smallRatio || smallValue) )
00617         {
00618            G4cout << " G4PF:Relocate> Ratio to revised safety is " 
00619                   << std::fabs(moveMinusSafety)/revisedSafety << G4endl;
00620            G4cout << " Difference of move and safety is not very small."
00621                   << G4endl;
00622         }
00623         else
00624         {
00625           moveMinusSafety = 0.0; 
00626           longMoveRevisedEnd = false;   // Numerical issue -- not too long!
00627 
00628           G4cout << " Difference of move & safety is very small in magnitude, "
00629                  << absMoveMinusSafety << G4endl;
00630           if( smallRatio )
00631           {
00632             G4cout << " ratio to safety " << revisedSafety 
00633                    << " is " <<  absMoveMinusSafety / revisedSafety
00634                    << "smaller than " << kRadTolerance << " of safety ";
00635           }
00636           else
00637           {
00638             G4cout << " as fraction " << absMoveMinusSafety / maxCoordPos 
00639                    << " of position vector max-coord " << maxCoordPos
00640                    << " smaller than " << cErrorTolerance ;
00641           }
00642           G4cout << " -- reset moveMinusSafety to "
00643                  << moveMinusSafety << G4endl;
00644         }
00645      }
00646 
00647      if ( longMoveEnd && longMoveSaf
00648        && longMoveRevisedEnd && (moveMinusSafety>0.0) )
00649      { 
00650         G4int oldPrec= G4cout.precision(9); 
00651         std::ostringstream message;
00652         message << "ReLocation is further than end-safety value." << G4endl
00653                 << " Moved from last endpoint by " << moveLenEndPosition 
00654                 << " compared to end safety (from preStep point) = " 
00655                 << endPointSafety_Est1 << G4endl
00656                 << "  --> last PreSafety Location was " << fPreSafetyLocation
00657                 << G4endl
00658                 << "       safety value =  " << fPreSafetyMinValue << G4endl
00659                 << "  --> last PreStep Location was " << fPreStepLocation
00660                 << G4endl
00661                 << "       safety value =  " << fMinSafety_PreStepPt << G4endl
00662                 << "  --> last EndStep Location was " << lastEndPosition
00663                 << G4endl
00664                 << "       safety value =  " << endPointSafety_Est1 
00665                 << " raw-value = " << endPointSafety_raw << G4endl
00666                 << "  --> Calling again at this endpoint, we get "
00667                 <<  revisedSafety << " as safety value."  << G4endl
00668                 << "  --> last position for safety " << fSafetyLocation
00669                 << G4endl
00670                 << "       its safety value =  " << fMinSafety_atSafLocation
00671                 << G4endl
00672                 << "       move from safety location = "
00673                 << std::sqrt(moveLenSafSq) << G4endl
00674                 << "         again= " << moveVecSafety.mag() << G4endl
00675                 << "       safety - Move-from-end= " 
00676                 << revisedSafety - moveLenEndPosition
00677                 << " (negative is Bad.)" << G4endl
00678                 << " Debug:  distCheckRevisedEnd = "
00679                 << distCheckRevisedEnd;
00680         ReportMove( lastEndPosition, position, "Position" ); 
00681         G4Exception("G4PathFinder::ReLocate", "GeomNav0003", 
00682                     FatalException, message); 
00683         G4cout.precision(oldPrec); 
00684     }
00685   }
00686 
00687   if( fVerboseLevel > 2 )
00688   {
00689     G4cout << G4endl; 
00690     G4cout << " G4PathFinder::ReLocate : entered " << G4endl;
00691     G4cout << " ----------------------   -------" <<  G4endl;
00692     G4cout << "  *Re*Locating at position " << position  << G4endl; 
00693       // << "  with direction " << direction 
00694       // << "  relative= " << relative << G4endl;
00695     if ( (fVerboseLevel > -1) || ( moveLenEndPosSq > 0.0) )
00696     {
00697        G4cout << "  lastEndPosition = " << lastEndPosition
00698               << "  moveVec from step-end = " << moveVecEndPos
00699               << "  is new Track = " << fNewTrack 
00700               << "  relocated = " << fRelocatedPoint << G4endl;
00701     }
00702   }
00703 #endif // G4DEBUG_PATHFINDER
00704 
00705   for ( register G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00706   {
00707      //  ... none limited the step
00708 
00709      (*pNavIter)->LocateGlobalPointWithinVolume( position ); 
00710 
00711      // Clear state related to the step
00712      //
00713      fLimitedStep[num]   = kDoNot; 
00714      fCurrentStepSize[num] = 0.0;      
00715      fLimitTruth[num] = false;   
00716   }
00717 
00718   fLastLocatedPosition= position; 
00719   fRelocatedPoint= false;
00720 
00721 #ifdef G4DEBUG_PATHFINDER
00722   if( fVerboseLevel > 2 )
00723   {
00724     G4cout << " G4PathFinder::ReLocate : exiting " 
00725            << "  at position " << fLastLocatedPosition << G4endl << G4endl;
00726   }
00727 #endif
00728 }

void G4PathFinder::ReportMove ( const G4ThreeVector OldV,
const G4ThreeVector NewV,
const G4String Quantity 
) const [protected]

Definition at line 436 of file G4PathFinder.cc.

References G4cerr, G4endl, G4Exception(), and JustWarning.

Referenced by Locate(), and ReLocate().

00439 {
00440     G4ThreeVector moveVec = ( NewVector - OldVector );
00441 
00442     G4int prc= G4cerr.precision(12); 
00443     std::ostringstream message;
00444     message << "Endpoint moved between value returned by ComputeStep()"
00445             << " and call to Locate(). " << G4endl
00446             << "          Change of " << Quantity << " is "
00447             << moveVec.mag() / mm << " mm long" << G4endl
00448             << "          and its vector is "
00449             << (1.0/mm) * moveVec << " mm " << G4endl
00450             << "          Endpoint of ComputeStep() was " << OldVector << G4endl
00451             << "          and current position to locate is " << NewVector;
00452     G4Exception("G4PathFinder::ReportMove()", "GeomNav1002",  
00453                 JustWarning, message); 
00454     G4cerr.precision(prc); 
00455 }

void G4PathFinder::SetChargeMomentumMass ( G4double  charge,
G4double  momentum,
G4double  pMass 
) [inline]

void G4PathFinder::SetMaxLoopCount ( G4int  new_max  )  [inline]

G4int G4PathFinder::SetVerboseLevel ( G4int  lev = -1  )  [inline]

Definition at line 282 of file G4PathFinder.hh.

00283 {
00284   G4int old= fVerboseLevel;  fVerboseLevel= newLevel; return old;
00285 }

G4bool G4PathFinder::UseSafetyForOptimization ( G4bool   )  [inline, protected]

void G4PathFinder::WhichLimited (  )  [protected]

Definition at line 1018 of file G4PathFinder.cc.

References G4cout, G4endl, kDoNot, kSharedOther, kSharedTransport, kUnique, and PrintLimited().

Referenced by DoNextLinearStep().

01019 {
01020   // Flag which processes limited the step
01021 
01022   G4int num=-1, last=-1; 
01023   G4int noLimited=0; 
01024   ELimited shared= kSharedOther; 
01025 
01026   const G4int IdTransport= 0;  // Id of Mass Navigator !!
01027 
01028   // Assume that [IdTransport] is Mass / Transport
01029   //
01030   G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
01031                            && ( fMinStep!= kInfinity) ; 
01032 
01033   if( transportLimited )  { 
01034      shared= kSharedTransport;
01035   }
01036 
01037   for ( num= 0; num < fNoActiveNavigators; num++ )
01038   { 
01039     G4bool limitedStep;
01040 
01041     G4double step= fCurrentStepSize[num]; 
01042 
01043     limitedStep = ( std::fabs(step - fMinStep) < kCarTolerance ) 
01044                  && ( step != kInfinity); 
01045 
01046     fLimitTruth[ num ] = limitedStep; 
01047     if( limitedStep )
01048     {
01049       noLimited++;  
01050       fLimitedStep[num] = shared;
01051       last= num; 
01052     }
01053     else
01054     {
01055       fLimitedStep[num] = kDoNot;
01056     }
01057   }
01058   fNoGeometriesLimiting= noLimited;  // Save # processes limiting step
01059 
01060   if( (last > -1) && (noLimited == 1 ) )
01061   {
01062     fLimitedStep[ last ] = kUnique; 
01063   }
01064 
01065 #ifdef G4DEBUG_PATHFINDER
01066   if( fVerboseLevel > 1 )
01067   {
01068     PrintLimited();   // --> for tracing 
01069     if( fVerboseLevel > 4 ) {
01070       G4cout << " G4PathFinder::WhichLimited - exiting. " << G4endl;
01071     }
01072   }
01073 #endif
01074 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:52:52 2013 for Geant4 by  doxygen 1.4.7