80 fTransportEndPosition( 0.0, 0.0, 0.0 ),
81 fTransportEndMomentumDir( 0.0, 0.0, 0.0 ),
82 fTransportEndKineticEnergy( 0.0 ),
83 fTransportEndSpin( 0.0, 0.0, 0.0 ),
84 fMomentumChanged(true),
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 ),
97 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
98 fShortStepOptimisation( false ),
99 fUseMagneticMoment( false ),
100 fVerboseLevel( verbosity )
122 fCurrentTouchableHandle = *pNullTouchableHandle;
126 if( fVerboseLevel > 0)
128 G4cout <<
" G4Transportation constructor> set fShortStepOptimisation to ";
129 if ( fShortStepOptimisation )
G4cout <<
"true" <<
G4endl;
139 if( (fVerboseLevel > 0) && (fSumEnergyKilled > 0.0 ) )
141 G4cout <<
" G4Transportation: Statistics for looping particles " <<
G4endl;
142 G4cout <<
" Sum of energy of loopers killed: " << fSumEnergyKilled <<
G4endl;
143 G4cout <<
" Max energy of loopers killed: " << fMaxEnergyKilled <<
G4endl;
161 G4double geometryStepLength= -1.0, newSafety= -1.0;
162 fParticleIsLooping = false ;
188 G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
190 if( MagSqShift >=
sqr(fPreviousSafety) )
192 currentSafety = 0.0 ;
196 currentSafety = fPreviousSafety - std::sqrt(MagSqShift) ;
205 fGeometryLimitedStep = false ;
215 G4bool fieldExertsForce = false ;
218 G4bool fieldExists=
false;
231 fieldExists = (ptrField!=0) ;
236 if( (particleCharge != 0.0)
237 || (fUseMagneticMoment && (magneticMoment != 0.0) )
238 || (gravityOn && (restMass != 0.0) )
241 fieldExertsForce = fieldExists;
248 if( !fieldExertsForce )
251 if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) )
255 geometryStepLength = currentMinimumStep ;
256 fGeometryLimitedStep = false ;
262 linearStepLength = fLinearNavigator->
ComputeStep( startPosition,
268 fPreviousSftOrigin = startPosition ;
269 fPreviousSafety = newSafety ;
272 currentSafety = newSafety ;
274 fGeometryLimitedStep= (linearStepLength <= currentMinimumStep);
275 if( fGeometryLimitedStep )
278 geometryStepLength = linearStepLength ;
283 geometryStepLength = currentMinimumStep ;
286 fEndPointDistance = geometryStepLength ;
290 fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ;
294 fTransportEndMomentumDir = startMomentumDir ;
297 fParticleIsLooping = false ;
298 fMomentumChanged = false ;
299 fEndGlobalTimeComputed = false ;
313 ->GetEquationOfMotion();
330 if( currentMinimumStep > 0 )
334 lengthAlongCurve = fFieldPropagator->
ComputeStep( aFieldTrack,
338 fGeometryLimitedStep= lengthAlongCurve < currentMinimumStep;
339 if( fGeometryLimitedStep )
341 geometryStepLength = lengthAlongCurve ;
345 geometryStepLength = currentMinimumStep ;
350 fPreviousSftOrigin = startPosition ;
351 fPreviousSafety = currentSafety ;
356 geometryStepLength = lengthAlongCurve= 0.0 ;
357 fGeometryLimitedStep = false ;
362 fTransportEndPosition = aFieldTrack.
GetPosition() ;
366 fMomentumChanged = true ;
377 fEndGlobalTimeComputed =
true;
387 fEndGlobalTimeComputed =
false;
392 G4double endEnergy= fTransportEndKineticEnergy;
395 G4double absEdiff = std::fabs(startEnergy- endEnergy);
401 if( fVerboseLevel > 1 )
403 if( std::fabs(startEnergy- endEnergy) >
perThousand * endEnergy )
408 if( (no_large_ediff% warnModulo) == 0 )
411 G4cout <<
"WARNING - G4Transportation::AlongStepGetPIL() "
412 <<
" Energy change in Step is above 1^-3 relative value. " <<
G4endl
413 <<
" Relative change in 'tracking' step = "
414 << std::setw(15) << (endEnergy-startEnergy)/startEnergy <<
G4endl
415 <<
" Starting E= " << std::setw(12) << startEnergy /
MeV <<
" MeV " <<
G4endl
416 <<
" Ending E= " << std::setw(12) << endEnergy /
MeV <<
" MeV " <<
G4endl;
417 G4cout <<
" Energy has been corrected -- however, review"
418 <<
" field propagation parameters for accuracy." <<
G4endl;
419 if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) )
421 G4cout <<
" These include EpsilonStepMax(/Min) in G4FieldManager "
422 <<
" which determine fractional error per step for integrated quantities. " << G4endl
423 <<
" Note also the influence of the permitted number of integration steps."
426 G4cerr <<
"ERROR - G4Transportation::AlongStepGetPIL()" << G4endl
427 <<
" Bad 'endpoint'. Energy change detected"
428 <<
" and corrected. "
429 <<
" Has occurred already "
430 << no_large_ediff <<
" times." <<
G4endl;
431 if( no_large_ediff == warnModulo * moduloFactor )
433 warnModulo *= moduloFactor;
445 fTransportEndSpin = aFieldTrack.
GetSpin();
447 fEndPointDistance = (fTransportEndPosition - startPosition).mag() ;
453 if( currentMinimumStep == 0.0 )
455 if( currentSafety == 0.0 ) { fGeometryLimitedStep =
true; }
461 if( currentSafety < fEndPointDistance )
463 if( particleCharge != 0.0 )
467 currentSafety = endSafety ;
468 fPreviousSftOrigin = fTransportEndPosition ;
469 fPreviousSafety = currentSafety ;
475 currentSafety += fEndPointDistance ;
477 #ifdef G4DEBUG_TRANSPORT
479 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
480 G4cout <<
" Called Navigator->ComputeSafety at " << fTransportEndPosition
481 <<
" and it returned safety= " << endSafety <<
G4endl ;
482 G4cout <<
" Adding endpoint distance " << fEndPointDistance
483 <<
" to obtain pseudo-safety= " << currentSafety <<
G4endl ;
487 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl ;
488 G4cout <<
" Avoiding call to ComputeSafety : " <<
G4endl;
497 return geometryStepLength ;
530 if (!fEndGlobalTimeComputed)
538 if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; }
540 fCandidateEndGlobalTime = startTime + deltaTime ;
545 deltaTime = fCandidateEndGlobalTime - startTime ;
562 if ( fParticleIsLooping )
564 G4double endEnergy= fTransportEndKineticEnergy;
566 if( (endEnergy < fThreshold_Important_Energy)
567 || (fNoLooperTrials >= fThresholdTrials ) )
574 fSumEnergyKilled += endEnergy;
575 if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
578 if( (fVerboseLevel > 1) &&
579 ( endEnergy > fThreshold_Warning_Energy ) )
581 G4cout <<
" G4Transportation is killing track that is looping or stuck "
584 <<
" MeV energy." <<
G4endl;
585 G4cout <<
" Number of trials = " << fNoLooperTrials
586 <<
" No of calls to AlongStepDoIt = " << noCalls
596 if( (fVerboseLevel > 2) )
598 G4cout <<
" G4Transportation::AlongStepDoIt(): Particle looping - "
599 <<
" Number of trials = " << fNoLooperTrials
600 <<
" No of calls to = " << noCalls
619 return &fParticleChange ;
655 if(fGeometryLimitedStep)
663 LocateGlobalPointAndUpdateTouchableHandle( track.
GetPosition(),
665 fCurrentTouchableHandle,
670 if( fCurrentTouchableHandle->
GetVolume() == 0 )
674 retCurrentTouchable = fCurrentTouchableHandle ;
681 #ifdef G4DEBUG_TRANSPORT
686 if( ! (exiting || entering) )
688 G4cout <<
" Transport> : Proposed isLastStep= " << isLastStep
711 #ifdef G4DEBUG_TRANSPORT
714 G4cout <<
" Transport> Proposed isLastStep= " << isLastStep
715 <<
" Geometry did not limit step. " <<
G4endl;
743 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
747 pNewMaterialCutsCouple =
762 return &fParticleChange ;
778 fPreviousSafety = 0.0 ;
void SetMaterialInTouchable(G4Material *fMaterial)
void SetTouchableHandle(const G4TouchableHandle &fTouchable)
const G4ThreeVector & GetPolarization() const
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4SafetyHelper * GetSafetyHelper() const
G4double GetLocalTime() 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
G4double GetVelocity() const
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()
G4Material * GetMaterial() const
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
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 SetProcessSubType(G4int)
G4bool EnteredDaughterVolume() const
G4bool DoesFieldChangeEnergy() const
G4double GetGlobalTime() const
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)
G4double GetPDGMass() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4FieldManagerStore * GetInstance()
void SetSensitiveDetectorInTouchable(G4VSensitiveDetector *fSensitiveDetector)
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()
void ProposeEnergy(G4double finalEnergy)
G4VPhysicalVolume * GetVolume() const
G4double GetTotalEnergy() const
G4double GetPDGSpin() const
void SetCurrentSafety(G4double val, const G4ThreeVector &pos)
void ClearPropagatorState()
G4bool ExitedMotherVolume() const
void ProposeLastStepInVolume(G4bool flag)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
const G4MaterialCutsCouple * GetMaterialCutsCouple() 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