61G4bool G4Transportation::fUseMagneticMoment=
false;
62G4bool G4Transportation::fUseGravity=
false;
63G4bool G4Transportation::fSilenceLooperWarnings=
false;
74 fEndPointDistance( -1.0 ),
75 fShortStepOptimisation( false )
107 if ( !pNullTouchableHandle)
111 fCurrentTouchableHandle = *pNullTouchableHandle;
118 G4cout <<
" G4Transportation constructor> set fShortStepOptimisation to ";
119 if ( fShortStepOptimisation ) {
G4cout <<
"true" <<
G4endl; }
129 if( fSumEnergyKilled > 0.0 )
141 outStr <<
" G4Transportation: Statistics for looping particles " <<
G4endl;
142 if( fSumEnergyKilled > 0.0 || fNumLoopersKilled > 0 )
144 outStr <<
" Sum of energy of looping tracks killed: "
145 << fSumEnergyKilled / CLHEP::MeV <<
" MeV "
146 <<
" from " << fNumLoopersKilled <<
" tracks " <<
G4endl
147 <<
" Sum of energy of non-electrons : "
148 << fSumEnergyKilled_NonElectron / CLHEP::MeV <<
" MeV "
149 <<
" from " << fNumLoopersKilled_NonElectron <<
" tracks "
151 outStr <<
" Max energy of *any type* looper killed: " << fMaxEnergyKilled
152 <<
" its PDG was " << fMaxEnergyKilledPDG <<
G4endl;
153 if( fMaxEnergyKilled_NonElectron > 0.0 )
155 outStr <<
" Max energy of non-electron looper killed: "
156 << fMaxEnergyKilled_NonElectron
157 <<
" its PDG was " << fMaxEnergyKilled_NonElecPDG <<
G4endl;
159 if( fMaxEnergySaved > 0.0 )
161 outStr <<
" Max energy of loopers 'saved': " << fMaxEnergySaved <<
G4endl;
162 outStr <<
" Sum of energy of loopers 'saved': "
163 << fSumEnergySaved <<
G4endl;
164 outStr <<
" Sum of energy of unstable loopers 'saved': "
165 << fSumEnergyUnstableSaved <<
G4endl;
170 outStr <<
" No looping tracks found or killed. " <<
G4endl;
234 (particleCharge != 0.0) || ((magneticMoment != 0.0) && fUseMagneticMoment);
235 G4bool eligibleGrav = (particleMass != 0.0) && fUseGravity;
239 if(eligibleEM || eligibleGrav)
245 fieldMgr->ConfigureForTrack(&track);
251 if(
const G4Field* ptrField = fieldMgr->GetDetectorField())
253 eligibleEM || (eligibleGrav && ptrField->IsGravityActive());
257 G4double geometryStepLength = currentMinimumStep;
259 if(currentMinimumStep == 0.0)
261 fEndPointDistance = 0.0;
263 fGeometryLimitedStep = (currentSafety == 0.0);
265 fMomentumChanged =
false;
266 fParticleIsLooping =
false;
267 fEndGlobalTimeComputed =
false;
268 fTransportEndPosition = startPosition;
269 fTransportEndMomentumDir = startMomentumDir;
270 fTransportEndKineticEnergy = kineticEnergy;
271 fTransportEndSpin = particleSpin;
275 fGeometryLimitedStep =
false;
276 if(geometryStepLength > currentSafety || !fShortStepOptimisation)
279 startPosition, startMomentumDir, currentMinimumStep, currentSafety);
281 if(linearStepLength <= currentMinimumStep)
283 geometryStepLength = linearStepLength;
284 fGeometryLimitedStep =
true;
293 fEndPointDistance = geometryStepLength;
295 fMomentumChanged =
false;
296 fParticleIsLooping =
false;
297 fEndGlobalTimeComputed =
false;
298 fTransportEndPosition =
299 startPosition + geometryStepLength * startMomentumDir;
300 fTransportEndMomentumDir = startMomentumDir;
301 fTransportEndKineticEnergy = kineticEnergy;
302 fTransportEndSpin = particleSpin;
307 const auto particlePDGSpin = pParticleDef->
GetPDGSpin();
308 const auto particlePDGMagM = pParticleDef->GetPDGMagneticMoment();
315 G4ChargeState(particleCharge, magneticMoment, particlePDGSpin),
320 startMomentumDir, kineticEnergy, particleMass,
321 particleCharge, particleSpin, particlePDGMagM,
328 aFieldTrack, currentMinimumStep, currentSafety, track.
GetVolume(),
329 kineticEnergy < fThreshold_Important_Energy);
331 if(lengthAlongCurve < geometryStepLength)
332 geometryStepLength = lengthAlongCurve;
349 fMomentumChanged =
true;
352 fEndGlobalTimeComputed = changesEnergy;
356 fEndPointDistance = (fTransportEndPosition - startPosition).mag();
360 fTransportEndKineticEnergy =
362 fTransportEndSpin = aFieldTrack.
GetSpin();
364 if(fEndGlobalTimeComputed)
374#if defined(G4VERBOSE) || defined(G4DEBUG_TRANSPORT)
382 G4double startEnergy = kineticEnergy;
383 G4double endEnergy = fTransportEndKineticEnergy;
386 G4double absEdiff = std::fabs(startEnergy - endEnergy);
387 if(absEdiff > perMillion * endEnergy)
394 if(std::fabs(startEnergy - endEnergy) > perThousand * endEnergy)
399 if((no_large_ediff % warnModulo) == 0)
402 std::ostringstream message;
403 message <<
"Energy change in Step is above 1^-3 relative value. "
404 <<
G4endl <<
" Relative change in 'tracking' step = "
405 << std::setw(15) << (endEnergy - startEnergy) / startEnergy
406 <<
G4endl <<
" Starting E= " << std::setw(12)
407 << startEnergy / MeV <<
" MeV " <<
G4endl
408 <<
" Ending E= " << std::setw(12) << endEnergy / MeV
410 <<
"Energy has been corrected -- however, review"
411 <<
" field propagation parameters for accuracy." <<
G4endl;
413 (no_large_ediff == warnModulo * moduloFactor))
415 message <<
"These include EpsilonStepMax(/Min) in G4FieldManager "
417 <<
"which determine fractional error per step for "
418 "integrated quantities. "
420 <<
"Note also the influence of the permitted number of "
424 message <<
"Bad 'endpoint'. Energy change detected and corrected."
425 <<
G4endl <<
"Has occurred already " << no_large_ediff
427 G4Exception(
"G4Transportation::AlongStepGetPIL()",
"EnergyChange",
429 if(no_large_ediff == warnModulo * moduloFactor)
431 warnModulo *= moduloFactor;
443 if(currentSafety < fEndPointDistance)
445 if(particleCharge != 0.0)
449 currentSafety = endSafety;
457 currentSafety += fEndPointDistance;
459#ifdef G4DEBUG_TRANSPORT
461 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl;
462 G4cout <<
" Called Navigator->ComputeSafety at " << fTransportEndPosition
463 <<
" and it returned safety= " << endSafety <<
G4endl;
464 G4cout <<
" Adding endpoint distance " << fEndPointDistance
465 <<
" to obtain pseudo-safety= " << currentSafety <<
G4endl;
469 G4cout <<
"***G4Transportation::AlongStepGPIL ** " <<
G4endl;
470 G4cout <<
" Avoiding call to ComputeSafety : " <<
G4endl;
477 fFirstStepInVolume =
fNewTrack || fLastStepInVolume;
478 fLastStepInVolume =
false;
484 return geometryStepLength;
496 const char *methodName=
"AlongStepDoIt";
518 if (!fEndGlobalTimeComputed)
526 if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; }
528 fCandidateEndGlobalTime = startTime + deltaTime ;
533 deltaTime = fCandidateEndGlobalTime - startTime ;
549 if ( fParticleIsLooping )
551 G4double endEnergy= fTransportEndKineticEnergy;
556 G4bool candidateForEnd = (endEnergy < fThreshold_Important_Energy)
557 || (fNoLooperTrials >= fThresholdTrials) ;
558 G4bool unstableAndKillable = !stable && ( fAbandonUnstableTrials != 0);
559 G4bool unstableForEnd = (endEnergy < fThreshold_Important_Energy)
560 && (fNoLooperTrials >= fAbandonUnstableTrials) ;
561 if( (candidateForEnd && stable) || (unstableAndKillable && unstableForEnd) )
566 G4int particlePDG= particleType->GetPDGEncoding();
567 const G4int electronPDG= 11;
570 fSumEnergyKilled += endEnergy;
571 fSumEnerSqKilled = endEnergy * endEnergy;
574 if( endEnergy > fMaxEnergyKilled ) {
575 fMaxEnergyKilled = endEnergy;
576 fMaxEnergyKilledPDG = particlePDG;
578 if( particleType->GetPDGEncoding() != electronPDG )
580 fSumEnergyKilled_NonElectron += endEnergy;
581 fSumEnerSqKilled_NonElectron += endEnergy * endEnergy;
582 fNumLoopersKilled_NonElectron++;
584 if( endEnergy > fMaxEnergyKilled_NonElectron )
586 fMaxEnergyKilled_NonElectron = endEnergy;
587 fMaxEnergyKilled_NonElecPDG = particlePDG;
591 if( endEnergy > fThreshold_Warning_Energy && ! fSilenceLooperWarnings )
594 noCallsASDI, methodName );
600 fMaxEnergySaved = std::max( endEnergy, fMaxEnergySaved);
601 if( fNoLooperTrials == 1 ) {
602 fSumEnergySaved += endEnergy;
604 fSumEnergyUnstableSaved += endEnergy;
609 G4cout <<
" " << methodName
610 <<
" Particle is looping but is saved ..." <<
G4endl
611 <<
" Number of trials = " << fNoLooperTrials <<
G4endl
612 <<
" No of calls to = " << noCallsASDI <<
G4endl;
630 return &fParticleChange ;
667 if(fGeometryLimitedStep)
675 LocateGlobalPointAndUpdateTouchableHandle( track.
GetPosition(),
677 fCurrentTouchableHandle,
682 if( fCurrentTouchableHandle->
GetVolume() == 0 )
686 retCurrentTouchable = fCurrentTouchableHandle ;
712 fLastStepInVolume= isLastStep;
736 if ( pNewVol!=0 && pNewMaterialCutsCouple!=0
737 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
741 pNewMaterialCutsCouple =
756 return &fParticleChange ;
770 fFirstStepInVolume=
true;
771 fLastStepInVolume=
false;
792 if( fFieldPropagator && fAnyFieldExists )
818 G4bool lastValue= fUseMagneticMoment;
819 fUseMagneticMoment= useMoment;
820 G4CoupledTransportation::fUseMagneticMoment= useMoment;
829 G4bool lastValue= fUseGravity;
830 fUseGravity= useGravity;
831 G4CoupledTransportation::fUseGravity= useGravity;
841 fSilenceLooperWarnings= val;
849 return fSilenceLooperWarnings;
863 G4int maxTrials = 10;
877 G4int maxTrials = 30;
889 const char* message=
"Logger object missing from G4Transportation object";
912 G4int oldPrec= outStr.precision(6);
914 outStr <<
G4endl << indent << GetProcessName() <<
": ";
916 outStr <<
" Parameters for looping particles: " <<
G4endl
917 <<
" warning-E = " << fThreshold_Warning_Energy / CLHEP::MeV <<
" MeV " <<
G4endl
918 <<
" important E = " << fThreshold_Important_Energy / CLHEP::MeV <<
" MeV " <<
G4endl
919 <<
" thresholdTrials " << fThresholdTrials <<
G4endl;
920 outStr.precision(oldPrec);
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define fPreviousSftOrigin
#define fFieldExertedForce
CLHEP::Hep3Vector G4ThreeVector
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4GLOB_DLL std::ostream G4cout
G4double GetCharge() const
const G4ParticleDefinition * GetParticleDefinition() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4double GetMagneticMoment() const
G4double GetTotalMomentum() const
const G4ThreeVector & GetPolarization() const
virtual void SetChargeMomentumMass(G4ChargeState particleCharge, G4double MomentumXc, G4double MassXc2)=0
static G4FieldManagerStore * GetInstance()
void ClearAllChordFindersState()
G4bool DoesFieldChangeEnergy() const
const G4ThreeVector & GetMomentumDir() const
G4double GetKineticEnergy() const
G4ThreeVector GetPosition() const
G4ThreeVector GetSpin() const
G4double GetLabTimeOfFlight() 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 SetPointerToVectorOfAuxiliaryPoints(std::vector< G4ThreeVector > *vec)
void SetMaterialInTouchable(G4Material *fMaterial)
void SetTouchableHandle(const G4TouchableHandle &fTouchable)
void SetMaterialCutsCoupleInTouchable(const G4MaterialCutsCouple *fMaterialCutsCouple)
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)
G4bool GetPDGStable() const
G4double GetPDGSpin() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
G4FieldManager * GetCurrentFieldManager()
G4bool IsLastStepInVolume()
G4bool IsParticleLooping() const
G4EquationOfMotion * GetCurrentEquationOfMotion()
void ClearPropagatorState()
std::vector< G4ThreeVector > * GimmeTrajectoryVectorAndForgetIt() const
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=nullptr, G4bool canRelaxDeltaChord=false)
void SetCurrentSafety(G4double val, const G4ThreeVector &pos)
G4double GetVelocity() const
G4StepPoint * GetPreStepPoint() const
G4TrackStatus GetTrackStatus() 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 GetStepLength() const
G4double GetTotalEnergy() const
void ReportLoopingTrack(const G4Track &track, const G4Step &stepInfo, G4int numTrials, G4long noCalls, const char *methodName) const
void ReportLooperThresholds(const char *className)
static G4TransportationManager * GetTransportationManager()
G4PropagatorInField * GetPropagatorInField() const
G4SafetyHelper * GetSafetyHelper() const
G4Navigator * GetNavigatorForTracking() const
void SetThresholdImportantEnergy(G4double newEnImp)
static void SetSilenceLooperWarnings(G4bool val)
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
static G4bool EnableGravity(G4bool useGravity=true)
void PushThresholdsToLogger()
void PrintStatistics(std::ostream &outStr) const
void SetHighLooperThresholds()
void SetLowLooperThresholds()
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
void SetThresholdTrials(G4int newMaxTrials)
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
static G4bool EnableMagneticMoment(G4bool useMoment=true)
void ReportLooperThresholds()
void StartTracking(G4Track *aTrack)
G4Transportation(G4int verbosityLevel=1)
G4bool DoesAnyFieldExist()
void SetThresholdWarningEnergy(G4double newEnWarn)
static G4bool GetSilenceLooperWarnings()
void ReportMissingLogger(const char *methodName)
virtual void ProcessDescription(std::ostream &outFile) const
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLastStepInVolume(G4bool flag)
void ProposeFirstStepInVolume(G4bool flag)
void ProposeTrueStepLength(G4double truePathLength)
G4LogicalVolume * GetLogicalVolume() const
void SetVerboseLevel(G4int value)
void SetProcessSubType(G4int)
virtual void StartTracking(G4Track *)
G4VParticleChange * pParticleChange
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const