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