Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Member Functions
G4Transportation Class Reference

#include <G4Transportation.hh>

Inheritance diagram for G4Transportation:
G4VProcess

Public Member Functions

 G4Transportation (G4int verbosityLevel=1)
 
 ~G4Transportation ()
 
G4double AlongStepGetPhysicalInteractionLength (const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &currentSafety, G4GPILSelection *selection)
 
G4VParticleChangeAlongStepDoIt (const G4Track &track, const G4Step &stepData)
 
G4VParticleChangePostStepDoIt (const G4Track &track, const G4Step &stepData)
 
G4double PostStepGetPhysicalInteractionLength (const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
 
G4PropagatorInFieldGetPropagatorInField ()
 
void SetPropagatorInField (G4PropagatorInField *pFieldPropagator)
 
void SetVerboseLevel (G4int verboseLevel)
 
G4int GetVerboseLevel () const
 
G4double GetThresholdWarningEnergy () const
 
G4double GetThresholdImportantEnergy () const
 
G4int GetThresholdTrials () const
 
void SetThresholdWarningEnergy (G4double newEnWarn)
 
void SetThresholdImportantEnergy (G4double newEnImp)
 
void SetThresholdTrials (G4int newMaxTrials)
 
G4double GetMaxEnergyKilled () const
 
G4double GetSumEnergyKilled () const
 
void ResetKilledStatistics (G4int report=1)
 
void EnableShortStepOptimisation (G4bool optimise=true)
 
G4bool EnableUseMagneticMoment (G4bool useMoment=true)
 
G4double AtRestGetPhysicalInteractionLength (const G4Track &, G4ForceCondition *)
 
G4VParticleChangeAtRestDoIt (const G4Track &, const G4Step &)
 
void StartTracking (G4Track *aTrack)
 
- Public Member Functions inherited from G4VProcess
 G4VProcess (const G4String &aName="NoName", G4ProcessType aType=fNotDefined)
 
 G4VProcess (const G4VProcess &right)
 
virtual ~G4VProcess ()
 
G4int operator== (const G4VProcess &right) const
 
G4int operator!= (const G4VProcess &right) const
 
G4double GetCurrentInteractionLength () const
 
void SetPILfactor (G4double value)
 
G4double GetPILfactor () const
 
G4double AlongStepGPIL (const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &proposedSafety, G4GPILSelection *selection)
 
G4double AtRestGPIL (const G4Track &track, G4ForceCondition *condition)
 
G4double PostStepGPIL (const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
 
virtual G4bool IsApplicable (const G4ParticleDefinition &)
 
virtual void BuildPhysicsTable (const G4ParticleDefinition &)
 
virtual void PreparePhysicsTable (const G4ParticleDefinition &)
 
virtual G4bool StorePhysicsTable (const G4ParticleDefinition *, const G4String &, G4bool)
 
virtual G4bool RetrievePhysicsTable (const G4ParticleDefinition *, const G4String &, G4bool)
 
const G4StringGetPhysicsTableFileName (const G4ParticleDefinition *, const G4String &directory, const G4String &tableName, G4bool ascii=false)
 
const G4StringGetProcessName () const
 
G4ProcessType GetProcessType () const
 
void SetProcessType (G4ProcessType)
 
G4int GetProcessSubType () const
 
void SetProcessSubType (G4int)
 
virtual void EndTracking ()
 
virtual void SetProcessManager (const G4ProcessManager *)
 
virtual const G4ProcessManagerGetProcessManager ()
 
virtual void ResetNumberOfInteractionLengthLeft ()
 
G4double GetNumberOfInteractionLengthLeft () const
 
G4double GetTotalNumberOfInteractionLengthTraversed () const
 
G4bool isAtRestDoItIsEnabled () const
 
G4bool isAlongStepDoItIsEnabled () const
 
G4bool isPostStepDoItIsEnabled () const
 
virtual void DumpInfo () const
 
void SetVerboseLevel (G4int value)
 
G4int GetVerboseLevel () const
 
virtual void SetMasterProcess (G4VProcess *masterP)
 
const G4VProcessGetMasterProcess () const
 
virtual void BuildWorkerPhysicsTable (const G4ParticleDefinition &part)
 
virtual void PrepareWorkerPhysicsTable (const G4ParticleDefinition &)
 

Protected Member Functions

G4bool DoesGlobalFieldExist ()
 
- Protected Member Functions inherited from G4VProcess
void SubtractNumberOfInteractionLengthLeft (G4double previousStepSize)
 
void ClearNumberOfInteractionLengthLeft ()
 

Additional Inherited Members

- Static Public Member Functions inherited from G4VProcess
static const G4StringGetProcessTypeName (G4ProcessType)
 
- Protected Attributes inherited from G4VProcess
const G4ProcessManageraProcessManager
 
G4VParticleChangepParticleChange
 
G4ParticleChange aParticleChange
 
G4double theNumberOfInteractionLengthLeft
 
G4double currentInteractionLength
 
G4double theInitialNumberOfInteractionLength
 
G4String theProcessName
 
G4String thePhysicsTableFileName
 
G4ProcessType theProcessType
 
G4int theProcessSubType
 
G4double thePILfactor
 
G4bool enableAtRestDoIt
 
G4bool enableAlongStepDoIt
 
G4bool enablePostStepDoIt
 
G4int verboseLevel
 

Detailed Description

Definition at line 58 of file G4Transportation.hh.

Constructor & Destructor Documentation

G4Transportation::G4Transportation ( G4int  verbosityLevel = 1)

Definition at line 78 of file G4Transportation.cc.

References G4cout, G4endl, G4ThreadLocal, G4TransportationManager::GetNavigatorForTracking(), G4TransportationManager::GetPropagatorInField(), G4TransportationManager::GetSafetyHelper(), G4TransportationManager::GetTransportationManager(), G4VProcess::SetProcessSubType(), and TRANSPORTATION.

79  : G4VProcess( G4String("Transportation"), fTransportation ),
80  fTransportEndPosition( 0.0, 0.0, 0.0 ),
81  fTransportEndMomentumDir( 0.0, 0.0, 0.0 ),
82  fTransportEndKineticEnergy( 0.0 ),
83  fTransportEndSpin( 0.0, 0.0, 0.0 ),
84  fMomentumChanged(true),
85  fEndGlobalTimeComputed(false),
86  fCandidateEndGlobalTime(0.0),
87  fParticleIsLooping( false ),
88  fGeometryLimitedStep(true),
89  fPreviousSftOrigin( 0.,0.,0. ),
90  fPreviousSafety( 0.0 ),
91  // fParticleChange(),
92  fEndPointDistance( -1.0 ),
93  fThreshold_Warning_Energy( 100 * MeV ),
94  fThreshold_Important_Energy( 250 * MeV ),
95  fThresholdTrials( 10 ),
96  fNoLooperTrials( 0 ),
97  fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
98  fShortStepOptimisation( false ), // Old default: true (=fast short steps)
99  fUseMagneticMoment( false ),
100  fVerboseLevel( verbosity )
101 {
102  // set Process Sub Type
103  SetProcessSubType(static_cast<G4int>(TRANSPORTATION));
104 
105  G4TransportationManager* transportMgr ;
106 
108 
109  fLinearNavigator = transportMgr->GetNavigatorForTracking() ;
110 
111  fFieldPropagator = transportMgr->GetPropagatorInField() ;
112 
113  fpSafetyHelper = transportMgr->GetSafetyHelper(); // New
114 
115  // Cannot determine whether a field exists here, as it would
116  // depend on the relative order of creating the detector's
117  // field and this process. That order is not guaranted.
118  // Instead later the method DoesGlobalFieldExist() is called
119 
120  static G4ThreadLocal G4TouchableHandle* pNullTouchableHandle = 0;
121  if ( !pNullTouchableHandle) { pNullTouchableHandle = new G4TouchableHandle; }
122  fCurrentTouchableHandle = *pNullTouchableHandle;
123  // Points to (G4VTouchable*) 0
124 
125 #ifdef G4VERBOSE
126  if( fVerboseLevel > 0)
127  {
128  G4cout << " G4Transportation constructor> set fShortStepOptimisation to ";
129  if ( fShortStepOptimisation ) G4cout << "true" << G4endl;
130  else G4cout << "false" << G4endl;
131  }
132 #endif
133 }
G4SafetyHelper * GetSafetyHelper() const
G4VProcess(const G4String &aName="NoName", G4ProcessType aType=fNotDefined)
Definition: G4VProcess.cc:52
G4Navigator * GetNavigatorForTracking() const
#define G4ThreadLocal
Definition: tls.hh:52
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4GLOB_DLL std::ostream G4cout
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:432
static G4TransportationManager * GetTransportationManager()
#define G4endl
Definition: G4ios.hh:61
G4PropagatorInField * GetPropagatorInField() const
G4Transportation::~G4Transportation ( )

Definition at line 137 of file G4Transportation.cc.

References G4cout, and G4endl.

138 {
139  if( (fVerboseLevel > 0) && (fSumEnergyKilled > 0.0 ) )
140  {
141  G4cout << " G4Transportation: Statistics for looping particles " << G4endl;
142  G4cout << " Sum of energy of loopers killed: " << fSumEnergyKilled << G4endl;
143  G4cout << " Max energy of loopers killed: " << fMaxEnergyKilled << G4endl;
144  }
145 }
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61

Member Function Documentation

G4VParticleChange * G4Transportation::AlongStepDoIt ( const G4Track track,
const G4Step stepData 
)
virtual

Implements G4VProcess.

Definition at line 505 of file G4Transportation.cc.

References fStopAndKill, G4cout, G4endl, G4ThreadLocal, G4Track::GetDynamicParticle(), G4Track::GetGlobalTime(), G4Track::GetKineticEnergy(), G4Track::GetLocalTime(), G4DynamicParticle::GetMass(), G4Step::GetPreStepPoint(), G4Track::GetProperTime(), G4Track::GetStepLength(), G4Track::GetTotalEnergy(), G4StepPoint::GetVelocity(), G4PropagatorInField::GimmeTrajectoryVectorAndForgetIt(), G4ParticleChangeForTransport::Initialize(), python.hepunit::MeV, G4ParticleChange::ProposeEnergy(), G4ParticleChange::ProposeGlobalTime(), G4ParticleChange::ProposeLocalTime(), G4ParticleChange::ProposeMomentumDirection(), G4ParticleChange::ProposePolarization(), G4ParticleChange::ProposePosition(), G4ParticleChange::ProposeProperTime(), G4VParticleChange::ProposeTrackStatus(), G4ParticleChangeForTransport::SetMomentumChanged(), and G4ParticleChangeForTransport::SetPointerToVectorOfAuxiliaryPoints().

507 {
508  static G4ThreadLocal G4int noCalls=0;
509  noCalls++;
510 
511  fParticleChange.Initialize(track) ;
512 
513  // Code for specific process
514  //
515  fParticleChange.ProposePosition(fTransportEndPosition) ;
516  fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir) ;
517  fParticleChange.ProposeEnergy(fTransportEndKineticEnergy) ;
518  fParticleChange.SetMomentumChanged(fMomentumChanged) ;
519 
520  fParticleChange.ProposePolarization(fTransportEndSpin);
521 
522  G4double deltaTime = 0.0 ;
523 
524  // Calculate Lab Time of Flight (ONLY if field Equations used it!)
525  // G4double endTime = fCandidateEndGlobalTime;
526  // G4double delta_time = endTime - startTime;
527 
528  G4double startTime = track.GetGlobalTime() ;
529 
530  if (!fEndGlobalTimeComputed)
531  {
532  // The time was not integrated .. make the best estimate possible
533  //
534  G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity();
535  G4double stepLength = track.GetStepLength();
536 
537  deltaTime= 0.0; // in case initialVelocity = 0
538  if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; }
539 
540  fCandidateEndGlobalTime = startTime + deltaTime ;
541  fParticleChange.ProposeLocalTime( track.GetLocalTime() + deltaTime) ;
542  }
543  else
544  {
545  deltaTime = fCandidateEndGlobalTime - startTime ;
546  fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ;
547  }
548 
549 
550  // Now Correct by Lorentz factor to get delta "proper" Time
551 
552  G4double restMass = track.GetDynamicParticle()->GetMass() ;
553  G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
554 
555  fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
556  //fParticleChange. ProposeTrueStepLength( track.GetStepLength() ) ;
557 
558  // If the particle is caught looping or is stuck (in very difficult
559  // boundaries) in a magnetic field (doing many steps)
560  // THEN this kills it ...
561  //
562  if ( fParticleIsLooping )
563  {
564  G4double endEnergy= fTransportEndKineticEnergy;
565 
566  if( (endEnergy < fThreshold_Important_Energy)
567  || (fNoLooperTrials >= fThresholdTrials ) )
568  {
569  // Kill the looping particle
570  //
571  fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
572 
573  // 'Bare' statistics
574  fSumEnergyKilled += endEnergy;
575  if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
576 
577 #ifdef G4VERBOSE
578  if( (fVerboseLevel > 1) &&
579  ( endEnergy > fThreshold_Warning_Energy ) )
580  {
581  G4cout << " G4Transportation is killing track that is looping or stuck "
582  << G4endl
583  << " This track has " << track.GetKineticEnergy() / MeV
584  << " MeV energy." << G4endl;
585  G4cout << " Number of trials = " << fNoLooperTrials
586  << " No of calls to AlongStepDoIt = " << noCalls
587  << G4endl;
588  }
589 #endif
590  fNoLooperTrials=0;
591  }
592  else
593  {
594  fNoLooperTrials ++;
595 #ifdef G4VERBOSE
596  if( (fVerboseLevel > 2) )
597  {
598  G4cout << " G4Transportation::AlongStepDoIt(): Particle looping - "
599  << " Number of trials = " << fNoLooperTrials
600  << " No of calls to = " << noCalls
601  << G4endl;
602  }
603 #endif
604  }
605  }
606  else
607  {
608  fNoLooperTrials=0;
609  }
610 
611  // Another (sometimes better way) is to use a user-limit maximum Step size
612  // to alleviate this problem ..
613 
614  // Introduce smooth curved trajectories to particle-change
615  //
617  (fFieldPropagator->GimmeTrajectoryVectorAndForgetIt() );
618 
619  return &fParticleChange ;
620 }
G4double GetLocalTime() const
G4double GetProperTime() const
std::vector< G4ThreeVector > * GimmeTrajectoryVectorAndForgetIt() const
const G4DynamicParticle * GetDynamicParticle() const
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
G4double GetVelocity() const
#define G4ThreadLocal
Definition: tls.hh:52
int G4int
Definition: G4Types.hh:78
void ProposePosition(G4double x, G4double y, G4double z)
G4StepPoint * GetPreStepPoint() const
virtual void Initialize(const G4Track &)
G4double GetKineticEnergy() const
G4GLOB_DLL std::ostream G4cout
G4double GetMass() const
G4double GetGlobalTime() const
void ProposeProperTime(G4double finalProperTime)
void SetPointerToVectorOfAuxiliaryPoints(std::vector< G4ThreeVector > *theNewVectorPointer)
void ProposeGlobalTime(G4double t)
void ProposeEnergy(G4double finalEnergy)
G4double GetTotalEnergy() const
#define G4endl
Definition: G4ios.hh:61
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
double G4double
Definition: G4Types.hh:76
void ProposeTrackStatus(G4TrackStatus status)
void SetMomentumChanged(G4bool b)
void ProposeLocalTime(G4double t)
G4double GetStepLength() const
G4double G4Transportation::AlongStepGetPhysicalInteractionLength ( const G4Track track,
G4double  previousStepSize,
G4double  currentMinimumStep,
G4double currentSafety,
G4GPILSelection selection 
)
virtual

