File indexing completed on 2026-08-26 09:10:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #ifndef G4TCACHED_MAGNETIC_FIELD_HH
0032 #define G4TCACHED_MAGNETIC_FIELD_HH
0033
0034 #include "G4Types.hh"
0035 #include "G4ThreeVector.hh"
0036 #include "G4MagneticField.hh"
0037
0038
0039
0040
0041
0042
0043 template <class T_Field>
0044 class G4TCachedMagneticField : public G4MagneticField
0045 {
0046 public:
0047
0048 G4TCachedMagneticField(T_Field* pTField, G4double distance)
0049 : G4MagneticField()
0050 , fLastLocation(DBL_MAX, DBL_MAX, DBL_MAX)
0051 , fLastValue(DBL_MAX, DBL_MAX, DBL_MAX)
0052 , fCountCalls(0)
0053 , fCountEvaluations(0)
0054 {
0055 fpMagneticField = pTField;
0056 fDistanceConst = distance;
0057
0058 this->ClearCounts();
0059 }
0060
0061 virtual ~G4TCachedMagneticField() = default;
0062
0063 G4TCachedMagneticField(const G4TCachedMagneticField<T_Field>& rightCMF)
0064 {
0065 fpMagneticField = rightCMF.fpMagneticField;
0066 fDistanceConst = rightCMF.fDistanceConst;
0067 fLastLocation = rightCMF.fLastLocation;
0068 fLastValue = rightCMF.fLastValue;
0069 this->ClearCounts();
0070 }
0071
0072 G4TCachedMagneticField& operator=(const G4TCachedMagneticField& right)
0073 {
0074 if(&right == this) { return *this; }
0075
0076 fpMagneticField = right.fpMagneticField;
0077
0078 fDistanceConst= right.fDistanceConst;
0079 fLastLocation = right.fLastLocation;
0080 fLastValue = right.fLastValue;
0081
0082 fCountCalls = 0;
0083 fCountEvaluations = 0;
0084
0085 return *this;
0086 }
0087
0088 G4TCachedMagneticField* Clone() const
0089 {
0090 G4cout << "Clone is called" << G4endl;
0091
0092 T_Field* aF = this->fpMagneticField->T_Field::Clone();
0093 G4TCachedMagneticField* cloned = new G4TCachedMagneticField(aF, this->fDistanceConst);
0094 cloned->fLastLocation = this->fLastLocation;
0095 cloned->fLastValue = this->fLastValue;
0096 return cloned;
0097 }
0098
0099 void ReportStatistics()
0100 {
0101 G4cout << " Cached field: " << G4endl
0102 << " Number of calls: " << fCountCalls << G4endl
0103 << " Number of evaluations : " << fCountEvaluations << G4endl;
0104 }
0105
0106 virtual void GetFieldValue(const G4double Point[4], G4double* Bfield) const
0107 {
0108 G4ThreeVector newLocation(Point[0], Point[1], Point[2]);
0109
0110 G4double distSq = (newLocation - fLastLocation).mag2();
0111 fCountCalls++;
0112 if(distSq < fDistanceConst * fDistanceConst)
0113 {
0114 Bfield[0] = fLastValue.x();
0115 Bfield[1] = fLastValue.y();
0116 Bfield[2] = fLastValue.z();
0117 }
0118 else
0119 {
0120 fpMagneticField->T_Field::GetFieldValue(Point, Bfield);
0121 fCountEvaluations++;
0122 fLastLocation = G4ThreeVector(Point[0], Point[1], Point[2]);
0123 fLastValue = G4ThreeVector(Bfield[0], Bfield[1], Bfield[2]);
0124 }
0125 }
0126
0127 G4double GetConstDistance() const { return fDistanceConst; }
0128 void SetConstDistance(G4double dist) { fDistanceConst = dist; }
0129
0130 G4int GetCountCalls() const { return fCountCalls; }
0131 G4int GetCountEvaluations() const { return fCountEvaluations; }
0132 void ClearCounts()
0133 {
0134 fCountCalls = 0;
0135 fCountEvaluations = 0;
0136 }
0137
0138 protected:
0139
0140 mutable G4int fCountCalls, fCountEvaluations;
0141
0142 private:
0143
0144 T_Field* fpMagneticField;
0145
0146
0147 G4double fDistanceConst;
0148
0149
0150 mutable G4ThreeVector fLastLocation;
0151 mutable G4ThreeVector fLastValue;
0152 };
0153
0154 #endif