CMS 3D CMS Logo

MonopoleTransportation.cc
Go to the documentation of this file.
1 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
2 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
3 //
4 // This class is a process responsible for the transportation of
5 // magnetic monopoles, ie the geometrical propagation that encounters the
6 // geometrical sub-volumes of the detectors.
7 //
8 // =======================================================================
9 // Created: 3 May 2010, J. Apostolakis, B. Bozsogi
10 // G4MonopoleTransportation class for
11 // Geant4 extended example "monopole"
12 //
13 // Adopted for CMSSW by V.Ivanchenko 30 April 2018
14 //
15 // =======================================================================
16 
21 
22 #include "G4ProductionCutsTable.hh"
23 #include "G4ParticleTable.hh"
24 #include "G4ChordFinder.hh"
25 #include "G4SafetyHelper.hh"
26 #include "G4FieldManagerStore.hh"
27 #include "G4TransportationProcessType.hh"
28 #include "G4SystemOfUnits.hh"
29 
30 class G4VSensitiveDetector;
31 
32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
33 
35  sim::ChordFinderSetter* chordFinderSetter,
36  G4int verb)
37  : G4VProcess( G4String("MonopoleTransportation"), fTransportation ),
38  fParticleDef(mpl),
39  fChordFinderSetter(chordFinderSetter),
40  fieldMgrCMS(nullptr),
41  fLinearNavigator(nullptr),
42  fFieldPropagator(nullptr),
43  fParticleIsLooping( false ),
44  fPreviousSftOrigin (0.,0.,0.),
45  fPreviousSafety ( 0.0 ),
46  fThreshold_Warning_Energy( 100 * MeV ),
47  fThreshold_Important_Energy( 250 * MeV ),
48  fThresholdTrials( 10 ),
49  fNoLooperTrials(0),
50  fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
51  fShortStepOptimisation(false), // Old default: true (=fast short steps)
52  fpSafetyHelper(nullptr)
53 {
54  verboseLevel = verb;
55 
56  // set Process Sub Type
57  SetProcessSubType(TRANSPORTATION);
58 
59 #ifdef G4MULTITHREADED
60  // Do not finalize the MonopoleTransportation class
61  if (G4Threading::IsMasterThread())
62  {
63  return;
64  }
65 #endif
66 
67  G4TransportationManager* transportMgr =
68  G4TransportationManager::GetTransportationManager();
69 
70  fLinearNavigator = transportMgr->GetNavigatorForTracking() ;
71 
72  fFieldPropagator = transportMgr->GetPropagatorInField() ;
73  fpSafetyHelper = transportMgr->GetSafetyHelper();
74 
75  // Cannot determine whether a field exists here,
76  // because it would only work if the field manager has informed
77  // about the detector's field before this transportation process
78  // is constructed.
79  // Instead later the method DoesGlobalFieldExist() is called
80 
81  fCurrentTouchableHandle = nullptr;
82 
83  fEndGlobalTimeComputed = false;
85 }
86 
87 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
88 
90 {
91  if( (verboseLevel > 0) && (fSumEnergyKilled > 0.0 ) ){
92  /*
93  G4cout << " MonopoleTransportation: Statistics for looping particles "
94  << G4endl;
95  G4cout << " Sum of energy of loopers killed: " << fSumEnergyKilled << G4endl;
96  G4cout << " Max energy of loopers killed: " << fMaxEnergyKilled << G4endl;
97  */
98  }
99 }
100 
101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
102 //
103 // Responsibilities:
104 // Find whether the geometry limits the Step, and to what length
105 // Calculate the new value of the safety and return it.
106 // Store the final time, position and momentum.
107 
110  G4double, // previousStepSize
111  G4double currentMinimumStep,
112  G4double& currentSafety,
113  G4GPILSelection* selection )
114 {
115  // change to monopole equation
117 
118  G4double geometryStepLength, newSafety ;
120 
121  // Initial actions moved to StartTrack()
122  // --------------------------------------
123  // Note: in case another process changes touchable handle
124  // it will be necessary to add here (for all steps)
125  // fCurrentTouchableHandle = aTrack->GetTouchableHandle();
126 
127  // GPILSelection is set to defaule value of CandidateForSelection
128  // It is a return value
129  //
130  *selection = CandidateForSelection ;
131 
132  // Get initial Energy/Momentum of the track
133  //
134  const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
135  const G4ThreeVector& startMomentumDir = pParticle->GetMomentumDirection() ;
136  G4ThreeVector startPosition = track.GetPosition() ;
137 
138  // The Step Point safety can be limited by other geometries and/or the
139  // assumptions of any process - it's not always the geometrical safety.
140  // We calculate the starting point's isotropic safety here.
141  //
142  G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
143  G4double MagSqShift = OriginShift.mag2() ;
144  if( MagSqShift >= sqr(fPreviousSafety) )
145  {
146  currentSafety = 0.0 ;
147  }
148  else
149  {
150  currentSafety = fPreviousSafety - std::sqrt(MagSqShift) ;
151  }
152 
153  // Is the monopole charged ?
154  //
155  G4double particleMagneticCharge = fParticleDef->MagneticCharge() ;
156  G4double particleElectricCharge = pParticle->GetCharge();
157 
159 
160  // There is no need to locate the current volume. It is Done elsewhere:
161  // On track construction
162  // By the tracking, after all AlongStepDoIts, in "Relocation"
163 
164  // Check whether the particle have an (EM) field force exerting upon it
165  G4bool fieldExertsForce = false ;
166 
167  if(particleMagneticCharge != 0.0 && fieldMgrCMS) {
168  // Message the field Manager, to configure it for this track
169  fieldMgrCMS->ConfigureForTrack( &track );
170  // Moved here, in order to allow a transition
171  // from a zero-field status (with fieldMgr->(field)0
172  // to a finite field status
173 
174  // If the field manager has no field, there is no field !
175  fieldExertsForce = (fieldMgrCMS->GetDetectorField() != nullptr);
176  }
177 
178  // G4cout << " G4Transport: field exerts force= " << fieldExertsForce
179  // << " fieldMgr= " << fieldMgr << G4endl;
180 
181  // Choose the calculation of the transportation: Field or not
182  //
183  if( !fieldExertsForce )
184  {
185  G4double linearStepLength ;
186  if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) )
187  {
188  // The Step is guaranteed to be taken
189  //
190  geometryStepLength = currentMinimumStep ;
192  }
193  else
194  {
195  // Find whether the straight path intersects a volume
196  //
197  linearStepLength = fLinearNavigator->ComputeStep( startPosition,
198  startMomentumDir,
199  currentMinimumStep,
200  newSafety) ;
201  // Remember last safety origin & value.
202  //
203  fPreviousSftOrigin = startPosition ;
204  fPreviousSafety = newSafety ;
205  // fpSafetyHelper->SetCurrentSafety( newSafety, startPosition);
206 
207  // The safety at the initial point has been re-calculated:
208  //
209  currentSafety = newSafety ;
210 
211  fGeometryLimitedStep= (linearStepLength <= currentMinimumStep);
213  {
214  // The geometry limits the Step size (an intersection was found.)
215  geometryStepLength = linearStepLength ;
216  }
217  else
218  {
219  // The full Step is taken.
220  geometryStepLength = currentMinimumStep ;
221  }
222  }
223  endpointDistance = geometryStepLength ;
224 
225  // Calculate final position
226  //
227  fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ;
228 
229  // Momentum direction, energy and polarisation are unchanged by transport
230  //
231  fTransportEndMomentumDir = startMomentumDir ;
232  fTransportEndKineticEnergy = track.GetKineticEnergy() ;
233  fTransportEndSpin = track.GetPolarization();
237  }
238  else // A field exerts force
239  {
240  G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
241  G4ThreeVector EndUnitMomentum ;
242  G4double lengthAlongCurve ;
243  G4double restMass = fParticleDef->GetPDGMass() ;
244 
245  G4ChargeState chargeState(particleElectricCharge, // The charge can change (dynamic)
246  fParticleDef->GetPDGSpin(),
247  0, // Magnetic moment: pParticleDef->GetMagneticMoment(),
248  0, // Electric Dipole moment - not in Particle Definition
249  particleMagneticCharge ); // in Mev/c
250 
251  G4EquationOfMotion* equationOfMotion =
252  fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetEquationOfMotion();
253 
254  equationOfMotion
255  ->SetChargeMomentumMass( chargeState, // Was particleMagneticCharge - in Mev/c
256  momentumMagnitude, // Was particleElectricCharge
257  restMass ) ;
258  // SetChargeMomentumMass now passes both the electric and magnetic charge - in chargeState
259 
260  G4ThreeVector spin = track.GetPolarization() ;
261  G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
262  track.GetMomentumDirection(),
263  0.0,
264  track.GetKineticEnergy(),
265  restMass,
266  track.GetVelocity(),
267  track.GetGlobalTime(), // Lab.
268  track.GetProperTime(), // Part.
269  &spin ) ;
270  if( currentMinimumStep > 0 )
271  {
272  // Do the Transport in the field (non recti-linear)
273  //
274  lengthAlongCurve = fFieldPropagator->ComputeStep( aFieldTrack,
275  currentMinimumStep,
276  currentSafety,
277  track.GetVolume() ) ;
278  fGeometryLimitedStep= lengthAlongCurve < currentMinimumStep;
279  if( fGeometryLimitedStep ) {
280  geometryStepLength = lengthAlongCurve ;
281  } else {
282  geometryStepLength = currentMinimumStep ;
283  }
284  }
285  else
286  {
287  geometryStepLength = lengthAlongCurve= 0.0 ;
289  }
290 
291  // Remember last safety origin & value.
292  //
293  fPreviousSftOrigin = startPosition ;
294  fPreviousSafety = currentSafety ;
295  // fpSafetyHelper->SetCurrentSafety( newSafety, startPosition);
296 
297  // Get the End-Position and End-Momentum (Dir-ection)
298  //
299  fTransportEndPosition = aFieldTrack.GetPosition() ;
300 
301  // Momentum: Magnitude and direction can be changed too now ...
302  //
304  fTransportEndMomentumDir = aFieldTrack.GetMomentumDir() ;
305 
306  fTransportEndKineticEnergy = aFieldTrack.GetKineticEnergy() ;
307 
308  fCandidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight();
309  fEndGlobalTimeComputed = true;
310 
311  fTransportEndSpin = aFieldTrack.GetSpin();
312  fParticleIsLooping = fFieldPropagator->IsParticleLooping() ;
313  endpointDistance = (fTransportEndPosition - startPosition).mag() ;
314  }
315 
316  // If we are asked to go a step length of 0, and we are on a boundary
317  // then a boundary will also limit the step -> we must flag this.
318  //
319  if( currentMinimumStep == 0.0 )
320  {
321  if( currentSafety == 0.0 ) fGeometryLimitedStep = true ;
322  }
323 
324  // Update the safety starting from the end-point,
325  // if it will become negative at the end-point.
326  //
327  if( currentSafety < endpointDistance )
328  {
329  // if( particleMagneticCharge == 0.0 )
330  // G4cout << " Avoiding call to ComputeSafety : charge = 0.0 " << G4endl;
331 
332  if( particleMagneticCharge != 0.0 ) {
333 
334  G4double endSafety =
335  fLinearNavigator->ComputeSafety( fTransportEndPosition) ;
336  currentSafety = endSafety ;
337  fPreviousSftOrigin = fTransportEndPosition ;
338  fPreviousSafety = currentSafety ;
339  fpSafetyHelper->SetCurrentSafety( currentSafety, fTransportEndPosition);
340 
341  // Because the Stepping Manager assumes it is from the start point,
342  // add the StepLength
343  //
344  currentSafety += endpointDistance ;
345 
346 #ifdef G4DEBUG_TRANSPORT
347  G4cout.precision(12) ;
348  G4cout << "***MonopoleTransportation::AlongStepGPIL ** " << G4endl ;
349  G4cout << " Called Navigator->ComputeSafety at " << fTransportEndPosition
350  << " and it returned safety= " << endSafety << G4endl ;
351  G4cout << " Adding endpoint distance " << endpointDistance
352  << " to obtain pseudo-safety= " << currentSafety << G4endl ;
353 #endif
354  }
355  }
356 
357  fParticleChange.ProposeTrueStepLength(geometryStepLength) ;
358 
359  return geometryStepLength ;
360 }
361 
362 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
363 //
364 // Initialize ParticleChange (by setting all its members equal
365 // to corresponding members in G4Track)
366 
367 G4VParticleChange* MonopoleTransportation::AlongStepDoIt( const G4Track& track,
368  const G4Step& stepData )
369 {
370  fParticleChange.Initialize(track) ;
371 
372  // Code for specific process
373  //
374  fParticleChange.ProposePosition(fTransportEndPosition) ;
375  fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir) ;
377  fParticleChange.SetMomentumChanged(fMomentumChanged) ;
378 
379  fParticleChange.ProposePolarization(fTransportEndSpin);
380 
381  G4double deltaTime = 0.0 ;
382 
383  // Calculate Lab Time of Flight (ONLY if field Equations used it!)
384  // G4double endTime = fCandidateEndGlobalTime;
385  // G4double delta_time = endTime - startTime;
386 
387  G4double startTime = track.GetGlobalTime() ;
388 
390  {
391  // The time was not integrated .. make the best estimate possible
392  //
393  G4double finalVelocity = track.GetVelocity() ;
394  G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity() ;
395  G4double stepLength = track.GetStepLength() ;
396 
397  deltaTime= 0.0; // in case initialVelocity = 0
398  //const G4DynamicParticle* fpDynamicParticle = track.GetDynamicParticle();
399  if (finalVelocity > 0.0)
400  {
401  G4double meanInverseVelocity ;
402  meanInverseVelocity = 0.5
403  * ( 1.0 / initialVelocity + 1.0 / finalVelocity ) ;
404  deltaTime = stepLength * meanInverseVelocity ;
405  }
406  else if( initialVelocity > 0.0 )
407  {
408  deltaTime = stepLength/initialVelocity ;
409  }
410  fCandidateEndGlobalTime = startTime + deltaTime ;
411  }
412  else
413  {
414  deltaTime = fCandidateEndGlobalTime - startTime ;
415  }
416 
417  fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ;
418 
419  // Now Correct by Lorentz factor to get "proper" deltaTime
420 
421  G4double restMass = track.GetDynamicParticle()->GetMass() ;
422  G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
423 
424  fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
425  //fParticleChange. ProposeTrueStepLength( track.GetStepLength() ) ;
426 
427  // If the particle is caught looping or is stuck (in very difficult
428  // boundaries) in a magnetic field (doing many steps)
429  // THEN this kills it ...
430  //
431  if ( fParticleIsLooping )
432  {
433  G4double endEnergy= fTransportEndKineticEnergy;
434 
435  if( (endEnergy < fThreshold_Important_Energy)
437  // Kill the looping particle
438  //
439  fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
440 
441  // 'Bare' statistics
442  fSumEnergyKilled += endEnergy;
443  if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
444 
445 #ifdef G4VERBOSE
446  if( (verboseLevel > 1) ||
447  ( endEnergy > fThreshold_Warning_Energy ) ) {
448  G4cout << " MonopoleTransportation is killing track that is looping or stuck "
449  << G4endl
450  << " This track has " << track.GetKineticEnergy() / MeV
451  << " MeV energy." << G4endl;
452  G4cout << " Number of trials = " << fNoLooperTrials
453  << " No of calls to AlongStepDoIt = " << noCalls
454  << G4endl;
455  }
456 #endif
457  fNoLooperTrials=0;
458  }
459  else{
460  fNoLooperTrials ++;
461 #ifdef G4VERBOSE
462  if( (verboseLevel > 2) ){
463  G4cout << " MonopoleTransportation::AlongStepDoIt(): Particle looping - "
464  << " Number of trials = " << fNoLooperTrials
465  << " No of calls to = " << noCalls
466  << G4endl;
467  }
468 #endif
469  }
470  }else{
471  fNoLooperTrials=0;
472  }
473 
474  // Another (sometimes better way) is to use a user-limit maximum Step size
475  // to alleviate this problem ..
476 
477  // Introduce smooth curved trajectories to particle-change
478  //
479  fParticleChange.SetPointerToVectorOfAuxiliaryPoints
480  (fFieldPropagator->GimmeTrajectoryVectorAndForgetIt() );
481 
482  return &fParticleChange ;
483 }
484 
485 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
486 //
487 // This ensures that the PostStep action is always called,
488 // so that it can do the relocation if it is needed.
489 //
490 
493  G4double, // previousStepSize
494  G4ForceCondition* pForceCond )
495 {
496  *pForceCond = Forced ;
497  return DBL_MAX ; // was kInfinity ; but convention now is DBL_MAX
498 }
499 
500 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
501 
502 G4VParticleChange* MonopoleTransportation::PostStepDoIt( const G4Track& track,
503  const G4Step& )
504 {
505  G4TouchableHandle retCurrentTouchable ; // The one to return
506 
507  fParticleChange.ProposeTrackStatus(track.GetTrackStatus()) ;
508 
509  // If the Step was determined by the volume boundary,
510  // logically relocate the particle
511 
513  {
514  // fCurrentTouchable will now become the previous touchable,
515  // and what was the previous will be freed.
516  // (Needed because the preStepPoint can point to the previous touchable)
517 
518  fLinearNavigator->SetGeometricallyLimitedStep() ;
520  LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
521  track.GetMomentumDirection(),
523  true ) ;
524  // Check whether the particle is out of the world volume
525  // If so it has exited and must be killed.
526  //
527  if( fCurrentTouchableHandle->GetVolume() == nullptr )
528  {
529  fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
530  }
531  retCurrentTouchable = fCurrentTouchableHandle ;
532  fParticleChange.SetTouchableHandle( fCurrentTouchableHandle ) ;
533  }
534  else // fGeometryLimitedStep is false
535  {
536  // This serves only to move the Navigator's location
537  //
538  fLinearNavigator->LocateGlobalPointWithinVolume( track.GetPosition() ) ;
539 
540  // The value of the track's current Touchable is retained.
541  // (and it must be correct because we must use it below to
542  // overwrite the (unset) one in particle change)
543  // It must be fCurrentTouchable too ??
544  //
545  fParticleChange.SetTouchableHandle( track.GetTouchableHandle() ) ;
546  retCurrentTouchable = track.GetTouchableHandle() ;
547  } // endif ( fGeometryLimitedStep )
548 
549  const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
550  const G4Material* pNewMaterial = nullptr ;
551  const G4VSensitiveDetector* pNewSensitiveDetector = nullptr ;
552 
553  if( pNewVol != nullptr )
554  {
555  pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
556  pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
557  }
558 
559  // ( <const_cast> pNewMaterial ) ;
560  // ( <const_cast> pNewSensitiveDetector) ;
561 
562  fParticleChange.SetMaterialInTouchable(
563  (G4Material *) pNewMaterial ) ;
564  fParticleChange.SetSensitiveDetectorInTouchable(
565  (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
566 
567  const G4MaterialCutsCouple* pNewMaterialCutsCouple = nullptr;
568  if( pNewVol != nullptr )
569  {
570  pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
571  }
572 
573  if( pNewVol!=nullptr && pNewMaterialCutsCouple!=nullptr &&
574  pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
575  {
576  // for parametrized volume
577  //
578  pNewMaterialCutsCouple =
579  G4ProductionCutsTable::GetProductionCutsTable()
580  ->GetMaterialCutsCouple(pNewMaterial,
581  pNewMaterialCutsCouple->GetProductionCuts());
582  }
583  fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
584 
585  // temporarily until Get/Set Material of ParticleChange,
586  // and StepPoint can be made const.
587  // Set the touchable in ParticleChange
588  // this must always be done because the particle change always
589  // uses this value to overwrite the current touchable pointer.
590  //
591  fParticleChange.SetTouchableHandle(retCurrentTouchable) ;
592 
593  // change to normal equation
595 
596  return &fParticleChange ;
597 }
598 
599 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
600 
601 // New method takes over the responsibility to reset the state
602 // of MonopoleTransportation object at the start of a new track
603 // or the resumption of a suspended track.
604 
605 void
607 {
608  // initialise pointer
609  if(!fieldMgrCMS) {
610  G4FieldManager* fieldMgr =
611  fFieldPropagator->FindAndSetFieldManager(aTrack->GetVolume());
612  fieldMgrCMS = static_cast<CMSFieldManager*>(fieldMgr);
613  }
614 
615  G4VProcess::StartTracking(aTrack);
616 
617  // The actions here are those that were taken in AlongStepGPIL
618  // when track.GetCurrentStepNumber()==1
619 
620  // reset safety value and center
621  //
622  fPreviousSafety = 0.0 ;
623  fPreviousSftOrigin = G4ThreeVector(0.,0.,0.) ;
624 
625  // reset looping counter -- for motion in field
626  fNoLooperTrials= 0;
627  // Must clear this state .. else it depends on last track's value
628  // --> a better solution would set this from state of suspended track TODO ?
629  // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
630 
631  // ChordFinder reset internal state
632  //
633  if( DoesGlobalFieldExist() ) {
634  fFieldPropagator->ClearPropagatorState();
635  // Resets all state of field propagator class (ONLY)
636  // including safety values (in case of overlaps and to wipe for first track).
637 
638  G4ChordFinder* chordF= fFieldPropagator->GetChordFinder();
639  if( chordF ) chordF->ResetStepEstimate();
640  }
641 
642  // Make sure to clear the chord finders of all fields (ie managers)
643  G4FieldManagerStore* fieldMgrStore= G4FieldManagerStore::GetInstance();
644  fieldMgrStore->ClearAllChordFindersState();
645 
646  // Update the current touchable handle (from the track's)
647  //
648  fCurrentTouchableHandle = aTrack->GetTouchableHandle();
649 }
650 
651 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
652 
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
void StartTracking(G4Track *aTrack) override
selection
main part
Definition: corrVsCorr.py:99
MonopoleTransportation(const Monopole *p, sim::ChordFinderSetter *cfs, G4int verbosityLevel=1)
#define nullptr
const double MeV
T sqrt(T t)
Definition: SSEVec.h:18
void ConfigureForTrack(const G4Track *) override
G4ParticleChangeForTransport fParticleChange
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &currentSafety, G4GPILSelection *selection) override
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond) override
G4PropagatorInField * fFieldPropagator
G4TouchableHandle fCurrentTouchableHandle
G4double MagneticCharge() const
Definition: Monopole.h:19
Square< F >::type sqr(const F &f)
Definition: Square.h:13
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData) override
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData) override
void SetMonopoleTracking(G4bool)
float spin(float ph)