13 #include <framework/logging/Logger.h>
15 #include "G4TransportationProcessType.hh"
17 #include "G4PhysicalConstants.hh"
18 #include "G4SystemOfUnits.hh"
19 #include "G4ProductionCutsTable.hh"
20 #include "G4PrimaryParticle.hh"
22 #include "G4FieldManagerStore.hh"
23 #include <simulation/longlivedneutral/G4LongLivedNeutralTransportation.h>
25 class G4VSensitiveDetector;
36 : G4VProcess(G4String(
"LongLivedNeutralTransportation"), fTransportation),
37 fFieldExertedForce(false),
38 fPreviousSftOrigin(0., 0., 0.),
40 fEndPointDistance(-1.0),
41 fShortStepOptimisation(false)
43 SetProcessSubType(
static_cast<G4int
>(TRANSPORTATION));
45 SetVerboseLevel(verbosity);
47 G4TransportationManager* transportMgr ;
49 transportMgr = G4TransportationManager::GetTransportationManager() ;
68 static G4ThreadLocal G4TouchableHandle* pNullTouchableHandle = 0;
69 if (!pNullTouchableHandle) {
70 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)
266 static G4ThreadLocal G4long noCallsASDI = 0;
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();
532 SetThresholdWarningEnergy(100.0 * CLHEP::MeV);
533 SetThresholdImportantEnergy(250.0 * CLHEP::MeV);
535 G4int maxTrials = 10;
536 SetThresholdTrials(maxTrials);
546 SetThresholdWarningEnergy(1.0 * CLHEP::keV);
547 SetThresholdImportantEnergy(1.0 * CLHEP::MeV);
549 G4int maxTrials = 30;
550 SetThresholdTrials(maxTrials);
567 G4String indent =
" ";
568 G4int oldPrec = outStr.precision(6);
570 outStr << G4endl << indent << GetProcessName() <<
": ";
572 outStr <<
" Parameters for looping particles: " << G4endl
573 <<
" warning-E = " << fThreshold_Warning_Energy / CLHEP::MeV <<
" MeV " << G4endl
574 <<
" important E = " << fThreshold_Important_Energy / CLHEP::MeV <<
" MeV " << G4endl
575 <<
" thresholdTrials " << fThresholdTrials << G4endl;
576 outStr.precision(oldPrec);