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();
111 G4double currentMinimumStep,
112 G4double& currentSafety,
118 G4double geometryStepLength, newSafety ;
130 *selection = CandidateForSelection ;
134 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
135 const G4ThreeVector& startMomentumDir = pParticle->GetMomentumDirection() ;
136 G4ThreeVector startPosition = track.GetPosition() ;
143 G4double MagSqShift = OriginShift.mag2() ;
146 currentSafety = 0.0 ;
156 G4double particleElectricCharge = pParticle->GetCharge();
165 G4bool fieldExertsForce =
false ;
175 fieldExertsForce = (
fieldMgrCMS->GetDetectorField() !=
nullptr);
183 if( !fieldExertsForce )
185 G4double linearStepLength ;
190 geometryStepLength = currentMinimumStep ;
203 fPreviousSftOrigin = startPosition ;
209 currentSafety = newSafety ;
215 geometryStepLength = linearStepLength ;
220 geometryStepLength = currentMinimumStep ;
240 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
241 G4ThreeVector EndUnitMomentum ;
242 G4double lengthAlongCurve ;
245 G4ChargeState chargeState(particleElectricCharge,
249 particleMagneticCharge );
251 G4EquationOfMotion* equationOfMotion =
252 fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetEquationOfMotion();
255 ->SetChargeMomentumMass( chargeState,
260 G4ThreeVector
spin = track.GetPolarization() ;
261 G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
262 track.GetMomentumDirection(),
264 track.GetKineticEnergy(),
267 track.GetGlobalTime(),
268 track.GetProperTime(),
270 if( currentMinimumStep > 0 )
277 track.GetVolume() ) ;
280 geometryStepLength = lengthAlongCurve ;
282 geometryStepLength = currentMinimumStep ;
287 geometryStepLength = lengthAlongCurve= 0.0 ;
293 fPreviousSftOrigin = startPosition ;
319 if( currentMinimumStep == 0.0 )
332 if( particleMagneticCharge != 0.0 ) {
336 currentSafety = endSafety ;
346 #ifdef G4DEBUG_TRANSPORT 348 G4cout <<
"***MonopoleTransportation::AlongStepGPIL ** " << G4endl ;
350 <<
" and it returned safety= " << endSafety << G4endl ;
352 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
359 return geometryStepLength ;
368 const G4Step& stepData )
381 G4double deltaTime = 0.0 ;
387 G4double startTime = track.GetGlobalTime() ;
393 G4double finalVelocity = track.GetVelocity() ;
394 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity() ;
395 G4double stepLength = track.GetStepLength() ;
399 if (finalVelocity > 0.0)
401 G4double meanInverseVelocity ;
402 meanInverseVelocity = 0.5
403 * ( 1.0 / initialVelocity + 1.0 / finalVelocity ) ;
404 deltaTime = stepLength * meanInverseVelocity ;
406 else if( initialVelocity > 0.0 )
408 deltaTime = stepLength/initialVelocity ;
421 G4double restMass = track.GetDynamicParticle()->GetMass() ;
422 G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
424 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
446 if( (verboseLevel > 1) ||
448 G4cout <<
" MonopoleTransportation is killing track that is looping or stuck " 450 <<
" This track has " << track.GetKineticEnergy() /
MeV 451 <<
" MeV energy." << G4endl;
453 <<
" No of calls to AlongStepDoIt = " << noCalls
462 if( (verboseLevel > 2) ){
463 G4cout <<
" MonopoleTransportation::AlongStepDoIt(): Particle looping - " 465 <<
" No of calls to = " << noCalls
494 G4ForceCondition* pForceCond )
496 *pForceCond = Forced ;
505 G4TouchableHandle retCurrentTouchable ;
520 LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
521 track.GetMomentumDirection(),
546 retCurrentTouchable = track.GetTouchableHandle() ;
549 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
550 const G4Material* pNewMaterial =
nullptr ;
551 const G4VSensitiveDetector* pNewSensitiveDetector =
nullptr ;
553 if( pNewVol !=
nullptr )
555 pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
556 pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
563 (G4Material *) pNewMaterial ) ;
565 (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
567 const G4MaterialCutsCouple* pNewMaterialCutsCouple =
nullptr;
568 if( pNewVol !=
nullptr )
570 pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
573 if( pNewVol!=
nullptr && pNewMaterialCutsCouple!=
nullptr &&
574 pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
578 pNewMaterialCutsCouple =
579 G4ProductionCutsTable::GetProductionCutsTable()
580 ->GetMaterialCutsCouple(pNewMaterial,
581 pNewMaterialCutsCouple->GetProductionCuts());
583 fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
610 G4FieldManager* fieldMgr =
615 G4VProcess::StartTracking(aTrack);
639 if( chordF ) chordF->ResetStepEstimate();
643 G4FieldManagerStore* fieldMgrStore= G4FieldManagerStore::GetInstance();
644 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