Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Transportation Class Reference

#include <G4Transportation.hh>

+ Inheritance diagram for G4Transportation:

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)
 
G4bool FieldExertedForce ()
 
G4PropagatorInFieldGetPropagatorInField ()
 
void SetPropagatorInField (G4PropagatorInField *pFieldPropagator)
 
G4double GetThresholdWarningEnergy () const
 
G4double GetThresholdImportantEnergy () const
 
G4int GetThresholdTrials () const
 
void SetThresholdWarningEnergy (G4double newEnWarn)
 
void SetThresholdImportantEnergy (G4double newEnImp)
 
void SetThresholdTrials (G4int newMaxTrials)
 
void SetHighLooperThresholds ()
 
void SetLowLooperThresholds ()
 
void PushThresholdsToLogger ()
 
void ReportLooperThresholds ()
 
G4double GetMaxEnergyKilled () const
 
G4double GetSumEnergyKilled () const
 
void ResetKilledStatistics (G4int report=1)
 
void EnableShortStepOptimisation (G4bool optimise=true)
 
G4double AtRestGetPhysicalInteractionLength (const G4Track &, G4ForceCondition *)
 
G4VParticleChangeAtRestDoIt (const G4Track &, const G4Step &)
 
void StartTracking (G4Track *aTrack)
 
virtual void ProcessDescription (std::ostream &outFile) const
 
void PrintStatistics (std::ostream &outStr) const
 
- Public Member Functions inherited from G4VProcess
 G4VProcess (const G4String &aName="NoName", G4ProcessType aType=fNotDefined)
 
 G4VProcess (const G4VProcess &right)
 
virtual ~G4VProcess ()
 
G4VProcessoperator= (const G4VProcess &)=delete
 
G4bool operator== (const G4VProcess &right) const
 
G4bool operator!= (const G4VProcess &right) const
 
virtual G4VParticleChangePostStepDoIt (const G4Track &track, const G4Step &stepData)=0
 
virtual G4VParticleChangeAlongStepDoIt (const G4Track &track, const G4Step &stepData)=0
 
virtual G4VParticleChangeAtRestDoIt (const G4Track &track, const G4Step &stepData)=0
 
virtual G4double AlongStepGetPhysicalInteractionLength (const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &proposedSafety, G4GPILSelection *selection)=0
 
virtual G4double AtRestGetPhysicalInteractionLength (const G4Track &track, G4ForceCondition *condition)=0
 
virtual G4double PostStepGetPhysicalInteractionLength (const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)=0
 
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 StartTracking (G4Track *)
 
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
 
virtual void ProcessDescription (std::ostream &outfile) 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 &)
 

Static Public Member Functions

static G4bool EnableMagneticMoment (G4bool useMoment=true)
 
static G4bool EnableGravity (G4bool useGravity=true)
 
static void SetSilenceLooperWarnings (G4bool val)
 
static G4bool GetSilenceLooperWarnings ()
 
static G4bool EnableUseMagneticMoment (G4bool useMoment=true)
 
- Static Public Member Functions inherited from G4VProcess
static const G4StringGetProcessTypeName (G4ProcessType)
 

Protected Member Functions

G4bool DoesAnyFieldExist ()
 
void ReportMissingLogger (const char *methodName)
 
- Protected Member Functions inherited from G4VProcess
void SubtractNumberOfInteractionLengthLeft (G4double prevStepSize)
 
void ClearNumberOfInteractionLengthLeft ()
 

Friends

class G4CoupledTransportation
 

Additional Inherited Members

- Protected Attributes inherited from G4VProcess
const G4ProcessManageraProcessManager = nullptr
 
G4VParticleChangepParticleChange = nullptr
 
G4ParticleChange aParticleChange
 
G4double theNumberOfInteractionLengthLeft = -1.0
 
G4double currentInteractionLength = -1.0
 
G4double theInitialNumberOfInteractionLength = -1.0
 
G4String theProcessName
 
G4String thePhysicsTableFileName
 
G4ProcessType theProcessType = fNotDefined
 
G4int theProcessSubType = -1
 
G4double thePILfactor = 1.0
 
G4int verboseLevel = 0
 
G4bool enableAtRestDoIt = true
 
G4bool enableAlongStepDoIt = true
 
G4bool enablePostStepDoIt = true
 

Detailed Description

Definition at line 60 of file G4Transportation.hh.

Constructor & Destructor Documentation

◆ G4Transportation()

G4Transportation::G4Transportation ( G4int  verbosityLevel = 1)

Definition at line 69 of file G4Transportation.cc.

