127 G4bool canRelaxDeltaChord)
135 const char* methodName =
"G4PropagatorInField::ComputeStep";
136 if (CurrentProposedStepLength<kCarTolerance)
143 if (fpTrajectoryFilter !=
nullptr)
148 fFirstStepInVolume = fNewTrack ? true : fLastStepInVolume;
149 fLastStepInVolume =
false;
152 if( fVerboseLevel > 2 )
155 G4cout <<
" Starting FT: " << pFieldTrack;
156 G4cout <<
" Requested length = " << CurrentProposedStepLength <<
G4endl;
158 if( pPhysVol !=
nullptr )
172 G4double TruePathLength = CurrentProposedStepLength;
176 G4bool first_substep =
true;
179 fParticleIsLooping =
false;
189 fSetFieldMgr =
false;
197 if( CurrentProposedStepLength >= fLargestAcceptableStep )
203 G4double trialProposedStep = fMaxStepSizeMultiplier * ( fMinBigDistance +
205 GetSolid()->DistanceToOut(StartPointA, VelocityUnit) );
206 CurrentProposedStepLength = std::min( trialProposedStep,
207 fLargestAcceptableStep );
223 if( fNoZeroStep > fActionThreshold_NoZeroSteps )
227 stepTrial = fFull_CurveLen_of_LastAttempt;
228 if( (stepTrial <= 0.0) && (fLast_ProposedStepLength > 0.0) )
230 stepTrial = fLast_ProposedStepLength;
234 if( (fNoZeroStep < fSevereActionThreshold_NoZeroSteps)
235 && (stepTrial > 100.0*fZeroStepThreshold) )
239 decreaseFactor= 0.25;
247 if( stepTrial > 100.0*fZeroStepThreshold ) {
248 decreaseFactor = 0.35;
249 }
else if( stepTrial > 30.0*fZeroStepThreshold ) {
251 }
else if( stepTrial > 10.0*fZeroStepThreshold ) {
252 decreaseFactor= 0.75;
257 stepTrial *= decreaseFactor;
260 if( fVerboseLevel > 2
261 || (fNoZeroStep >= fSevereActionThreshold_NoZeroSteps) )
263 G4cerr <<
" " << methodName
264 <<
" Decreasing step after " << fNoZeroStep <<
" zero steps "
265 <<
" - in volume " << pPhysVol;
269 G4cerr <<
" i.e. *unknown* volume.";
272 stepTrial, pFieldTrack);
275 if( stepTrial == 0.0 )
277 std::ostringstream message;
278 message <<
"Particle abandoned due to lack of progress in field."
280 <<
" Properties : " << pFieldTrack <<
G4endl
281 <<
" Attempting a zero step = " << stepTrial <<
G4endl
282 <<
" while attempting to progress after " << fNoZeroStep
283 <<
" trial steps. Will abandon step.";
285 fParticleIsLooping =
true;
288 if( stepTrial < CurrentProposedStepLength )
290 CurrentProposedStepLength = stepTrial;
293 fLast_ProposedStepLength = CurrentProposedStepLength;
295 G4int do_loop_count = 0;
303 if( fVerboseLevel > 4 )
305 G4cout <<
" PiF: Calling Nav/Locate Global Point within-Volume "
313 h_TrialStepSize = CurrentProposedStepLength - StepTaken;
315 if (canRelaxDeltaChord &&
316 fIncreaseChordDistanceThreshold > 0 &&
317 do_loop_count > fIncreaseChordDistanceThreshold &&
318 do_loop_count % fIncreaseChordDistanceThreshold == 0)
335 fFull_CurveLen_of_LastAttempt = s_length_taken;
344 NewSafety, LinearStepLength,
345 InterSectionPointE );
351 currentSafety = NewSafety;
360 G4bool recalculatedEndPt =
false;
362 G4bool found_intersection = fIntersectionLocator->
363 EstimateIntersectionPoint( SubStepStartState, CurrentState,
364 InterSectionPointE, IntersectPointVelct_G,
365 recalculatedEndPt, fPreviousSafety,
367 intersects = found_intersection;
368 if( found_intersection )
370 End_PointAndTangent= IntersectPointVelct_G;
371 StepTaken = TruePathLength = IntersectPointVelct_G.
GetCurveLength()
379 if( recalculatedEndPt )
385 G4bool shortEnd = endAchieved
386 < (endExpected*(1.0-CLHEP::perMillion));
394 CurrentState = IntersectPointVelct_G;
395 s_length_taken = stepAchieved;
398 fParticleIsLooping =
true;
405 StepTaken += s_length_taken;
407 if (fpTrajectoryFilter !=
nullptr)
412 first_substep =
false;
415 if( fNoZeroStep > fActionThreshold_NoZeroSteps )
417 if( fNoZeroStep > fSevereActionThreshold_NoZeroSteps )
418 G4cout <<
" Above 'Severe Action' threshold -- for Zero steps. ";
420 G4cout <<
" Above 'action' threshold -- for Zero steps. ";
421 G4cout <<
" Number of zero steps = " << fNoZeroStep <<
G4endl;
423 CurrentState, CurrentProposedStepLength,
424 NewSafety, do_loop_count, pPhysVol );
426 if( (fVerboseLevel > 1) && (do_loop_count > fMax_loop_count-10 ))
428 if( do_loop_count == fMax_loop_count-9 )
430 G4cout <<
" G4PropagatorInField::ComputeStep(): " <<
G4endl
431 <<
" Difficult track - taking many sub steps." <<
G4endl;
432 printStatus( SubStepStartState, SubStepStartState, CurrentProposedStepLength,
433 NewSafety, 0, pPhysVol );
435 printStatus( SubStepStartState, CurrentState, CurrentProposedStepLength,
436 NewSafety, do_loop_count, pPhysVol );
442 }
while( (!intersects )
443 && (!fParticleIsLooping)
444 && (StepTaken + kCarTolerance < CurrentProposedStepLength)
445 && ( do_loop_count < fMax_loop_count ) );
447 if( do_loop_count >= fMax_loop_count
448 && (StepTaken + kCarTolerance < CurrentProposedStepLength) )
450 fParticleIsLooping =
true;
452 if ( ( fParticleIsLooping ) && (fVerboseLevel > 0) )
455 CurrentProposedStepLength, methodName,
464 End_PointAndTangent = CurrentState;
465 TruePathLength = StepTaken;
471 fLastStepInVolume = intersects;
475 pFieldTrack = End_PointAndTangent;
481 - End_PointAndTangent.
GetCurveLength()) > 3.e-4 * TruePathLength )
483 std::ostringstream message;
484 message <<
"Curve length mis-match between original state "
485 <<
"and proposed endpoint of propagation." <<
G4endl
486 <<
" The curve length of the endpoint should be: "
488 <<
" and it is instead: "
490 <<
" A difference of: "
493 <<
" Original state = " << OriginalState <<
G4endl
494 <<
" Proposed state = " << End_PointAndTangent;
499 if( TruePathLength+kCarTolerance >= CurrentProposedStepLength )
508 if( TruePathLength < std::max( fZeroStepThreshold, 0.5*kCarTolerance ) )
517 if( fNoZeroStep > fAbandonThreshold_NoZeroSteps )
519 fParticleIsLooping =
true;
521 fFull_CurveLen_of_LastAttempt, pPhysVol );
526 return TruePathLength;
540 const G4int verboseLevel = fVerboseLevel;
550 if( ((stepNo == 0) && (verboseLevel <3)) || (verboseLevel >= 3) )
552 oldprec =
G4cout.precision(4);
553 G4cout << std::setw( 5) <<
"Step#"
554 << std::setw(10) <<
" s " <<
" "
555 << std::setw(10) <<
"X(mm)" <<
" "
556 << std::setw(10) <<
"Y(mm)" <<
" "
557 << std::setw(10) <<
"Z(mm)" <<
" "
558 << std::setw( 7) <<
" N_x " <<
" "
559 << std::setw( 7) <<
" N_y " <<
" "
560 << std::setw( 7) <<
" N_z " <<
" " ;
561 G4cout << std::setw( 7) <<
" Delta|N|" <<
" "
562 << std::setw( 9) <<
"StepLen" <<
" "
563 << std::setw(12) <<
"StartSafety" <<
" "
564 << std::setw( 9) <<
"PhsStep" <<
" ";
565 if( startVolume !=
nullptr )
566 {
G4cout << std::setw(18) <<
"NextVolume" <<
" "; }
567 G4cout.precision(oldprec);
570 if((stepNo == 0) && (verboseLevel <=3))
574 printStatus( StartFT, StartFT, -1.0, safety, -1, startVolume);
576 if( verboseLevel <= 3 )
579 {
G4cout << std::setw( 4) << stepNo <<
" "; }
581 {
G4cout << std::setw( 5) <<
"Start" ; }
582 oldprec =
G4cout.precision(8);
585 G4cout << std::setw(10) << CurrentPosition.
x() <<
" "
586 << std::setw(10) << CurrentPosition.
y() <<
" "
587 << std::setw(10) << CurrentPosition.
z() <<
" ";
589 G4cout << std::setw( 7) << CurrentUnitVelocity.
x() <<
" "
590 << std::setw( 7) << CurrentUnitVelocity.
y() <<
" "
591 << std::setw( 7) << CurrentUnitVelocity.
z() <<
" ";
595 G4cout << std::setw( 9) << step_len <<
" ";
596 G4cout << std::setw(12) << safety <<
" ";
597 if( requestStep != -1.0 )
598 {
G4cout << std::setw( 9) << requestStep <<
" "; }
600 {
G4cout << std::setw( 9) <<
"Init/NotKnown" <<
" "; }
601 if( startVolume !=
nullptr)
602 {
G4cout << std::setw(12) << startVolume->
GetName() <<
" "; }
603 G4cout.precision(oldprec);
610 G4cout <<
"Step taken was " << step_len
611 <<
" out of PhysicalStep = " << requestStep <<
G4endl;
613 G4cout <<
"Chord length = " << (CurrentPosition-StartPosition).mag()