79 fTransportEndPosition( 0.0, 0.0, 0.0 ),
80 fTransportEndMomentumDir( 0.0, 0.0, 0.0 ),
81 fTransportEndKineticEnergy( 0.0 ),
82 fTransportEndSpin( 0.0, 0.0, 0.0 ),
83 fMomentumChanged(true),
84 fEnergyChanged(false),
85 fEndGlobalTimeComputed(false),
86 fCandidateEndGlobalTime(0.0),
87 fParticleIsLooping( false ),
88 fGeometryLimitedStep(true),
89 fPreviousSftOrigin( 0.,0.,0. ),
90 fPreviousSafety( 0.0 ),
92 fEndPointDistance( -1.0 ),
93 fThreshold_Warning_Energy( 100 * MeV ),
94 fThreshold_Important_Energy( 250 * MeV ),
95 fThresholdTrials( 10 ),
96 fUnimportant_Energy( 1 * MeV ),
98 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
99 fShortStepOptimisation( false ),
100 fUseMagneticMoment( false ),
101 fVerboseLevel( verbosity )
122 fCurrentTouchableHandle = nullTouchableHandle;
126 if( fVerboseLevel > 0)
128 G4cout <<
" G4Transportation constructor> set fShortStepOptimisation to ";
129 if ( fShortStepOptimisation )
G4cout <<
"true" <<
G4endl;
139 if( (fVerboseLevel > 0) && (fSumEnergyKilled > 0.0 ) ){
140 G4cout <<
" G4Transportation: Statistics for looping particles " <<
G4endl;
141 G4cout <<
" Sum of energy of loopers killed: " << fSumEnergyKilled <<
G4endl;
142 G4cout <<
" Max energy of loopers killed: " << fMaxEnergyKilled <<
G4endl;
160 G4double geometryStepLength= -1.0, newSafety= -1.0;
161 fParticleIsLooping = false ;
187 G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
189 if( MagSqShift >=
sqr(fPreviousSafety) )
191 currentSafety = 0.0 ;
195 currentSafety = fPreviousSafety - std::sqrt(MagSqShift) ;
204 fGeometryLimitedStep = false ;
214 G4bool fieldExertsForce = false ;
217 G4bool fieldExists=
false;
230 fieldExists = (ptrField!=0) ;
235 if( (particleCharge != 0.0)
236 || (fUseMagneticMoment && (magneticMoment != 0.0) )
237 || (gravityOn && (restMass != 0.0) )
240 fieldExertsForce = fieldExists;
247 if( !fieldExertsForce )
250 if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) )
254 geometryStepLength = currentMinimumStep ;
255 fGeometryLimitedStep = false ;
261 linearStepLength = fLinearNavigator->
ComputeStep( startPosition,
267 fPreviousSftOrigin = startPosition ;
268 fPreviousSafety = newSafety ;
271 currentSafety = newSafety ;
273 fGeometryLimitedStep= (linearStepLength <= currentMinimumStep);
274 if( fGeometryLimitedStep )
277 geometryStepLength = linearStepLength ;
282 geometryStepLength = currentMinimumStep ;
285 fEndPointDistance = geometryStepLength ;
289 fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ;
293 fTransportEndMomentumDir = startMomentumDir ;
296 fParticleIsLooping = false ;
297 fMomentumChanged = false ;
298 fEndGlobalTimeComputed = false ;
320 if( currentMinimumStep > 0 )
324 lengthAlongCurve = fFieldPropagator->
ComputeStep( aFieldTrack,
328 fGeometryLimitedStep= lengthAlongCurve < currentMinimumStep;
329 if( fGeometryLimitedStep ) {
330 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);
383 if( absEdiff > perMillion * 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) ){
406 G4cout <<
" These include EpsilonStepMax(/Min) in G4FieldManager "
407 <<
" which determine fractional error per step for integrated quantities. " <<
G4endl
408 <<
" Note also the influence of the permitted number of integration steps."
411 G4cerr <<
"ERROR - G4Transportation::AlongStepGetPIL()" <<
G4endl
412 <<
" Bad 'endpoint'. Energy change detected"
413 <<
" and corrected. "
414 <<
" Has occurred already "
415 << no_large_ediff <<
" times." <<
G4endl;
416 if( no_large_ediff == warnModulo * moduloFactor )
418 warnModulo *= moduloFactor;
430 fTransportEndSpin = aFieldTrack.
GetSpin();
432 fEndPointDistance = (fTransportEndPosition - startPosition).mag() ;
438 if( currentMinimumStep == 0.0 )
440 if( currentSafety == 0.0 ) fGeometryLimitedStep = true ;
446 if( currentSafety < fEndPointDistance )
448 if( particleCharge != 0.0 )
452 currentSafety = endSafety ;
453 fPreviousSftOrigin = fTransportEndPosition ;
454 fPreviousSafety = currentSafety ;
460 currentSafety += fEndPointDistance ;
462#ifdef G4DEBUG_TRANSPORT
464 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
465 G4cout <<
" Called Navigator->ComputeSafety at " << fTransportEndPosition
466 <<
" and it returned safety= " << endSafety <<
G4endl ;
467 G4cout <<
" Adding endpoint distance " << fEndPointDistance
468 <<
" to obtain pseudo-safety= " << currentSafety <<
G4endl ;
470 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
471 G4cout <<
" Avoiding call to ComputeSafety : " <<
G4endl;
480 return geometryStepLength ;
491 static G4int noCalls=0;
513 if (!fEndGlobalTimeComputed)
521 if ( initialVelocity > 0.0 ) deltaTime = stepLength/initialVelocity ;
523 fCandidateEndGlobalTime = startTime + deltaTime ;
528 deltaTime = fCandidateEndGlobalTime - startTime ;
545 if ( fParticleIsLooping )
547 G4double endEnergy= fTransportEndKineticEnergy;
549 if( (endEnergy < fThreshold_Important_Energy)
550 || (fNoLooperTrials >= fThresholdTrials ) ){
556 fSumEnergyKilled += endEnergy;
557 if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
560 if( (fVerboseLevel > 1) ||
561 ( endEnergy > fThreshold_Warning_Energy ) ) {
562 G4cout <<
" G4Transportation is killing track that is looping or stuck "
565 <<
" MeV energy." <<
G4endl;
566 G4cout <<
" Number of trials = " << fNoLooperTrials
567 <<
" No of calls to AlongStepDoIt = " << noCalls
576 if( (fVerboseLevel > 2) ){
577 G4cout <<
" G4Transportation::AlongStepDoIt(): Particle looping - "
578 <<
" Number of trials = " << fNoLooperTrials
579 <<
" No of calls to = " << noCalls
596 return &fParticleChange ;
632 if(fGeometryLimitedStep)
640 LocateGlobalPointAndUpdateTouchableHandle( track.
GetPosition(),
642 fCurrentTouchableHandle,
647 if( fCurrentTouchableHandle->
GetVolume() == 0 )
651 retCurrentTouchable = fCurrentTouchableHandle ;
658#ifdef G4DEBUG_TRANSPORT
662 if( ! (exiting || entering) ) {
663 G4cout <<
" Transport> : Proposed isLastStep= " << isLastStep
685#ifdef G4DEBUG_TRANSPORT
687 G4cout <<
" Transport> Proposed isLastStep= " << isLastStep
688 <<
" Geometry did not limit step. " <<
G4endl;
716 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
720 pNewMaterialCutsCouple =
735 return &fParticleChange ;
751 fPreviousSafety = 0.0 ;
CLHEP::Hep3Vector G4ThreeVector
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4double GetCharge() const
G4ParticleDefinition * GetDefinition() const
G4double GetMagneticMoment() const
G4double GetTotalMomentum() const
static G4FieldManagerStore * GetInstance()
void ClearAllChordFindersState()
G4bool DoesFieldChangeEnergy() const
virtual void ConfigureForTrack(const G4Track *)
const G4Field * GetDetectorField() const
const G4ThreeVector & GetMomentumDir() const
G4double GetKineticEnergy() const
G4ThreeVector GetPosition() const
G4ThreeVector GetSpin() const
G4double GetLabTimeOfFlight() const
G4bool IsGravityActive() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4Material * GetMaterial() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
const G4Material * GetMaterial() const
G4ProductionCuts * GetProductionCuts() const
void SetGeometricallyLimitedStep()
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
G4bool EnteredDaughterVolume() const
G4bool ExitedMotherVolume() const
void SetMaterialInTouchable(G4Material *fMaterial)
void SetTouchableHandle(const G4TouchableHandle &fTouchable)
void SetMaterialCutsCoupleInTouchable(const G4MaterialCutsCouple *fMaterialCutsCouple)
void SetPointerToVectorOfAuxiliaryPoints(std::vector< G4ThreeVector > *theNewVectorPointer)
virtual void Initialize(const G4Track &)
void SetSensitiveDetectorInTouchable(G4VSensitiveDetector *fSensitiveDetector)
void SetMomentumChanged(G4bool b)
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
void ProposePosition(G4double x, G4double y, G4double z)
void ProposeLocalTime(G4double t)
void ProposeProperTime(G4double finalProperTime)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
void ProposeGlobalTime(G4double t)
G4double GetPDGMass() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=0)
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
G4FieldManager * GetCurrentFieldManager()
G4bool IsParticleLooping() const
void ClearPropagatorState()
void SetChargeMomentumMass(G4double charge, G4double momentum, G4double pMass)
std::vector< G4ThreeVector > * GimmeTrajectoryVectorAndForgetIt() const
void SetCurrentSafety(G4double val, const G4ThreeVector &pos)
G4double GetVelocity() const
G4StepPoint * GetPreStepPoint() const
G4TrackStatus GetTrackStatus() const
G4double GetVelocity() const
G4VPhysicalVolume * GetVolume() const
const G4ThreeVector & GetPosition() const
G4double GetGlobalTime() const
G4double GetProperTime() const
G4double GetLocalTime() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
G4double GetStepLength() const
G4double GetTotalEnergy() const
static G4TransportationManager * GetTransportationManager()
G4PropagatorInField * GetPropagatorInField() const
G4SafetyHelper * GetSafetyHelper() const
G4Navigator * GetNavigatorForTracking() const
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4bool DoesGlobalFieldExist()
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
void StartTracking(G4Track *aTrack)
G4Transportation(G4int verbosityLevel=1)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLastStepInVolume(G4bool flag)
void ProposeTrueStepLength(G4double truePathLength)
G4LogicalVolume * GetLogicalVolume() const
void SetProcessSubType(G4int)
virtual void StartTracking(G4Track *)
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const