Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 09:10:43

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4PropagatorInField 
0027 //
0028 // Class description:
0029 // 
0030 // This class performs the navigation/propagation of a particle/track 
0031 // in a magnetic field. The field is in general non-uniform.
0032 // For the calculation of the path, it relies on the class G4ChordFinder.
0033 // It utilises an ODE solver (with the Runge-Kutta method) to evolve the
0034 // particle, and drives it until the particle has traveled a set distance
0035 // or it enters a new volume.
0036 
0037 // Author: John Apostolakis (CERN), 25 October 1996
0038 // ---------------------------------------------------------------------------
0039 #ifndef G4PropagatorInField_hh 
0040 #define G4PropagatorInField_hh 1
0041 
0042 #include "G4Types.hh"
0043 
0044 #include <vector>
0045 
0046 #include "G4FieldTrack.hh"
0047 #include "G4FieldManager.hh"
0048 #include "G4VIntersectionLocator.hh"
0049 
0050 class G4ChordFinder; 
0051 
0052 class G4Navigator;
0053 class G4VPhysicalVolume;
0054 class G4VCurvedTrajectoryFilter;
0055 
0056 /**
0057  * @brief G4PropagatorInField performs the navigation/propagation of a
0058  * particle/track in a magnetic field. The field is in general non-uniform.
0059  * For the calculation of the path, it relies on the class G4ChordFinder.
0060  * It utilises an ODE solver (with the Runge-Kutta method) to evolve the
0061  * particle, and drives it until the particle has traveled a set distance
0062  * or it enters a new volume.
0063  */
0064 
0065 class G4PropagatorInField
0066 {
0067   public:
0068 
0069     /**
0070      * Constructor and Destructor.
0071      */
0072     G4PropagatorInField( G4Navigator* theNavigator, 
0073                          G4FieldManager* detectorFieldMgr,
0074                          G4VIntersectionLocator* vLocator = nullptr );
0075    ~G4PropagatorInField();
0076 
0077     /**
0078      * Computes the next geometric Step.
0079      *  @param[in,out] pFieldTrack Field track to be filled.
0080      *  @param[in] pCurrentProposedStepLength Current proposed step length.
0081      *  @param[in,out] pNewSafety New safety.
0082      *  @param[in] pPhysVol Pointer to the current volume.
0083      *  @param[in] canRelaxDeltaChord To enable relaxing delta-chord parameter.
0084      *  @returns Step length.
0085      */
0086     G4double ComputeStep( G4FieldTrack& pFieldTrack,
0087                           G4double pCurrentProposedStepLength,
0088                           G4double& pNewSafety, 
0089                           G4VPhysicalVolume* pPhysVol = nullptr,
0090                           G4bool canRelaxDeltaChord = false);
0091 
0092     /**
0093      * Returning the state after the Step.
0094      */
0095     inline G4ThreeVector EndPosition() const;       
0096     inline G4ThreeVector EndMomentumDir() const;
0097     inline G4bool        IsParticleLooping() const;
0098 
0099     /**
0100      * Returning the relative accuracy for the current Step.
0101      */
0102     inline G4double GetEpsilonStep() const;
0103 
0104     /**
0105      * Setting the relative accuracy for the current Step.
0106      * The ratio DeltaOneStep()/h_current_step.
0107      */
0108     inline void SetEpsilonStep(G4double newEps);
0109 
0110     /**
0111      * Sets (and returns) the correct field manager (global or local), 
0112      * if it exists.
0113      *  @note Should be called before ComputeStep is called;
0114      *        Currently, ComputeStep() will call it, if it has not been called.
0115      *  @param[in] pCurrentPhysVol Pointer to the current volume.
0116      *  @returns The pointer to the field manager.
0117      */
0118     G4FieldManager* FindAndSetFieldManager(G4VPhysicalVolume* pCurrentPhysVol);
0119  
0120     /**
0121      * Returning the pointer to the chord finder.
0122      */
0123     inline G4ChordFinder* GetChordFinder();
0124 
0125     /**
0126      * Verbosity control.
0127      */
0128     G4int SetVerboseLevel( G4int verbose );
0129     inline G4int GetVerboseLevel() const;
0130     inline G4int Verbose() const;
0131 
0132     /**
0133      * Enabling check mode for further diagnostics.
0134      */
0135     inline void CheckMode(G4bool mode);
0136 
0137     /**
0138      * Accessor/modifier for tracing key parts of ComputeStep().
0139      */
0140     inline void SetVerboseTrace( G4bool enable );
0141     inline G4bool GetVerboseTrace();
0142    
0143     /**
0144      * Accessor/modifier for controlling the maximum for the number of
0145      * substeps that a particle can take. Above this number it is signaled
0146      * as 'looping'.
0147      */
0148     inline G4int GetMaxLoopCount() const;
0149     inline void  SetMaxLoopCount( G4int new_max );
0150 
0151     /**
0152      * Print method, useful mostly for debugging.
0153      */
0154     void printStatus( const G4FieldTrack&      startFT,
0155                       const G4FieldTrack&      currentFT, 
0156                             G4double           requestStep, 
0157                             G4double           safety,
0158                             G4int              step, 
0159                             G4VPhysicalVolume* startVolume);
0160 
0161     /**
0162      * Accessor for retrieving the field track.
0163      */
0164     inline G4FieldTrack GetEndState() const;
0165 
0166     /**
0167      * Methods to control values for the global field manager.
0168      *  @deprecated The four methods below are now obsolescent but *for now*
0169      *     will work. They are being replaced by same-name methods in
0170      *     G4FieldManager, allowing the specialisation in different volumes. 
0171      */
0172     inline G4double GetMinimumEpsilonStep() const; // Min for relative accuracy
0173     inline void     SetMinimumEpsilonStep( G4double newEpsMin ); // of any step
0174     inline G4double GetMaximumEpsilonStep() const;
0175     inline void     SetMaximumEpsilonStep( G4double newEpsMax );
0176 
0177     /**
0178      * Methods to obtain / change the size of the largest step the method
0179      * will undertake. The Reset method uses the world volume's.
0180      */
0181     void     SetLargestAcceptableStep( G4double newBigDist );
0182     G4double GetLargestAcceptableStep();
0183     void     ResetLargestAcceptableStep();
0184 
0185     /**
0186      * Methods to control extra Multiplier parameter for limiting long steps.
0187      */
0188     G4double GetMaxStepSizeMultiplier();
0189     void     SetMaxStepSizeMultiplier(G4double vm);
0190 
0191     /**
0192      * Methods to Control minimum 'directional' distance in case of
0193      * too-large step.
0194      */
0195     G4double GetMinBigDistance();
0196     void     SetMinBigDistance(G4double val);
0197 
0198     /**
0199      * Sets the filter that examines & stores 'intermediate' 
0200      * curved trajectory points.
0201      *  @note Currently only position is stored.
0202      */
0203     void SetTrajectoryFilter(G4VCurvedTrajectoryFilter* filter);
0204 
0205     /**
0206      * Accesses the points which have passed by the filter.
0207      *   @note Responsibility for deleting the points lies with the client.
0208      *         This method MUST BE called exactly ONCE per step.
0209      */ 
0210     std::vector<G4ThreeVector>* GimmeTrajectoryVectorAndForgetIt() const;
0211 
0212     /**
0213      * Clears the State of this class and its current associates.
0214      *   @note The current field manager & chord finder will also be called.
0215      */
0216     void ClearPropagatorState();
0217 
0218     /**
0219      * Setter for global field manager. Updates the state.
0220      */
0221     inline void SetDetectorFieldManager( G4FieldManager* newGlobalFieldManager );
0222   
0223     /**
0224      * Toggles & views parameter for using safety to discard unneccesary calls
0225      * to the navigator (thus 'optimising' performance).
0226      */
0227     inline void   SetUseSafetyForOptimization( G4bool );
0228     inline G4bool GetUseSafetyForOptimization();
0229 
0230     /**
0231      * Intersects the chord from StartPointA to EndPointB and returns
0232      * whether an intersection occurred.
0233      *   @note Safety is changed!
0234      */
0235     inline G4bool IntersectChord( const G4ThreeVector& StartPointA,
0236                                   const G4ThreeVector& EndPointB,
0237                                         G4double&      NewSafety,
0238                                         G4double&      LinearStepLength,
0239                                         G4ThreeVector& IntersectionPoint);
0240 
0241     /**
0242      * Returns if it is the first step in the volume.
0243      */
0244     inline G4bool IsFirstStepInVolume();
0245 
0246     /**
0247      * Returns if it is the last step in the volume.
0248      */
0249     inline G4bool IsLastStepInVolume();
0250 
0251     /**
0252      * Initialises track flags.
0253      */
0254     inline void PrepareNewTrack();
0255 
0256     /**
0257      * Changes or gets the object which calculates the exact intersection
0258      * point with the next boundary.
0259      */
0260     inline G4VIntersectionLocator* GetIntersectionLocator();
0261     inline void SetIntersectionLocator(G4VIntersectionLocator* pLocator );
0262 
0263     /**
0264      * Controls the parameter which enables the temporary 'relaxation' which
0265      * ensures that chord segments are short enough so that their sagitta is
0266      * small than delta-chord parameter.
0267      * The Set method increases the value of delta-chord temporarily, doubling
0268      * it once the number of iterations substeps reach value of
0269      * 'IncreaseChordDistanceThreshold'. It is also doubled again every time
0270      * the iteration count reaches a multiple of this value.
0271      *   @note The delta-chord is reset to its original value at the end of
0272      *         each call to ComputeStep().
0273      */
0274     inline G4int GetIterationsToIncreaseChordDistance() const;
0275     inline void  SetIterationsToIncreaseChordDistance(G4int numIters);
0276 
0277     /**
0278      * Accessors.
0279      */
0280     inline G4double GetDeltaIntersection() const;
0281     inline G4double GetDeltaOneStep() const;
0282 
0283     /**
0284      * Auxiliary methods.
0285      *   @note Their results can/will change during propagation.
0286      */
0287     inline G4FieldManager* GetCurrentFieldManager();
0288     inline G4EquationOfMotion* GetCurrentEquationOfMotion();
0289 
0290     /**
0291      * Accessor and modifier for navigator.
0292      */
0293     inline void SetNavigatorForPropagating(G4Navigator* SimpleOrMultiNavigator); 
0294     inline G4Navigator* GetNavigatorForPropagating();
0295 
0296     /**
0297      * Accessors and modifiers for no-zero steps threshold.
0298      */
0299     inline void SetThresholdNoZeroStep( G4int noAct,
0300                                         G4int noHarsh,
0301                                         G4int noAbandon );
0302     inline G4int GetThresholdNoZeroSteps( G4int i ); 
0303     inline G4double GetZeroStepThreshold(); 
0304     inline void     SetZeroStepThreshold( G4double newLength ); 
0305    
0306     /**
0307      * Updates the Locator with parameters from this class and from current
0308      * field manager.
0309      */
0310     void RefreshIntersectionLocator(); 
0311 
0312   protected:
0313 
0314     /**
0315      * Logging methods.
0316      */
0317     void PrintStepLengthDiagnostic( G4double      currentProposedStepLength,
0318                                     G4double      decreaseFactor,
0319                                     G4double      stepTrial,
0320                               const G4FieldTrack& aFieldTrack);
0321     void ReportLoopingParticle( G4int count,  G4double StepTaken,
0322                                 G4double stepRequest, const char* methodName,
0323                                 const G4ThreeVector&      momentumVec,
0324                                 G4VPhysicalVolume* physVol);
0325     void ReportStuckParticle(G4int noZeroSteps, G4double proposedStep,
0326                              G4double lastTriedStep, G4VPhysicalVolume* physVol);
0327 
0328   private:
0329 
0330     // ----------------------------------------------------------------------
0331     //  DATA Members
0332     // ----------------------------------------------------------------------
0333 
0334     //  ==================================================================
0335     //  INVARIANTS - Must not change during tracking
0336 
0337     //  ** PARAMETERS -----------
0338     G4int fMax_loop_count = 1000;
0339       // Limit for the number of sub-steps taken in one call to ComputeStep
0340     G4int fIncreaseChordDistanceThreshold = 100;
0341     G4bool fUseSafetyForOptimisation = true;
0342       // (false) is less sensitive to incorrect safety
0343 
0344     //  Thresholds for identifying "abnormal" cases - which cause looping
0345     //
0346     G4int fActionThreshold_NoZeroSteps = 2;        // Threshold # - above it act
0347     G4int fSevereActionThreshold_NoZeroSteps = 10; // Threshold # to act harshly
0348     G4int fAbandonThreshold_NoZeroSteps = 50;      // Threshold # to abandon
0349     G4double fZeroStepThreshold = 0.0; 
0350       // Threshold *length* for counting of tiny or 'zero' steps 
0351 
0352     // Parameters related to handling of very large steps which
0353     // occur typically in large volumes with vacuum or very thin gas
0354     //
0355     G4double fLargestAcceptableStep;
0356       // Maximum size of a step - for optimization (and to avoid problems)
0357     G4double fMaxStepSizeMultiplier = 3;
0358       // Multiplier for directional exit distance used as extra long-step limit 
0359     G4double fMinBigDistance= 100. ; // * CLHEP::mm
0360       // Minimum distance added to directional exit distance
0361     //  ** End of PARAMETERS -----
0362 
0363     G4double kCarTolerance;
0364         // Geometrical tolerance defining surface thickness
0365 
0366     G4bool fAllocatedLocator;                    //  Book-keeping
0367 
0368     //  --------------------------------------------------------
0369     //  ** Dependent Objects - to which work is delegated 
0370 
0371     G4FieldManager* fDetectorFieldMgr; 
0372       // The  Field Manager of the whole Detector.  (default)
0373 
0374     G4VIntersectionLocator* fIntersectionLocator;
0375       // Refines candidate intersection
0376 
0377     G4VCurvedTrajectoryFilter* fpTrajectoryFilter = nullptr;
0378       // The filter encapsulates the algorithm which selects which
0379       // intermediate points should be stored in a trajectory. 
0380       // When it is NULL, no intermediate points will be stored.
0381       // Else PIF::ComputeStep must submit (all) intermediate
0382       // points it calculates, to this filter.  (jacek 04/11/2002)
0383 
0384     G4Navigator* fNavigator;
0385       // Set externally - only by tracking / run manager
0386     //
0387     //  ** End of Dependent Objects ----------------------------
0388 
0389     //  End of INVARIANTS 
0390     //  ==================================================================
0391 
0392     //  STATE information
0393     //  -----------------
0394     G4FieldManager* fCurrentFieldMgr;
0395       // The  Field Manager of the current volume (may be the global)
0396     G4bool fSetFieldMgr = false;  // Has it been set for the current step?
0397 
0398     // Parameters of current step
0399     //
0400     G4double fEpsilonStep;            // Relative accuracy of current Step
0401     G4FieldTrack End_PointAndTangent; // End point storage
0402     G4bool fParticleIsLooping = false;
0403     G4int fNoZeroStep = 0;            // Count of zero Steps
0404 
0405     // State used for Optimisation
0406     //
0407     G4double fFull_CurveLen_of_LastAttempt = -1; 
0408     G4double fLast_ProposedStepLength = -1; 
0409       // Previous step information -- for use in adjust step size
0410     G4ThreeVector fPreviousSftOrigin;
0411     G4double fPreviousSafety = 0.0; 
0412       // Last safety origin & value: for optimisation
0413 
0414     G4int fVerboseLevel = 0;
0415     G4bool fVerbTracePiF = false;
0416     G4bool fCheck = false;
0417       // For debugging purposes
0418 
0419     G4bool fFirstStepInVolume = true; 
0420     G4bool fLastStepInVolume = true; 
0421     G4bool fNewTrack = true;
0422 };
0423 
0424 // Inline methods
0425 //
0426 #include "G4PropagatorInField.icc"
0427 
0428 #endif