22 #include "G4ProductionCutsTable.hh" 23 #include "G4ParticleTable.hh" 24 #include "G4ChordFinder.hh" 25 #include "G4SafetyHelper.hh" 26 #include "G4FieldManagerStore.hh" 27 #include "G4TransportationProcessType.hh" 28 #include "G4SystemOfUnits.hh" 30 class G4VSensitiveDetector;
37 : G4VProcess( G4String(
"MonopoleTransportation"), fTransportation ),
39 fChordFinderSetter(chordFinderSetter),
43 fParticleIsLooping(
false ),
44 fPreviousSftOrigin (0.,0.,0.),
45 fPreviousSafety ( 0.0 ),
46 fThreshold_Warning_Energy( 100 *
MeV ),
47 fThreshold_Important_Energy( 250 *
MeV ),
48 fThresholdTrials( 10 ),
50 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
51 fShortStepOptimisation(
false),
57 SetProcessSubType(TRANSPORTATION);
59 #ifdef G4MULTITHREADED 61 if (G4Threading::IsMasterThread())
67 G4TransportationManager* transportMgr =
68 G4TransportationManager::GetTransportationManager();
81 static G4TouchableHandle nullTouchableHandle;
112 G4double currentMinimumStep,
113 G4double& currentSafety,
119 G4double geometryStepLength, newSafety ;
131 *selection = CandidateForSelection ;
135 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
136 const G4ThreeVector& startMomentumDir = pParticle->GetMomentumDirection() ;
137 G4ThreeVector startPosition = track.GetPosition() ;
144 G4double MagSqShift = OriginShift.mag2() ;
147 currentSafety = 0.0 ;
157 G4double particleElectricCharge = pParticle->GetCharge();
166 G4bool fieldExertsForce =
false ;
176 fieldExertsForce = (
fieldMgrCMS->GetDetectorField() !=
nullptr);
184 if( !fieldExertsForce )
186 G4double linearStepLength ;
191 geometryStepLength = currentMinimumStep ;
204 fPreviousSftOrigin = startPosition ;
210 currentSafety = newSafety ;
216 geometryStepLength = linearStepLength ;
221 geometryStepLength = currentMinimumStep ;
241 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
242 G4ThreeVector EndUnitMomentum ;
243 G4double lengthAlongCurve ;
246 G4ChargeState chargeState(particleElectricCharge,
250 particleMagneticCharge );
252 G4EquationOfMotion* equationOfMotion =
253 fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetEquationOfMotion();
256 ->SetChargeMomentumMass( chargeState,
261 G4ThreeVector
spin = track.GetPolarization() ;
262 G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
263 track.GetMomentumDirection(),
265 track.GetKineticEnergy(),
268 track.GetGlobalTime(),
269 track.GetProperTime(),
271 if( currentMinimumStep > 0 )
278 track.GetVolume() ) ;
281 geometryStepLength = lengthAlongCurve ;
283 geometryStepLength = currentMinimumStep ;
288 geometryStepLength = lengthAlongCurve= 0.0 ;
294 fPreviousSftOrigin = startPosition ;
320 if( currentMinimumStep == 0.0 )
333 if( particleMagneticCharge != 0.0 ) {
337 currentSafety = endSafety ;
347 #ifdef G4DEBUG_TRANSPORT 349 G4cout <<
"***MonopoleTransportation::AlongStepGPIL ** " << G4endl ;
351 <<
" and it returned safety= " << endSafety << G4endl ;
353 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
360 return geometryStepLength ;
369 const G4Step& stepData )
382 G4double deltaTime = 0.0 ;
388 G4double startTime = track.GetGlobalTime() ;
394 G4double finalVelocity = track.GetVelocity() ;
395 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity() ;
396 G4double stepLength = track.GetStepLength() ;
400 if (finalVelocity > 0.0)
402 G4double meanInverseVelocity ;
403 meanInverseVelocity = 0.5
404 * ( 1.0 / initialVelocity + 1.0 / finalVelocity ) ;
405 deltaTime = stepLength * meanInverseVelocity ;
407 else if( initialVelocity > 0.0 )
409 deltaTime = stepLength/initialVelocity ;
422 G4double restMass = track.GetDynamicParticle()->GetMass() ;
423 G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
425 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
447 if( (verboseLevel > 1) ||
449 G4cout <<
" MonopoleTransportation is killing track that is looping or stuck " 451 <<
" This track has " << track.GetKineticEnergy() /
MeV 452 <<
" MeV energy." << G4endl;
454 <<
" No of calls to AlongStepDoIt = " << noCalls
463 if( (verboseLevel > 2) ){
464 G4cout <<
" MonopoleTransportation::AlongStepDoIt(): Particle looping - " 466 <<
" No of calls to = " << noCalls
495 G4ForceCondition* pForceCond )
497 *pForceCond = Forced ;
506 G4TouchableHandle retCurrentTouchable ;
521 LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
522 track.GetMomentumDirection(),
547 retCurrentTouchable = track.GetTouchableHandle() ;
550 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
551 const G4Material* pNewMaterial =
nullptr ;
552 const G4VSensitiveDetector* pNewSensitiveDetector =
nullptr ;
554 if( pNewVol !=
nullptr )
556 pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
557 pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
564 (G4Material *) pNewMaterial ) ;
566 (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
568 const G4MaterialCutsCouple* pNewMaterialCutsCouple =
nullptr;
569 if( pNewVol !=
nullptr )
571 pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
574 if( pNewVol!=
nullptr && pNewMaterialCutsCouple!=
nullptr &&
575 pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
579 pNewMaterialCutsCouple =
580 G4ProductionCutsTable::GetProductionCutsTable()
581 ->GetMaterialCutsCouple(pNewMaterial,
582 pNewMaterialCutsCouple->GetProductionCuts());
584 fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
611 G4FieldManager* fieldMgr =
616 G4VProcess::StartTracking(aTrack);
640 if( chordF ) chordF->ResetStepEstimate();
644 G4FieldManagerStore* fieldMgrStore= G4FieldManagerStore::GetInstance();
645 fieldMgrStore->ClearAllChordFindersState();
G4double fThreshold_Warning_Energy
G4bool DoesGlobalFieldExist()
G4double fMaxEnergyKilled
G4double endpointDistance
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
void StartTracking(G4Track *aTrack) override
MonopoleTransportation(const Monopole *p, sim::ChordFinderSetter *cfs, G4int verbosityLevel=1)
G4bool fGeometryLimitedStep
const Monopole * fParticleDef
G4double fCandidateEndGlobalTime
G4double fThreshold_Important_Energy
G4ThreeVector fTransportEndMomentumDir
G4ThreeVector fPreviousSftOrigin
G4bool fShortStepOptimisation
G4double fSumEnergyKilled
void ConfigureForTrack(const G4Track *) override
G4bool fEndGlobalTimeComputed
G4ThreeVector fTransportEndSpin
G4ParticleChangeForTransport fParticleChange
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection) override
G4Navigator * fLinearNavigator
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond) override
G4PropagatorInField * fFieldPropagator
G4SafetyHelper * fpSafetyHelper
G4TouchableHandle fCurrentTouchableHandle
G4double MagneticCharge() const
G4double fTransportEndKineticEnergy
G4bool fParticleIsLooping
Square< F >::type sqr(const F &f)
~MonopoleTransportation() override
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData) override
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData) override
CMSFieldManager * fieldMgrCMS
void SetMonopoleTracking(G4bool)
G4ThreeVector fTransportEndPosition