70 : G4VProcess( G4String("Transportation"), fTransportation ),
71 fFieldExertedForce( false ),
72 fPreviousSftOrigin( 0.,0.,0. ),
73 fPreviousSafety( 0.0 ),
74 fEndPointDistance( -1.0 ),
75 fShortStepOptimisation( false ) // Old default: true (=fast short steps)
76{
78 pParticleChange= &fParticleChange; // Required to conform to G4VProcess
79 SetVerboseLevel(verbosity);
80
81 G4TransportationManager* transportMgr ;
82
84
85 fLinearNavigator = transportMgr->GetNavigatorForTracking() ;
86
87 fFieldPropagator = transportMgr->GetPropagatorInField() ;
88
89 fpSafetyHelper = transportMgr->GetSafetyHelper(); // New
90
91 fpLogger = new G4TransportationLogger("G4Transportation", verbosity);
92
94 // Use the old defaults: Warning = 100 MeV, Important = 250 MeV, No Trials = 10;
95
97 // Should be done by Set methods in SetHighLooperThresholds -- making sure
98
99 // Cannot determine whether a field exists here, as it would
100 // depend on the relative order of creating the detector's
101 // field and this process. That order is not guaranted.
102 fAnyFieldExists= DoesAnyFieldExist();
103 // This value must be updated using DoesAnyFieldExist() at least at the
104 // start of each Run -- for now this is at the Start of every Track. TODO
105
106 static G4ThreadLocal G4TouchableHandle* pNullTouchableHandle = 0;
107 if ( !pNullTouchableHandle)
108 {
109 pNullTouchableHandle = new G4TouchableHandle;
110 }
111 fCurrentTouchableHandle = *pNullTouchableHandle;
112 // Points to (G4VTouchable*) 0
113
114
115#ifdef G4VERBOSE
116 if( verboseLevel > 0)
117 {
118 G4cout << " G4Transportation constructor> set fShortStepOptimisation to ";
119 if ( fShortStepOptimisation ) { G4cout << "true" << G4endl; }
120 else { G4cout << "false" << G4endl; }
121 }
122#endif
123}
@ fTransportation
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4TransportationManager * GetTransportationManager()
G4PropagatorInField * GetPropagatorInField() const
G4SafetyHelper * GetSafetyHelper() const
G4Navigator * GetNavigatorForTracking() const
void PushThresholdsToLogger()
G4bool DoesAnyFieldExist()
void SetVerboseLevel(G4int value)
Definition: G4VProcess.hh:412
G4int verboseLevel
Definition: G4VProcess.hh:356
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:406
G4VParticleChange * pParticleChange
Definition: G4VProcess.hh:321
#define G4ThreadLocal
Definition: tls.hh:77

◆ ~G4Transportation()

G4Transportation::~G4Transportation ( )

Definition at line 127 of file G4Transportation.cc.

128{
129 if( fSumEnergyKilled > 0.0 )
130 {
132 }
133 delete fpLogger;
134}
void PrintStatistics(std::ostream &outStr) const

Member Function Documentation

◆ AlongStepDoIt()

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

Implements G4VProcess.

Definition at line 492 of file G4Transportation.cc.

494{
495 static G4ThreadLocal G4long noCallsASDI=0;
496 const char *methodName= "AlongStepDoIt";
497 noCallsASDI++;
498
499 fParticleChange.Initialize(track) ;
500
501 // Code for specific process
502 //
503 fParticleChange.ProposePosition(fTransportEndPosition) ;
504 fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir) ;
505 fParticleChange.ProposeEnergy(fTransportEndKineticEnergy) ;
506 fParticleChange.SetMomentumChanged(fMomentumChanged) ;
507
508 fParticleChange.ProposePolarization(fTransportEndSpin);
509
510 G4double deltaTime = 0.0 ;
511
512 // Calculate Lab Time of Flight (ONLY if field Equations used it!)
513 // G4double endTime = fCandidateEndGlobalTime;
514 // G4double delta_time = endTime - startTime;
515
516 G4double startTime = track.GetGlobalTime() ;
517
518 if (!fEndGlobalTimeComputed)
519 {
520 // The time was not integrated .. make the best estimate possible
521 //
522 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity();
523 G4double stepLength = track.GetStepLength();
524
525 deltaTime= 0.0; // in case initialVelocity = 0
526 if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; }
527
528 fCandidateEndGlobalTime = startTime + deltaTime ;
529 fParticleChange.ProposeLocalTime( track.GetLocalTime() + deltaTime) ;
530 }
531 else
532 {
533 deltaTime = fCandidateEndGlobalTime - startTime ;
534 fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ;
535 }
536
537
538 // Now Correct by Lorentz factor to get delta "proper" Time
539
540 G4double restMass = track.GetDynamicParticle()->GetMass() ;
541 G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
542
543 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
544 //fParticleChange.ProposeTrueStepLength( track.GetStepLength() ) ;
545
546 // If the particle is caught looping or is stuck (in very difficult
547 // boundaries) in a magnetic field (doing many steps) THEN can kill it ...
548 //
549 if ( fParticleIsLooping )
550 {
551 G4double endEnergy= fTransportEndKineticEnergy;
552 fNoLooperTrials ++;
553 auto particleType= track.GetDynamicParticle()->GetParticleDefinition();
554
555 G4bool stable = particleType->GetPDGStable();
556 G4bool candidateForEnd = (endEnergy < fThreshold_Important_Energy)
557 || (fNoLooperTrials >= fThresholdTrials) ;
558 G4bool unstableAndKillable = !stable && ( fAbandonUnstableTrials != 0);
559 G4bool unstableForEnd = (endEnergy < fThreshold_Important_Energy)
560 && (fNoLooperTrials >= fAbandonUnstableTrials) ;
561 if( (candidateForEnd && stable) || (unstableAndKillable && unstableForEnd) )
562 {
563 // Kill the looping particle
564 //
565 fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
566 G4int particlePDG= particleType->GetPDGEncoding();
567 const G4int electronPDG= 11; // G4Electron::G4Electron()->GetPDGEncoding();
568
569 // Simple statistics
570 fSumEnergyKilled += endEnergy;
571 fSumEnerSqKilled = endEnergy * endEnergy;
572 fNumLoopersKilled++;
573
574 if( endEnergy > fMaxEnergyKilled ) {
575 fMaxEnergyKilled = endEnergy;
576 fMaxEnergyKilledPDG = particlePDG;
577 }
578 if( particleType->GetPDGEncoding() != electronPDG )
579 {
580 fSumEnergyKilled_NonElectron += endEnergy;
581 fSumEnerSqKilled_NonElectron += endEnergy * endEnergy;
582 fNumLoopersKilled_NonElectron++;
583
584 if( endEnergy > fMaxEnergyKilled_NonElectron )
585 {
586 fMaxEnergyKilled_NonElectron = endEnergy;
587 fMaxEnergyKilled_NonElecPDG = particlePDG;
588 }
589 }
590
591 if( endEnergy > fThreshold_Warning_Energy && ! fSilenceLooperWarnings )
592 {
593 fpLogger->ReportLoopingTrack( track, stepData, fNoLooperTrials,
594 noCallsASDI, methodName );
595 }
596 fNoLooperTrials=0;
597 }
598 else
599 {
600 fMaxEnergySaved = std::max( endEnergy, fMaxEnergySaved);
601 if( fNoLooperTrials == 1 ) {
602 fSumEnergySaved += endEnergy;
603 if ( !stable )
604 fSumEnergyUnstableSaved += endEnergy;
605 }
606#ifdef G4VERBOSE
607 if( verboseLevel > 2 && ! fSilenceLooperWarnings )
608 {
609 G4cout << " " << methodName
610 << " Particle is looping but is saved ..." << G4endl
611 << " Number of trials = " << fNoLooperTrials << G4endl
612 << " No of calls to = " << noCallsASDI << G4endl;
613 }
614#endif
615 }
616 }
617 else
618 {
619 fNoLooperTrials=0;
620 }
621
622 // Another (sometimes better way) is to use a user-limit maximum Step size
623 // to alleviate this problem ..
624
625 // Introduce smooth curved trajectories to particle-change
626 //
628 (fFieldPropagator->GimmeTrajectoryVectorAndForgetIt() );
629
630 return &fParticleChange ;
631}
@ fStopAndKill
double G4double
Definition: G4Types.hh:83
long G4long
Definition: G4Types.hh:87
bool G4bool
Definition: G4Types.hh:86
G4double GetMass() const
const G4ParticleDefinition * GetParticleDefinition() const
void SetPointerToVectorOfAuxiliaryPoints(std::vector< G4ThreeVector > *vec)
virtual void Initialize(const G4Track &)
void SetMomentumChanged(G4bool b)
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
void ProposePosition(G4double x, G4double y, G4double z)
void ProposeLocalTime(G4double t)
void ProposeProperTime(G4double finalProperTime)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
void ProposeGlobalTime(G4double t)
G4bool GetPDGStable() const
std::vector< G4ThreeVector > * GimmeTrajectoryVectorAndForgetIt() const
G4double GetVelocity() const
G4StepPoint * GetPreStepPoint() const
G4double GetGlobalTime() const
G4double GetProperTime() const
G4double GetLocalTime() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetStepLength() const
G4double GetTotalEnergy() const
void ReportLoopingTrack(const G4Track &track, const G4Step &stepInfo, G4int numTrials, G4long noCalls, const char *methodName) const
void ProposeTrackStatus(G4TrackStatus status)