Implements G4VProcess.

Definition at line 155 of file G4Transportation.cc.

References CandidateForSelection, G4Navigator::ComputeSafety(), G4PropagatorInField::ComputeStep(), G4Navigator::ComputeStep(), G4FieldManager::ConfigureForTrack(), G4FieldManager::DoesFieldChangeEnergy(), G4PropagatorInField::FindAndSetFieldManager(), G4cerr, G4cout, G4endl, G4ThreadLocal, G4DynamicParticle::GetCharge(), G4PropagatorInField::GetChordFinder(), G4PropagatorInField::GetCurrentFieldManager(), G4DynamicParticle::GetDefinition(), G4FieldManager::GetDetectorField(), G4Track::GetDynamicParticle(), G4Track::GetGlobalTime(), G4ChordFinder::GetIntegrationDriver(), G4FieldTrack::GetKineticEnergy(), G4Track::GetKineticEnergy(), G4FieldTrack::GetLabTimeOfFlight(), G4DynamicParticle::GetMagneticMoment(), G4FieldTrack::GetMomentumDir(), G4DynamicParticle::GetMomentumDirection(), G4Track::GetMomentumDirection(), G4ParticleDefinition::GetPDGMass(), G4ParticleDefinition::GetPDGSpin(), G4Track::GetPolarization(), G4FieldTrack::GetPosition(), G4Track::GetPosition(), G4Track::GetProperTime(), G4FieldTrack::GetSpin(), G4MagInt_Driver::GetStepper(), G4DynamicParticle::GetTotalMomentum(), G4Track::GetVelocity(), G4Track::GetVolume(), G4Field::IsGravityActive(), G4PropagatorInField::IsParticleLooping(), CLHEP::Hep3Vector::mag2(), python.hepunit::MeV, python.hepunit::perMillion, python.hepunit::perThousand, G4VParticleChange::ProposeTrueStepLength(), G4EquationOfMotion::SetChargeMomentumMass(), G4SafetyHelper::SetCurrentSafety(), and sqr().

