120 G4bool canRelaxDeltaChord)
128 const char* methodName =
"G4PropagatorInField::ComputeStep";
129 if (CurrentProposedStepLength<kCarTolerance)
136 if (fpTrajectoryFilter !=
nullptr)
138 fpTrajectoryFilter->CreateNewTrajectorySegment();
141 fFirstStepInVolume = fNewTrack ? true : fLastStepInVolume;
142 fLastStepInVolume =
false;
145 if( fVerboseLevel > 2 )
148 G4cout <<
" Starting FT: " << pFieldTrack;
149 G4cout <<
" Requested length = " << CurrentProposedStepLength <<
G4endl;
151 if( pPhysVol !=
nullptr )
165 G4double TruePathLength = CurrentProposedStepLength;
169 G4bool first_substep =
true;
172 fParticleIsLooping =
false;
182 fSetFieldMgr =
false;
190 if( CurrentProposedStepLength >= fLargestAcceptableStep )
196 G4double trialProposedStep = fMaxStepSizeMultiplier * ( fMinBigDistance +
197 fNavigator->GetWorldVolume()->GetLogicalVolume()->
198 GetSolid()->DistanceToOut(StartPointA, VelocityUnit) );
199 CurrentProposedStepLength = std::min( trialProposedStep,
200 fLargestAcceptableStep );
202 epsilon = fCurrentFieldMgr->GetDeltaOneStep() / CurrentProposedStepLength;
203 G4double epsilonMin= fCurrentFieldMgr->GetMinimumEpsilonStep();
204 G4double epsilonMax= fCurrentFieldMgr->GetMaximumEpsilonStep();
216 if( fNoZeroStep > fActionThreshold_NoZeroSteps )
220 stepTrial = fFull_CurveLen_of_LastAttempt;
221 if( (stepTrial <= 0.0) && (fLast_ProposedStepLength > 0.0) )
223 stepTrial = fLast_ProposedStepLength;
227 if( (fNoZeroStep < fSevereActionThreshold_NoZeroSteps)
228 && (stepTrial > 100.0*fZeroStepThreshold) )
232 decreaseFactor= 0.25;
240 if( stepTrial > 100.0*fZeroStepThreshold ) {
241 decreaseFactor = 0.35;
242 }
else if( stepTrial > 30.0*fZeroStepThreshold ) {
244 }
else if( stepTrial > 10.0*fZeroStepThreshold ) {
245 decreaseFactor= 0.75;
250 stepTrial *= decreaseFactor;
253 if( fVerboseLevel > 2
254 || (fNoZeroStep >= fSevereActionThreshold_NoZeroSteps) )
256 G4cerr <<
" " << methodName
257 <<
" Decreasing step after " << fNoZeroStep <<
" zero steps "
258 <<
" - in volume " << pPhysVol;
260 G4cerr <<
" with name " << pPhysVol->GetName();
262 G4cerr <<
" i.e. *unknown* volume.";
265 stepTrial, pFieldTrack);
268 if( stepTrial == 0.0 )
270 std::ostringstream message;
271 message <<
"Particle abandoned due to lack of progress in field."
273 <<
" Properties : " << pFieldTrack <<
G4endl
274 <<
" Attempting a zero step = " << stepTrial <<
G4endl
275 <<
" while attempting to progress after " << fNoZeroStep
276 <<
" trial steps. Will abandon step.";
278 fParticleIsLooping =
true;
281 if( stepTrial < CurrentProposedStepLength )
283 CurrentProposedStepLength = stepTrial;
286 fLast_ProposedStepLength = CurrentProposedStepLength;
288 G4int do_loop_count = 0;
296 if( fVerboseLevel > 4 )
298 G4cout <<
" PiF: Calling Nav/Locate Global Point within-Volume "
301 fNavigator->LocateGlobalPointWithinVolume( SubStartPoint );
306 h_TrialStepSize = CurrentProposedStepLength - StepTaken;
308 if (canRelaxDeltaChord &&
309 fIncreaseChordDistanceThreshold > 0 &&
310 do_loop_count > fIncreaseChordDistanceThreshold &&
311 do_loop_count % fIncreaseChordDistanceThreshold == 0)
328 fFull_CurveLen_of_LastAttempt = s_length_taken;
337 NewSafety, LinearStepLength,
338 InterSectionPointE );
344 currentSafety = NewSafety;
353 G4bool recalculatedEndPt =
false;
355 G4bool found_intersection = fIntersectionLocator->
356 EstimateIntersectionPoint( SubStepStartState, CurrentState,
357 InterSectionPointE, IntersectPointVelct_G,
358 recalculatedEndPt, fPreviousSafety,
360 intersects = found_intersection;
361 if( found_intersection )
363 End_PointAndTangent= IntersectPointVelct_G;
364 StepTaken = TruePathLength = IntersectPointVelct_G.
GetCurveLength()
372 if( recalculatedEndPt )
378 G4bool shortEnd = endAchieved
379 < (endExpected*(1.0-CLHEP::perMillion));
387 CurrentState = IntersectPointVelct_G;
388 s_length_taken = stepAchieved;
391 fParticleIsLooping =
true;
398 StepTaken += s_length_taken;
400 if (fpTrajectoryFilter !=
nullptr)
402 fpTrajectoryFilter->TakeIntermediatePoint(CurrentState.
GetPosition());
405 first_substep =
false;
408 if( fNoZeroStep > fActionThreshold_NoZeroSteps )
410 if( fNoZeroStep > fSevereActionThreshold_NoZeroSteps )
411 G4cout <<
" Above 'Severe Action' threshold -- for Zero steps. ";
413 G4cout <<
" Above 'action' threshold -- for Zero steps. ";
414 G4cout <<
" Number of zero steps = " << fNoZeroStep <<
G4endl;
416 CurrentState, CurrentProposedStepLength,
417 NewSafety, do_loop_count, pPhysVol );
419 if( (fVerboseLevel > 1) && (do_loop_count > fMax_loop_count-10 ))
421 if( do_loop_count == fMax_loop_count-9 )
423 G4cout <<
" G4PropagatorInField::ComputeStep(): " <<
G4endl
424 <<
" Difficult track - taking many sub steps." <<
G4endl;
425 printStatus( SubStepStartState, SubStepStartState, CurrentProposedStepLength,
426 NewSafety, 0, pPhysVol );
428 printStatus( SubStepStartState, CurrentState, CurrentProposedStepLength,
429 NewSafety, do_loop_count, pPhysVol );
435 }
while( (!intersects )
436 && (!fParticleIsLooping)
437 && (StepTaken + kCarTolerance < CurrentProposedStepLength)
438 && ( do_loop_count < fMax_loop_count ) );
440 if( do_loop_count >= fMax_loop_count
441 && (StepTaken + kCarTolerance < CurrentProposedStepLength) )
443 fParticleIsLooping =
true;
445 if ( ( fParticleIsLooping ) && (fVerboseLevel > 0) )
448 CurrentProposedStepLength, methodName,
457 End_PointAndTangent = CurrentState;
458 TruePathLength = StepTaken;
464 fLastStepInVolume = intersects;
468 pFieldTrack = End_PointAndTangent;
474 - End_PointAndTangent.GetCurveLength()) > 3.e-4 * TruePathLength )
476 std::ostringstream message;
477 message <<
"Curve length mis-match between original state "
478 <<
"and proposed endpoint of propagation." <<
G4endl
479 <<
" The curve length of the endpoint should be: "
481 <<
" and it is instead: "
482 << End_PointAndTangent.GetCurveLength() <<
"." <<
G4endl
483 <<
" A difference of: "
485 - End_PointAndTangent.GetCurveLength() <<
G4endl
486 <<
" Original state = " << OriginalState <<
G4endl
487 <<
" Proposed state = " << End_PointAndTangent;
492 if( TruePathLength+kCarTolerance >= CurrentProposedStepLength )
501 if( TruePathLength < std::max( fZeroStepThreshold, 0.5*kCarTolerance ) )
510 if( fNoZeroStep > fAbandonThreshold_NoZeroSteps )
512 fParticleIsLooping =
true;
514 fFull_CurveLen_of_LastAttempt, pPhysVol );
519 return TruePathLength;
533 const G4int verboseLevel = fVerboseLevel;
543 if( ((stepNo == 0) && (verboseLevel <3)) || (verboseLevel >= 3) )
545 oldprec =
G4cout.precision(4);
546 G4cout << std::setw( 5) <<
"Step#"
547 << std::setw(10) <<
" s " <<
" "
548 << std::setw(10) <<
"X(mm)" <<
" "
549 << std::setw(10) <<
"Y(mm)" <<
" "
550 << std::setw(10) <<
"Z(mm)" <<
" "
551 << std::setw( 7) <<
" N_x " <<
" "
552 << std::setw( 7) <<
" N_y " <<
" "
553 << std::setw( 7) <<
" N_z " <<
" " ;
554 G4cout << std::setw( 7) <<
" Delta|N|" <<
" "
555 << std::setw( 9) <<
"StepLen" <<
" "
556 << std::setw(12) <<
"StartSafety" <<
" "
557 << std::setw( 9) <<
"PhsStep" <<
" ";
558 if( startVolume !=
nullptr )
559 {
G4cout << std::setw(18) <<
"NextVolume" <<
" "; }
560 G4cout.precision(oldprec);
563 if((stepNo == 0) && (verboseLevel <=3))
567 printStatus( StartFT, StartFT, -1.0, safety, -1, startVolume);
569 if( verboseLevel <= 3 )
572 {
G4cout << std::setw( 4) << stepNo <<
" "; }
574 {
G4cout << std::setw( 5) <<
"Start" ; }
575 oldprec =
G4cout.precision(8);
578 G4cout << std::setw(10) << CurrentPosition.
x() <<
" "
579 << std::setw(10) << CurrentPosition.
y() <<
" "
580 << std::setw(10) << CurrentPosition.
z() <<
" ";
582 G4cout << std::setw( 7) << CurrentUnitVelocity.
x() <<
" "
583 << std::setw( 7) << CurrentUnitVelocity.
y() <<
" "
584 << std::setw( 7) << CurrentUnitVelocity.
z() <<
" ";
588 G4cout << std::setw( 9) << step_len <<
" ";
589 G4cout << std::setw(12) << safety <<
" ";
590 if( requestStep != -1.0 )
591 {
G4cout << std::setw( 9) << requestStep <<
" "; }
593 {
G4cout << std::setw( 9) <<
"Init/NotKnown" <<
" "; }
594 if( startVolume !=
nullptr)
595 {
G4cout << std::setw(12) << startVolume->
GetName() <<
" "; }
596 G4cout.precision(oldprec);
603 G4cout <<
"Step taken was " << step_len
604 <<
" out of PhysicalStep = " << requestStep <<
G4endl;
606 G4cout <<
"Chord length = " << (CurrentPosition-StartPosition).mag()