◆ AlongStepGetPhysicalInteractionLength()

G4double G4Transportation::AlongStepGetPhysicalInteractionLength ( const G4Track track,
G4double  previousStepSize,
G4double  currentMinimumStep,
G4double currentSafety,
G4GPILSelection selection 
)
virtual

Implements G4VProcess.

Definition at line 181 of file G4Transportation.cc.

186{
187 // Initial actions moved to StartTrack()
188 // --------------------------------------
189 // Note: in case another process changes touchable handle
190 // it will be necessary to add here (for all steps)
191 // fCurrentTouchableHandle = aTrack->GetTouchableHandle();
192
193 // GPILSelection is set to defaule value of CandidateForSelection
194 // It is a return value
195 //
196 *selection = CandidateForSelection;
197
198 // Get initial Energy/Momentum of the track
199 //
200 const G4ThreeVector startPosition = track.GetPosition();
201 const G4ThreeVector startMomentumDir = track.GetMomentumDirection();
202
203 // The Step Point safety can be limited by other geometries and/or the
204 // assumptions of any process - it's not always the geometrical safety.
205 // We calculate the starting point's isotropic safety here.
206 {
207 const G4double MagSqShift = (startPosition - fPreviousSftOrigin).mag2();
208
209 if(MagSqShift >= sqr(fPreviousSafety))
210 currentSafety = 0.0;
211 else
212 currentSafety = fPreviousSafety - std::sqrt(MagSqShift);
213 }
214
215 // Is the particle charged or has it a magnetic moment?
216 //
217 const G4DynamicParticle* pParticle = track.GetDynamicParticle();
218
219 const G4double particleMass = pParticle->GetMass();
220 const G4double particleCharge = pParticle->GetCharge();
221 const G4double kineticEnergy = pParticle->GetKineticEnergy();
222
223 const G4double magneticMoment = pParticle->GetMagneticMoment();
224 const G4ThreeVector particleSpin = pParticle->GetPolarization();
225
226 // There is no need to locate the current volume. It is Done elsewhere:
227 // On track construction
228 // By the tracking, after all AlongStepDoIts, in "Relocation"
229
230 // Check if the particle has a force, EM or gravitational, exerted on it
231 //
232
233 G4bool eligibleEM =
234 (particleCharge != 0.0) || ((magneticMoment != 0.0) && fUseMagneticMoment);
235 G4bool eligibleGrav = (particleMass != 0.0) && fUseGravity;
236
237 fFieldExertedForce = false;
238
239 if(eligibleEM || eligibleGrav)
240 {
241 if(G4FieldManager* fieldMgr =
242 fFieldPropagator->FindAndSetFieldManager(track.GetVolume()))
243 {
244 // User can configure the field Manager for this track
245 fieldMgr->ConfigureForTrack(&track);
246 // Called here to allow a transition from no-field pointer
247 // to finite field (non-zero pointer).
248
249 // If the field manager has no field ptr, the field is zero
250 // by definition ( = there is no field ! )
251 if(const G4Field* ptrField = fieldMgr->GetDetectorField())
252 fFieldExertedForce =
253 eligibleEM || (eligibleGrav && ptrField->IsGravityActive());
254 }
255 }
256
257 G4double geometryStepLength = currentMinimumStep;
258
259 if(currentMinimumStep == 0.0)
260 {
261 fEndPointDistance = 0.0;
262 // flag step as geometry limited if current safety is also zero
263 fGeometryLimitedStep = (currentSafety == 0.0);
264
265 fMomentumChanged = false;
266 fParticleIsLooping = false;
267 fEndGlobalTimeComputed = false;
268 fTransportEndPosition = startPosition;
269 fTransportEndMomentumDir = startMomentumDir;
270 fTransportEndKineticEnergy = kineticEnergy;
271 fTransportEndSpin = particleSpin;
272 }
273 else if(!fFieldExertedForce)
274 {
275 fGeometryLimitedStep = false;
276 if(geometryStepLength > currentSafety || !fShortStepOptimisation)
277 {
278 const G4double linearStepLength = fLinearNavigator->ComputeStep(
279 startPosition, startMomentumDir, currentMinimumStep, currentSafety);
280
281 if(linearStepLength <= currentMinimumStep)
282 {
283 geometryStepLength = linearStepLength;
284 fGeometryLimitedStep = true;
285 }
286 // Remember last safety origin & value.
287 //
288 fPreviousSftOrigin = startPosition;
289 fPreviousSafety = currentSafety;
290 fpSafetyHelper->SetCurrentSafety(currentSafety, startPosition);
291 }
292
293 fEndPointDistance = geometryStepLength;
294
295 fMomentumChanged = false;
296 fParticleIsLooping = false;
297 fEndGlobalTimeComputed = false;
298 fTransportEndPosition =
299 startPosition + geometryStepLength * startMomentumDir;
300 fTransportEndMomentumDir = startMomentumDir;
301 fTransportEndKineticEnergy = kineticEnergy;
302 fTransportEndSpin = particleSpin;
303 }
304 else // A field exerts force
305 {
306 const auto pParticleDef = pParticle->GetDefinition();
307 const auto particlePDGSpin = pParticleDef->GetPDGSpin();
308 const auto particlePDGMagM = pParticleDef->GetPDGMagneticMoment();
309
310 auto equationOfMotion = fFieldPropagator->GetCurrentEquationOfMotion();
311
312 // The charge can change (dynamic), therefore the use of G4ChargeState
313 //
314 equationOfMotion->SetChargeMomentumMass(
315 G4ChargeState(particleCharge, magneticMoment, particlePDGSpin),
316 pParticle->GetTotalMomentum(), particleMass);
317
318 G4FieldTrack aFieldTrack(startPosition,
319 track.GetGlobalTime(), // Lab.
320 startMomentumDir, kineticEnergy, particleMass,
321 particleCharge, particleSpin, particlePDGMagM,
322 0.0, // Length along track
323 particlePDGSpin);
324
325 // Do the Transport in the field (non recti-linear)
326 //
327 const G4double lengthAlongCurve = fFieldPropagator->ComputeStep(
328 aFieldTrack, currentMinimumStep, currentSafety, track.GetVolume(),
329 kineticEnergy < fThreshold_Important_Energy);
330
331 if(lengthAlongCurve < geometryStepLength)
332 geometryStepLength = lengthAlongCurve;
333
334 // Remember last safety origin & value.
335 //
336 fPreviousSftOrigin = startPosition;
337 fPreviousSafety = currentSafety;
338 fpSafetyHelper->SetCurrentSafety(currentSafety, startPosition);
339
340 fGeometryLimitedStep = fFieldPropagator->IsLastStepInVolume();
341 //
342 // It is possible that step was reduced in PropagatorInField due to
343 // previous zero steps. To cope with case that reduced step is taken
344 // in full, we must rely on PiF to obtain this value
345
346 G4bool changesEnergy =
347 fFieldPropagator->GetCurrentFieldManager()->DoesFieldChangeEnergy();
348
349 fMomentumChanged = true;
350 fParticleIsLooping = fFieldPropagator->IsParticleLooping();
351
352 fEndGlobalTimeComputed = changesEnergy;
353 fTransportEndPosition = aFieldTrack.GetPosition();
354 fTransportEndMomentumDir = aFieldTrack.GetMomentumDir();
355
356 fEndPointDistance = (fTransportEndPosition - startPosition).mag();
357
358 // Ignore change in energy for fields that conserve energy
359 // This hides the integration error, but gives a better physical answer
360 fTransportEndKineticEnergy =
361 changesEnergy ? aFieldTrack.GetKineticEnergy() : kineticEnergy;
362 fTransportEndSpin = aFieldTrack.GetSpin();
363
364 if(fEndGlobalTimeComputed)
365 {
366 // If the field can change energy, then the time must be integrated
367 // - so this should have been updated
368 //
369 fCandidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight();
370
371 // was ( fCandidateEndGlobalTime != track.GetGlobalTime() );
372 // a cleaner way is to have FieldTrack knowing whether time is updated.
373 }
374#if defined(G4VERBOSE) || defined(G4DEBUG_TRANSPORT)
375 else
376 {
377 // The energy should be unchanged by field transport,
378 // - so the time changed will be calculated elsewhere
379 //
380 // Check that the integration preserved the energy
381 // - and if not correct this!
382 G4double startEnergy = kineticEnergy;
383 G4double endEnergy = fTransportEndKineticEnergy;
384
385 static G4ThreadLocal G4int no_inexact_steps = 0, no_large_ediff;
386 G4double absEdiff = std::fabs(startEnergy - endEnergy);
387 if(absEdiff > perMillion * endEnergy)
388 {
389 no_inexact_steps++;
390 // Possible statistics keeping here ...
391 }
392 if(verboseLevel > 1)
393 {
394 if(std::fabs(startEnergy - endEnergy) > perThousand * endEnergy)
395 {
396 static G4ThreadLocal G4int no_warnings = 0, warnModulo = 1,
397 moduloFactor = 10;
398 no_large_ediff++;
399 if((no_large_ediff % warnModulo) == 0)
400 {
401 no_warnings++;
402 std::ostringstream message;
403 message << "Energy change in Step is above 1^-3 relative value. "
404 << G4endl << " Relative change in 'tracking' step = "
405 << std::setw(15) << (endEnergy - startEnergy) / startEnergy
406 << G4endl << " Starting E= " << std::setw(12)
407 << startEnergy / MeV << " MeV " << G4endl
408 << " Ending E= " << std::setw(12) << endEnergy / MeV
409 << " MeV " << G4endl
410 << "Energy has been corrected -- however, review"
411 << " field propagation parameters for accuracy." << G4endl;
412 if((verboseLevel > 2) || (no_warnings < 4) ||
413 (no_large_ediff == warnModulo * moduloFactor))
414 {
415 message << "These include EpsilonStepMax(/Min) in G4FieldManager "
416 << G4endl
417 << "which determine fractional error per step for "
418 "integrated quantities. "
419 << G4endl
420 << "Note also the influence of the permitted number of "
421 "integration steps."
422 << G4endl;
423 }
424 message << "Bad 'endpoint'. Energy change detected and corrected."
425 << G4endl << "Has occurred already " << no_large_ediff
426 << " times.";
427 G4Exception("G4Transportation::AlongStepGetPIL()", "EnergyChange",
428 JustWarning, message);
429 if(no_large_ediff == warnModulo * moduloFactor)
430 {
431 warnModulo *= moduloFactor;
432 }
433 }
434 }
435 } // end of if (verboseLevel)
436 }
437#endif
438 }
439
440 // Update the safety starting from the end-point,
441 // if it will become negative at the end-point.
442 //
443 if(currentSafety < fEndPointDistance)
444 {
445 if(particleCharge != 0.0)
446 {
447 G4double endSafety =
448 fLinearNavigator->ComputeSafety(fTransportEndPosition);
449 currentSafety = endSafety;
450 fPreviousSftOrigin = fTransportEndPosition;
451 fPreviousSafety = currentSafety;
452 fpSafetyHelper->SetCurrentSafety(currentSafety, fTransportEndPosition);
453
454 // Because the Stepping Manager assumes it is from the start point,
455 // add the StepLength
456 //
457 currentSafety += fEndPointDistance;
458
459#ifdef G4DEBUG_TRANSPORT
460 G4cout.precision(12);
461 G4cout << "***G4Transportation::AlongStepGPIL ** " << G4endl;
462 G4cout << " Called Navigator->ComputeSafety at " << fTransportEndPosition
463 << " and it returned safety= " << endSafety << G4endl;
464 G4cout << " Adding endpoint distance " << fEndPointDistance
465 << " to obtain pseudo-safety= " << currentSafety << G4endl;
466 }
467 else
468 {
469 G4cout << "***G4Transportation::AlongStepGPIL ** " << G4endl;
470 G4cout << " Avoiding call to ComputeSafety : " << G4endl;
471 G4cout << " charge = " << particleCharge << G4endl;
472 G4cout << " mag moment = " << magneticMoment << G4endl;
473#endif
474 }
475 }
476
477 fFirstStepInVolume = fNewTrack || fLastStepInVolume;
478 fLastStepInVolume = false;
479 fNewTrack = false;
480
481 fParticleChange.ProposeFirstStepInVolume(fFirstStepInVolume);
482 fParticleChange.ProposeTrueStepLength(geometryStepLength);
483
484 return geometryStepLength;
485}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
@ CandidateForSelection
G4double GetCharge() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4double GetMagneticMoment() const
G4double GetTotalMomentum() const
const G4ThreeVector & GetPolarization() const
virtual void SetChargeMomentumMass(G4ChargeState particleCharge, G4double MomentumXc, G4double MassXc2)=0
G4bool DoesFieldChangeEnergy() const
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
Definition: G4Navigator.cc:764
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
G4FieldManager * GetCurrentFieldManager()
G4bool IsLastStepInVolume()
G4bool IsParticleLooping() const
G4EquationOfMotion * GetCurrentEquationOfMotion()
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=nullptr, G4bool canRelaxDeltaChord=false)
void SetCurrentSafety(G4double val, const G4ThreeVector &pos)
G4VPhysicalVolume * GetVolume() const
const G4ThreeVector & GetPosition() const
const G4ThreeVector & GetMomentumDirection() const
void ProposeFirstStepInVolume(G4bool flag)
void ProposeTrueStepLength(G4double truePathLength)
T sqr(const T &x)
Definition: templates.hh:128

