78 fTransportEndPosition( 0.0, 0.0, 0.0 ),
79 fTransportEndMomentumDir( 0.0, 0.0, 0.0 ),
80 fTransportEndKineticEnergy( 0.0 ),
81 fTransportEndSpin( 0.0, 0.0, 0.0 ),
82 fMomentumChanged(true),
83 fEndGlobalTimeComputed(false),
84 fCandidateEndGlobalTime(0.0),
85 fParticleIsLooping( false ),
86 fGeometryLimitedStep(true),
87 fPreviousSftOrigin( 0.,0.,0. ),
88 fPreviousSafety( 0.0 ),
90 fEndPointDistance( -1.0 ),
91 fThreshold_Warning_Energy( 100 *
MeV ),
92 fThreshold_Important_Energy( 250 *
MeV ),
93 fThresholdTrials( 10 ),
95 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
96 fShortStepOptimisation( false ),
97 fUseMagneticMoment( false ),
98 fVerboseLevel( verbosity )
119 fCurrentTouchableHandle = nullTouchableHandle;
122 if( fVerboseLevel > 0)
124 G4cout <<
" G4Transportation constructor> set fShortStepOptimisation to ";
125 if ( fShortStepOptimisation )
G4cout <<
"true" <<
G4endl;
135 if( (fVerboseLevel > 0) && (fSumEnergyKilled > 0.0 ) )
137 G4cout <<
" G4Transportation: Statistics for looping particles " <<
G4endl;
138 G4cout <<
" Sum of energy of loopers killed: " << fSumEnergyKilled <<
G4endl;
139 G4cout <<
" Max energy of loopers killed: " << fMaxEnergyKilled <<
G4endl;
157 G4double geometryStepLength= -1.0, newSafety= -1.0;
158 fParticleIsLooping = false ;
184 G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
186 if( MagSqShift >=
sqr(fPreviousSafety) )
188 currentSafety = 0.0 ;
192 currentSafety = fPreviousSafety - std::sqrt(MagSqShift) ;
201 fGeometryLimitedStep = false ;
211 G4bool fieldExertsForce = false ;
214 G4bool fieldExists=
false;
227 fieldExists = (ptrField!=0) ;
232 if( (particleCharge != 0.0)
233 || (fUseMagneticMoment && (magneticMoment != 0.0) )
234 || (gravityOn && (restMass != 0.0) )
237 fieldExertsForce = fieldExists;
244 if( !fieldExertsForce )
247 if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) )
251 geometryStepLength = currentMinimumStep ;
252 fGeometryLimitedStep = false ;
258 linearStepLength = fLinearNavigator->
ComputeStep( startPosition,
264 fPreviousSftOrigin = startPosition ;
265 fPreviousSafety = newSafety ;
268 currentSafety = newSafety ;
270 fGeometryLimitedStep= (linearStepLength <= currentMinimumStep);
271 if( fGeometryLimitedStep )
274 geometryStepLength = linearStepLength ;
279 geometryStepLength = currentMinimumStep ;
282 fEndPointDistance = geometryStepLength ;
286 fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ;
290 fTransportEndMomentumDir = startMomentumDir ;
293 fParticleIsLooping = false ;
294 fMomentumChanged = false ;
295 fEndGlobalTimeComputed = false ;
317 if( currentMinimumStep > 0 )
321 lengthAlongCurve = fFieldPropagator->
ComputeStep( aFieldTrack,
325 fGeometryLimitedStep= lengthAlongCurve < currentMinimumStep;
326 if( fGeometryLimitedStep )
328 geometryStepLength = lengthAlongCurve ;
332 geometryStepLength = currentMinimumStep ;
337 fPreviousSftOrigin = startPosition ;
338 fPreviousSafety = currentSafety ;
343 geometryStepLength = lengthAlongCurve= 0.0 ;
344 fGeometryLimitedStep = false ;
349 fTransportEndPosition = aFieldTrack.
GetPosition() ;
353 fMomentumChanged = true ;
364 fEndGlobalTimeComputed =
true;
374 fEndGlobalTimeComputed =
false;
379 G4double endEnergy= fTransportEndKineticEnergy;
381 static G4int no_inexact_steps=0, no_large_ediff;
382 G4double absEdiff = std::fabs(startEnergy- endEnergy);
388 if( fVerboseLevel > 1 )
390 if( std::fabs(startEnergy- endEnergy) >
perThousand * endEnergy )
392 static G4int no_warnings= 0, warnModulo=1, moduloFactor= 10;
394 if( (no_large_ediff% warnModulo) == 0 )
397 G4cout <<
"WARNING - G4Transportation::AlongStepGetPIL() "
398 <<
" Energy change in Step is above 1^-3 relative value. " <<
G4endl
399 <<
" Relative change in 'tracking' step = "
400 << std::setw(15) << (endEnergy-startEnergy)/startEnergy <<
G4endl
401 <<
" Starting E= " << std::setw(12) << startEnergy /
MeV <<
" MeV " <<
G4endl
402 <<
" Ending E= " << std::setw(12) << endEnergy /
MeV <<
" MeV " <<
G4endl;
403 G4cout <<
" Energy has been corrected -- however, review"
404 <<
" field propagation parameters for accuracy." <<
G4endl;
405 if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) )
407 G4cout <<
" These include EpsilonStepMax(/Min) in G4FieldManager "
408 <<
" which determine fractional error per step for integrated quantities. " << G4endl
409 <<
" Note also the influence of the permitted number of integration steps."
412 G4cerr <<
"ERROR - G4Transportation::AlongStepGetPIL()" << G4endl
413 <<
" Bad 'endpoint'. Energy change detected"
414 <<
" and corrected. "
415 <<
" Has occurred already "
416 << no_large_ediff <<
" times." <<
G4endl;
417 if( no_large_ediff == warnModulo * moduloFactor )
419 warnModulo *= moduloFactor;
431 fTransportEndSpin = aFieldTrack.
GetSpin();
433 fEndPointDistance = (fTransportEndPosition - startPosition).mag() ;
439 if( currentMinimumStep == 0.0 )
441 if( currentSafety == 0.0 ) { fGeometryLimitedStep =
true; }
447 if( currentSafety < fEndPointDistance )
449 if( particleCharge != 0.0 )
453 currentSafety = endSafety ;
454 fPreviousSftOrigin = fTransportEndPosition ;
455 fPreviousSafety = currentSafety ;
461 currentSafety += fEndPointDistance ;
463 #ifdef G4DEBUG_TRANSPORT
465 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
466 G4cout <<
" Called Navigator->ComputeSafety at " << fTransportEndPosition
467 <<
" and it returned safety= " << endSafety <<
G4endl ;
468 G4cout <<
" Adding endpoint distance " << fEndPointDistance
469 <<
" to obtain pseudo-safety= " << currentSafety <<
G4endl ;
473 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
474 G4cout <<
" Avoiding call to ComputeSafety : " <<
G4endl;
483 return geometryStepLength ;
494 static G4int noCalls=0;
516 if (!fEndGlobalTimeComputed)
524 if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; }
526 fCandidateEndGlobalTime = startTime + deltaTime ;
531 deltaTime = fCandidateEndGlobalTime - startTime ;
548 if ( fParticleIsLooping )
550 G4double endEnergy= fTransportEndKineticEnergy;
552 if( (endEnergy < fThreshold_Important_Energy)
553 || (fNoLooperTrials >= fThresholdTrials ) )
560 fSumEnergyKilled += endEnergy;
561 if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
564 if( (fVerboseLevel > 1) &&
565 ( endEnergy > fThreshold_Warning_Energy ) )
567 G4cout <<
" G4Transportation is killing track that is looping or stuck "
570 <<
" MeV energy." <<
G4endl;
571 G4cout <<
" Number of trials = " << fNoLooperTrials
572 <<
" No of calls to AlongStepDoIt = " << noCalls
582 if( (fVerboseLevel > 2) )
584 G4cout <<
" G4Transportation::AlongStepDoIt(): Particle looping - "
585 <<
" Number of trials = " << fNoLooperTrials
586 <<
" No of calls to = " << noCalls
605 return &fParticleChange ;
641 if(fGeometryLimitedStep)
649 LocateGlobalPointAndUpdateTouchableHandle( track.
GetPosition(),
651 fCurrentTouchableHandle,
656 if( fCurrentTouchableHandle->
GetVolume() == 0 )
660 retCurrentTouchable = fCurrentTouchableHandle ;
667 #ifdef G4DEBUG_TRANSPORT
672 if( ! (exiting || entering) )
674 G4cout <<
" Transport> : Proposed isLastStep= " << isLastStep
697 #ifdef G4DEBUG_TRANSPORT
700 G4cout <<
" Transport> Proposed isLastStep= " << isLastStep
701 <<
" Geometry did not limit step. " <<
G4endl;
729 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
733 pNewMaterialCutsCouple =
748 return &fParticleChange ;
764 fPreviousSafety = 0.0 ;