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;
121 *selection = CandidateForSelection;
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);
184 fPreviousSftOrigin = startPosition;
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) {
250 fFieldPropagator->ComputeStep(aFieldTrack, currentMinimumStep, currentSafety, track.GetVolume());
253 geometryStepLength = lengthAlongCurve;
255 geometryStepLength = currentMinimumStep;
258 geometryStepLength = 0.0;
264 fPreviousSftOrigin = startPosition;
290 if (currentMinimumStep == 0.0) {
291 if (currentSafety == 0.0)
299 if (particleMagneticCharge != 0.0) {
301 currentSafety = endSafety;
311 #ifdef G4DEBUG_TRANSPORT
312 G4cout.precision(12);
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;
347 G4double
startTime = track.GetGlobalTime();
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());
376 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime);
399 G4cout <<
" MonopoleTransportation is killing track that is looping or stuck " << G4endl <<
" This track has "
400 << track.GetKineticEnergy() /
MeV <<
" MeV energy." << G4endl;
408 if ((verboseLevel > 2)) {
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;
585 G4cout <<
" Sum of energy of loopers killed: " <<
fSumEnergyKilled << G4endl;
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
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 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
G4VParticleChange * AtRestDoIt(const G4Track &, const G4Step &) override
G4SafetyHelper * fpSafetyHelper
G4TouchableHandle fCurrentTouchableHandle
G4double MagneticCharge() const
G4double fTransportEndKineticEnergy
G4bool fParticleIsLooping
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