◆ AtRestDoIt()

G4VParticleChange * G4Transportation::AtRestDoIt ( const G4Track ,
const G4Step  
)
inlinevirtual

Implements G4VProcess.

Definition at line 147 of file G4Transportation.hh.

148 { return 0; } // No operation in AtRestDoIt

◆ AtRestGetPhysicalInteractionLength()

G4double G4Transportation::AtRestGetPhysicalInteractionLength ( const G4Track ,
G4ForceCondition  
)
inlinevirtual

Implements G4VProcess.

Definition at line 143 of file G4Transportation.hh.

145 { return -1.0; } // No operation in AtRestGPIL

◆ DoesAnyFieldExist()

G4bool G4Transportation::DoesAnyFieldExist ( )
protected

Referenced by G4Transportation(), and StartTracking().

◆ EnableGravity()

G4bool G4Transportation::EnableGravity ( G4bool  useGravity = true)
static

Definition at line 827 of file G4Transportation.cc.

828{
829 G4bool lastValue= fUseGravity;
830 fUseGravity= useGravity;
831 G4CoupledTransportation::fUseGravity= useGravity;
832 return lastValue;
833}

◆ EnableMagneticMoment()

G4bool G4Transportation::EnableMagneticMoment ( G4bool  useMoment = true)
static