160 {
161  G4double geometryStepLength= -1.0, newSafety= -1.0;
162  fParticleIsLooping = false ;
163 
164  // Initial actions moved to StartTrack()
165  // --------------------------------------
166  // Note: in case another process changes touchable handle
167  // it will be necessary to add here (for all steps)
168  // fCurrentTouchableHandle = aTrack->GetTouchableHandle();
169 
170  // GPILSelection is set to defaule value of CandidateForSelection
171  // It is a return value
172  //
173  *selection = CandidateForSelection ;
174 
175  // Get initial Energy/Momentum of the track
176  //
177  const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
178  const G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ;
179  G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection() ;
180  G4ThreeVector startPosition = track.GetPosition() ;
181 
182  // G4double theTime = track.GetGlobalTime() ;
183 
184  // The Step Point safety can be limited by other geometries and/or the
185  // assumptions of any process - it's not always the geometrical safety.
186  // We calculate the starting point's isotropic safety here.
187  //
188  G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
189  G4double MagSqShift = OriginShift.mag2() ;
190  if( MagSqShift >= sqr(fPreviousSafety) )
191  {
192  currentSafety = 0.0 ;
193  }
194  else
195  {
196  currentSafety = fPreviousSafety - std::sqrt(MagSqShift) ;
197  }
198 
199  // Is the particle charged or has it a magnetic moment?
200  //
201  G4double particleCharge = pParticle->GetCharge() ;
202  G4double magneticMoment = pParticle->GetMagneticMoment() ;
203  G4double restMass = pParticleDef->GetPDGMass() ;
204 
205  fGeometryLimitedStep = false ;
206  // fEndGlobalTimeComputed = false ;
207 
208  // There is no need to locate the current volume. It is Done elsewhere:
209  // On track construction
210  // By the tracking, after all AlongStepDoIts, in "Relocation"
211 
212  // Check if the particle has a force, EM or gravitational, exerted on it
213  //
214  G4FieldManager* fieldMgr=0;
215  G4bool fieldExertsForce = false ;
216 
217  G4bool gravityOn = false;
218  G4bool fieldExists= false; // Field is not 0 (null pointer)
219 
220  fieldMgr = fFieldPropagator->FindAndSetFieldManager( track.GetVolume() );
221  if( fieldMgr != 0 )
222  {
223  // Message the field Manager, to configure it for this track
224  fieldMgr->ConfigureForTrack( &track );
225  // Is here to allow a transition from no-field pointer
226  // to finite field (non-zero pointer).
227 
228  // If the field manager has no field ptr, the field is zero
229  // by definition ( = there is no field ! )
230  const G4Field* ptrField= fieldMgr->GetDetectorField();
231  fieldExists = (ptrField!=0) ;
232  if( fieldExists )
233  {
234  gravityOn= ptrField->IsGravityActive();
235 
236  if( (particleCharge != 0.0)
237  || (fUseMagneticMoment && (magneticMoment != 0.0) )
238  || (gravityOn && (restMass != 0.0) )
239  )
240  {
241  fieldExertsForce = fieldExists;
242  }
243  }
244  }
245  // G4cout << " G4Transport: field exerts force= " << fieldExertsForce
246  // << " fieldMgr= " << fieldMgr << G4endl;
247 
248  if( !fieldExertsForce )
249  {
250  G4double linearStepLength ;
251  if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) )
252  {
253  // The Step is guaranteed to be taken
254  //
255  geometryStepLength = currentMinimumStep ;
256  fGeometryLimitedStep = false ;
257  }
258  else
259  {
260  // Find whether the straight path intersects a volume
261  //
262  linearStepLength = fLinearNavigator->ComputeStep( startPosition,
263  startMomentumDir,
264  currentMinimumStep,
265  newSafety) ;
266  // Remember last safety origin & value.
267  //
268  fPreviousSftOrigin = startPosition ;
269  fPreviousSafety = newSafety ;
270  fpSafetyHelper->SetCurrentSafety( newSafety, startPosition);
271 
272  currentSafety = newSafety ;
273 
274  fGeometryLimitedStep= (linearStepLength <= currentMinimumStep);
275  if( fGeometryLimitedStep )
276  {
277  // The geometry limits the Step size (an intersection was found.)
278  geometryStepLength = linearStepLength ;
279  }
280  else
281  {
282  // The full Step is taken.
283  geometryStepLength = currentMinimumStep ;
284  }
285  }
286  fEndPointDistance = geometryStepLength ;
287 
288  // Calculate final position
289  //
290  fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ;
291 
292  // Momentum direction, energy and polarisation are unchanged by transport
293  //
294  fTransportEndMomentumDir = startMomentumDir ;
295  fTransportEndKineticEnergy = track.GetKineticEnergy() ;
296  fTransportEndSpin = track.GetPolarization();
297  fParticleIsLooping = false ;
298  fMomentumChanged = false ;
299  fEndGlobalTimeComputed = false ;
300  }
301  else // A field exerts force
302  {
303  G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
304  G4ThreeVector EndUnitMomentum ;
305  G4double lengthAlongCurve ;
306 
307  G4ChargeState chargeState(particleCharge, // The charge can change (dynamic)
308  pParticleDef->GetPDGSpin(),
309  magneticMoment);
310 
311  G4EquationOfMotion* equationOfMotion =
312  (fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())
313  ->GetEquationOfMotion();
314 
315 // equationOfMotion->SetChargeMomentumMass( particleCharge,
316  equationOfMotion->SetChargeMomentumMass( chargeState,
317  momentumMagnitude,
318  restMass);
319 
320  G4ThreeVector spin = track.GetPolarization() ;
321  G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
322  track.GetMomentumDirection(),
323  0.0,
324  track.GetKineticEnergy(),
325  restMass,
326  track.GetVelocity(),
327  track.GetGlobalTime(), // Lab.
328  track.GetProperTime(), // Part.
329  &spin ) ;
330  if( currentMinimumStep > 0 )
331  {
332  // Do the Transport in the field (non recti-linear)
333  //
334  lengthAlongCurve = fFieldPropagator->ComputeStep( aFieldTrack,
335  currentMinimumStep,
336  currentSafety,
337  track.GetVolume() ) ;
338  fGeometryLimitedStep= lengthAlongCurve < currentMinimumStep;
339  if( fGeometryLimitedStep )
340  {
341  geometryStepLength = lengthAlongCurve ;
342  }
343  else
344  {
345  geometryStepLength = currentMinimumStep ;
346  }
347 
348  // Remember last safety origin & value.
349  //
350  fPreviousSftOrigin = startPosition ;
351  fPreviousSafety = currentSafety ;
352  fpSafetyHelper->SetCurrentSafety( currentSafety, startPosition);
353  }
354  else
355  {
356  geometryStepLength = lengthAlongCurve= 0.0 ;
357  fGeometryLimitedStep = false ;
358  }
359 
360  // Get the End-Position and End-Momentum (Dir-ection)
361  //
362  fTransportEndPosition = aFieldTrack.GetPosition() ;
363 
364  // Momentum: Magnitude and direction can be changed too now ...
365  //
366  fMomentumChanged = true ;
367  fTransportEndMomentumDir = aFieldTrack.GetMomentumDir() ;
368 
369  fTransportEndKineticEnergy = aFieldTrack.GetKineticEnergy() ;
370 
371  if( fFieldPropagator->GetCurrentFieldManager()->DoesFieldChangeEnergy() )
372  {
373  // If the field can change energy, then the time must be integrated
374  // - so this should have been updated
375  //
376  fCandidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight();
377  fEndGlobalTimeComputed = true;
378 
379  // was ( fCandidateEndGlobalTime != track.GetGlobalTime() );
380  // a cleaner way is to have FieldTrack knowing whether time is updated.
381  }
382  else
383  {
384  // The energy should be unchanged by field transport,
385  // - so the time changed will be calculated elsewhere
386  //
387  fEndGlobalTimeComputed = false;
388 
389  // Check that the integration preserved the energy
390  // - and if not correct this!
391  G4double startEnergy= track.GetKineticEnergy();
392  G4double endEnergy= fTransportEndKineticEnergy;
393 
394  static G4ThreadLocal G4int no_inexact_steps=0, no_large_ediff;
395  G4double absEdiff = std::fabs(startEnergy- endEnergy);
396  if( absEdiff > perMillion * endEnergy )
397  {
398  no_inexact_steps++;
399  // Possible statistics keeping here ...
400  }
401  if( fVerboseLevel > 1 )
402  {
403  if( std::fabs(startEnergy- endEnergy) > perThousand * endEnergy )
404  {
405  static G4ThreadLocal G4int no_warnings= 0, warnModulo=1,
406  moduloFactor= 10;
407  no_large_ediff ++;
408  if( (no_large_ediff% warnModulo) == 0 )
409  {
410  no_warnings++;
411  G4cout << "WARNING - G4Transportation::AlongStepGetPIL() "
412  << " Energy change in Step is above 1^-3 relative value. " << G4endl
413  << " Relative change in 'tracking' step = "
414  << std::setw(15) << (endEnergy-startEnergy)/startEnergy << G4endl
415  << " Starting E= " << std::setw(12) << startEnergy / MeV << " MeV " << G4endl
416  << " Ending E= " << std::setw(12) << endEnergy / MeV << " MeV " << G4endl;
417  G4cout << " Energy has been corrected -- however, review"
418  << " field propagation parameters for accuracy." << G4endl;
419  if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) )
420  {
421  G4cout << " These include EpsilonStepMax(/Min) in G4FieldManager "
422  << " which determine fractional error per step for integrated quantities. " << G4endl
423  << " Note also the influence of the permitted number of integration steps."
424  << G4endl;
425  }
426  G4cerr << "ERROR - G4Transportation::AlongStepGetPIL()" << G4endl
427  << " Bad 'endpoint'. Energy change detected"
428  << " and corrected. "
429  << " Has occurred already "
430  << no_large_ediff << " times." << G4endl;
431  if( no_large_ediff == warnModulo * moduloFactor )
432  {
433  warnModulo *= moduloFactor;
434  }
435  }
436  }
437  } // end of if (fVerboseLevel)
438 
439  // Correct the energy for fields that conserve it
440  // This - hides the integration error
441  // - but gives a better physical answer
442  fTransportEndKineticEnergy= track.GetKineticEnergy();
443  }
444 
445  fTransportEndSpin = aFieldTrack.GetSpin();
446  fParticleIsLooping = fFieldPropagator->IsParticleLooping() ;
447  fEndPointDistance = (fTransportEndPosition - startPosition).mag() ;
448  }
449 
450  // If we are asked to go a step length of 0, and we are on a boundary
451  // then a boundary will also limit the step -> we must flag this.
452  //
453  if( currentMinimumStep == 0.0 )
454  {
455  if( currentSafety == 0.0 ) { fGeometryLimitedStep = true; }
456  }
457 
458  // Update the safety starting from the end-point,
459  // if it will become negative at the end-point.
460  //
461  if( currentSafety < fEndPointDistance )
462  {
463  if( particleCharge != 0.0 )
464  {
465  G4double endSafety =
466  fLinearNavigator->ComputeSafety( fTransportEndPosition) ;
467  currentSafety = endSafety ;
468  fPreviousSftOrigin = fTransportEndPosition ;
469  fPreviousSafety = currentSafety ;
470  fpSafetyHelper->SetCurrentSafety( currentSafety, fTransportEndPosition);
471 
472  // Because the Stepping Manager assumes it is from the start point,
473  // add the StepLength
474  //
475  currentSafety += fEndPointDistance ;
476 
477 #ifdef G4DEBUG_TRANSPORT
478  G4cout.precision(12) ;
479  G4cout << "***G4Transportation::AlongStepGPIL ** " << G4endl ;
480  G4cout << " Called Navigator->ComputeSafety at " << fTransportEndPosition
481  << " and it returned safety= " << endSafety << G4endl ;
482  G4cout << " Adding endpoint distance " << fEndPointDistance
483  << " to obtain pseudo-safety= " << currentSafety << G4endl ;
484  }
485  else
486  {
487  G4cout << "***G4Transportation::AlongStepGPIL ** " << G4endl ;
488  G4cout << " Avoiding call to ComputeSafety : " << G4endl;
489  G4cout << " charge = " << particleCharge << G4endl;
490  G4cout << " mag moment = " << magneticMoment << G4endl;
491 #endif
492  }
493  }
494 
495  fParticleChange.ProposeTrueStepLength(geometryStepLength) ;
496 
497  return geometryStepLength ;
498 }
const G4ThreeVector & GetPolarization() const
virtual void SetChargeMomentumMass(G4ChargeState particleCharge, G4double MomentumXc, G4double MassXc2)=0
G4double GetProperTime() const
G4double GetVelocity() const
G4double GetKineticEnergy() const
const G4DynamicParticle * GetDynamicParticle() const
const G4MagIntegratorStepper * GetStepper() const
const G4ThreeVector & GetPosition() const
const G4ThreeVector & GetMomentumDir() const
G4ThreeVector GetSpin() const
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
Definition: G4Navigator.cc:701
float perThousand
Definition: hepunit.py:240
G4ParticleDefinition * GetDefinition() const
#define G4ThreadLocal
Definition: tls.hh:52
int G4int
Definition: G4Types.hh:78
G4double GetTotalMomentum() const
virtual void ConfigureForTrack(const G4Track *)
G4double GetKineticEnergy() const
G4ThreeVector GetPosition() const
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
const G4ThreeVector & GetMomentumDirection() const
G4double GetCharge() const
void ProposeTrueStepLength(G4double truePathLength)
G4bool DoesFieldChangeEnergy() const
G4double GetGlobalTime() const
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=0)
const G4ThreeVector & GetMomentumDirection() const
G4double GetPDGMass() const
G4bool IsParticleLooping() const
G4double GetLabTimeOfFlight() const
G4bool IsGravityActive() const
Definition: G4Field.hh:98
G4ChordFinder * GetChordFinder()
G4FieldManager * GetCurrentFieldManager()
double mag2() const
G4VPhysicalVolume * GetVolume() const
G4double GetPDGSpin() const
void SetCurrentSafety(G4double val, const G4ThreeVector &pos)
#define G4endl
Definition: G4ios.hh:61
T sqr(const T &x)
Definition: templates.hh:145
double G4double
Definition: G4Types.hh:76
const G4Field * GetDetectorField() const
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4MagInt_Driver * GetIntegrationDriver()
G4double GetMagneticMoment() const
G4GLOB_DLL std::ostream G4cerr
float perMillion
Definition: hepunit.py:241
G4VParticleChange* G4Transportation::AtRestDoIt ( const G4Track ,
const G4Step  
)
inlinevirtual

