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_transportEndKineticEnergy( 0.0 ),
82 m_momentumChanged( false ),
83 m_particleIsLooping( false ),
84 m_currentTouchableHandle(),
85 m_geometryLimitedStep( false ),
86 m_previousSftOrigin (0.,0.,0.),
87 m_previousSafety ( 0.0 ),
88 m_endpointDistance( 0.0 ),
89 m_threshold_Warning_Energy( 100 *
CLHEP::
MeV ),
90 m_threshold_Important_Energy( 250 *
CLHEP::
MeV ),
91 m_thresholdTrials( 10 ),
93 m_sumEnergyKilled( 0.0 ), m_maxEnergyKilled( 0.0 ),
94 m_shortStepOptimisation(false),
95 m_verboseLevel( verboseLevel )
97 G4TransportationManager* transportMgr ;
99 transportMgr = G4TransportationManager::GetTransportationManager() ;
122 G4cout <<
" QuirkTransportation: Statistics for looping particles " << G4endl;
138 G4double currentMinimumStep,
139 G4double& currentSafety,
142 G4double geometryStepLength;
158 const G4DynamicParticle* pParticle =
track.GetDynamicParticle() ;
159 G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ;
160 G4ThreeVector startPosition =
track.GetPosition() ;
169 G4double MagSqShift = OriginShift.mag2() ;
172 currentSafety = 0.0 ;
181 G4double particleCharge = pParticle->GetCharge() ;
191 fieldMgr->ConfigureForTrack( &
track );
193 G4Exception(
"QuirkTransportation::AlongStepGetPhysicalInteractionLength",
"QuirkNoFieldMgr", RunMustBeAborted,
"no field manager");
197 Quirk* quirkDef =
dynamic_cast<Quirk*
>(pParticleDef);
199 G4Exception(
"QuirkTransportation::AlongStepGetPhysicalInteractionLength",
"NonQuirk", FatalErrorInArgument,
"QuirkTransportation run on non-quirk particle");
205 fieldMgr->DoesFieldExist() ? fieldMgr->GetDetectorField() : 0
209 G4ChordFinder* oldChordFinder = fieldMgr->GetChordFinder();
210 G4ChordFinder quirkChordFinder(
211 new G4MagInt_Driver(0.0, &quirkStepper, quirkStepper.GetNumberOfVariables())
213 fieldMgr->SetChordFinder(&quirkChordFinder);
215 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
216 G4ThreeVector EndUnitMomentum ;
217 G4double restMass = pParticleDef->GetPDGMass() ;
219 #if G4VERSION_NUMBER > 1009
221 G4ChargeState chargeState(particleCharge,
222 quirkDef->GetPDGSpin(),
226 G4EquationOfMotion* equationOfMotion = (
m_fieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())->GetEquationOfMotion();
227 equationOfMotion->SetChargeMomentumMass( chargeState,
236 G4ThreeVector
spin =
track.GetPolarization() ;
237 G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
238 track.GetMomentumDirection(),
240 track.GetKineticEnergy(),
243 track.GetGlobalTime(),
258 if (
dbg) G4cout <<
"QuirkTransportation: start = " << aFieldTrack.GetPosition() << G4endl;
259 if (
dbg) G4cout <<
"QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
260 if (
dbg) G4cout <<
"QuirkTransportation: maxlength = " << quirkStepper.
GetMaxLength() << G4endl;
262 if (
dbg) G4cout <<
"QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
263 if( currentMinimumStep > 0 )
269 track.GetVolume() ) ;
270 if (
dbg) G4cout <<
"QuirkTransportation: moved " << lengthAlongCurve << G4endl;
273 geometryStepLength = lengthAlongCurve ;
275 geometryStepLength = currentMinimumStep ;
282 geometryStepLength = 0.0 ;
285 if (
dbg) G4cout <<
"QuirkTransportation: moved " << aFieldTrack.GetCurveLength() << G4endl;
286 if (
dbg) G4cout <<
"QuirkTransportation: end = " << aFieldTrack.GetPosition() <<
" [" << aFieldTrack.GetProperTimeOfFlight() <<
"]" << G4endl;
295 geometryStepLength = aFieldTrack.GetCurveLength();
308 if( currentMinimumStep == 0.0 )
320 currentSafety = endSafety ;
330 #ifdef G4DEBUG_TRANSPORT
331 G4cout.precision(12) ;
332 G4cout <<
"***QuirkTransportation::AlongStepGPIL ** " << G4endl ;
334 <<
" and it returned safety= " << endSafety << G4endl ;
336 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
343 fieldMgr->SetChordFinder(oldChordFinder);
345 return geometryStepLength ;
357 static std::atomic<G4int> noCalls=0;
382 G4double restMass =
track.GetDynamicParticle()->GetMass() ;
383 G4double deltaProperTime = deltaTime*( restMass/
track.GetTotalEnergy() ) ;
409 G4cout <<
" QuirkTransportation is killing track that is looping or stuck "
412 <<
" MeV energy." << G4endl;
414 <<
" No of calls to AlongStepDoIt = " << noCalls
424 G4cout <<
" QuirkTransportation::AlongStepDoIt(): Particle looping - "
426 <<
" No of calls to = " << noCalls
455 G4ForceCondition* pForceCond )
457 *pForceCond = Forced ;
467 G4TouchableHandle retCurrentTouchable ;
468 G4bool isLastStep=
false;
487 LocateGlobalPointAndUpdateTouchableHandle(
track.GetPosition(),
488 track.GetMomentumDirection(),
497 G4cout <<
"QuirkTransportation: number of steps = " <<
track.GetCurrentStepNumber() << G4endl;
506 #ifdef G4DEBUG_TRANSPORT
510 if( ! (exiting || entering) ) {
511 G4cout <<
" Transport> : Proposed isLastStep= " << isLastStep
530 retCurrentTouchable =
track.GetTouchableHandle() ;
533 #ifdef G4DEBUG_TRANSPORT
535 G4cout <<
" Transport> Proposed isLastStep= " << isLastStep
536 <<
" Geometry did not limit step. " << G4endl;
542 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
543 G4Material* pNewMaterial = 0 ;
544 G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
548 pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
549 pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
558 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
561 pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
564 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
568 pNewMaterialCutsCouple =
569 G4ProductionCutsTable::GetProductionCutsTable()
570 ->GetMaterialCutsCouple(pNewMaterial,
571 pNewMaterialCutsCouple->GetProductionCuts());
573 m_particleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
592 G4VProcess::StartTracking(aTrack);
618 G4FieldManagerStore::GetInstance()->ClearAllChordFindersState();
626 const_cast<G4ParticleDefinition*
>(aTrack->GetParticleDefinition());
627 Quirk* quirkDef =
dynamic_cast<Quirk*
>(part_nc);
629 G4Exception(
"QuirkTransportation::StartTracking",
"NonQuirk", FatalErrorInArgument,
"QuirkTransportation run on non-quirk particle");