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 = lengthAlongCurve = 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;
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());
399 G4cout <<
" MonopoleTransportation is killing track that is looping or stuck " << G4endl <<
" This track has "
400 <<
track.GetKineticEnergy() /
MeV <<
" MeV energy." << G4endl;
410 G4cout <<
" MonopoleTransportation::AlongStepDoIt(): Particle looping - "
411 <<
" Number of trials = " <<
fNoLooperTrials <<
" No of calls to = " << noCalls << G4endl;
437 G4ForceCondition* pForceCond) {
438 *pForceCond = Forced;
445 G4TouchableHandle retCurrentTouchable;
480 retCurrentTouchable =
track.GetTouchableHandle();
483 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume();
484 const G4Material* pNewMaterial =
nullptr;
485 const G4VSensitiveDetector* pNewSensitiveDetector =
nullptr;
487 if (pNewVol !=
nullptr) {
488 pNewMaterial = pNewVol->GetLogicalVolume()->GetMaterial();
489 pNewSensitiveDetector = pNewVol->GetLogicalVolume()->GetSensitiveDetector();
493 fParticleChange.SetSensitiveDetectorInTouchable((G4VSensitiveDetector*)pNewSensitiveDetector);
495 const G4MaterialCutsCouple* pNewMaterialCutsCouple =
nullptr;
496 if (pNewVol !=
nullptr) {
497 pNewMaterialCutsCouple = pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
500 if (pNewVol !=
nullptr && pNewMaterialCutsCouple !=
nullptr &&
501 pNewMaterialCutsCouple->GetMaterial() != pNewMaterial) {
504 pNewMaterialCutsCouple = G4ProductionCutsTable::GetProductionCutsTable()->GetMaterialCutsCouple(
505 pNewMaterial, pNewMaterialCutsCouple->GetProductionCuts());
507 fParticleChange.SetMaterialCutsCoupleInTouchable(pNewMaterialCutsCouple);
532 G4FieldManager* fieldMgr =
fFieldPropagator->FindAndSetFieldManager(aTrack->GetVolume());
533 fieldMgrCMS = static_cast<CMSFieldManager*>(fieldMgr);
536 G4VProcess::StartTracking(aTrack);
559 chordF->ResetStepEstimate();
563 G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance();
564 fieldMgrStore->ClearAllChordFindersState();
585 G4cout <<
" MonopoleTransportation: Statistics for looping particles " << G4endl;