63     fMax_loop_count(1000),
 
   64     fUseSafetyForOptimisation(true),   
 
   65     fZeroStepThreshold( 0.0 ),         
 
   66     fDetectorFieldMgr(detectorFieldMgr), 
 
   67     fpTrajectoryFilter( 0 ),
 
   68     fNavigator(theNavigator),
 
   69     fCurrentFieldMgr(detectorFieldMgr),
 
   71     fCharge(0.0), fInitialMomentumModulus(0.0), fMass(0.0),
 
   74     fParticleIsLooping(false),
 
   79   else                  { fEpsilonStep= 1.0e-5; } 
 
   80   fActionThreshold_NoZeroSteps = 2; 
 
   81   fSevereActionThreshold_NoZeroSteps = 10; 
 
   82   fAbandonThreshold_NoZeroSteps = 50; 
 
   83   fFull_CurveLen_of_LastAttempt = -1; 
 
   84   fLast_ProposedStepLength = -1;
 
   85   fLargestAcceptableStep = 1000.0 * 
meter;
 
   90   fZeroStepThreshold= std::max( 1.0e5 * kCarTolerance, 1.0
e-1 * 
micrometer );
 
   93   G4cout << 
" PiF: Zero Step Threshold set to " 
   96   G4cout << 
" PiF:   Value of kCarTolerance = " 
  104     fAllocatedLocator=
true;
 
  106     fIntersectionLocator=vLocator;
 
  107     fAllocatedLocator=
false;
 
  114   if(fAllocatedLocator)
delete  fIntersectionLocator; 
 
  140   if(CurrentProposedStepLength<kCarTolerance)
 
  147   if (fpTrajectoryFilter)
 
  155   G4double      TruePathLength = CurrentProposedStepLength;
 
  159   G4bool        first_substep = 
true;
 
  162   fParticleIsLooping = 
false;
 
  184   if( CurrentProposedStepLength >= fLargestAcceptableStep )
 
  190     G4double trialProposedStep = 1.e2 * ( 10.0 * 
cm + 
 
  192                   GetSolid()->DistanceToOut(StartPointA, VelocityUnit) );
 
  193     CurrentProposedStepLength= std::min( trialProposedStep,
 
  194                                            fLargestAcceptableStep ); 
 
  196   epsilon = fCurrentFieldMgr->
GetDeltaOneStep() / CurrentProposedStepLength;
 
  200   if( epsilon < epsilonMin ) epsilon = epsilonMin;
 
  201   if( epsilon > epsilonMax ) epsilon = epsilonMax;
 
  209   if( fNoZeroStep > fActionThreshold_NoZeroSteps )
 
  213     stepTrial= fFull_CurveLen_of_LastAttempt; 
 
  214     if( (stepTrial <= 0.0) && (fLast_ProposedStepLength > 0.0) ) 
 
  215       stepTrial= fLast_ProposedStepLength; 
 
  218     if(   (fNoZeroStep < fSevereActionThreshold_NoZeroSteps)
 
  219        && (stepTrial > 100.0*fZeroStepThreshold) )
 
  223       decreaseFactor= 0.25;
 
  231       if( stepTrial > 100.0*fZeroStepThreshold )
 
  232         decreaseFactor = 0.35;     
 
  233       else if( stepTrial > 30.0*fZeroStepThreshold )
 
  235       else if( stepTrial > 10.0*fZeroStepThreshold )
 
  236         decreaseFactor= 0.75;      
 
  240      stepTrial *= decreaseFactor;
 
  243      G4cout << 
" G4PropagatorInField::ComputeStep(): " << 
G4endl 
  244         << 
"  Decreasing step -  "  
  245         << 
" decreaseFactor= " << std::setw(8) << decreaseFactor 
 
  246         << 
" stepTrial = "     << std::setw(18) << stepTrial << 
" " 
  247         << 
" fZeroStepThreshold = " << fZeroStepThreshold << 
G4endl;
 
  249                                stepTrial, pFieldTrack);
 
  251      if( stepTrial == 0.0 )  
 
  253        std::ostringstream message;
 
  254        message << 
"Particle abandoned due to lack of progress in field." 
  256                << 
"  Properties : " << pFieldTrack << G4endl
 
  257                << 
"  Attempting a zero step = " << stepTrial << G4endl
 
  258                << 
"  while attempting to progress after " << fNoZeroStep
 
  259                << 
