58 #include "G4ProductionCutsTable.hh"
59 #include "G4ParticleTable.hh"
60 #include "G4ChordFinder.hh"
61 #include "G4SafetyHelper.hh"
62 #include "G4FieldManagerStore.hh"
63 #include "G4MagIntegratorDriver.hh"
64 #include "G4Version.hh"
73 class G4VSensitiveDetector;
80 : G4VProcess( G4String(
"QuirkTransportation"), fTransportation ),
81 m_particleIsLooping( false ),
82 m_currentTouchableHandle(),
83 m_previousSftOrigin (0.,0.,0.),
84 m_previousSafety ( 0.0 ),
85 m_threshold_Warning_Energy( 100 *
CLHEP::
MeV ),
86 m_threshold_Important_Energy( 250 *
CLHEP::
MeV ),
87 m_thresholdTrials( 10 ),
89 m_sumEnergyKilled( 0.0 ), m_maxEnergyKilled( 0.0 ),
90 m_shortStepOptimisation(false),
91 m_verboseLevel( verboseLevel )
93 G4TransportationManager* transportMgr ;
95 transportMgr = G4TransportationManager::GetTransportationManager() ;
118 G4cout <<
" QuirkTransportation: Statistics for looping particles " << G4endl;
134 G4double currentMinimumStep,
135 G4double& currentSafety,
138 G4double geometryStepLength;
154 const G4DynamicParticle* pParticle =
track.GetDynamicParticle() ;
155 G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ;
156 G4ThreeVector startPosition =
track.GetPosition() ;
165 G4double MagSqShift = OriginShift.mag2() ;
168 currentSafety = 0.0 ;
177 G4double particleCharge = pParticle->GetCharge() ;
187 fieldMgr->ConfigureForTrack( &
track );
189 G4Exception(
"QuirkTransportation::AlongStepGetPhysicalInteractionLength",
"QuirkNoFieldMgr", RunMustBeAborted,
"no field manager");
193 Quirk* quirkDef =
dynamic_cast<Quirk*
>(pParticleDef);
195 G4Exception(
"QuirkTransportation::AlongStepGetPhysicalInteractionLength",
"NonQuirk", FatalErrorInArgument,
"QuirkTransportation run on non-quirk particle");
201 fieldMgr->DoesFieldExist() ? fieldMgr->GetDetectorField() : 0
205 G4ChordFinder* oldChordFinder = fieldMgr->GetChordFinder();
206 G4ChordFinder quirkChordFinder(
207 new G4MagInt_Driver(0.0, &quirkStepper, quirkStepper.GetNumberOfVariables())
209 fieldMgr->SetChordFinder(&quirkChordFinder);
211 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
212 G4ThreeVector EndUnitMomentum ;
213 G4double restMass = pParticleDef->GetPDGMass() ;
215 #if G4VERSION_NUMBER > 1009
217 G4ChargeState chargeState(particleCharge,
218 quirkDef->GetPDGSpin(),
222 G4EquationOfMotion* equationOfMotion = (
m_fieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())->GetEquationOfMotion();
223 equationOfMotion->SetChargeMomentumMass( chargeState,
232 G4ThreeVector
spin =
track.GetPolarization() ;
233 G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
234 track.GetMomentumDirection(),
236 track.GetKineticEnergy(),
239 track.GetGlobalTime(),
254 if (
dbg) G4cout <<
"QuirkTransportation: start = " << aFieldTrack.GetPosition() << G4endl;
255 if (
dbg) G4cout <<
"QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
256 if (
dbg) G4cout <<
"QuirkTransportation: maxlength = " << quirkStepper.
GetMaxLength() << G4endl;
258 if (
dbg) G4cout <<
"QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
259 if( currentMinimumStep > 0 )
265 track.GetVolume() ) ;
266 if (
dbg) G4cout <<
"QuirkTransportation: moved " << lengthAlongCurve << G4endl;
269 geometryStepLength = lengthAlongCurve ;
271 geometryStepLength = currentMinimumStep ;
278 geometryStepLength = 0.0 ;
281 if (
dbg) G4cout <<
"QuirkTransportation: moved " << aFieldTrack.GetCurveLength() << G4endl;
282 if (
dbg) G4cout <<
"QuirkTransportation: end = " << aFieldTrack.GetPosition() <<
" [" << aFieldTrack.GetProperTimeOfFlight() <<
"]" << G4endl;
291 geometryStepLength = aFieldTrack.GetCurveLength();
304 if( currentMinimumStep == 0.0 )
316 currentSafety = endSafety ;
326 #ifdef G4DEBUG_TRANSPORT
327 G4cout.precision(12) ;
328 G4cout <<
"***QuirkTransportation::AlongStepGPIL ** " << G4endl ;
330 <<
" and it returned safety= " << endSafety << G4endl ;
332 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
339 fieldMgr->SetChordFinder(oldChordFinder);
341 return geometryStepLength ;
353 static std::atomic<G4int> noCalls=0;
378 G4double restMass =
track.GetDynamicParticle()->GetMass() ;
379 G4double deltaProperTime = deltaTime*( restMass/
track.GetTotalEnergy() ) ;
405 G4cout <<
" QuirkTransportation is killing track that is looping or stuck "
408 <<
" MeV energy." << G4endl;
410 <<
" No of calls to AlongStepDoIt = " << noCalls
420 G4cout <<
" QuirkTransportation::AlongStepDoIt(): Particle looping - "
422 <<
" No of calls to = " << noCalls
451 G4ForceCondition* pForceCond )
453 *pForceCond = Forced ;
463 G4TouchableHandle retCurrentTouchable ;
464 G4bool isLastStep=
false;
483 LocateGlobalPointAndUpdateTouchableHandle(
track.GetPosition(),
484 track.GetMomentumDirection(),
493 G4cout <<
"QuirkTransportation: number of steps = " <<
track.GetCurrentStepNumber() << G4endl;
502 #ifdef G4DEBUG_TRANSPORT
506 if( ! (exiting || entering) ) {
507 G4cout <<
" Transport> : Proposed isLastStep= " << isLastStep
526 retCurrentTouchable =
track.GetTouchableHandle() ;
529 #ifdef G4DEBUG_TRANSPORT
531 G4cout <<
" Transport> Proposed isLastStep= " << isLastStep
532 <<
" Geometry did not limit step. " << G4endl;
538 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
539 G4Material* pNewMaterial = 0 ;
540 G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
544 pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
545 pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
554 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
557 pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
560 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
564 pNewMaterialCutsCouple =
565 G4ProductionCutsTable::GetProductionCutsTable()
566 ->GetMaterialCutsCouple(pNewMaterial,
567 pNewMaterialCutsCouple->GetProductionCuts());
569 m_particleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
588 G4VProcess::StartTracking(aTrack);
614 G4FieldManagerStore::GetInstance()->ClearAllChordFindersState();
622 const_cast<G4ParticleDefinition*
>(aTrack->GetParticleDefinition());
623 Quirk* quirkDef =
dynamic_cast<Quirk*
>(part_nc);
625 G4Exception(
"QuirkTransportation::StartTracking",
"NonQuirk", FatalErrorInArgument,
"QuirkTransportation run on non-quirk particle");