129   const char* MethodName= 
"G4MultiLevelLocator::EstimateIntersectionPoint()";
 
  131   G4bool found_approximate_intersection = 
false;
 
  132   G4bool there_is_no_intersection       = 
false;
 
  134   G4FieldTrack  CurrentA_PointVelocity = CurveStartPointVelocity; 
 
  135   G4FieldTrack  CurrentB_PointVelocity = CurveEndPointVelocity;
 
  137   G4bool        validNormalAtE = 
false;
 
  140   G4FieldTrack  ApproxIntersecPointV(CurveEndPointVelocity); 
 
  142   G4bool        validIntersectP= 
true;   
 
  144   G4bool        last_AF_intersection = 
false;   
 
  148   G4bool first_section = 
true;
 
  150   recalculatedEndPoint = 
false; 
 
  152   G4bool restoredFullEndpoint = 
false;
 
  154   unsigned int substep_no = 0;
 
  170   const G4int param_substeps=5;  
 
  174   G4bool Second_half = 
false;    
 
  182   unsigned int depth=0; 
 
  186   unsigned int trigger_substepno_print=0;
 
  188   unsigned int biggest_depth= 0;
 
  190 #if (G4DEBUG_FIELD>1)  
  191   G4ThreeVector  StartPosition= CurveStartPointVelocity.GetPosition(); 
 
  192   if( (TrialPoint - StartPosition).mag2() < tolerance*tolerance) 
 
  195                          tolerance, fNumCalls); 
 
  206   *ptrInterMedFT[0] = CurveEndPointVelocity;
 
  207   for (
G4int idepth=1; idepth<max_depth+1; idepth++ )
 
  209     *ptrInterMedFT[idepth]=CurveStartPointVelocity;
 
  214   G4bool fin_section_depth[max_depth];
 
  215   for (
G4int idepth=0; idepth<max_depth; idepth++ )
 
  217     fin_section_depth[idepth]=
true;
 
  221   G4FieldTrack SubStart_PointVelocity = CurveStartPointVelocity;
 
  225     unsigned int substep_no_p = 0;
 
  226     G4bool sub_final_section = 
false; 
 
  228     SubStart_PointVelocity = CurrentA_PointVelocity;
 
  240                                                   CurrentB_PointVelocity, 
 
  248       if( ApproxIntersecPointV.GetCurveLength() > 
 
  252                     "Intermediate F point is past end B point" ); 
 
  256       G4ThreeVector CurrentF_Point= ApproxIntersecPointV.GetPosition();
 
  261       G4ThreeVector  ChordEF_Vector = CurrentF_Point - CurrentE_Point;
 
  263       G4ThreeVector  NewMomentumDir= ApproxIntersecPointV.GetMomentumDir(); 
 
  264       G4double       MomDir_dot_Norm= NewMomentumDir.
dot( NormalAtEntry ) ;
 
  272          MomDir_dot_ABchord = (1.0 / ABchord_length)
 
  273                             * NewMomentumDir.
dot( ChordAB );
 
  275               ChordEF_Vector, NewMomentumDir, NormalAtEntry, validNormalAtE ); 
 
  276          G4cout << 
" dot( MomentumDir, ABchord_unit ) = " 
  277                 << MomDir_dot_ABchord << 
G4endl;
 
  281              ( MomDir_dot_Norm >= 0.0 ) 
 
  282           || (! validNormalAtE );       
 
  287         found_approximate_intersection = 
true;
 
  291         IntersectedOrRecalculatedFT = ApproxIntersecPointV;
 
  292         IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point );
 
  299           G4ThreeVector MomentumDir=ApproxIntersecPointV.GetMomentumDirection();
 
  301                                     CurrentE_Point, CurrentF_Point, MomentumDir,
 
  302                                     last_AF_intersection, IP, NewSafety,
 
  303                                     previousSafety, previousSftOrigin );
 
  304           if ( goodCorrection )
 
  306             IntersectedOrRecalculatedFT = ApproxIntersecPointV;
 
  307             IntersectedOrRecalculatedFT.SetPosition(IP);
 
  329                                                NewSafety, previousSafety,
 
  333         last_AF_intersection = Intersects_AF;
 
  342           CurrentB_PointVelocity = ApproxIntersecPointV;
 
  343           CurrentE_Point = PointG;  
 
  345           validIntersectP= 
true;    
 
  350           validNormalAtE = validNormalLast; 
 
  355           fin_section_depth[depth]=
false;
 
  360             G4cout << 
"G4PiF::LI> Investigating intermediate point" 
  361                    << 
" at s=" << ApproxIntersecPointV.GetCurveLength()
 
  362                    << 
" on way to full s=" 
  363                    << CurveEndPointVelocity.GetCurveLength() << 
