11#include <framework/logging/Logger.h>
13#include "G4TransportationProcessType.hh"
15#include "G4PhysicalConstants.hh"
16#include "G4SystemOfUnits.hh"
17#include "G4ProductionCutsTable.hh"
18#include "G4PrimaryParticle.hh"
19#include "G4FieldManager.hh"
20#include "G4Navigator.hh"
24#include "G4FieldManagerStore.hh"
25#include <simulation/longlivedneutral/G4LongLivedNeutralTransportation.h>
27class G4VSensitiveDetector;
38 : G4VProcess(G4String(
"LongLivedNeutralTransportation"), fTransportation),
45 SetProcessSubType(
static_cast<G4int
>(TRANSPORTATION));
47 SetVerboseLevel(verbosity);
49 G4TransportationManager* transportMgr ;
51 transportMgr = G4TransportationManager::GetTransportationManager() ;
70 static G4ThreadLocal G4TouchableHandle* pNullTouchableHandle = 0;
71 pNullTouchableHandle =
new G4TouchableHandle;
77 if (verboseLevel > 0) {
78 G4cout <<
" G4LongLivedNeutralTransportation constructor> set fShortStepOptimisation to ";
80 else { G4cout <<
"false" << G4endl; }
100 outStr <<
" G4LongLivedNeutralTransportation: Statistics for looping particles " << G4endl;
101 outStr <<
" No looping tracks found or killed. " << G4endl;
115 G4double currentMinimumStep,
116 G4double& currentSafety,
117 G4GPILSelection* selection)
119 G4double geometryStepLength = -1.0, newSafety = -1.0;
130 *selection = CandidateForSelection ;
140 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
141 const G4PrimaryParticle* primaryParticle = pParticle->GetPrimaryParticle();
142 G4ThreeVector startMomentumDir = primaryParticle->GetMomentumDirection() ;
143 G4ThreeVector startPosition = track.GetPosition() ;
150 G4double MagSqShift = OriginShift.mag2() ;
152 currentSafety = 0.0 ;
159 G4double particleCharge = 0 ;
167 G4double linearStepLength ;
171 geometryStepLength = currentMinimumStep ;
186 currentSafety = newSafety ;
191 geometryStepLength = linearStepLength ;
194 geometryStepLength = currentMinimumStep ;
216 if (currentMinimumStep == 0.0) {
224 if (particleCharge != 0.0) {
227 currentSafety = endSafety ;
237#ifdef G4DEBUG_TRANSPORT
238 G4cout.precision(12) ;
239 G4cout <<
"***G4LongLivedNeutralTransportation::AlongStepGPIL ** " << G4endl ;
241 <<
" and it returned safety= " << endSafety << G4endl ;
243 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
245 G4cout <<
"***G4LongLivedNeutralTransportation::AlongStepGPIL ** " << G4endl ;
246 G4cout <<
" Avoiding call to ComputeSafety : " << G4endl;
247 G4cout <<
" charge = " << particleCharge << G4endl;
248 G4cout <<
" mag moment = " << magneticMoment << G4endl;
255 return geometryStepLength ;
264 const G4Step& stepData)
280 G4double deltaTime = 0.0 ;
286 G4double startTime = track.GetGlobalTime() ;
288 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
289 const G4PrimaryParticle* primaryParticle = pParticle->GetPrimaryParticle();
298 B2DEBUG(0,
"Velocity calculated from Step data: " << stepData.GetPreStepPoint()->GetVelocity());
300 G4double initialVelocity = c_light * primaryParticle->GetTotalMomentum() / primaryParticle->GetTotalEnergy();
301 G4double stepLength = track.GetStepLength();
304 if (initialVelocity > 0.0) { deltaTime = stepLength / initialVelocity; }
314 G4double restMass = primaryParticle->GetMass() ;
315 G4double deltaProperTime = deltaTime * (restMass / primaryParticle->GetTotalEnergy()) ;
317 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
340 G4ForceCondition* pForceCond)
343 *pForceCond = Forced ;
353 G4TouchableHandle retCurrentTouchable ;
354 G4bool isLastStep =
false;
372 LocateGlobalPointAndUpdateTouchableHandle(track.GetPosition(),
373 track.GetMomentumDirection(),
402 retCurrentTouchable = track.GetTouchableHandle() ;
411 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
412 G4Material* pNewMaterial = nullptr ;
413 G4VSensitiveDetector* pNewSensitiveDetector = nullptr ;
416 pNewMaterial = pNewVol->GetLogicalVolume()->GetMaterial();
417 pNewSensitiveDetector = pNewVol->GetLogicalVolume()->GetSensitiveDetector();
421 fParticleChange.SetSensitiveDetectorInTouchable(pNewSensitiveDetector) ;
423 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
425 pNewMaterialCutsCouple = pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
428 if (pNewVol != 0 && pNewMaterialCutsCouple != 0
429 && pNewMaterialCutsCouple->GetMaterial() != pNewMaterial) {
432 pNewMaterialCutsCouple =
433 G4ProductionCutsTable::GetProductionCutsTable()
434 ->GetMaterialCutsCouple(pNewMaterial,
435 pNewMaterialCutsCouple->GetProductionCuts());
437 fParticleChange.SetMaterialCutsCoupleInTouchable(pNewMaterialCutsCouple);
459 G4VProcess::StartTracking(aTrack);
491 G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance();
492 fieldMgrStore->ClearAllChordFindersState();
535 G4int maxTrials = 10;
549 G4int maxTrials = 30;
567 G4String indent =
" ";
568 G4int oldPrec = outStream.precision(6);
570 outStream << G4endl << indent << GetProcessName() <<
": ";
572 outStream <<
" Parameters for looping particles: " << G4endl
576 outStream.precision(oldPrec);
G4bool fFirstStepInVolume
Flag first step in a geom.
G4TouchableHandle fCurrentTouchableHandle
Current touchable handle.
void PrintStatistics(std::ostream &outStr) const
returns current logging info of the algorithm
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4VProcess::PostStepDoIt() implementation,.
G4bool fAnyFieldExists
Flag for existing fields.
G4double fCandidateEndGlobalTime
The particle's state after this Step, Store for DoIt.
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
G4VProcess::AlongStepGetPhysicalInteractionLength() implementation,.
G4int fThresholdTrials
Number of trials an important looper survives.
void SetThresholdWarningEnergy(G4double newEnWarn)
Set fThreshold_Warning_Energy.
void SetThresholdImportantEnergy(G4double newEnImp)
Set fThreshold_Important_Energy.
virtual void ProcessDescription(std::ostream &outStream) const
G4LongLivedNeutralTransportation::ProcessDescription()
G4bool fGeometryLimitedStep
Flag to determine whether a boundary was reached.
G4bool fFieldExertedForce
During current step.
G4ThreeVector fTransportEndMomentumDir
The particle's state after this Step, Store for DoIt.
void SetThresholdTrials(G4int newMaxTrials)
Set fThresholdTrials.
G4double fPreviousSafety
Remember last safety value.
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
G4VProcess::AlongStepDoIt() implementation,.
G4double fEndPointDistance
Endpoint distance.
G4bool fLastStepInVolume
Flag last step in a geom.
void SetHighLooperThresholds()
Get/Set parameters for killing loopers: Above 'important' energy a 'looping' particle in field will N...
G4double fSumEnergyKilled
Sum of abandoned looping tracks energies.
G4ThreeVector fPreviousSftOrigin
Remember last safety origin.
static void SetSilenceLooperWarnings(G4bool val)
Do not warn about 'looping' particles.
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *pForceCond)
G4VProcess::PostStepGetPhysicalInteractionLength() implementation.
G4ThreeVector fTransportEndSpin
The particle's state after this Step, Store for DoIt.
G4Navigator * fLinearNavigator
Propagator used to transport the particle.
static G4bool fSilenceLooperWarnings
Flag to Supress all 'looper' warnings.
G4double fThreshold_Important_Energy
Give a few trial above this E for looping particle.
G4ThreeVector fTransportEndPosition
The particle's state after this Step, Store for DoIt.
G4bool fEndGlobalTimeComputed
The particle's state after this Step, Store for DoIt.
G4bool fShortStepOptimisation
Whether to avoid calling G4Navigator for short step ( < safety) If using it, the safety estimate for ...
G4int fNoLooperTrials
Counter for steps in which particle reports 'looping', if it is above 'Important' Energy.
G4bool fMomentumChanged
The particle's state after this Step, Store for DoIt.
G4bool fNewTrack
Flag from StartTracking.
G4LongLivedNeutralTransportation(G4int verbosityLevel=1)
Constructor.
void StartTracking(G4Track *aTrack)
Reset state for new (potentially resumed) track.
G4ParticleChangeForTransport fParticleChange
New ParticleChange.
void SetLowLooperThresholds()
Shortcut method - old values (meant for HEP)
G4double fThreshold_Warning_Energy
Warn above this energy about looping particle.
G4bool DoesGlobalFieldExist()
Checks whether a field exists for the "global" field manager.
~G4LongLivedNeutralTransportation()
Destructor.
static G4bool GetSilenceLooperWarnings()
Do not throw exception about 'looping' particles.
G4PropagatorInField * fFieldPropagator
Propagator used to transport the particle.
G4double fTransportEndKineticEnergy
The particle's state after this Step, Store for DoIt.
Abstract base class for different kinds of events.