66 fParticleIsLooping( false ),
67 fPreviousSftOrigin( 0.,0.,0. ),
68 fPreviousMassSafety( 0.0 ),
69 fPreviousFullSafety( 0.0 ),
70 fThreshold_Warning_Energy( 100 *
MeV ),
71 fThreshold_Important_Energy( 250 *
MeV ),
72 fThresholdTrials( 10 ),
74 fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
75 fUseMagneticMoment( false ),
76 fVerboseLevel( verbosity )
89 if( fVerboseLevel > 0 )
91 G4cout <<
" G4CoupledTransportation constructor: ----- " <<
G4endl;
92 G4cout <<
" Verbose level is " << fVerboseLevel <<
G4endl;
93 G4cout <<
" Navigator Id obtained in G4CoupledTransportation constructor "
101 fCurrentTouchableHandle = nullTouchableHandle;
103 fEndGlobalTimeComputed =
false;
104 fCandidateEndGlobalTime = 0;
113 if( (fVerboseLevel > 0) || (fSumEnergyKilled > 0.0 ) )
115 G4cout <<
" G4CoupledTransportation: Statistics for looping particles " <<
G4endl;
116 G4cout <<
" Sum of energy of loopers killed: " << fSumEnergyKilled <<
G4endl;
117 G4cout <<
" Max energy of loopers killed: " << fMaxEnergyKilled <<
G4endl;
143 fParticleIsLooping = false ;
164 #ifdef G4DEBUG_TRANSPORT
165 if( fVerboseLevel > 1 )
167 G4cout <<
"G4CoupledTransportation::AlongStepGPIL> called in volume "
177 G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
179 startMassSafety = 0.0;
180 startFullSafety= 0.0;
184 if( MagSqShift <
sqr(fPreviousFullSafety) )
186 G4double mag_shift= std::sqrt(MagSqShift);
187 startMassSafety = std::max( (fPreviousMassSafety - mag_shift), 0.0);
188 startFullSafety = std::max( (fPreviousFullSafety - mag_shift), 0.0);
202 fMassGeometryLimitedStep = false ;
203 fAnyGeometryLimitedStep =
false;
214 G4bool fieldExertsForce = false ;
233 if( (particleCharge != 0.0)
234 || (fUseMagneticMoment && (magneticMoment != 0.0) )
235 || (gravityOn && (restMass != 0.0))
238 fieldExertsForce =
true;
266 fMassGeometryLimitedStep = false ;
267 fAnyGeometryLimitedStep = false ;
268 if( currentMinimumStep > 0 )
274 lengthAlongCurve = fPathFinder->
ComputeStep( theFieldTrack,
290 fMassGeometryLimitedStep = true ;
296 if( fMassGeometryLimitedStep && !fAnyGeometryLimitedStep )
298 G4cerr <<
" Error in determining geometries limiting the step" <<
G4endl;
299 G4cerr <<
" Limiting: mass=" << fMassGeometryLimitedStep
300 <<
" any= " << fAnyGeometryLimitedStep <<
G4endl;
301 G4Exception(
"G4CoupledTransportation::AlongStepGetPhysicalInteractionLength()",
303 "Incompatible conditions - was limited by a geometry?");
313 geometryStepLength = std::min( lengthAlongCurve, currentMinimumStep);
317 fMomentumChanged = true ;
321 fPreviousSftOrigin = startPosition ;
322 fPreviousMassSafety = newMassSafety ;
323 fPreviousFullSafety = newFullSafety ;
326 #ifdef G4DEBUG_TRANSPORT
327 if( fVerboseLevel > 1 )
329 G4cout <<
"G4Transport:CompStep> "
330 <<
" called the pathfinder for a new step at " << startPosition
331 <<
" and obtained step = " << lengthAlongCurve <<
G4endl;
332 G4cout <<
" New safety (preStep) = " << newMassSafety
333 <<
" versus precalculated = " << startMassSafety <<
G4endl;
338 startMassSafety = newMassSafety ;
339 startFullSafety = newFullSafety ;
342 fTransportEndPosition = endTrackState.
GetPosition() ;
347 geometryStepLength = lengthAlongCurve= 0.0 ;
348 fMomentumChanged = false ;
354 fTransportEndPosition = startPosition;
357 if( startMassSafety == 0.0 )
359 fMassGeometryLimitedStep = true ;
360 fAnyGeometryLimitedStep =
true;
366 if( !fieldExertsForce )
368 fParticleIsLooping = false ;
369 fMomentumChanged = false ;
370 fEndGlobalTimeComputed = false ;
376 #ifdef G4DEBUG_TRANSPORT
377 if( fVerboseLevel > 1 )
379 G4cout <<
" G4CT::CS End Position = " << fTransportEndPosition <<
G4endl;
380 G4cout <<
" G4CT::CS End Direction = " << fTransportEndMomentumDir <<
G4endl;
389 fEndGlobalTimeComputed =
true;
399 fEndGlobalTimeComputed =
false;
404 G4double endEnergy= fTransportEndKineticEnergy;
406 static G4int no_inexact_steps=0;
407 G4double absEdiff = std::fabs(startEnergy- endEnergy);
414 if( (fVerboseLevel > 1) && ( absEdiff >
perThousand * endEnergy) )
426 endpointDistance = (fTransportEndPosition - startPosition).mag() ;
429 fTransportEndSpin = endTrackState.
GetSpin();
432 safetyProposal= startFullSafety;
437 if( (startFullSafety < endpointDistance )
438 && ( particleCharge != 0.0 ) )
456 fPreviousMassSafety = endMassSafety ;
457 fPreviousFullSafety = endFullSafety;
458 fPreviousSftOrigin = fTransportEndPosition ;
462 safetyProposal = endFullSafety + endpointDistance;
468 #ifdef G4DEBUG_TRANSPORT
470 G4cout <<
"***Transportation::AlongStepGPIL ** " <<
G4endl ;
471 G4cout <<
" Revised Safety at endpoint " << fTransportEndPosition
472 <<
" give safety values: Mass= " << endMassSafety
473 <<
" All= " << endFullSafety <<
G4endl ;
474 G4cout <<
" Adding endpoint distance " << endpointDistance
475 <<
" to obtain pseudo-safety= " << safetyProposal <<
G4endl ;
481 G4cout <<
"***Transportation::AlongStepGPIL ** " <<
G4endl ;
482 G4cout <<
" Quick Safety estimate at endpoint " << fTransportEndPosition
483 <<
" gives safety endpoint value = " << startFullSafety - endpointDistance
484 <<
" using start-point value " << startFullSafety
485 <<
" and endpointDistance " << endpointDistance <<
G4endl;
490 proposedSafetyForStart= safetyProposal;
493 return geometryStepLength ;
502 static G4int noCalls=0;
528 if (!fEndGlobalTimeComputed)
535 if( finalVelocity > 0.0 ) { finalInverseVel= 1.0 / finalVelocity; }
537 if( initialVelocity > 0.0 ) { initialInverseVel= 1.0 / initialVelocity; }
540 if (finalVelocity > 0.0)
543 G4double meanInverseVelocity = 0.5 * ( initialInverseVel + finalInverseVel );
544 deltaTime = stepLength * meanInverseVelocity ;
550 deltaTime = stepLength * initialInverseVel ;
555 fCandidateEndGlobalTime = startTime + deltaTime ;
563 deltaTime = fCandidateEndGlobalTime - startTime ;
585 if ( fParticleIsLooping )
587 G4double endEnergy= fTransportEndKineticEnergy;
589 if( (endEnergy < fThreshold_Important_Energy)
590 || (fNoLooperTrials >= fThresholdTrials ) )
597 fSumEnergyKilled += endEnergy;
598 if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; }
601 if((fVerboseLevel > 1) && ( endEnergy > fThreshold_Warning_Energy ))
603 G4cout <<
" G4CoupledTransportation is killing track that is looping or stuck " <<
G4endl
605 <<
" MeV energy." <<
G4endl;
607 if( fVerboseLevel > 0 )
618 if( (fVerboseLevel > 2) )
620 G4cout <<
" ** G4CoupledTransportation::AlongStepDoIt(): Particle looping - " <<
G4endl
621 <<
" Number of consecutive problem step (this track) = " << fNoLooperTrials <<
G4endl
623 <<
" Total no of calls to this method (all tracks) = " << noCalls <<
G4endl;
641 return &fParticleChange ;
666 <<
"**************************************************************" <<
G4endl;
667 G4cerr <<
"Endpoint has moved between value expected from TransportEndPosition "
668 <<
" and value from Track in PostStepDoIt. " << G4endl
669 <<
"Change of " << Quantity <<
" is " << moveVec.
mag() /
mm <<
" mm long, "
670 <<
" and its vector is " << (1.0/
mm) * moveVec <<
" mm " << G4endl
671 <<
"Endpoint of ComputeStep was " << OldVector
672 <<
" and current position to locate is " << NewVector << G4endl;
691 #ifdef G4DEBUG_TRANSPORT
692 if( ( fVerboseLevel > 0 ) && ((fTransportEndPosition - track.
GetPosition()).mag2() >= 1.0e-16) )
695 G4cerr <<
" Problem in G4CoupledTransportation::PostStepDoIt " <<
G4endl;
701 if( fVerboseLevel > 0 )
703 G4cout <<
" Calling PathFinder::Locate() from "
704 <<
" G4CoupledTransportation::PostStepDoIt " <<
G4endl;
705 G4cout <<
" fAnyGeometryLimitedStep is " << fAnyGeometryLimitedStep <<
G4endl;
710 if(fAnyGeometryLimitedStep)
720 fCurrentTouchableHandle=
723 #ifdef G4DEBUG_TRANSPORT
724 if( fVerboseLevel > 0 )
726 G4cout <<
"G4CoupledTransportation::PostStepDoIt --- fNavigatorId = "
727 << fNavigatorId <<
G4endl;
729 if( fVerboseLevel > 1 )
732 G4cout <<
"CHECK !!!!!!!!!!! fCurrentTouchableHandle->GetVolume() = " << vol;
733 if( vol ) {
G4cout <<
"Name=" << vol->GetName(); }
741 if( fCurrentTouchableHandle->
GetVolume() == 0 )
745 retCurrentTouchable = fCurrentTouchableHandle ;
753 #ifdef G4DEBUG_TRANSPORT
754 if( fVerboseLevel > 1 )
756 G4cout <<
"G4CoupledTransportation::PostStepDoIt -- "
757 <<
" fAnyGeometryLimitedStep = " << fAnyGeometryLimitedStep
758 <<
" must be false " <<
G4endl;
803 if( pNewMaterialCutsCouple!=0
804 && pNewMaterialCutsCouple->
GetMaterial()!=pNewMaterial )
808 pNewMaterialCutsCouple =
819 return &fParticleChange ;
861 fPreviousMassSafety = 0.0 ;
862 fPreviousFullSafety = 0.0 ;
873 if( fGlobalFieldExists )
887 #ifdef G4DEBUG_TRANSPORT
888 if( fVerboseLevel > 1 )
890 G4cout <<
" Returning touchable handle " << fCurrentTouchableHandle <<
G4endl;
909 static G4int no_warnings= 0, warnModulo=1, moduloFactor= 10, no_large_ediff= 0;
911 if( std::fabs(startEnergy- endEnergy) >
perThousand * endEnergy )
914 if( (no_large_ediff% warnModulo) == 0 )
917 G4cout <<
"WARNING - G4CoupledTransportation::AlongStepGetPIL() "
918 <<
" Energy change in Step is above 1^-3 relative value. " <<
G4endl
919 <<
" Relative change in 'tracking' step = "
920 << std::setw(15) << (endEnergy-startEnergy)/startEnergy <<
G4endl
921 <<
" Starting E= " << std::setw(12) << startEnergy /
MeV <<
" MeV " <<
G4endl
922 <<
" Ending E= " << std::setw(12) << endEnergy /
MeV <<
" MeV " <<
G4endl;
923 G4cout <<
" Energy has been corrected -- however, review"
924 <<
" field propagation parameters for accuracy." <<
G4endl;
925 if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) )
927 G4cout <<
" These include EpsilonStepMax(/Min) in G4FieldManager "
928 <<
" which determine fractional error per step for integrated quantities. " << G4endl
929 <<
" Note also the influence of the permitted number of integration steps."
932 G4cerr <<
"ERROR - G4CoupledTransportation::AlongStepGetPIL()" << G4endl
933 <<
" Bad 'endpoint'. Energy change detected"
934 <<
" and corrected. "
935 <<
" Has occurred already "
936 << no_large_ediff <<
" times." <<
G4endl;
937 if( no_large_ediff == warnModulo * moduloFactor )
939 warnModulo *= moduloFactor;