52G4bool G4CoupledTransportation::fSignifyStepInAnyVolume=
false;
55G4bool G4CoupledTransportation::fUseMagneticMoment=
false;
56G4bool G4CoupledTransportation::fUseGravity=
false;
57G4bool G4CoupledTransportation::fSilenceLooperWarnings=
false;
64 fTransportEndPosition(0.0, 0.0, 0.0),
65 fTransportEndMomentumDir(0.0, 0.0, 0.0),
66 fTransportEndKineticEnergy(0.0),
67 fTransportEndSpin(0.0, 0.0, 0.0),
68 fMomentumChanged(false),
69 fEndGlobalTimeComputed(false),
70 fCandidateEndGlobalTime(0.0),
71 fParticleIsLooping( false ),
74 fPreviousMassSafety( 0.0 ),
75 fPreviousFullSafety( 0.0 ),
76 fMassGeometryLimitedStep( false ),
77 fAnyGeometryLimitedStep( false ),
78 fEndpointDistance( -1.0 ),
79 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
80 fFirstStepInMassVolume( true ),
81 fFirstStepInAnyVolume( true )
96 G4cout <<
" G4CoupledTransportation constructor: ----- " <<
G4endl;
98 G4cout <<
" Navigator Id obtained in G4CoupledTransportation constructor "
100 G4cout <<
" Reports First/Last in "
101 << (fSignifyStepInAnyVolume ?
" any " :
" mass " )
102 <<
" geometry " <<
G4endl;
117 fCurrentTouchableHandle = *pNullTouchableHandle;
127 if( fSumEnergyKilled > 0.0 )
139 if( fSumEnergyKilled > 0.0 )
141 outStr <<
" G4CoupledTransportation: Statistics for looping particles "
143 outStr <<
" Sum of energy of loopers killed: "
144 << fSumEnergyKilled / MeV <<
" MeV " <<
G4endl;
145 outStr <<
" Max energy of loopers killed: "
146 << fMaxEnergyKilled / MeV <<
" MeV " <<
G4endl;
149 outStr <<
" Max energy of loopers 'saved': " << fMaxEnergySaved <<
G4endl;
150 outStr <<
" Sum of energy of loopers 'saved': "
151 << fSumEnergySaved <<
G4endl;
152 outStr <<
" Sum of energy of unstable loopers 'saved': "
153 << fSumEnergyUnstableSaved <<
G4endl;
179 fParticleIsLooping = false ;
192 fFirstStepInMassVolume =
fNewTrack | fMassGeometryLimitedStep ;
193 fFirstStepInAnyVolume =
fNewTrack | fAnyGeometryLimitedStep ;
195#ifdef G4DEBUG_TRANSPORT
196 G4cout <<
" CoupledTransport::AlongStep GPIL: "
197 <<
" 1st-step: any= " <<fFirstStepInAnyVolume <<
" ( geom= "
198 << fAnyGeometryLimitedStep <<
" ) "
199 <<
" mass= " << fFirstStepInMassVolume <<
" ( geom= "
200 << fMassGeometryLimitedStep <<
" ) "
215#ifdef G4DEBUG_TRANSPORT
218 G4cout <<
"G4CoupledTransportation::AlongStepGPIL> called in volume "
230 startMassSafety = 0.0;
231 startFullSafety= 0.0;
235 if( MagSqShift <
sqr(fPreviousFullSafety) )
237 G4double mag_shift= std::sqrt(MagSqShift);
238 startMassSafety = std::max( (fPreviousMassSafety - mag_shift), 0.0);
239 startFullSafety = std::max( (fPreviousFullSafety - mag_shift), 0.0);
254 fMassGeometryLimitedStep = false ;
255 fAnyGeometryLimitedStep =
false;
264 G4bool fieldExertsForce = false ;
266 const G4Field* ptrField=
nullptr;
269 G4bool eligibleEM = (particleCharge != 0.0)
270 || ( fUseMagneticMoment && (magneticMoment != 0.0) );
271 G4bool eligibleGrav = fUseGravity && (restMass != 0.0) ;
273 if( (fieldMgr!=
nullptr) && (eligibleEM||eligibleGrav) )
285 if( ptrField !=
nullptr)
287 fieldExertsForce = eligibleEM
293 if( fieldExertsForce )
300 if( equationOfMotion )
302 equationOfMotion->SetChargeMomentumMass( chargeState,
306#ifdef G4DEBUG_TRANSPORT
309 G4cerr <<
" ERROR in G4CoupledTransportation> "
310 <<
"Cannot find valid Equation of motion: " <<
G4endl;
311 <<
" Unable to pass Charge, Momentum and Mass " <<
G4endl;
332 fMassGeometryLimitedStep = false ;
333 fAnyGeometryLimitedStep = false ;
334 if( currentMinimumStep > 0 )
340 lengthAlongCurve = fPathFinder->
ComputeStep( aFieldTrack,
354 fMassGeometryLimitedStep = true ;
359#ifdef G4DEBUG_TRANSPORT
360 if( fMassGeometryLimitedStep && !fAnyGeometryLimitedStep )
362 std::ostringstream message;
363 message <<
" ERROR in determining geometries limiting the step" <<
G4endl;
364 message <<
" Limiting: mass=" << fMassGeometryLimitedStep
365 <<
" any= " << fAnyGeometryLimitedStep <<
G4endl;
366 message <<
"Incompatible conditions - by which geometries was it limited ?";
367 G4Exception(
"G4CoupledTransportation::AlongStepGetPhysicalInteractionLength()",
372 geometryStepLength = std::min( lengthAlongCurve, currentMinimumStep);
376 fMomentumChanged = true ;
381 fPreviousMassSafety = newMassSafety ;
382 fPreviousFullSafety = newFullSafety ;
385#ifdef G4DEBUG_TRANSPORT
388 G4cout <<
"G4Transport:CompStep> "
389 <<
" called the pathfinder for a new step at " << startPosition
390 <<
" and obtained step = " << lengthAlongCurve <<
G4endl;
391 G4cout <<
" New safety (preStep) = " << newMassSafety
392 <<
" versus precalculated = " << startMassSafety <<
G4endl;
397 startMassSafety = newMassSafety ;
398 startFullSafety = newFullSafety ;
401 fTransportEndPosition = endTrackState.
GetPosition() ;
406 geometryStepLength = lengthAlongCurve= 0.0 ;
407 fMomentumChanged = false ;
413 fTransportEndPosition = startPosition;
415 endTrackState= aFieldTrack;
419 if( startMassSafety == 0.0 )
421 fMassGeometryLimitedStep = true ;
422 fAnyGeometryLimitedStep =
true;
428 if( !fieldExertsForce )
430 fParticleIsLooping = false ;
431 fMomentumChanged = false ;
432 fEndGlobalTimeComputed = false ;
438#ifdef G4DEBUG_TRANSPORT
441 G4cout <<
" G4CT::CS End Position = "
442 << fTransportEndPosition <<
G4endl;
443 G4cout <<
" G4CT::CS End Direction = "
444 << fTransportEndMomentumDir <<
G4endl;
453 fEndGlobalTimeComputed =
true;
464 fEndGlobalTimeComputed =
false;
469 G4double endEnergy= fTransportEndKineticEnergy;
472 G4double absEdiff = std::fabs(startEnergy- endEnergy);
473 if( absEdiff > perMillion * endEnergy )
479 if( (
verboseLevel > 1) && ( absEdiff > perThousand * endEnergy) )
491 fEndpointDistance = (fTransportEndPosition - startPosition).mag() ;
492 fTransportEndSpin = endTrackState.
GetSpin();
496 safetyProposal= startFullSafety;
501 if( (startFullSafety < fEndpointDistance )
502 && ( particleCharge != 0.0 ) )
520 fPreviousMassSafety = endMassSafety ;
521 fPreviousFullSafety = endFullSafety;
526 safetyProposal = endFullSafety + fEndpointDistance;
530#ifdef G4DEBUG_TRANSPORT
532 G4cout <<
"***CoupledTransportation::AlongStepGPIL ** " <<
G4endl ;
533 G4cout <<
" Revised Safety at endpoint " << fTransportEndPosition
534 <<
" give safety values: Mass= " << endMassSafety
535 <<
" All= " << endFullSafety <<
G4endl ;
536 G4cout <<
" Adding endpoint distance " << fEndpointDistance
537 <<
" to obtain pseudo-safety= " << safetyProposal <<
G4endl ;
543 G4cout <<
"***CoupledTransportation::AlongStepGPIL ** " <<
G4endl ;
544 G4cout <<
" Quick Safety estimate at endpoint "
545 << fTransportEndPosition
546 <<
" gives safety endpoint value = "
547 << startFullSafety - fEndpointDistance
548 <<
" using start-point value " << startFullSafety
549 <<
" and endpointDistance " << fEndpointDistance <<
G4endl;
554 proposedSafetyForStart= safetyProposal;
557 return geometryStepLength ;
567 const char *methodName=
"AlongStepDoIt";
591 if (!fEndGlobalTimeComputed)
598 if( finalVelocity > 0.0 ) { finalInverseVel= 1.0 / finalVelocity; }
600 if( initialVelocity > 0.0 ) { initialInverseVel= 1.0 / initialVelocity; }
603 if (finalVelocity > 0.0)
607 * (initialInverseVel + finalInverseVel);
608 deltaTime = stepLength * meanInverseVelocity ;
612 deltaTime = stepLength * initialInverseVel ;
615 fCandidateEndGlobalTime = startTime + deltaTime ;
620 deltaTime = fCandidateEndGlobalTime - startTime ;
635 if ( fParticleIsLooping )
637 G4double endEnergy= fTransportEndKineticEnergy;
643 G4bool candidateForEnd = (endEnergy < fThreshold_Important_Energy)
644 || (fNoLooperTrials >= fThresholdTrials) ;
646 if( candidateForEnd && stable )
648 const G4int electronPDG= 11;
656 fSumEnergyKilled += endEnergy;
657 fSumEnerSqKilled = endEnergy * endEnergy;
660 if( endEnergy > fMaxEnergyKilled ) {
661 fMaxEnergyKilled = endEnergy;
662 fMaxEnergyKilledPDG = particlePDG;
667 fSumEnergyKilled_NonElectron += endEnergy;
668 fSumEnerSqKilled_NonElectron += endEnergy * endEnergy;
669 fNumLoopersKilled_NonElectron++;
671 if( endEnergy > fMaxEnergyKilled_NonElectron )
673 fMaxEnergyKilled_NonElectron = endEnergy;
674 fMaxEnergyKilled_NonElecPDG = particlePDG;
678 if( endEnergy > fThreshold_Warning_Energy && ! fSilenceLooperWarnings )
681 noCallsCT_ASDI, methodName );
690 fMaxEnergySaved = std::max( endEnergy, fMaxEnergySaved);
691 if( fNoLooperTrials == 1 ) {
692 fSumEnergySaved += endEnergy;
694 fSumEnergyUnstableSaved += endEnergy;
699 G4cout <<
" ** G4CoupledTransportation::AlongStepDoIt():"
700 <<
" Particle is looping but is saved ..." <<
G4endl
701 <<
" Number of trials (this track) = " << fNoLooperTrials
705 <<
" Total no of calls to this method (all tracks) = "
706 << noCallsCT_ASDI <<
G4endl;
723 return &fParticleChange ;
751 <<
"**************************************************************"
753 G4cerr <<
"Endpoint has moved between value expected from TransportEndPosition "
754 <<
" and value from Track in PostStepDoIt. " <<
G4endl
755 <<
"Change of " << Quantity <<
" is " << moveVec.
mag() / mm
757 <<
" and its vector is " << (1.0/mm) * moveVec <<
" mm " <<
G4endl
758 <<
"Endpoint of ComputeStep was " << OldVector
759 <<
" and current position to locate is " << NewVector <<
G4endl;
775 if( fSignifyStepInAnyVolume )
787#ifdef G4DEBUG_TRANSPORT
789 && ((fTransportEndPosition - track.
GetPosition()).mag2() >= 1.0e-16) )
792 "End of Step Position" );
793 G4cerr <<
" Problem in G4CoupledTransportation::PostStepDoIt " <<
G4endl;
801 G4cout <<
" Calling PathFinder::Locate() from "
802 <<
" G4CoupledTransportation::PostStepDoIt " <<
G4endl;
803 G4cout <<
" fAnyGeometryLimitedStep is " << fAnyGeometryLimitedStep
809 if(fAnyGeometryLimitedStep)
819 fCurrentTouchableHandle=
822#ifdef G4DEBUG_TRANSPORT
825 G4cout <<
"G4CoupledTransportation::PostStepDoIt --- fNavigatorId = "
826 << fNavigatorId <<
G4endl;
831 G4cout <<
"CHECK !!!!!!!!!!! fCurrentTouchableHandle->GetVolume() = "
841 if( fCurrentTouchableHandle->
GetVolume() == 0 )
845 retCurrentTouchable = fCurrentTouchableHandle ;
850#ifdef G4DEBUG_TRANSPORT
853 G4cout <<
"G4CoupledTransportation::PostStepDoIt -- "
854 <<
" fAnyGeometryLimitedStep = " << fAnyGeometryLimitedStep
855 <<
" must be false " <<
G4endl;
874#ifdef G4DEBUG_NAVIGATION
875 G4cout <<
" CoupledTransport::AlongStep GPIL: "
876 <<
" last-step: any= " << fAnyGeometryLimitedStep
878 <<
" mass= " << fMassGeometryLimitedStep
882 if( fSignifyStepInAnyVolume )
909 if( pNewMaterialCutsCouple!=0
910 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
925 return &fParticleChange ;
963 fPreviousMassSafety = 0.0 ;
964 fPreviousFullSafety = 0.0 ;
976 if( fFieldPropagator && fAnyFieldExists )
990#ifdef G4DEBUG_TRANSPORT
993 G4cout <<
" Returning touchable handle " << fCurrentTouchableHandle
1020 moduloFactor= 10, no_large_ediff= 0;
1022 if( std::fabs(startEnergy- endEnergy) > perThousand * endEnergy )
1025 if( (no_large_ediff% warnModulo) == 0 )
1028 std::ostringstream message;
1029 message <<
"Energy change in Step is above 1^-3 relative value. "
1031 <<
" Relative change in 'tracking' step = "
1032 << std::setw(15) << (endEnergy-startEnergy)/startEnergy
1034 <<
" Starting E= " << std::setw(12) << startEnergy / MeV
1036 <<
" Ending E= " << std::setw(12) << endEnergy / MeV
1038 <<
"Energy has been corrected -- however, review"
1039 <<
" field propagation parameters for accuracy." <<
G4endl;
1041 || (no_large_ediff == warnModulo * moduloFactor) )
1043 message <<
"These include EpsilonStepMax(/Min) in G4FieldManager,"
1045 <<
"which determine fractional error per step for integrated quantities."
1047 <<
"Note also the influence of the permitted number of integration steps."
1050 message <<
"Bad 'endpoint'. Energy change detected and corrected."
1052 <<
"Has occurred already " << no_large_ediff <<
" times.";
1053 G4Exception(
"G4CoupledTransportation::AlongStepGetPIL()",
1055 if( no_large_ediff == warnModulo * moduloFactor )
1057 warnModulo *= moduloFactor;
1067 G4bool lastValue= fUseMagneticMoment;
1068 fUseMagneticMoment= useMoment;
1069 G4Transportation::fUseMagneticMoment= useMoment;
1078 G4bool lastValue= fUseGravity;
1079 fUseGravity= useGravity;
1080 G4Transportation::fUseGravity= useGravity;
1090 fSilenceLooperWarnings= val;
1098 return fSilenceLooperWarnings;
1110 G4int maxTrials = 10;
1123 G4int maxTrials = 30;
1134 const char* message=
"Logger object missing from G4CoupledTransportation";
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define fPreviousSftOrigin
CLHEP::Hep3Vector G4ThreeVector
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
void SetLowLooperThresholds()
void PushThresholdsToLogger()
static G4bool GetSilenceLooperWarnings()
void ReportLooperThresholds()
void SetHighLooperThresholds()
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
void SetThresholdTrials(G4int newMaxTrials)
static G4bool EnableGravity(G4bool useGravity)
void ReportMove(G4ThreeVector OldVector, G4ThreeVector NewVector, const G4String &Quantity)
static void SetSilenceLooperWarnings(G4bool val)
void ReportInexactEnergy(G4double startEnergy, G4double endEnergy)
static G4bool EnableMagneticMoment(G4bool useMoment=true)
void PrintStatistics(std::ostream &outStr) const
G4CoupledTransportation(G4int verbosityLevel=0)
G4bool DoesAnyFieldExist()
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
void SetThresholdImportantEnergy(G4double newEnImp)
void SetThresholdWarningEnergy(G4double newEnWarn)
void StartTracking(G4Track *aTrack)
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
~G4CoupledTransportation()
void ReportMissingLogger(const char *methodName)
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 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)
G4double GetPDGMagneticMoment() const
G4bool GetPDGStable() const
G4int GetPDGEncoding() const
G4double GetPDGSpin() const
G4double ComputeSafety(const G4ThreeVector &globalPoint)
void ReLocate(const G4ThreeVector &position)
unsigned int GetNumberGeometriesLimitingStep() const
G4double ObtainSafety(G4int navId, G4ThreeVector &globalCenterPoint)
G4double ComputeStep(const G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4int navigatorId, G4int stepNo, G4double &pNewSafety, ELimited &limitedStep, G4FieldTrack &EndState, G4VPhysicalVolume *currentVolume)
void Locate(const G4ThreeVector &position, const G4ThreeVector &direction, G4bool relativeSearch=true)
G4double GetCurrentSafety() const
void PrepareNewTrack(const G4ThreeVector &position, const G4ThreeVector &direction, G4VPhysicalVolume *massStartVol=nullptr)
static G4PathFinder * GetInstance()
G4TouchableHandle CreateTouchableHandle(G4int navId) const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
G4FieldManager * GetCurrentFieldManager()
G4bool IsParticleLooping() const
G4ChordFinder * GetChordFinder()
G4EquationOfMotion * GetCurrentEquationOfMotion()
void ClearPropagatorState()
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
G4int GetCurrentStepNumber() 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
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
G4int ActivateNavigator(G4Navigator *aNavigator)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLastStepInVolume(G4bool flag)
void ProposeFirstStepInVolume(G4bool flag)
void ProposeTrueStepLength(G4double truePathLength)
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
void SetVerboseLevel(G4int value)
void SetProcessSubType(G4int)
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const