Implements G4VProcess.

Definition at line 135 of file G4Transportation.hh.

138  {return 0;};
G4double G4Transportation::AtRestGetPhysicalInteractionLength ( const G4Track ,
G4ForceCondition  
)
inlinevirtual

Implements G4VProcess.

Definition at line 129 of file G4Transportation.hh.

132  { return -1.0; };
G4bool G4Transportation::DoesGlobalFieldExist ( )
protected

Referenced by StartTracking().

void G4Transportation::EnableShortStepOptimisation ( G4bool  optimise = true)
inline
G4bool G4Transportation::EnableUseMagneticMoment ( G4bool  useMoment = true)
inline
G4double G4Transportation::GetMaxEnergyKilled ( ) const
inline
G4PropagatorInField* G4Transportation::GetPropagatorInField ( )
G4double G4Transportation::GetSumEnergyKilled ( ) const
inline
G4double G4Transportation::GetThresholdImportantEnergy ( ) const
inline
G4int G4Transportation::GetThresholdTrials ( ) const
inline
G4double G4Transportation::GetThresholdWarningEnergy ( ) const
inline
G4int G4Transportation::GetVerboseLevel ( ) const
inline
G4VParticleChange * G4Transportation::PostStepDoIt ( const G4Track track,
const G4Step stepData 
)
virtual