Definition at line 816 of file G4Transportation.cc.

817{
818 G4bool lastValue= fUseMagneticMoment;
819 fUseMagneticMoment= useMoment;
820 G4CoupledTransportation::fUseMagneticMoment= useMoment;
821 return lastValue;
822}

Referenced by EnableUseMagneticMoment().

◆ EnableShortStepOptimisation()

void G4Transportation::EnableShortStepOptimisation ( G4bool  optimise = true)
inline

◆ EnableUseMagneticMoment()

static G4bool G4Transportation::EnableUseMagneticMoment ( G4bool  useMoment = true)
inlinestatic

Definition at line 138 of file G4Transportation.hh.

139 { return EnableMagneticMoment(useMoment); } // Old name - will be deprecated
static G4bool EnableMagneticMoment(G4bool useMoment=true)

◆ FieldExertedForce()

G4bool G4Transportation::FieldExertedForce ( )
inline

Definition at line 96 of file G4Transportation.hh.

96{ return fFieldExertedForce; }

◆ GetMaxEnergyKilled()

G4double G4Transportation::GetMaxEnergyKilled ( ) const
inline

◆ GetPropagatorInField()

G4PropagatorInField * G4Transportation::GetPropagatorInField ( )

◆ GetSilenceLooperWarnings()

