21 #include "G4ProductionCutsTable.hh" 22 #include "G4ParticleTable.hh" 23 #include "G4ChordFinder.hh" 24 #include "G4SafetyHelper.hh" 25 #include "G4FieldManagerStore.hh" 26 #include "G4TransportationProcessType.hh" 27 #include "G4SystemOfUnits.hh" 29 class G4VSensitiveDetector;
34 : G4VProcess(G4String(
"MonopoleTransportation"), fTransportation),
37 fLinearNavigator(nullptr),
38 fFieldPropagator(nullptr),
39 fParticleIsLooping(
false),
40 fPreviousSftOrigin(0., 0., 0.),
42 fThreshold_Warning_Energy(100 * MeV),
43 fThreshold_Important_Energy(250 * MeV),
46 fSumEnergyKilled(0.0),
47 fMaxEnergyKilled(0.0),
48 fShortStepOptimisation(
false),
49 fpSafetyHelper(nullptr) {
53 SetProcessSubType(TRANSPORTATION);
55 #ifdef G4MULTITHREADED 57 if (G4Threading::IsMasterThread()) {
62 G4TransportationManager* transportMgr = G4TransportationManager::GetTransportationManager();
103 G4double currentMinimumStep,
104 G4double& currentSafety,
109 G4double geometryStepLength, newSafety;
125 const G4DynamicParticle* pParticle =
track.GetDynamicParticle();
126 const G4ThreeVector& startMomentumDir = pParticle->GetMomentumDirection();
127 G4ThreeVector startPosition =
track.GetPosition();
134 G4double MagSqShift = OriginShift.mag2();
144 G4double particleElectricCharge = pParticle->GetCharge();
153 G4bool fieldExertsForce =
false;
155 if (particleMagneticCharge != 0.0 &&
fieldMgrCMS) {
163 fieldExertsForce = (
fieldMgrCMS->GetDetectorField() !=
nullptr);
171 if (!fieldExertsForce) {
172 G4double linearStepLength;
176 geometryStepLength = currentMinimumStep;
181 linearStepLength =
fLinearNavigator->ComputeStep(startPosition, startMomentumDir, currentMinimumStep, newSafety);
190 currentSafety = newSafety;
195 geometryStepLength = linearStepLength;
198 geometryStepLength = currentMinimumStep;
217 G4double momentumMagnitude = pParticle->GetTotalMomentum();
218 G4ThreeVector EndUnitMomentum;
219 G4double lengthAlongCurve;
222 G4ChargeState chargeState(particleElectricCharge,
226 particleMagneticCharge);
228 G4EquationOfMotion* equationOfMotion =
229 fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetEquationOfMotion();
231 equationOfMotion->SetChargeMomentumMass(chargeState,
236 G4ThreeVector spin =
track.GetPolarization();
237 G4FieldTrack aFieldTrack = G4FieldTrack(startPosition,
238 track.GetMomentumDirection(),
240 track.GetKineticEnergy(),
243 track.GetGlobalTime(),
244 track.GetProperTime(),
246 if (currentMinimumStep > 0) {
253 geometryStepLength = lengthAlongCurve;
255 geometryStepLength = currentMinimumStep;
258 geometryStepLength = 0.0;
290 if (currentMinimumStep == 0.0) {
291 if (currentSafety == 0.0)
299 if (particleMagneticCharge != 0.0) {
301 currentSafety = endSafety;
311 #ifdef G4DEBUG_TRANSPORT 313 G4cout <<
"***MonopoleTransportation::AlongStepGPIL ** " << G4endl;
315 <<
" and it returned safety= " << endSafety << G4endl;
316 G4cout <<
" Adding endpoint distance " <<
endpointDistance <<
" to obtain pseudo-safety= " << currentSafety
324 return geometryStepLength;
344 G4double deltaTime = 0.0;
352 G4double finalVelocity =
track.GetVelocity();
353 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity();
354 G4double stepLength =
track.GetStepLength();
357 if (finalVelocity > 0.0) {
358 G4double meanInverseVelocity;
359 meanInverseVelocity = 0.5 * (1.0 / initialVelocity + 1.0 / finalVelocity);
360 deltaTime = stepLength * meanInverseVelocity;
361 }
else if (initialVelocity > 0.0) {
362 deltaTime = stepLength / initialVelocity;
373 G4double restMass =
track.GetDynamicParticle()->GetMass();
374 G4double deltaProperTime = deltaTime * (restMass /
track.GetTotalEnergy());
399 G4cout <<
" MonopoleTransportation is killing track that is looping or stuck " << G4endl <<
" This track has " 400 <<
track.GetKineticEnergy() / MeV <<
" MeV energy." << G4endl;
409 G4cout <<
" MonopoleTransportation::AlongStepDoIt(): Particle looping - " 436 G4ForceCondition* pForceCond) {
437 *pForceCond = Forced;
444 G4TouchableHandle retCurrentTouchable;
479 retCurrentTouchable =
track.GetTouchableHandle();
482 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume();
483 const G4Material* pNewMaterial =
nullptr;
484 G4VSensitiveDetector* pNewSensitiveDetector =
nullptr;
486 if (pNewVol !=
nullptr) {
487 pNewMaterial = pNewVol->GetLogicalVolume()->GetMaterial();
488 pNewSensitiveDetector = pNewVol->GetLogicalVolume()->GetSensitiveDetector();
492 fParticleChange.SetSensitiveDetectorInTouchable((G4VSensitiveDetector*)pNewSensitiveDetector);
494 const G4MaterialCutsCouple* pNewMaterialCutsCouple =
nullptr;
495 if (pNewVol !=
nullptr) {
496 pNewMaterialCutsCouple = pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
499 if (pNewVol !=
nullptr && pNewMaterialCutsCouple !=
nullptr &&
500 pNewMaterialCutsCouple->GetMaterial() != pNewMaterial) {
503 pNewMaterialCutsCouple = G4ProductionCutsTable::GetProductionCutsTable()->GetMaterialCutsCouple(
504 pNewMaterial, pNewMaterialCutsCouple->GetProductionCuts());
506 fParticleChange.SetMaterialCutsCoupleInTouchable(pNewMaterialCutsCouple);
531 G4FieldManager* fieldMgr =
fFieldPropagator->FindAndSetFieldManager(aTrack->GetVolume());
535 G4VProcess::StartTracking(aTrack);
558 chordF->ResetStepEstimate();
562 G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance();
563 fieldMgrStore->ClearAllChordFindersState();
584 G4cout <<
" MonopoleTransportation: Statistics for looping particles " << G4endl;
G4double fThreshold_Warning_Energy
G4bool DoesGlobalFieldExist()
G4double fMaxEnergyKilled
G4double endpointDistance
void StartTracking(G4Track *aTrack) override
G4bool fGeometryLimitedStep
const Monopole * fParticleDef
void ResetKilledStatistics(G4int report=1)
G4double AtRestGetPhysicalInteractionLength(const G4Track &, G4ForceCondition *) override
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 MagneticCharge() const
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
MonopoleTransportation(const Monopole *p, G4int verbosityLevel=1)
G4PropagatorInField * fFieldPropagator
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
G4VParticleChange * AtRestDoIt(const G4Track &, const G4Step &) override
G4SafetyHelper * fpSafetyHelper
G4TouchableHandle fCurrentTouchableHandle
G4double fTransportEndKineticEnergy
G4bool fParticleIsLooping
Square< F >::type sqr(const F &f)
void setMonopoleTracking(G4bool)
~MonopoleTransportation() override
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData) override
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData) override
CMSFieldManager * fieldMgrCMS
G4ThreeVector fTransportEndPosition