" trial steps. Will abandon step.";
 
  260        G4Exception(
"G4PropagatorInField::ComputeStep()", 
"GeomNav1002",
 
  262        fParticleIsLooping= 
true;
 
  265      if( stepTrial < CurrentProposedStepLength )
 
  266        CurrentProposedStepLength = stepTrial;
 
  268   fLast_ProposedStepLength = CurrentProposedStepLength;
 
  270   G4int do_loop_count = 0; 
 
  276     if( !first_substep) {
 
  282     h_TrialStepSize = CurrentProposedStepLength - StepTaken;
 
  295     fFull_CurveLen_of_LastAttempt = s_length_taken;
 
  303                                 NewSafety,     LinearStepLength, 
 
  304                                 InterSectionPointE );
 
  308     if( first_substep ) { 
 
  309        currentSafety = NewSafety;
 
  318        G4bool recalculatedEndPt= 
false;
 
  320          G4bool found_intersection = fIntersectionLocator->
 
  321          EstimateIntersectionPoint( SubStepStartState, CurrentState, 
 
  322                                   InterSectionPointE, IntersectPointVelct_G,
 
  323                                   recalculatedEndPt,fPreviousSafety,fPreviousSftOrigin);
 
  324        intersects = intersects && found_intersection;
 
  325        if( found_intersection ) {        
 
  326           End_PointAndTangent= IntersectPointVelct_G;  
 
  327           StepTaken = TruePathLength = IntersectPointVelct_G.
GetCurveLength()
 
  331           if( recalculatedEndPt ){
 
  332              CurrentState= IntersectPointVelct_G; 
 
  338       StepTaken += s_length_taken; 
 
  340       if (fpTrajectoryFilter) {
 
  344     first_substep = 
false;
 
  347     if( fNoZeroStep > fActionThreshold_NoZeroSteps ) {
 
  349                    CurrentState,  CurrentProposedStepLength, 
 
  350                    NewSafety,     do_loop_count,  pPhysVol );
 
  352     if( (fVerboseLevel > 1) && (do_loop_count > fMax_loop_count-10 )) {
 
  353       if( do_loop_count == fMax_loop_count-9 ){
 
  354         G4cout << 
" G4PropagatorInField::ComputeStep(): " << 
G4endl 
  355                << 
"  Difficult track - taking many sub steps." << 
G4endl;
 
  357       printStatus( SubStepStartState, CurrentState, CurrentProposedStepLength, 
 
  358                    NewSafety, do_loop_count, pPhysVol );
 
  364   } 
while( (!intersects )
 
  365         && (StepTaken + kCarTolerance < CurrentProposedStepLength)  
 
  366         && ( do_loop_count < fMax_loop_count ) );
 
  368   if( do_loop_count >= fMax_loop_count  )
 
  370     fParticleIsLooping = 
true;
 
  372     if ( fVerboseLevel > 0 )
 
  374        G4cout << 
" G4PropagateInField::ComputeStep(): " << 
G4endl 
  375               << 
"  Killing looping particle "  
  377               << 
" after " << do_loop_count << 
" field substeps " 
  378               << 
" totaling " << StepTaken / 
mm << 
" mm " ;
 
  382          G4cout << 
" in unknown or null volume. " ; 
 
  392     End_PointAndTangent = CurrentState; 
 
  393     TruePathLength = StepTaken;
 
  398   pFieldTrack = End_PointAndTangent;
 
  406     std::ostringstream message;
 
  407     message << 
"Curve length mis-match between original state " 
  408             << 
"and proposed endpoint of propagation." << 
G4endl 
  409             << 
"  The curve length of the endpoint should be: "  
  411             << 
"  and it is instead: " 
  413             << 
"  A difference of: " 
  416             << 
"  Original state = " << OriginalState   << 
G4endl 
  417             << 
"  Proposed state = " << End_PointAndTangent;
 
  427   if( ( (TruePathLength < fZeroStepThreshold) 
 
  428     && ( TruePathLength+kCarTolerance < CurrentProposedStepLength  ) 
 
  430       || ( TruePathLength < 0.5*kCarTolerance )
 
  439   if( fNoZeroStep > fAbandonThreshold_NoZeroSteps )
 
  441      fParticleIsLooping = 
true;
 
  442      std::ostringstream message;
 
  443      message << 
"Particle is stuck; it will be killed." << 
G4endl 
  444              << 
"  Zero progress for "  << fNoZeroStep << 
" attempted steps."  
  446              << 
"  Proposed Step is " << CurrentProposedStepLength
 
  447              << 
" but Step Taken is "<< fFull_CurveLen_of_LastAttempt << 
G4endl 
  448              << 
"  For Particle with Charge = " << fCharge
 
  449              << 
" Momentum = "<< fInitialMomentumModulus
 
  450              << 
" Mass = " << fMass << 
G4endl;
 
  452        message << 
" in volume " << pPhysVol->
GetName() ; 
 
  454        message << 
" in unknown or null volume. " ; 
 
  460   return TruePathLength;
 
  475   const G4int verboseLevel=fVerboseLevel;
 
  485   if( ((stepNo == 0) && (verboseLevel <3)) || (verboseLevel >= 3) )
 
  487     oldprec = 
G4cout.precision(4);
 
  488     G4cout << std::setw( 6)  << 
" "  
  489            << std::setw( 25) << 
" Current Position  and  Direction" << 
" " 
  491     G4cout << std::setw( 5) << 
"Step#"  
  492            << std::setw(10) << 
"  s  " << 
" " 
  493            << std::setw(10) << 
"X(mm)" << 
" " 
  494            << std::setw(10) << 
"Y(mm)" << 
" "   
  495            << std::setw(10) << 
"Z(mm)" << 
" " 
  496            << std::setw( 7) << 
" N_x " << 
" " 
  497            << std::setw( 7) << 
" N_y " << 
" " 
  498            << std::setw( 7) << 
" N_z " << 
" " ;
 
  499     G4cout << std::setw( 7) << 
" Delta|N|" << 
" " 
  500            << std::setw( 9) << 
"StepLen" << 
" "   
  501            << std::setw(12) << 
"StartSafety" << 
" "   
  502            << std::setw( 9) << 
"PhsStep" << 
" ";  
 
  504       { 
G4cout << std::setw(18) << 
"NextVolume" << 
" "; }
 
  505     G4cout.precision(oldprec);
 
  508   if((stepNo == 0) && (verboseLevel <=3))
 
  512     printStatus( StartFT, StartFT, -1.0, safety, -1, startVolume);
 
  514   if( verboseLevel <= 3 )
 
  517       { 
G4cout << std::setw( 4) << stepNo << 
" "; }
 
  519       { 
G4cout << std::setw( 5) << 
"Start" ; }
 
  520     oldprec = 
G4cout.precision(8);
 
  523     G4cout << std::setw(10) << CurrentPosition.
x() << 
" " 
  524            << std::setw(10) << CurrentPosition.
y() << 
" " 
  525            << std::setw(10) << CurrentPosition.
z() << 
" ";
 
  527     G4cout << std::setw( 7) << CurrentUnitVelocity.
x() << 
" " 
  528            << std::setw( 7) << CurrentUnitVelocity.
y() << 
" " 
  529            << std::setw( 7) << CurrentUnitVelocity.
z() << 
" ";
 
  533     G4cout << std::setw( 9) << step_len << 
" "; 
 
  534     G4cout << std::setw(12) << safety << 
" ";
 
  535     if( requestStep != -1.0 ) 
 
  536       { 
G4cout << std::setw( 9) << requestStep << 
" "; }
 
  538       { 
G4cout << std::setw( 9) << 
"Init/NotKnown" << 
" "; }
 
  539     if( startVolume != 0)
 
  540       { 
G4cout << std::setw(12) << startVolume->
GetName() << 
" "; }
 
  541     G4cout.precision(oldprec);
 
  548     G4cout << 
"Step taken was " << step_len  
 
  549            << 
" out of PhysicalStep = " <<  requestStep << 
G4endl;
 
  551     G4cout << 
"Chord length = " << (CurrentPosition-StartPosition).mag()
 
  569   G4cout << 
" " << std::setw(12) << 
" PiF: NoZeroStep "  
  570          << 
" " << std::setw(20) << 
" CurrentProposed len "  
  571          << 
" " << std::setw(18) << 
" Full_curvelen_last"  
  572          << 
" " << std::setw(18) << 
" last proposed len "  
  573          << 
" " << std::setw(18) << 
" decrease factor   "  
  574          << 
" " << std::setw(15) << 
" step trial  "  
  577   G4cout << 
" " << std::setw(10) << fNoZeroStep << 
"  " 
  578          << 
" " << std::setw(20) << CurrentProposedStepLength
 
  579          << 
" " << std::setw(18) << fFull_CurveLen_of_LastAttempt
 
  580          << 
" " << std::setw(18) << fLast_ProposedStepLength 
 
  581          << 
" " << std::setw(18) << decreaseFactor
 
  582          << 
" " << std::setw(15) << stepTrial
 
  584   G4cout.precision( iprec ); 
 
  597 std::vector<G4ThreeVector>*
 
  603   if (fpTrajectoryFilter)
 
  616   fpTrajectoryFilter = filter;
 
  623   fParticleIsLooping= 
false;
 
  628                                      0.0,0.0,0.0,0.0,0.0); 
 
  629   fFull_CurveLen_of_LastAttempt = -1; 
 
  630   fLast_ProposedStepLength = -1;
 
  633   fPreviousSafety= 0.0;
 
  641   currentFieldMgr = fDetectorFieldMgr;
 
  642   if( pCurrentPhysicalVolume)
 
  652        if( pRegionFieldMgr ) 
 
  653          currentFieldMgr= pRegionFieldMgr;
 
  659        currentFieldMgr = localFieldMgr;
 
  662   fCurrentFieldMgr= currentFieldMgr;
 
  667   return currentFieldMgr;
 
  672   G4int oldval= fVerboseLevel;
 
  673   fVerboseLevel= level;
 
  680   G4cout << 
"Set Driver verbosity to " << fVerboseLevel - 2 << 
G4endl;