Implements G4VProcess.

Definition at line 640 of file G4Transportation.cc.

References G4Navigator::EnteredDaughterVolume(), G4Navigator::ExitedMotherVolume(), fStopAndKill, G4cout, G4endl, G4VPhysicalVolume::GetLogicalVolume(), G4MaterialCutsCouple::GetMaterial(), G4LogicalVolume::GetMaterial(), G4ProductionCutsTable::GetMaterialCutsCouple(), G4LogicalVolume::GetMaterialCutsCouple(), G4Track::GetMomentumDirection(), G4Track::GetPosition(), G4MaterialCutsCouple::GetProductionCuts(), G4ProductionCutsTable::GetProductionCutsTable(), G4LogicalVolume::GetSensitiveDetector(), G4Track::GetTouchableHandle(), G4Track::GetTrackStatus(), G4VTouchable::GetVolume(), G4Navigator::LocateGlobalPointWithinVolume(), G4VParticleChange::ProposeLastStepInVolume(), G4VParticleChange::ProposeTrackStatus(), G4Navigator::SetGeometricallyLimitedStep(), G4ParticleChangeForTransport::SetMaterialCutsCoupleInTouchable(), G4ParticleChangeForTransport::SetMaterialInTouchable(), G4ParticleChangeForTransport::SetSensitiveDetectorInTouchable(), and G4ParticleChangeForTransport::SetTouchableHandle().

