2// ********************************************************************
3// * License and Disclaimer *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
26// class G4PropagatorInField Inline implementation
28// To create an object of this type, must have:
29// - an object that calculates the Curved paths
30// - the navigator to find (linear) intersections
31// - and also must know the value of the maximum displacement allowed
33// 25.10.96 John Apostolakis, design and implementation
34// 25.03.97 John Apostolakis, adaptation for G4Transportation and cleanup
35// ------------------------------------------------------------------------
37// ------------------------------------------------------------------------
40G4ChordFinder* G4PropagatorInField::GetChordFinder()
42 // The "Chord Finder" of the current Field Mgr is used
43 // -- this could be of the global field manager
44 // or that of another, from the current volume
45 return fCurrentFieldMgr->GetChordFinder();
48// ------------------------------------------------------------------------
49// Obtain the final space-point and velocity (normal) at the end of the Step
52G4ThreeVector G4PropagatorInField::EndPosition() const
54 return End_PointAndTangent.GetPosition();
57// ------------------------------------------------------------------------
60G4ThreeVector G4PropagatorInField::EndMomentumDir() const
62 return End_PointAndTangent.GetMomentumDir();
65// ------------------------------------------------------------------------
68G4double G4PropagatorInField::GetEpsilonStep() const
73// ------------------------------------------------------------------------
76void G4PropagatorInField::SetEpsilonStep( G4double newEps )
78 fEpsilonStep = newEps;
81// ------------------------------------------------------------------------
84G4bool G4PropagatorInField::IsParticleLooping() const
86 return fParticleIsLooping;
89// ------------------------------------------------------------------------
92G4int G4PropagatorInField::GetMaxLoopCount() const
94 return fMax_loop_count;
97// ------------------------------------------------------------------------
100void G4PropagatorInField::SetMaxLoopCount( G4int new_max )
102 fMax_loop_count = new_max;
105// ------------------------------------------------------------------------
108G4double G4PropagatorInField::GetDeltaIntersection() const
110 return fCurrentFieldMgr->GetDeltaIntersection();
113// ------------------------------------------------------------------------
116G4double G4PropagatorInField::GetDeltaOneStep() const
118 return fCurrentFieldMgr->GetDeltaOneStep();
121// ------------------------------------------------------------------------
124G4int G4PropagatorInField::GetVerboseLevel() const
126 return fVerboseLevel;
129// ------------------------------------------------------------------------
132G4int G4PropagatorInField::Verbose() const // Obsolete
134 return GetVerboseLevel();
137// ------------------------------------------------------------------------
140void G4PropagatorInField::SetVerboseTrace( G4bool enable )
142 fVerbTracePiF = enable;
145// ------------------------------------------------------------------------
148G4bool G4PropagatorInField::GetVerboseTrace()
150 return fVerbTracePiF;
153// ------------------------------------------------------------------------
156void G4PropagatorInField::CheckMode(G4bool mode)
159 if (fIntersectionLocator != nullptr)
161 fIntersectionLocator->SetCheckMode(mode);
165// ------------------------------------------------------------------------
168G4FieldTrack G4PropagatorInField::GetEndState() const
170 return End_PointAndTangent;
173// ------------------------------------------------------------------------
174// Minimum for Relative accuracy of a Step in volumes of global field
177G4double G4PropagatorInField::GetMinimumEpsilonStep() const
179 return fDetectorFieldMgr->GetMinimumEpsilonStep();
182// ------------------------------------------------------------------------
185void G4PropagatorInField::SetMinimumEpsilonStep( G4double newEpsMin )
187 fDetectorFieldMgr->SetMinimumEpsilonStep(newEpsMin);
190// ------------------------------------------------------------------------
191// Maximum for Relative accuracy of any Step
194G4double G4PropagatorInField::GetMaximumEpsilonStep() const
196 return fDetectorFieldMgr->GetMaximumEpsilonStep();
199// ------------------------------------------------------------------------
202void G4PropagatorInField::SetMaximumEpsilonStep( G4double newEpsMax )
204 fDetectorFieldMgr->SetMaximumEpsilonStep( newEpsMax );
207// ------------------------------------------------------------------------
210void G4PropagatorInField::SetLargestAcceptableStep( G4double newBigDist )
212 if( fLargestAcceptableStep>0.0 )
214 fLargestAcceptableStep = newBigDist;
218// ------------------------------------------------------------------------
221G4double G4PropagatorInField::GetLargestAcceptableStep()
223 return fLargestAcceptableStep;
226// ------------------------------------------------------------------------
229G4FieldManager* G4PropagatorInField::GetCurrentFieldManager()
231 return fCurrentFieldMgr;
234// ------------------------------------------------------------------------
237void G4PropagatorInField::SetThresholdNoZeroStep( G4int noAct,
242 fActionThreshold_NoZeroSteps = noAct;
244 if( noHarsh > fActionThreshold_NoZeroSteps )
245 fSevereActionThreshold_NoZeroSteps = noHarsh;
247 fSevereActionThreshold_NoZeroSteps = 2*(fActionThreshold_NoZeroSteps+1);
249 if( noAbandon > fSevereActionThreshold_NoZeroSteps+5 )
250 fAbandonThreshold_NoZeroSteps = noAbandon;
252 fAbandonThreshold_NoZeroSteps = 2*(fSevereActionThreshold_NoZeroSteps+3);
255// ------------------------------------------------------------------------
258G4int G4PropagatorInField::GetThresholdNoZeroSteps( G4int i )
261 if( i==0 ) { t = 3; } // No of parameters
262 else if (i==1) { t = fActionThreshold_NoZeroSteps; }
263 else if (i==2) { t = fSevereActionThreshold_NoZeroSteps; }
264 else if (i==3) { t = fAbandonThreshold_NoZeroSteps; }
269// ------------------------------------------------------------------------
271inline G4double G4PropagatorInField::GetZeroStepThreshold()
273 return fZeroStepThreshold;
276// ------------------------------------------------------------------------
278inline void G4PropagatorInField::SetZeroStepThreshold( G4double newLength )
280 fZeroStepThreshold= newLength;
283// ------------------------------------------------------------------------
286void G4PropagatorInField::SetDetectorFieldManager(G4FieldManager* newDFMan)
288 fDetectorFieldMgr = newDFMan;
291// ------------------------------------------------------------------------
294void G4PropagatorInField:: SetUseSafetyForOptimization( G4bool value )
296 fUseSafetyForOptimisation = value;
299// ------------------------------------------------------------------------
302G4bool G4PropagatorInField::GetUseSafetyForOptimization()
304 return fUseSafetyForOptimisation;
307// ------------------------------------------------------------------------
310void G4PropagatorInField::
311SetNavigatorForPropagating( G4Navigator* SimpleOrMultiNavigator )
313 if (SimpleOrMultiNavigator != nullptr)
315 fNavigator = SimpleOrMultiNavigator;
316 if( fIntersectionLocator )
318 fIntersectionLocator->SetNavigatorFor( SimpleOrMultiNavigator );
323// ------------------------------------------------------------------------
326G4Navigator* G4PropagatorInField::GetNavigatorForPropagating()
331// ------------------------------------------------------------------------
334void G4PropagatorInField::
335SetIntersectionLocator( G4VIntersectionLocator* pIntLoc )
337 if (pIntLoc != nullptr)
339 fIntersectionLocator= pIntLoc;
341 // Ensure that the Intersection Locator uses the correct Navigator
343 pIntLoc->SetNavigatorFor( fNavigator );
347// ------------------------------------------------------------------------
350G4VIntersectionLocator* G4PropagatorInField::GetIntersectionLocator()
352 return fIntersectionLocator;
355// ------------------------------------------------------------------------
358G4bool G4PropagatorInField::IntersectChord( const G4ThreeVector& StartPointA,
359 const G4ThreeVector& EndPointB,
361 G4double& LinearStepLength,
362 G4ThreeVector& IntersectionPoint )
364 // Calculate the direction and length of the chord AB
366#ifdef G4DEBUG_PROPAGATION
368 G4cout << "**** G4PropagatorInField::IntersectChord called."
369 << " InPut: StartPointA: " << StartPointA
370 << " EndPointB= " << EndPointB
371 << " StepLength= " << LinearStepLength
372 << " IntersecLen= " << IntersectionPoint
376 G4bool retVal= fIntersectionLocator
377 ->IntersectChord(StartPointA,EndPointB,NewSafety,
378 fPreviousSafety,fPreviousSftOrigin,
379 LinearStepLength,IntersectionPoint);
381#ifdef G4DEBUG_PROPAGATION
383 G4cout << "**** G4PropagatorInField::IntersectChord ended."
384 << " OutPut: Safety= " << NewSafety
385 << " StepLength= " << LinearStepLength
386 << " IntersecPt= " << IntersectionPoint
393// ------------------------------------------------------------------------
395inline G4bool G4PropagatorInField::IsFirstStepInVolume()
397 return fFirstStepInVolume;
400// ------------------------------------------------------------------------
402inline G4bool G4PropagatorInField::IsLastStepInVolume()
404 return fLastStepInVolume;
407// ------------------------------------------------------------------------
409inline void G4PropagatorInField::PrepareNewTrack()
412 fFirstStepInVolume = false;
413 fLastStepInVolume = false;
416// ------------------------------------------------------------------------
418inline G4EquationOfMotion* G4PropagatorInField::GetCurrentEquationOfMotion()
420 if (auto pChordFinder = GetChordFinder())
422 if (auto pIntDriver = pChordFinder->GetIntegrationDriver())
424 return pIntDriver->GetEquationOfMotion();
430// ------------------------------------------------------------------------
432G4int G4PropagatorInField::GetIterationsToIncreaseChordDistance() const
434 return fIncreaseChordDistanceThreshold;
437// ------------------------------------------------------------------------
439void G4PropagatorInField::SetIterationsToIncreaseChordDistance(G4int numIters)
441 fIncreaseChordDistanceThreshold = numIters;
444 // Disables relaxation
446 G4cout << "G4PropagatorInField: Turned OFF the Relaxation of chord "
447 << "finder as iteration threshold = " << numIters
448 << " is not positive." << G4endl;