75 G4bool G4Transportation::fUseMagneticMoment=
false;
85 fTransportEndPosition( 0.0, 0.0, 0.0 ),
86 fTransportEndMomentumDir( 0.0, 0.0, 0.0 ),
87 fTransportEndKineticEnergy( 0.0 ),
88 fTransportEndSpin( 0.0, 0.0, 0.0 ),
89 fMomentumChanged(true),
90 fEndGlobalTimeComputed(false),
91 fCandidateEndGlobalTime(0.0),
92 fParticleIsLooping( false ),
94 fFirstStepInVolume( true ),
95 fLastStepInVolume( false ),
96 fGeometryLimitedStep(true),
101 fEndPointDistance( -1.0 ),
102 fThreshold_Warning_Energy( 100 *
MeV ),
103 fThreshold_Important_Energy( 250 *
MeV ),
104 fThresholdTrials( 10 ),
105 fNoLooperTrials( 0 ),
106 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
107 fShortStepOptimisation( false ),
108 fVerboseLevel( verbosity )
131 fCurrentTouchableHandle = *pNullTouchableHandle;
135 if( fVerboseLevel > 0)
137 G4cout <<
" G4Transportation constructor> set fShortStepOptimisation to ";
138 if ( fShortStepOptimisation )
G4cout <<
"true" <<
G4endl;
148 if( (fVerboseLevel > 0) && (fSumEnergyKilled > 0.0 ) )
150 G4cout <<
" G4Transportation: Statistics for looping particles " <<
G4endl;
151 G4cout <<
" Sum of energy of loopers killed: " << fSumEnergyKilled <<
G4endl;
152 G4cout <<
" Max energy of loopers killed: " << fMaxEnergyKilled <<
G4endl;
170 G4double geometryStepLength= -1.0, newSafety= -1.0;
171 fParticleIsLooping = false ;
184 fFirstStepInVolume=
fNewTrack || fLastStepInVolume;
186 fLastStepInVolume=
false;
208 currentSafety = 0.0 ;
221 fGeometryLimitedStep = false ;
231 G4bool fieldExertsForce = false ;
234 G4bool fieldExists=
false;
247 fieldExists = (ptrField!=0) ;
252 if( (particleCharge != 0.0)
253 || (fUseMagneticMoment && (magneticMoment != 0.0) )
254 || (gravityOn && (restMass != 0.0) )
257 fieldExertsForce = fieldExists;
265 if( !fieldExertsForce )
268 if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) )
272 geometryStepLength = currentMinimumStep ;
273 fGeometryLimitedStep = false ;
279 linearStepLength = fLinearNavigator->
ComputeStep( startPosition,
285 fPreviousSftOrigin = startPosition ;
289 currentSafety = newSafety ;
291 fGeometryLimitedStep= (linearStepLength <= currentMinimumStep);
292 if( fGeometryLimitedStep )
295 geometryStepLength = linearStepLength ;
300 geometryStepLength = currentMinimumStep ;
303 fEndPointDistance = geometryStepLength ;
307 fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ;
311 fTransportEndMomentumDir = startMomentumDir ;
314 fParticleIsLooping = false ;
315 fMomentumChanged = false ;
316 fEndGlobalTimeComputed = false ;
332 ->GetEquationOfMotion();
352 if( currentMinimumStep > 0 )
356 lengthAlongCurve = fFieldPropagator->
ComputeStep( aFieldTrack,
366 geometryStepLength =
std::min( lengthAlongCurve, currentMinimumStep );
370 fPreviousSftOrigin = startPosition ;
376 geometryStepLength = lengthAlongCurve= 0.0 ;
377 fGeometryLimitedStep = false ;
382 fTransportEndPosition = aFieldTrack.
GetPosition() ;
386 fMomentumChanged = true ;
397 fEndGlobalTimeComputed =
true;
407 fEndGlobalTimeComputed =
false;
412 G4double endEnergy= fTransportEndKineticEnergy;
415 G4double absEdiff = std::fabs(startEnergy- endEnergy);
421 if( fVerboseLevel > 1 )
423 if( std::fabs(startEnergy- endEnergy) >
perThousand * endEnergy )
428 if( (no_large_ediff% warnModulo) == 0 )
431 G4cout <<
"WARNING - G4Transportation::AlongStepGetPIL() "
432 <<
" Energy change in Step is above 1^-3 relative value. " <<
G4endl
433 <<
" Relative change in 'tracking' step = "
434 << std::setw(15) << (endEnergy-startEnergy)/startEnergy <<
G4endl
435 <<
" Starting E= " << std::setw(12) << startEnergy /
MeV <<
" MeV " <<
G4endl
436 <<
" Ending E= " << std::setw(12) << endEnergy /
MeV <<
" MeV " <<
G4endl;
437 G4cout <<
" Energy has been corrected -- however, review"
438 <<
" field propagation parameters for accuracy." <<
G4endl;
439 if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) )
441 G4cout <<
" These include EpsilonStepMax(/Min) in G4FieldManager "
442 <<
" which determine fractional error per step for integrated quantities. " << G4endl
443 <<
" Note also the influence of the permitted number of integration steps."
446 G4cerr <<
"ERROR - G4Transportation::AlongStepGetPIL()" << G4endl
447 <<
" Bad 'endpoint'. Energy change detected"
448 <<
" and corrected. "
449 <<
" Has occurred already "
450 << no_large_ediff <<
" times." <<
G4endl;
451 if( no_large_ediff == warnModulo * moduloFactor )
453 warnModulo *= moduloFactor;
465 fTransportEndSpin = aFieldTrack.
GetSpin();
467 fEndPointDistance = (fTransportEndPosition - startPosition).mag() ;
473 if( currentMinimumStep == 0.0 )
475 if( currentSafety == 0.0 ) { fGeometryLimitedStep =
true; }
481 if( currentSafety < fEndPointDistance )
483 if( particleCharge != 0.0 )
487 currentSafety = endSafety ;
488 fPreviousSftOrigin = fTransportEndPosition ;
495 currentSafety += fEndPointDistance ;
497 #ifdef G4DEBUG_TRANSPORT
499 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
500 G4cout <<
" Called Navigator->ComputeSafety at " << fTransportEndPosition
501 <<
" and it returned safety= " << endSafety <<
G4endl ;
502 G4cout <<
" Adding endpoint distance " << fEndPointDistance
503 <<
" to obtain pseudo-safety= " << currentSafety <<
G4endl ;
507 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
508 G4cout <<
" Avoiding call to ComputeSafety : " <<
G4endl;
517 return geometryStepLength ;
550 if (!fEndGlobalTimeComputed)
558 if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; }
560 fCandidateEndGlobalTime = startTime + deltaTime ;
565 deltaTime = fCandidateEndGlobalTime - startTime ;
582 if ( fParticleIsLooping )
584 G4double endEnergy= fTransportEndKineticEnergy;
586 if( (endEnergy < fThreshold_Important_Energy)
587 || (fNoLooperTrials >= fThresholdTrials ) )
594 fSumEnergyKilled += endEnergy;
595 if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
598 if( (fVerboseLevel > 1) &&
599 ( endEnergy > fThreshold_Warning_Energy ) )
601 G4cout <<
" G4Transportation is killing track that is looping or stuck "
604 <<
" MeV energy." <<
G4endl;
605 G4cout <<
" Number of trials = " << fNoLooperTrials
606 <<
" No of calls to AlongStepDoIt = " << noCalls
616 if( (fVerboseLevel > 2) )
618 G4cout <<
" G4Transportation::AlongStepDoIt(): Particle looping - "
619 <<
" Number of trials = " << fNoLooperTrials
620 <<
" No of calls to = " << noCalls
639 return &fParticleChange ;
676 if(fGeometryLimitedStep)
684 LocateGlobalPointAndUpdateTouchableHandle( track.
GetPosition(),
686 fCurrentTouchableHandle,
691 if( fCurrentTouchableHandle->
GetVolume() == 0 )
695 retCurrentTouchable = fCurrentTouchableHandle ;
721 fLastStepInVolume= isLastStep;
748 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
752 pNewMaterialCutsCouple =
767 return &fParticleChange ;
778 fFirstStepInVolume=
true;
779 fLastStepInVolume=
false;
823 G4bool lastValue= fUseMagneticMoment;
824 fUseMagneticMoment= useMoment;
825 G4CoupledTransportation::fUseMagneticMoment= useMoment;
void SetMaterialInTouchable(G4Material *fMaterial)
static constexpr double perMillion
void SetTouchableHandle(const G4TouchableHandle &fTouchable)
const G4ThreeVector & GetPolarization() const
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4SafetyHelper * GetSafetyHelper() const
G4double GetLocalTime() const
G4Material * GetMaterial() const
void SetMaterialCutsCoupleInTouchable(const G4MaterialCutsCouple *fMaterialCutsCouple)
virtual void SetChargeMomentumMass(G4ChargeState particleCharge, G4double MomentumXc, G4double MassXc2)=0
G4double GetProperTime() const
std::vector< G4ThreeVector > * GimmeTrajectoryVectorAndForgetIt() const
CLHEP::Hep3Vector G4ThreeVector
void StartTracking(G4Track *aTrack)
G4double GetKineticEnergy() const
const G4DynamicParticle * GetDynamicParticle() const
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
const G4MagIntegratorStepper * GetStepper() const
void ClearAllChordFindersState()
const G4ThreeVector & GetPosition() const
const G4ThreeVector & GetMomentumDir() const
G4TrackStatus GetTrackStatus() const
G4ThreeVector GetSpin() const
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
G4Navigator * GetNavigatorForTracking() const
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
G4ParticleDefinition * GetDefinition() const
G4double GetVelocity() const
#define fFieldExertedForce
void ProposePosition(G4double x, G4double y, G4double z)
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4double GetTotalMomentum() const
G4StepPoint * GetPreStepPoint() const
virtual void Initialize(const G4Track &)
virtual void StartTracking(G4Track *)
virtual void ConfigureForTrack(const G4Track *)
void SetGeometricallyLimitedStep()
G4double GetKineticEnergy() const
G4ThreeVector GetPosition() const
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4double GetCharge() const
void ProposeTrueStepLength(G4double truePathLength)
G4bool DoesGlobalFieldExist()
void ProposeFirstStepInVolume(G4bool flag)
void SetProcessSubType(G4int)
G4bool EnteredDaughterVolume() const
G4bool DoesFieldChangeEnergy() const
G4double GetGlobalTime() const
G4bool IsLastStepInVolume()
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
G4Transportation(G4int verbosityLevel=1)
const G4TouchableHandle & GetTouchableHandle() const
static G4TransportationManager * GetTransportationManager()
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=0)
static G4ProductionCutsTable * GetProductionCutsTable()
const G4ThreeVector & GetMomentumDirection() const
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
G4LogicalVolume * GetLogicalVolume() const
void ProposeProperTime(G4double finalProperTime)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4FieldManagerStore * GetInstance()
void SetSensitiveDetectorInTouchable(G4VSensitiveDetector *fSensitiveDetector)
#define fPreviousSftOrigin
G4bool IsParticleLooping() const
G4double GetLabTimeOfFlight() const
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
void SetPointerToVectorOfAuxiliaryPoints(std::vector< G4ThreeVector > *theNewVectorPointer)
G4bool IsGravityActive() const
void ProposeGlobalTime(G4double t)
G4ChordFinder * GetChordFinder()
G4FieldManager * GetCurrentFieldManager()
G4VParticleChange * pParticleChange
void ProposeEnergy(G4double finalEnergy)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4VPhysicalVolume * GetVolume() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
G4double GetTotalEnergy() const
G4double GetPDGSpin() const
void SetCurrentSafety(G4double val, const G4ThreeVector &pos)
void ClearPropagatorState()
G4bool ExitedMotherVolume() const
static constexpr double MeV
void ProposeLastStepInVolume(G4bool flag)
static constexpr double perThousand
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double GetPDGMagneticMoment() const
void ProposeTrackStatus(G4TrackStatus status)
const G4Field * GetDetectorField() const
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4MagInt_Driver * GetIntegrationDriver()
void SetMomentumChanged(G4bool b)
G4PropagatorInField * GetPropagatorInField() const
G4ProductionCuts * GetProductionCuts() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4double GetMagneticMoment() const
void ProposeLocalTime(G4double t)
G4double GetStepLength() const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
const G4Material * GetMaterial() const
G4GLOB_DLL std::ostream G4cerr
static G4bool EnableUseMagneticMoment(G4bool useMoment=true)