66 fParticleIsLooping( false ),
67 fPreviousSftOrigin( 0.,0.,0. ),
68 fPreviousMassSafety( 0.0 ),
69 fPreviousFullSafety( 0.0 ),
70 fThreshold_Warning_Energy( 100 * MeV ),
71 fThreshold_Important_Energy( 250 * MeV ),
72 fThresholdTrials( 10 ),
73 fUnimportant_Energy( 1 * MeV ),
75 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
76 fUseMagneticMoment( false ),
77 fVerboseLevel( verbosity )
90 if( fVerboseLevel > 0 ){
91 G4cout <<
" G4CoupledTransportation constructor: ----- " <<
G4endl;
92 G4cout <<
" Verbose level is " << fVerboseLevel <<
G4endl;
93 G4cout <<
" Navigator Id obtained in G4CoupledTransportation constructor "
101 fCurrentTouchableHandle = nullTouchableHandle;
104 fEndGlobalTimeComputed =
false;
105 fCandidateEndGlobalTime = 0;
114 if( (fVerboseLevel > 0) || (fSumEnergyKilled > 0.0 ) ){
115 G4cout <<
" G4CoupledTransportation: Statistics for looping particles " <<
G4endl;
116 G4cout <<
" Sum of energy of loopers killed: " << fSumEnergyKilled <<
G4endl;
117 G4cout <<
" Max energy of loopers killed: " << fMaxEnergyKilled <<
G4endl;
143 fParticleIsLooping = false ;
164#ifdef G4DEBUG_TRANSPORT
165 if( fVerboseLevel > 1 ) {
166 G4cout <<
"G4CoupledTransportation::AlongStepGPIL> called in volume "
176 G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
178 startMassSafety = 0.0;
179 startFullSafety= 0.0;
183 if( MagSqShift <
sqr(fPreviousFullSafety) ) {
184 G4double mag_shift= std::sqrt(MagSqShift);
185 startMassSafety = std::max( (fPreviousMassSafety - mag_shift), 0.0);
186 startFullSafety = std::max( (fPreviousFullSafety - mag_shift), 0.0);
200 fMassGeometryLimitedStep = false ;
201 fAnyGeometryLimitedStep =
false;
212 G4bool fieldExertsForce = false ;
232 if( (particleCharge != 0.0)
233 || (fUseMagneticMoment && (magneticMoment != 0.0) )
234 || (gravityOn && (restMass != 0.0))
237 fieldExertsForce =
true;
265 fMassGeometryLimitedStep = false ;
266 fAnyGeometryLimitedStep = false ;
267 if( currentMinimumStep > 0 ) {
272 lengthAlongCurve = fPathFinder->
ComputeStep( theFieldTrack,
287 fMassGeometryLimitedStep = true ;
293 if( fMassGeometryLimitedStep && !fAnyGeometryLimitedStep ){
294 G4cerr <<
" Error in determining geometries limiting the step" <<
G4endl;
295 G4cerr <<
" Limiting: mass=" << fMassGeometryLimitedStep
296 <<
" any= " << fAnyGeometryLimitedStep <<
G4endl;
297 G4Exception(
"G4CoupledTransportation::AlongStepGetPhysicalInteractionLength()",
298 "PathFinderConfused",
300 "Incompatible conditions - was limited by a geometry?");
310 geometryStepLength = std::min( lengthAlongCurve, currentMinimumStep);
314 fMomentumChanged = true ;
318 fPreviousSftOrigin = startPosition ;
319 fPreviousMassSafety = newMassSafety ;
320 fPreviousFullSafety = newFullSafety ;
323#ifdef G4DEBUG_TRANSPORT
324 if( fVerboseLevel > 1 ){
325 G4cout <<
"G4Transport:CompStep> "
326 <<
" called the pathfinder for a new step at " << startPosition
327 <<
" and obtained step = " << lengthAlongCurve <<
G4endl;
328 G4cout <<
" New safety (preStep) = " << newMassSafety
329 <<
" versus precalculated = " << startMassSafety <<
G4endl;
334 startMassSafety = newMassSafety ;
335 startFullSafety = newFullSafety ;
338 fTransportEndPosition = endTrackState.
GetPosition() ;
341 geometryStepLength = lengthAlongCurve= 0.0 ;
342 fMomentumChanged = false ;
348 fTransportEndPosition = startPosition;
351 if( startMassSafety == 0.0 ) {
352 fMassGeometryLimitedStep = true ;
353 fAnyGeometryLimitedStep =
true;
359 if( !fieldExertsForce )
361 fParticleIsLooping = false ;
362 fMomentumChanged = false ;
363 fEndGlobalTimeComputed = false ;
369#ifdef G4DEBUG_TRANSPORT
370 if( fVerboseLevel > 1 ){
371 G4cout <<
" G4CT::CS End Position = " << fTransportEndPosition <<
G4endl;
372 G4cout <<
" G4CT::CS End Direction = " << fTransportEndMomentumDir <<
G4endl;
382 fEndGlobalTimeComputed =
true;
393 fEndGlobalTimeComputed =
false;
398 G4double endEnergy= fTransportEndKineticEnergy;
400 static G4int no_inexact_steps=0;
401 G4double absEdiff = std::fabs(startEnergy- endEnergy);
402 if( absEdiff > perMillion * endEnergy ) {
407 if( (fVerboseLevel > 1) && ( absEdiff > perThousand * endEnergy) ){
419 endpointDistance = (fTransportEndPosition - startPosition).mag() ;
422 fTransportEndSpin = endTrackState.
GetSpin();
425 safetyProposal= startFullSafety;
430 if( (startFullSafety < endpointDistance )
431 && ( particleCharge != 0.0 ) )
449 fPreviousMassSafety = endMassSafety ;
450 fPreviousFullSafety = endFullSafety;
451 fPreviousSftOrigin = fTransportEndPosition ;
455 safetyProposal = endFullSafety + endpointDistance;
461#ifdef G4DEBUG_TRANSPORT
462 int prec=
G4cout.precision(12) ;
463 G4cout <<
"***Transportation::AlongStepGPIL ** " <<
G4endl ;
464 G4cout <<
" Revised Safety at endpoint " << fTransportEndPosition
465 <<
" give safety values: Mass= " << endMassSafety
466 <<
" All= " << endFullSafety <<
G4endl ;
467 G4cout <<
" Adding endpoint distance " << endpointDistance
468 <<
" to obtain pseudo-safety= " << safetyProposal <<
G4endl ;
472 int prec=
G4cout.precision(12) ;
473 G4cout <<
"***Transportation::AlongStepGPIL ** " <<
G4endl ;
474 G4cout <<
" Quick Safety estimate at endpoint " << fTransportEndPosition
475 <<
" gives safety endpoint value = " << startFullSafety - endpointDistance
476 <<
" using start-point value " << startFullSafety
477 <<
" and endpointDistance " << endpointDistance <<
G4endl;
482 proposedSafetyForStart= safetyProposal;
485 return geometryStepLength ;
493 static G4int noCalls=0;
519 if (!fEndGlobalTimeComputed)
526 if( finalVelocity > 0.0 ) { finalInverseVel= 1.0 / finalVelocity; }
528 if( initialVelocity > 0.0 ) { initialInverseVel= 1.0 / initialVelocity; }
531 if (finalVelocity > 0.0)
534 G4double meanInverseVelocity = 0.5 * ( initialInverseVel + finalInverseVel );
535 deltaTime = stepLength * meanInverseVelocity ;
541 deltaTime = stepLength * initialInverseVel ;
546 fCandidateEndGlobalTime = startTime + deltaTime ;
554 deltaTime = fCandidateEndGlobalTime - startTime ;
576 if ( fParticleIsLooping )
578 G4double endEnergy= fTransportEndKineticEnergy;
580 if( (endEnergy < fThreshold_Important_Energy)
581 || (fNoLooperTrials >= fThresholdTrials ) ){
587 fSumEnergyKilled += endEnergy;
588 if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
591 if( (fVerboseLevel > 1) ||
592 ( endEnergy > fThreshold_Warning_Energy ) ) {
593 G4cout <<
" G4CoupledTransportation is killing track that is looping or stuck " <<
G4endl
595 <<
" MeV energy." <<
G4endl;
597 if( fVerboseLevel > 0 ) {
605 if( (fVerboseLevel > 2) ){
606 G4cout <<
" ** G4CoupledTransportation::AlongStepDoIt(): Particle looping - " <<
G4endl
607 <<
" Number of consecutive problem step (this track) = " << fNoLooperTrials <<
G4endl
609 <<
" Total no of calls to this method (all tracks) = " << noCalls <<
G4endl;
625 return &fParticleChange ;
650 <<
"**************************************************************" <<
G4endl;
651 G4cerr <<
"Endpoint has moved between value expected from TransportEndPosition "
652 <<
" and value from Track in PostStepDoIt. " <<
G4endl
653 <<
"Change of " << Quantity <<
" is " << moveVec.
mag() / mm <<
" mm long, "
654 <<
" and its vector is " << (1.0/mm) * moveVec <<
" mm " <<
G4endl
655 <<
"Endpoint of ComputeStep was " << OldVector
656 <<
" and current position to locate is " << NewVector <<
G4endl;
674 if( (fTransportEndPosition - track.
GetPosition()).mag2() >= 1.0e-16 ){
675 static G4String EndLabelString(
"End of Step Position");
676 ReportMove( track.
GetPosition(), fTransportEndPosition, EndLabelString );
677 G4cerr <<
" Problem in G4CoupledTransportation::PostStepDoIt " <<
G4endl;
683 if( fVerboseLevel > 0 ){
684 G4cout <<
" Calling PathFinder::Locate() from "
685 <<
" G4CoupledTransportation::PostStepDoIt " <<
G4endl;
686 G4cout <<
" fAnyGeometryLimitedStep is " << fAnyGeometryLimitedStep <<
G4endl;
689 if(fAnyGeometryLimitedStep)
698 if( fVerboseLevel > 0 )
699 G4cout <<
"G4CoupledTransportation::PostStepDoIt --- fNavigatorId = "
700 << fNavigatorId <<
G4endl;
702 fCurrentTouchableHandle=
708#ifdef G4DEBUG_TRANSPORT
709 if( fVerboseLevel > 1 ){
711 G4cout <<
"CHECK !!!!!!!!!!! fCurrentTouchableHandle->GetVolume() = " << vol;
716 if( fCurrentTouchableHandle->
GetVolume() == 0 )
720 retCurrentTouchable = fCurrentTouchableHandle ;
731#ifdef G4DEBUG_TRANSPORT
732 if( fVerboseLevel > 1 ){
733 G4cout <<
"G4CoupledTransportation::PostStepDoIt -- "
734 <<
" fAnyGeometryLimitedStep = " << fAnyGeometryLimitedStep
735 <<
" must be false " <<
G4endl;
780 if( pNewMaterialCutsCouple!=0
781 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
785 pNewMaterialCutsCouple =
796 return &fParticleChange ;
838 fPreviousMassSafety = 0.0 ;
839 fPreviousFullSafety = 0.0 ;
850 if( fGlobalFieldExists ) {
861#ifdef G4DEBUG_TRANSPORT
862 if( fVerboseLevel > 1 ){
863 G4cout <<
" Returning touchable handle " << fCurrentTouchableHandle <<
G4endl;
882 static G4int no_warnings= 0, warnModulo=1, moduloFactor= 10, no_large_ediff= 0;
884 if( std::fabs(startEnergy- endEnergy) > perThousand * endEnergy )
887 if( (no_large_ediff% warnModulo) == 0 )
890 G4cout <<
"WARNING - G4CoupledTransportation::AlongStepGetPIL() "
891 <<
" Energy change in Step is above 1^-3 relative value. " <<
G4endl
892 <<
" Relative change in 'tracking' step = "
893 << std::setw(15) << (endEnergy-startEnergy)/startEnergy <<
G4endl
894 <<
" Starting E= " << std::setw(12) << startEnergy / MeV <<
" MeV " <<
G4endl
895 <<
" Ending E= " << std::setw(12) << endEnergy / MeV <<
" MeV " <<
G4endl;
896 G4cout <<
" Energy has been corrected -- however, review"
897 <<
" field propagation parameters for accuracy." <<
G4endl;
898 if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) ){
899 G4cout <<
" These include EpsilonStepMax(/Min) in G4FieldManager "
900 <<
" which determine fractional error per step for integrated quantities. " <<
G4endl
901 <<
" Note also the influence of the permitted number of integration steps."
904 G4cerr <<
"ERROR - G4CoupledTransportation::AlongStepGetPIL()" <<
G4endl
905 <<
" Bad 'endpoint'. Energy change detected"
906 <<
" and corrected. "
907 <<
" Has occurred already "
908 << no_large_ediff <<
" times." <<
G4endl;
909 if( no_large_ediff == warnModulo * moduloFactor )
911 warnModulo *= moduloFactor;
CLHEP::Hep3Vector G4ThreeVector
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4bool DoesGlobalFieldExist()
void ReportInexactEnergy(G4double startEnergy, G4double endEnergy)
G4CoupledTransportation(G4int verbosityLevel=0)
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
void StartTracking(G4Track *aTrack)
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
~G4CoupledTransportation()
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
void SetChargeAndMoments(G4double charge, G4double magnetic_dipole_moment=DBL_MAX, G4double electric_dipole_moment=DBL_MAX, G4double magnetic_charge=DBL_MAX)
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 GetPDGMass() 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=0)
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()
void ClearPropagatorState()
void SetChargeMomentumMass(G4double charge, G4double momentum, G4double pMass)
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
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 ProposeTrueStepLength(G4double truePathLength)
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
void SetProcessSubType(G4int)
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)