G4endl;
 
  382                                                  NewSafety, previousSafety,
 
  400             CurrentA_PointVelocity = ApproxIntersecPointV;
 
  401             CurrentE_Point = PointH;
 
  403             validIntersectP = 
true;    
 
  408             validNormalAtE = validNormalH; 
 
  412             if(fin_section_depth[depth])
 
  422               if( ((Second_half)&&(depth==0)) || (first_section) )
 
  424                 there_is_no_intersection = 
true;   
 
  430                 substep_no_p = param_substeps+2;  
 
  435                 sub_final_section = 
true;
 
  440               CurrentA_PointVelocity = CurrentB_PointVelocity;  
 
  441               CurrentB_PointVelocity = (depth==0) ? CurveEndPointVelocity 
 
  442                                                   : *ptrInterMedFT[depth] ;
 
  443               SubStart_PointVelocity = CurrentA_PointVelocity;
 
  444               restoredFullEndpoint = 
true;
 
  446               validIntersectP=  
false;  
 
  455                                                          CurrentB_PointVelocity,
 
  460           CurrentB_PointVelocity= RevisedB_FT;  
 
  469           if ( (fin_section_depth[depth])           
 
  470              &&( first_section || ((Second_half)&&(depth==0)) ) )
 
  472             recalculatedEndPoint = 
true;
 
  473             IntersectedOrRecalculatedFT = RevisedB_FT;
 
  485            std::ostringstream errmsg; 
 
  486            errmsg << 
"Location: " << MethodName
 
  487                   << 
"- After EndIf(Intersects_AF)" << 
G4endl;
 
  489                      CurveStartPointVelocity, CurveEndPointVelocity,
 
  491                      CurrentA_PointVelocity, CurrentB_PointVelocity,
 
  492                      SubStart_PointVelocity, CurrentE_Point,
 
  493                      ApproxIntersecPointV, substep_no, substep_no_p, depth);
 
  496         if( restoredFullEndpoint )
 
  498           fin_section_depth[depth] = restoredFullEndpoint;
 
  499           restoredFullEndpoint = 
false;
 
  505       if( trigger_substepno_print == 0)
 
  507         trigger_substepno_print= fWarnSteps - 20;
 
  510       if( substep_no >= trigger_substepno_print )
 
  512         G4cout << 
"Difficulty in converging in " << MethodName
 
  514                << 
"    Substep no = " << substep_no << 
G4endl;
 
  515         if( substep_no == trigger_substepno_print )
 
  517           printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
 
  520         G4cout << 
" State of point A: "; 
 
  521         printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
 
  522                      -1.0, NewSafety, substep_no-1);
 
  523         G4cout << 
" State of point B: "; 
 
  524         printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
 
  525                      -1.0, NewSafety, substep_no);
 
  531     } 
while (  ( ! found_approximate_intersection )
 
  532             && ( ! there_is_no_intersection )     
 
  533             && ( substep_no_p <= param_substeps) );  
 
  536     if( (!found_approximate_intersection) && (!there_is_no_intersection) )
 
  549       if(   (did_len < fraction_done*all_len)
 
  550          && (depth<max_depth) && (!sub_final_section) )
 
  554         biggest_depth= 
std::max(depth, biggest_depth);
 
  559         first_section = 
false;
 
  561         G4double Sub_len = (all_len-did_len)/(2.);
 
  569         if( fullAdvance )  { fNumAdvanceFull++; }
 
  575         G4bool goodAdvance = (lenAchieved >= adequateFraction * Sub_len);
 
  576         if ( goodAdvance )  { fNumAdvanceGood++; }
 
  581            G4cout << 
"MLL> AdvanceChordLimited not full at depth=" << depth 
 
  582                   << 
"  total length achieved = " << lenAchieved << 
" of " 
  583                   << Sub_len << 
"  fraction= ";
 
  584            if (Sub_len != 0.0 ) { 
G4cout << lenAchieved / Sub_len; }
 
  585            else                 { 
G4cout << 
"DivByZero"; }
 
  586            G4cout << 
"  Good-enough fraction = " << adequateFraction;
 
  587            G4cout << 
"  Number of call to mll = " << fNumCalls
 
  588                   << 
"   iteration " << substep_no
 
  589                   << 
"  inner =  " << substep_no_p << 
G4endl;
 
  591            G4cout << 
"  State at start is      = " << CurrentA_PointVelocity
 
  593                   << 
"        at end (midpoint)= " << midPoint << 
G4endl;
 
  598            ReportFieldValue( CurrentA_PointVelocity, 
"start", equation );
 
  599            ReportFieldValue( midPoint, 
"midPoint", equation );            
 
  600            G4cout << 
"  Original Start = " 
  601                   << CurveStartPointVelocity << 