642 {
643  G4TouchableHandle retCurrentTouchable ; // The one to return
644  G4bool isLastStep= false;
645 
646  // Initialize ParticleChange (by setting all its members equal
647  // to corresponding members in G4Track)
648  // fParticleChange.Initialize(track) ; // To initialise TouchableChange
649 
650  fParticleChange.ProposeTrackStatus(track.GetTrackStatus()) ;
651 
652  // If the Step was determined by the volume boundary,
653  // logically relocate the particle
654 
655  if(fGeometryLimitedStep)
656  {
657  // fCurrentTouchable will now become the previous touchable,
658  // and what was the previous will be freed.
659  // (Needed because the preStepPoint can point to the previous touchable)
660 
661  fLinearNavigator->SetGeometricallyLimitedStep() ;
662  fLinearNavigator->
663  LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
664  track.GetMomentumDirection(),
665  fCurrentTouchableHandle,
666  true ) ;
667  // Check whether the particle is out of the world volume
668  // If so it has exited and must be killed.
669  //
670  if( fCurrentTouchableHandle->GetVolume() == 0 )
671  {
672  fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
673  }
674  retCurrentTouchable = fCurrentTouchableHandle ;
675  fParticleChange.SetTouchableHandle( fCurrentTouchableHandle ) ;
676 
677  // Update the Step flag which identifies the Last Step in a volume
678  isLastStep = fLinearNavigator->ExitedMotherVolume()
679  | fLinearNavigator->EnteredDaughterVolume() ;
680 
681 #ifdef G4DEBUG_TRANSPORT
682  // Checking first implementation of flagging Last Step in Volume
683  //
684  G4bool exiting = fLinearNavigator->ExitedMotherVolume();
685  G4bool entering = fLinearNavigator->EnteredDaughterVolume();
686  if( ! (exiting || entering) )
687  {
688  G4cout << " Transport> : Proposed isLastStep= " << isLastStep
689  << " Exiting " << fLinearNavigator->ExitedMotherVolume()
690  << " Entering " << fLinearNavigator->EnteredDaughterVolume()
691  << G4endl;
692  }
693 #endif
694  }
695  else // fGeometryLimitedStep is false
696  {
697  // This serves only to move the Navigator's location
698  //
699  fLinearNavigator->LocateGlobalPointWithinVolume( track.GetPosition() ) ;
700 
701  // The value of the track's current Touchable is retained.
702  // (and it must be correct because we must use it below to
703  // overwrite the (unset) one in particle change)
704  // It must be fCurrentTouchable too ??
705  //
706  fParticleChange.SetTouchableHandle( track.GetTouchableHandle() ) ;
707  retCurrentTouchable = track.GetTouchableHandle() ;
708 
709  isLastStep= false;
710 
711 #ifdef G4DEBUG_TRANSPORT
712  // Checking first implementation of flagging Last Step in Volume
713  //
714  G4cout << " Transport> Proposed isLastStep= " << isLastStep
715  << " Geometry did not limit step. " << G4endl;
716 #endif
717  } // endif ( fGeometryLimitedStep )
718 
719  fParticleChange.ProposeLastStepInVolume(isLastStep);
720 
721  const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
722  const G4Material* pNewMaterial = 0 ;
723  const G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
724 
725  if( pNewVol != 0 )
726  {
727  pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
728  pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
729  }
730 
731  // ( <const_cast> pNewMaterial ) ;
732  // ( <const_cast> pNewSensitiveDetector) ;
733 
734  fParticleChange.SetMaterialInTouchable( (G4Material *) pNewMaterial ) ;
735  fParticleChange.SetSensitiveDetectorInTouchable( (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
736 
737  const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
738  if( pNewVol != 0 )
739  {
740  pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
741  }
742 
743  if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
744  {
745  // for parametrized volume
746  //
747  pNewMaterialCutsCouple =
749  ->GetMaterialCutsCouple(pNewMaterial,
750  pNewMaterialCutsCouple->GetProductionCuts());
751  }
752  fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
753 
754  // temporarily until Get/Set Material of ParticleChange,
755  // and StepPoint can be made const.
756  // Set the touchable in ParticleChange
757  // this must always be done because the particle change always
758  // uses this value to overwrite the current touchable pointer.
759  //
760  fParticleChange.SetTouchableHandle(retCurrentTouchable) ;
761 
762  return &fParticleChange ;
763 }
void SetMaterialInTouchable(G4Material *fMaterial)
void SetTouchableHandle(const G4TouchableHandle &fTouchable)
void SetMaterialCutsCoupleInTouchable(const G4MaterialCutsCouple *fMaterialCutsCouple)
G4Material * GetMaterial() const
const G4ThreeVector & GetPosition() const
G4TrackStatus GetTrackStatus() const
void SetGeometricallyLimitedStep()
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
G4bool EnteredDaughterVolume() const
const G4TouchableHandle & GetTouchableHandle() const
static G4ProductionCutsTable * GetProductionCutsTable()
const G4ThreeVector & GetMomentumDirection() const
G4LogicalVolume * GetLogicalVolume() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
void SetSensitiveDetectorInTouchable(G4VSensitiveDetector *fSensitiveDetector)
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
Definition: G4VTouchable.cc:44
#define G4endl
Definition: G4ios.hh:61
G4bool ExitedMotherVolume() const
void ProposeLastStepInVolume(G4bool flag)
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
void ProposeTrackStatus(G4TrackStatus status)
G4ProductionCuts * GetProductionCuts() const
G4VSensitiveDetector * GetSensitiveDetector() const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
Definition: G4Navigator.cc:550
const G4Material * GetMaterial() const
G4double G4Transportation::PostStepGetPhysicalInteractionLength ( const G4Track ,
G4double  previousStepSize,
G4ForceCondition pForceCond 
)
virtual

Implements G4VProcess.

Definition at line 629 of file G4Transportation.cc.

References DBL_MAX, and Forced.

632 {
633  *pForceCond = Forced ;
634  return DBL_MAX ; // was kInfinity ; but convention now is DBL_MAX
635 }
#define DBL_MAX
Definition: templates.hh:83
void G4Transportation::ResetKilledStatistics ( G4int  report = 1)
inline
void G4Transportation::SetPropagatorInField ( G4PropagatorInField pFieldPropagator)
void G4Transportation::SetThresholdImportantEnergy ( G4double  newEnImp)
inline
void G4Transportation::SetThresholdTrials ( G4int  newMaxTrials)
inline
void G4Transportation::SetThresholdWarningEnergy ( G4double  newEnWarn)
inline
void G4Transportation::SetVerboseLevel ( G4int  verboseLevel)
inline
void G4Transportation::StartTracking ( G4Track aTrack)
virtual

Reimplemented from G4VProcess.

Definition at line 769 of file G4Transportation.cc.

References G4FieldManagerStore::ClearAllChordFindersState(), G4PropagatorInField::ClearPropagatorState(), DoesGlobalFieldExist(), G4FieldManagerStore::GetInstance(), G4Track::GetTouchableHandle(), and G4VProcess::StartTracking().

770 {
772 
773  // The actions here are those that were taken in AlongStepGPIL
774  // when track.GetCurrentStepNumber()==1
775 
776  // reset safety value and center
777  //
778  fPreviousSafety = 0.0 ;
779  fPreviousSftOrigin = G4ThreeVector(0.,0.,0.) ;
780 
781  // reset looping counter -- for motion in field
782  fNoLooperTrials= 0;
783  // Must clear this state .. else it depends on last track's value
784  // --> a better solution would set this from state of suspended track TODO ?
785  // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
786 
787  // ChordFinder reset internal state
788  //
789  if( DoesGlobalFieldExist() )
790  {
791  fFieldPropagator->ClearPropagatorState();
792  // Resets all state of field propagator class (ONLY)
793  // including safety values (in case of overlaps and to wipe for first track).
794 
795  // G4ChordFinder* chordF= fFieldPropagator->GetChordFinder();
796  // if( chordF ) chordF->ResetStepEstimate();
797  }
798 
799  // Make sure to clear the chord finders of all fields (ie managers)
800  //
802  fieldMgrStore->ClearAllChordFindersState();
803 
804  // Update the current touchable handle (from the track's)
805  //
806  fCurrentTouchableHandle = aTrack->GetTouchableHandle();
807 }
CLHEP::Hep3Vector G4ThreeVector
virtual void StartTracking(G4Track *)
Definition: G4VProcess.cc:101
G4bool DoesGlobalFieldExist()
const G4TouchableHandle & GetTouchableHandle() const
static G4FieldManagerStore * GetInstance()

The documentation for this class was generated from the following files: