45 fNumAdvanceFull(0.), fNumAdvanceGood(0), fNumAdvanceTrials(0)
52 for (
G4int idepth=0; idepth<max_depth+1; idepth++ )
54 ptrInterMedFT[ idepth ] =
new G4FieldTrack( zeroV, zeroV, 0., 0., 0., 0.);
67 for (
G4int idepth=0; idepth<max_depth+1; idepth++)
69 delete ptrInterMedFT[idepth];
124 G4bool& recalculatedEndPoint,
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)
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,
252 "Intermediate F point is past end B point" );
261 G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point;
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 );
301 CurrentE_Point, CurrentF_Point, MomentumDir,
302 last_AF_intersection, IP, NewSafety,
303 previousSafety, previousSftOrigin );
304 if ( goodCorrection )
306 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
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"
362 <<
" on way to full s="
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 );
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;
841 G4cout <<
" Number of split level ('advances'): "
842 << fNumAdvanceTrials <<
G4endl;
843 G4cout <<
" Number of full advances: "
844 << fNumAdvanceGood <<
G4endl;
845 G4cout <<
" Number of good advances: "
846 << fNumAdvanceFull <<
G4endl;
849 void G4MultiLevelLocator::ReportFieldValue(
const G4FieldTrack& locationPV,
853 enum { maxNumFieldComp= 24 };
856 G4double startPoint[4] = { position.
x(), position.
y(), position.
z(),
859 for (
unsigned int i=0; i<maxNumFieldComp; ++i )
864 G4cout <<
" B-field value (" << nameLoc <<
")= "
865 << FieldVec[0] <<
" " << FieldVec[1] <<
" " << FieldVec[2];
868 FieldVec[5] ).
mag2();
871 G4cout <<
" Electric = " << FieldVec[3] <<
" "
872 << FieldVec[4] <<
" "
void SetPosition(G4ThreeVector nPos)
G4double GetCurveLength() const
CLHEP::Hep3Vector G4ThreeVector
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)
const G4ThreeVector & GetMomentumDir() const
G4bool EstimateIntersectionPoint(const G4FieldTrack &curveStartPointTangent, const G4FieldTrack &curveEndPointTangent, const G4ThreeVector &trialPoint, G4FieldTrack &intersectPointTangent, G4bool &recalculatedEndPoint, G4double &fPreviousSafety, G4ThreeVector &fPreviousSftOrigin)
void SetWarnSteps(unsigned int valWarn)
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
G4MultiLevelLocator(G4Navigator *theNavigator)
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)
void GetFieldValue(const G4double Point[4], G4double Field[]) const
G4double GetLabTimeOfFlight() const
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 SetMaxSteps(unsigned int valMax)
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)
G4ThreeVector GetMomentumDirection() const