G4endl;
 
  602            G4cout << 
"  Original   End = " 
  603                   << CurveEndPointVelocity << 
G4endl;
 
  604            G4cout << 
"  Original TrialPoint = " 
  606            G4cout << 
"  (this is STRICT mode) " 
  607                   << 
"  num Splits= " << numSplits;           
 
  612         *ptrInterMedFT[depth] =  midPoint;
 
  613         CurrentB_PointVelocity = midPoint; 
 
  617         SubStart_PointVelocity = CurrentA_PointVelocity;
 
  626                                               NewSafety, previousSafety,
 
  627                                               previousSftOrigin, distAB,
 
  631           last_AF_intersection = Intersects_AB;
 
  632           CurrentE_Point = PointGe;
 
  633           fin_section_depth[depth]=
true;
 
  635           validIntersectP=  
true;  
 
  640           validNormalAtE = validNormalAB;
 
  649           validIntersectP=  
false;  
 
  654       unsigned int levelPops=0;
 
  656       G4bool unfinished = Second_half;
 
  657       while ( unfinished && (depth>0) )  
 
  666         SubStart_PointVelocity = *ptrInterMedFT[depth];
 
  667         CurrentA_PointVelocity = *ptrInterMedFT[depth];
 
  668         CurrentB_PointVelocity = *ptrInterMedFT[depth-1];
 
  677                                        CurrentB_PointVelocity,
 
  682           CurrentB_PointVelocity= RevisedEndPointFT;  
 
  686             recalculatedEndPoint = 
true;
 
  687             IntersectedOrRecalculatedFT = RevisedEndPointFT;
 
  693           std::ostringstream errmsg; 
 
  694           errmsg << 
"Location:  " << MethodName << 
"- Second-Half" << 
G4endl;
 
  696                     CurveStartPointVelocity, CurveEndPointVelocity,
 
  698                     CurrentA_PointVelocity, CurrentA_PointVelocity,
 
  699                     SubStart_PointVelocity, CurrentE_Point,
 
  700                     ApproxIntersecPointV, substep_no, substep_no_p, depth);
 
  708                                               previousSftOrigin, distAB,
 
  712           last_AF_intersection = Intersects_AB;
 
  713           CurrentE_Point = PointGe;
 
  715           validIntersectP=  
true;  
 
  720           validNormalAtE = validNormalAB;
 
  724           validIntersectP=  
false;  
 
  728             there_is_no_intersection = 
true;
 
  732         fin_section_depth[depth]=
true;
 
  733         unfinished = !validIntersectP;
 
  736       if( ! ( validIntersectP || there_is_no_intersection ) )
 
  739          G4cout << 
"MLL - WARNING Potential FAILURE: Conditions not met!" 
  741                 << 
" Depth = " << depth << G4endl
 
  742                 << 
" Levels popped = " << levelPops
 
  743                 << 
" Num Substeps= " << substep_no << 
G4endl;
 
  744          G4cout << 
" Found intersection= " << found_approximate_intersection
 
  748                         CurveStartPointVelocity, CurveEndPointVelocity,
 
  749                         substep_no, CurrentA_PointVelocity,
 
  750                         CurrentB_PointVelocity,
 
  757     assert( validIntersectP || there_is_no_intersection
 
  758          || found_approximate_intersection);
 
  760   } 
while ( ( ! found_approximate_intersection )
 
  761             && ( ! there_is_no_intersection )     
 
  762             && ( substep_no <= fMaxSteps) ); 
 
  764   if( substep_no > max_no_seen )
 
  766     max_no_seen = substep_no; 
 
  768     if( max_no_seen > fWarnSteps )
 
  770       trigger_substepno_print = max_no_seen-20; 
 
  775   if( !there_is_no_intersection && !found_approximate_intersection )
 
  777      if( substep_no >= fMaxSteps)
 
  781         recalculatedEndPoint = 
true;
 
  782         IntersectedOrRecalculatedFT = CurrentA_PointVelocity;
 
  783         found_approximate_intersection = 
false; 
 
  785         std::ostringstream message;
 
  787         message << 
"Convergence is requiring too many substeps: " 
  788                 << substep_no << 
"  ( limit = "<<  fMaxSteps << 
")" 
  790                 << 
"  Abandoning effort to intersect. " << G4endl << 
G4endl;
 
  791         message << 
"    Number of calls to MLL: " <<   fNumCalls;
 
  792         message << 
"  iteration = " << substep_no <<G4endl << 
G4endl;
 
  794         message.precision( 12 ); 
 
  796         G4double full_len = CurveEndPointVelocity.GetCurveLength();
 
  797         message << 
"        Undertaken only length: " << done_len
 
  798                 << 
" out of " << full_len << 
" required." << G4endl
 
  799                 << 
"        Remaining length = " << full_len - done_len; 
 
  801         message << 
"     Start and end-point of requested Step:" << 
G4endl;
 
  802         printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
 
  803                      -1.0, NewSafety, 0,     message, -1 );
 
  804         message << 
"        Start and end-point of current Sub-Step:" << 
G4endl;
 
  805         printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
 
  806                      -1.0, NewSafety, substep_no-1, message, -1 );
 
  807         printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
 
  808                      -1.0, NewSafety, substep_no, message, -1 );
 
  812      else if( substep_no >= fWarnSteps)
 
  814         std::ostringstream message;
 
  815         message << 
"Many substeps while trying to locate intersection." 
  817                 << 
"          Undertaken length: "   
  819                 << 
" - Needed: "  << substep_no << 
" substeps." << G4endl
 
  820                 << 
"          Warning number = " << fWarnSteps
 
  821                 << 
" and maximum substeps = " << fMaxSteps;
 
  827   if( found_approximate_intersection )
 
  829     assert( validApproxIntPV &&
 
  830             "Approximate Intersection must not have been invalidated." );
 
  834   return  (!there_is_no_intersection) && found_approximate_intersection;
 
G4double GetCurveLength() const 
 
double dot(const Hep3Vector &) const 
 
const G4MagIntegratorStepper * GetStepper() const 
 
G4ThreeVector GetSurfaceNormal(const G4ThreeVector &CurrentInt_Point, G4bool &validNormal)
 
G4bool IntersectChord(const G4ThreeVector &StartPointA, const G4ThreeVector &EndPointB, G4double &NewSafety, G4double &PreviousSafety, G4ThreeVector &PreviousSftOrigin, G4double &LinearStepLength, G4ThreeVector &IntersectionPoint, G4bool *calledNavigator=0)
 
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector ¤tEPoint, G4double epsStep)
 
void printStatus(const G4FieldTrack &startFT, const G4FieldTrack ¤tFT, G4double requestStep, G4double safety, G4int stepNum)
 
static constexpr double perThousand
 
G4double GetEpsilonStepFor()
 
void ReportImmediateHit(const char *MethodName, const G4ThreeVector &StartPosition, const G4ThreeVector &TrialPoint, double tolerance, unsigned long int numCalls)
 
G4EquationOfMotion * GetEquationOfMotion()
 
G4ThreeVector GetPosition() const 
 
G4GLOB_DLL std::ostream G4cout
 
static constexpr double mm
 
G4double GetRestMass() const 
 
void ReportReversedPoints(std::ostringstream &ossMsg, const G4FieldTrack &StartPointVel, const G4FieldTrack &EndPointVel, G4double NewSafety, G4double epsStep, const G4FieldTrack &CurrentA_PointVelocity, const G4FieldTrack &CurrentB_PointVelocity, const G4FieldTrack &SubStart_PointVelocity, const G4ThreeVector &CurrentE_Point, const G4FieldTrack &ApproxIntersecPointV, G4int sbstp_no, G4int sbstp_no_p, G4int depth)
 
void ReportTrialStep(G4int step_no, const G4ThreeVector &ChordAB_v, const G4ThreeVector &ChordEF_v, const G4ThreeVector &NewMomentumDir, const G4ThreeVector &NormalAtEntry, G4bool validNormal)
 
G4Navigator * GetNavigatorFor()
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
T max(const T t1, const T t2)
brief Return the largest of the two arguments 
 
G4bool CheckAndReEstimateEndpoint(const G4FieldTrack &CurrentStartA, const G4FieldTrack &EstimatedEndB, G4FieldTrack &RevisedEndPoint, G4int &errorCode)
 
G4bool GetAdjustementOfFoundIntersection()
 
void ReportProgress(std::ostream &oss, const G4FieldTrack &StartPointVel, const G4FieldTrack &EndPointVel, G4int substep_no, const G4FieldTrack &A_PtVel, const G4FieldTrack &B_PtVel, G4double safetyLast, G4int depth=-1)
 
G4MagInt_Driver * GetIntegrationDriver()
 
G4double fiDeltaIntersection
 
G4ChordFinder * GetChordFinderFor()
 
G4bool AccurateAdvance(G4FieldTrack &y_current, G4double hstep, G4double eps, G4double hinitial=0.0)
 
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
 
G4bool AdjustmentOfFoundIntersection(const G4ThreeVector &A, const G4ThreeVector &CurrentE_Point, const G4ThreeVector &CurrentF_Point, const G4ThreeVector &MomentumDir, const G4bool IntersectAF, G4ThreeVector &IntersectionPoint, G4double &NewSafety, G4double &fPrevSafety, G4ThreeVector &fPrevSftOrigin)