G4bool G4Transportation::GetSilenceLooperWarnings ( )
static

Definition at line 847 of file G4Transportation.cc.

848{
849 return fSilenceLooperWarnings;
850}

◆ GetSumEnergyKilled()

G4double G4Transportation::GetSumEnergyKilled ( ) const
inline

◆ GetThresholdImportantEnergy()

G4double G4Transportation::GetThresholdImportantEnergy ( ) const
inline

◆ GetThresholdTrials()

G4int G4Transportation::GetThresholdTrials ( ) const
inline

◆ GetThresholdWarningEnergy()

G4double G4Transportation::GetThresholdWarningEnergy ( ) const
inline

◆ PostStepDoIt()

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

Implements G4VProcess.

Definition at line 652 of file G4Transportation.cc.

654{
655 G4TouchableHandle retCurrentTouchable ; // The one to return
656 G4bool isLastStep= false;
657
658 // Initialize ParticleChange (by setting all its members equal
659 // to corresponding members in G4Track)
660 // fParticleChange.Initialize(track) ; // To initialise TouchableChange
661
662 fParticleChange.ProposeTrackStatus(track.GetTrackStatus()) ;
663
664 // If the Step was determined by the volume boundary,
665 // logically relocate the particle
666
667 if(fGeometryLimitedStep)
668 {
669 // fCurrentTouchable will now become the previous touchable,
670 // and what was the previous will be freed.
671 // (Needed because the preStepPoint can point to the previous touchable)
672
673 fLinearNavigator->SetGeometricallyLimitedStep() ;
674 fLinearNavigator->
675 LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
676 track.GetMomentumDirection(),
677 fCurrentTouchableHandle,
678 true ) ;
679 // Check whether the particle is out of the world volume
680 // If so it has exited and must be killed.
681 //
682 if( fCurrentTouchableHandle->GetVolume() == 0 )
683 {
684 fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
685 }
686 retCurrentTouchable = fCurrentTouchableHandle ;
687 fParticleChange.SetTouchableHandle( fCurrentTouchableHandle ) ;
688
689 // Update the Step flag which identifies the Last Step in a volume
690 if( !fFieldExertedForce )
691 isLastStep = fLinearNavigator->ExitedMotherVolume()
692 | fLinearNavigator->EnteredDaughterVolume() ;
693 else
694 isLastStep = fFieldPropagator->IsLastStepInVolume();
695 }
696 else // fGeometryLimitedStep is false
697 {
698 // This serves only to move the Navigator's location
699 //
700 fLinearNavigator->LocateGlobalPointWithinVolume( track.GetPosition() ) ;
701
702 // The value of the track's current Touchable is retained.
703 // (and it must be correct because we must use it below to
704 // overwrite the (unset) one in particle change)
705 // It must be fCurrentTouchable too ??
706 //
707 fParticleChange.SetTouchableHandle( track.GetTouchableHandle() ) ;
708 retCurrentTouchable = track.GetTouchableHandle() ;
709
710 isLastStep= false;
711 } // endif ( fGeometryLimitedStep )
712 fLastStepInVolume= isLastStep;
713
714 fParticleChange.ProposeFirstStepInVolume(fFirstStepInVolume);
715 fParticleChange.ProposeLastStepInVolume(isLastStep);
716
717 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
718 const G4Material* pNewMaterial = 0 ;
719 const G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
720
721 if( pNewVol != 0 )
722 {
723 pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
724 pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
725 }
726
727 fParticleChange.SetMaterialInTouchable( (G4Material *) pNewMaterial ) ;
728 fParticleChange.SetSensitiveDetectorInTouchable( (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
729
730 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
731 if( pNewVol != 0 )
732 {
733 pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
734 }
735
736 if ( pNewVol!=0 && pNewMaterialCutsCouple!=0
737 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
738 {
739 // for parametrized volume
740 //
741 pNewMaterialCutsCouple =
743 ->GetMaterialCutsCouple(pNewMaterial,
744 pNewMaterialCutsCouple->GetProductionCuts());
745 }
746 fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
747
748 // temporarily until Get/Set Material of ParticleChange,
749 // and StepPoint can be made const.
750 // Set the touchable in ParticleChange
751 // this must always be done because the particle change always
752 // uses this value to overwrite the current touchable pointer.
753 //
754 fParticleChange.SetTouchableHandle(retCurrentTouchable) ;
755
756 return &fParticleChange ;
757}
G4VSensitiveDetector * GetSensitiveDetector() const
G4Material * GetMaterial() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
const G4Material * GetMaterial() const
G4ProductionCuts * GetProductionCuts() const
void SetGeometricallyLimitedStep()
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
Definition: G4Navigator.cc:608
G4bool EnteredDaughterVolume() const
G4bool ExitedMotherVolume() const
void SetMaterialInTouchable(G4Material *fMaterial)
void SetTouchableHandle(const G4TouchableHandle &fTouchable)
void SetMaterialCutsCoupleInTouchable(const G4MaterialCutsCouple *fMaterialCutsCouple)
void SetSensitiveDetectorInTouchable(G4VSensitiveDetector *fSensitiveDetector)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4TrackStatus GetTrackStatus() const
const G4TouchableHandle & GetTouchableHandle() const
void ProposeLastStepInVolume(G4bool flag)
G4LogicalVolume * GetLogicalVolume() const
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
Definition: G4VTouchable.cc:41

◆ PostStepGetPhysicalInteractionLength()

G4double G4Transportation::PostStepGetPhysicalInteractionLength ( const G4Track ,
G4double  previousStepSize,
G4ForceCondition pForceCond 
)
virtual

Implements G4VProcess.

Definition at line 639 of file G4Transportation.cc.

643{
644 fFieldExertedForce = false; // Not known
645 *pForceCond = Forced ;
646 return DBL_MAX ; // was kInfinity ; but convention now is DBL_MAX
647}
@ Forced
#define DBL_MAX
Definition: templates.hh:62

◆ PrintStatistics()

void G4Transportation::PrintStatistics ( std::ostream &  outStr) const

Definition at line 139 of file G4Transportation.cc.

140{
141 outStr << " G4Transportation: Statistics for looping particles " << G4endl;
142 if( fSumEnergyKilled > 0.0 || fNumLoopersKilled > 0 )
143 {
144 outStr << " Sum of energy of looping tracks killed: "
145 << fSumEnergyKilled / CLHEP::MeV << " MeV "
146 << " from " << fNumLoopersKilled << " tracks " << G4endl
147 << " Sum of energy of non-electrons : "
148 << fSumEnergyKilled_NonElectron / CLHEP::MeV << " MeV "
149 << " from " << fNumLoopersKilled_NonElectron << " tracks "
150 << G4endl;
151 outStr << " Max energy of *any type* looper killed: " << fMaxEnergyKilled
152 << " its PDG was " << fMaxEnergyKilledPDG << G4endl;
153 if( fMaxEnergyKilled_NonElectron > 0.0 )
154 {
155 outStr << " Max energy of non-electron looper killed: "
156 << fMaxEnergyKilled_NonElectron
157 << " its PDG was " << fMaxEnergyKilled_NonElecPDG << G4endl;
158 }
159 if( fMaxEnergySaved > 0.0 )
160 {
161 outStr << " Max energy of loopers 'saved': " << fMaxEnergySaved << G4endl;
162 outStr << " Sum of energy of loopers 'saved': "
163 << fSumEnergySaved << G4endl;
164 outStr << " Sum of energy of unstable loopers 'saved': "
165 << fSumEnergyUnstableSaved << G4endl;
166 }
167 }
168 else
169 {
170 outStr << " No looping tracks found or killed. " << G4endl;
171 }
172}

Referenced by ~G4Transportation().

◆ ProcessDescription()

void G4Transportation::ProcessDescription ( std::ostream &  outFile) const
virtual

Reimplemented from G4VProcess.

Definition at line 906 of file G4Transportation.cc.

910{
911 G4String indent = " "; // : "");
912 G4int oldPrec= outStr.precision(6);
913 // outStr << std::setprecision(6);
914 outStr << G4endl << indent << GetProcessName() << ": ";
915
916 outStr << " Parameters for looping particles: " << G4endl
917 << " warning-E = " << fThreshold_Warning_Energy / CLHEP::MeV << " MeV " << G4endl
918 << " important E = " << fThreshold_Important_Energy / CLHEP::MeV << " MeV " << G4endl
919 << " thresholdTrials " << fThresholdTrials << G4endl;
920 outStr.precision(oldPrec);
921}
const G4String & GetProcessName() const
Definition: G4VProcess.hh:382

◆ PushThresholdsToLogger()

void G4Transportation::PushThresholdsToLogger ( )

◆ ReportLooperThresholds()

void G4Transportation::ReportLooperThresholds ( )

Definition at line 898 of file G4Transportation.cc.

899{
900 PushThresholdsToLogger(); // To be absolutely certain they are in sync
901 fpLogger->ReportLooperThresholds("G4Transportation");
902}
void ReportLooperThresholds(const char *className)

Referenced by SetHighLooperThresholds(), and SetLowLooperThresholds().

◆ ReportMissingLogger()

void G4Transportation::ReportMissingLogger ( const char *  methodName)
protected

Definition at line 887 of file G4Transportation.cc.

888{
889 const char* message= "Logger object missing from G4Transportation object";
890 G4String classAndMethod= G4String("G4Transportation") + G4String( methodName );
891 G4Exception(classAndMethod, "Missing Logger", JustWarning, message);
892}

◆ ResetKilledStatistics()

void G4Transportation::ResetKilledStatistics ( G4int  report = 1)
inline

◆ SetHighLooperThresholds()

void G4Transportation::SetHighLooperThresholds ( )

Definition at line 855 of file G4Transportation.cc.

856{
857 // Restores the old high values -- potentially appropriate for energy-frontier
858 // HEP experiments.
859 // Caution: All tracks with E < 100 MeV that are found to loop are
860 SetThresholdWarningEnergy( 100.0 * CLHEP::MeV ); // Warn above this energy
861 SetThresholdImportantEnergy( 250.0 * CLHEP::MeV ); // Extra trial above this En
862
863 G4int maxTrials = 10;
864 SetThresholdTrials( maxTrials );
865
866 PushThresholdsToLogger(); // Again, to be sure
868}
void SetThresholdImportantEnergy(G4double newEnImp)
void SetThresholdTrials(G4int newMaxTrials)
void SetThresholdWarningEnergy(G4double newEnWarn)

Referenced by G4Transportation().

◆ SetLowLooperThresholds()

void G4Transportation::SetLowLooperThresholds ( )

Definition at line 871 of file G4Transportation.cc.

872{
873 // These values were the default in Geant4 10.5 - beta
874 SetThresholdWarningEnergy( 1.0 * CLHEP::keV ); // Warn above this En
875 SetThresholdImportantEnergy( 1.0 * CLHEP::MeV ); // Extra trials above it
876
877 G4int maxTrials = 30; // A new value - was 10
878 SetThresholdTrials( maxTrials );
879
880 PushThresholdsToLogger(); // Again, to be sure
882}

◆ SetPropagatorInField()

void G4Transportation::SetPropagatorInField ( G4PropagatorInField pFieldPropagator)

◆ SetSilenceLooperWarnings()

void G4Transportation::SetSilenceLooperWarnings ( G4bool  val)
static

Definition at line 839 of file G4Transportation.cc.

840{
841 fSilenceLooperWarnings= val; // Flag to *Supress* all 'looper' warnings
842 // G4CoupledTransportation::fSilenceLooperWarnings= val;
843}

◆ SetThresholdImportantEnergy()

void G4Transportation::SetThresholdImportantEnergy ( G4double  newEnImp)
inline

◆ SetThresholdTrials()

void G4Transportation::SetThresholdTrials ( G4int  newMaxTrials)
inline

◆ SetThresholdWarningEnergy()

void G4Transportation::SetThresholdWarningEnergy ( G4double  newEnWarn)
inline

◆ StartTracking()

void G4Transportation::StartTracking ( G4Track aTrack)
virtual

Reimplemented from G4VProcess.

Definition at line 766 of file G4Transportation.cc.

767{
769 fNewTrack= true;
770 fFirstStepInVolume= true;
771 fLastStepInVolume= false;
772
773 // The actions here are those that were taken in AlongStepGPIL
774 // when track.GetCurrentStepNumber()==1
775
776 // Whether field exists should be determined at run level -- TODO
777 fAnyFieldExists= DoesAnyFieldExist();
778
779 // reset safety value and center
780 //
781 fPreviousSafety = 0.0 ;
782 fPreviousSftOrigin = G4ThreeVector(0.,0.,0.) ;
783
784 // reset looping counter -- for motion in field
785 fNoLooperTrials= 0;
786 // Must clear this state .. else it depends on last track's value
787 // --> a better solution would set this from state of suspended track TODO ?
788 // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
789
790 // ChordFinder reset internal state
791 //
792 if( fFieldPropagator && fAnyFieldExists )
793 {
794 fFieldPropagator->ClearPropagatorState();
795 // Resets all state of field propagator class (ONLY) including safety
796 // values (in case of overlaps and to wipe for first track).
797 }
798
799 // Make sure to clear the chord finders of all fields (i.e. managers)
800 //
802 fieldMgrStore->ClearAllChordFindersState();
803
804 // Update the current touchable handle (from the track's)
805 //
806 fCurrentTouchableHandle = aTrack->GetTouchableHandle();
807
808 // Inform field propagator of new track
809 //
810 fFieldPropagator->PrepareNewTrack();
811}
CLHEP::Hep3Vector G4ThreeVector
static G4FieldManagerStore * GetInstance()
virtual void StartTracking(G4Track *)
Definition: G4VProcess.cc:87

Friends And Related Function Documentation

◆ G4CoupledTransportation

friend class G4CoupledTransportation
friend

Definition at line 240 of file G4Transportation.hh.


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