// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // Class G4PropagatorInField Inline implementation // // To create an object of this type, must have: // - an object that calculates the Curved paths // - the navigator to find (linear) intersections // - and also must know the value of the maximum displacement allowed // // Author: John Apostolakis (CERN), 25 October 1996 // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // inline G4ChordFinder* G4PropagatorInField::GetChordFinder() { // The "Chord Finder" of the current Field Mgr is used // -- this could be of the global field manager // or that of another, from the current volume return fCurrentFieldMgr->GetChordFinder(); } // ------------------------------------------------------------------------ // Obtain the final space-point and velocity (normal) at the end of the Step // inline G4ThreeVector G4PropagatorInField::EndPosition() const { return End_PointAndTangent.GetPosition(); } // ------------------------------------------------------------------------ // inline G4ThreeVector G4PropagatorInField::EndMomentumDir() const { return End_PointAndTangent.GetMomentumDir(); } // ------------------------------------------------------------------------ // inline G4double G4PropagatorInField::GetEpsilonStep() const { return fEpsilonStep; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetEpsilonStep( G4double newEps ) { fEpsilonStep = newEps; } // ------------------------------------------------------------------------ // inline G4bool G4PropagatorInField::IsParticleLooping() const { return fParticleIsLooping; } // ------------------------------------------------------------------------ // inline G4int G4PropagatorInField::GetMaxLoopCount() const { return fMax_loop_count; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetMaxLoopCount( G4int new_max ) { fMax_loop_count = new_max; } // ------------------------------------------------------------------------ // inline G4double G4PropagatorInField::GetDeltaIntersection() const { return fCurrentFieldMgr->GetDeltaIntersection(); } // ------------------------------------------------------------------------ // inline G4double G4PropagatorInField::GetDeltaOneStep() const { return fCurrentFieldMgr->GetDeltaOneStep(); } // ------------------------------------------------------------------------ // inline G4int G4PropagatorInField::GetVerboseLevel() const { return fVerboseLevel; } // ------------------------------------------------------------------------ // inline G4int G4PropagatorInField::Verbose() const // Obsolete { return GetVerboseLevel(); } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetVerboseTrace( G4bool enable ) { fVerbTracePiF = enable; } // ------------------------------------------------------------------------ // inline G4bool G4PropagatorInField::GetVerboseTrace() { return fVerbTracePiF; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::CheckMode(G4bool mode) { fCheck = mode; if (fIntersectionLocator != nullptr) { fIntersectionLocator->SetCheckMode(mode); } } // ------------------------------------------------------------------------ // inline G4FieldTrack G4PropagatorInField::GetEndState() const { return End_PointAndTangent; } // ------------------------------------------------------------------------ // Minimum for Relative accuracy of a Step in volumes of global field // inline G4double G4PropagatorInField::GetMinimumEpsilonStep() const { return fDetectorFieldMgr->GetMinimumEpsilonStep(); } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetMinimumEpsilonStep( G4double newEpsMin ) { fDetectorFieldMgr->SetMinimumEpsilonStep(newEpsMin); } // ------------------------------------------------------------------------ // Maximum for Relative accuracy of any Step // inline G4double G4PropagatorInField::GetMaximumEpsilonStep() const { return fDetectorFieldMgr->GetMaximumEpsilonStep(); } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetMaximumEpsilonStep( G4double newEpsMax ) { fDetectorFieldMgr->SetMaximumEpsilonStep( newEpsMax ); } // ------------------------------------------------------------------------ // inline G4FieldManager* G4PropagatorInField::GetCurrentFieldManager() { return fCurrentFieldMgr; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetThresholdNoZeroStep( G4int noAct, G4int noHarsh, G4int noAbandon ) { if( noAct>0 ) { fActionThreshold_NoZeroSteps = noAct; } if( noHarsh > fActionThreshold_NoZeroSteps ) { fSevereActionThreshold_NoZeroSteps = noHarsh; } else { fSevereActionThreshold_NoZeroSteps = 2*(fActionThreshold_NoZeroSteps+1); } if( noAbandon > fSevereActionThreshold_NoZeroSteps+5 ) { fAbandonThreshold_NoZeroSteps = noAbandon; } else { fAbandonThreshold_NoZeroSteps = 2*(fSevereActionThreshold_NoZeroSteps+3); } } // ------------------------------------------------------------------------ // inline G4int G4PropagatorInField::GetThresholdNoZeroSteps( G4int i ) { G4int t=0; if( i==0 ) { t = 3; } // No of parameters else if (i==1) { t = fActionThreshold_NoZeroSteps; } else if (i==2) { t = fSevereActionThreshold_NoZeroSteps; } else if (i==3) { t = fAbandonThreshold_NoZeroSteps; } return t; } // ------------------------------------------------------------------------ // inline G4double G4PropagatorInField::GetZeroStepThreshold() { return fZeroStepThreshold; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetZeroStepThreshold( G4double newLength ) { fZeroStepThreshold= newLength; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::SetDetectorFieldManager(G4FieldManager* newDFMan) { fDetectorFieldMgr = newDFMan; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField:: SetUseSafetyForOptimization( G4bool value ) { fUseSafetyForOptimisation = value; } // ------------------------------------------------------------------------ // inline G4bool G4PropagatorInField::GetUseSafetyForOptimization() { return fUseSafetyForOptimisation; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField:: SetNavigatorForPropagating( G4Navigator* SimpleOrMultiNavigator ) { if (SimpleOrMultiNavigator != nullptr) { fNavigator = SimpleOrMultiNavigator; if( fIntersectionLocator != nullptr ) { fIntersectionLocator->SetNavigatorFor( SimpleOrMultiNavigator ); } } } // ------------------------------------------------------------------------ // inline G4Navigator* G4PropagatorInField::GetNavigatorForPropagating() { return fNavigator; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField:: SetIntersectionLocator( G4VIntersectionLocator* pIntLoc ) { if (pIntLoc != nullptr) { fIntersectionLocator= pIntLoc; // Ensure that the Intersection Locator uses the correct Navigator // pIntLoc->SetNavigatorFor( fNavigator ); } } // ------------------------------------------------------------------------ // inline G4VIntersectionLocator* G4PropagatorInField::GetIntersectionLocator() { return fIntersectionLocator; } // ------------------------------------------------------------------------ // inline G4bool G4PropagatorInField::IntersectChord( const G4ThreeVector& StartPointA, const G4ThreeVector& EndPointB, G4double& NewSafety, G4double& LinearStepLength, G4ThreeVector& IntersectionPoint ) { // Calculate the direction and length of the chord AB // #ifdef G4DEBUG_PROPAGATION if( fVerbTracePiF ) G4cout << "**** G4PropagatorInField::IntersectChord called." << " InPut: StartPointA: " << StartPointA << " EndPointB= " << EndPointB << " StepLength= " << LinearStepLength << " IntersecLen= " << IntersectionPoint << G4endl; #endif G4bool retVal= fIntersectionLocator ->IntersectChord(StartPointA,EndPointB,NewSafety, fPreviousSafety,fPreviousSftOrigin, LinearStepLength,IntersectionPoint); #ifdef G4DEBUG_PROPAGATION if( fVerbTracePiF ) G4cout << "**** G4PropagatorInField::IntersectChord ended." << " OutPut: Safety= " << NewSafety << " StepLength= " << LinearStepLength << " IntersecPt= " << IntersectionPoint << G4endl; #endif return retVal; } // ------------------------------------------------------------------------ // inline G4bool G4PropagatorInField::IsFirstStepInVolume() { return fFirstStepInVolume; } // ------------------------------------------------------------------------ // inline G4bool G4PropagatorInField::IsLastStepInVolume() { return fLastStepInVolume; } // ------------------------------------------------------------------------ // inline void G4PropagatorInField::PrepareNewTrack() { fNewTrack = true; fFirstStepInVolume = false; fLastStepInVolume = false; } // ------------------------------------------------------------------------ // inline G4EquationOfMotion* G4PropagatorInField::GetCurrentEquationOfMotion() { if (auto pChordFinder = GetChordFinder()) { if (auto pIntDriver = pChordFinder->GetIntegrationDriver()) { return pIntDriver->GetEquationOfMotion(); } } return nullptr; } // ------------------------------------------------------------------------ // G4int G4PropagatorInField::GetIterationsToIncreaseChordDistance() const { return fIncreaseChordDistanceThreshold; } // ------------------------------------------------------------------------ // void G4PropagatorInField::SetIterationsToIncreaseChordDistance(G4int numIters) { fIncreaseChordDistanceThreshold = numIters; if(numIters <= 0) { // Disables relaxation if( fVerboseLevel != 0 ){ G4cout << "G4PropagatorInField: Turned OFF the Relaxation of chord " << "finder as iteration threshold = " << numIters << " is not positive." << G4endl; } } }