LBNEMagneticField.hh
Go to the documentation of this file.
1 
2 // $Id: LBNEMagneticField.hh,v 1.2.2.8 2013/12/24 20:30:46 lebrun Exp $
3 // --------------------------------------------------------------
4 // LBNEMagneticField.hh modified by Yuki 2004/7/16
5 // modified by Yuki 8/2/04
6 #ifndef LBNEMagneticField_H
7 #define LBNEMagneticField_H 1
8 #include <fstream>
9 #include <vector>
10 
11 #include "globals.hh"
12 #include "G4MagneticField.hh"
13 #include <fstream>
14 #include "G4RotationMatrix.hh"
15 
16 
17 class LBNEMagneticFieldHorn : public G4MagneticField
18 {
19  public:
20  explicit LBNEMagneticFieldHorn(bool isHorn1);
22 
23  virtual void GetFieldValue( const double Point[3], double *Bfield ) const;
24 
25  private:
26  G4bool amHorn1;
27  G4double fHornCurrent;
28  // Data for the World coordinate transform to the Horn coordinate system.
29  // We linearize the tranformation, leave Z unchanged, except for a translation.
30  mutable G4bool fCoordinateSet; // set when we got the first track entering the logical volume for which the field manager is defined
31  bool fHornIsMisaligned; // Then, we will rotate the field
32  G4RotationMatrix fRotMatrixHornContainer;
33  std::vector<double> fShift;
34  std::vector<double> fShiftSlope;
35  mutable G4double fZShiftDrawingCoordinate;
36  // The outer radius of the conuctor is computed from the LBNEVolumePlacement Radial equations.
37  // in the coordinate system of the drawing 8875.112-MD-363104 and 383385
38  mutable G4double fZShiftUpstrWorldToLocal; // The Zcoordinate in world system of the entrance of the volume for which the field is defined.
39  // For Horn1, this volue is named "Horn1TopLevelUpstr"
40  //(or Horn1IOTransCont, which start 2 microns downstream of it...
41  // and Horn1Hall
42  // For Horn2, it is Horn2TopLevel.
43  G4double fEffectiveLength; // The length assumed to compute the coordinate change.
44  G4double fHornNeckOuterRadius; // Copy of the VolumePlacement Neck Outer Radius, rescaled if need be..
45  G4double fHornNeckInnerRadius; // Copy of the VolumePlacement Neck Outer Radius, rescaled if need be..
46  G4double fOuterRadius;
47  G4double fOuterRadiusEff; // the effective outer radius, physical outer radius - 2.0*skindepth at 0.43 kHz
48  G4double fSkinDepth; // at (1./(2.3 ms))
49  // We now need to determine the radius where the current flows.
50  // We will call the utility meothds from the LBNEVolumePlacements class.
51  std::vector<size_t> fEqnIndicesOuter;
52  std::vector<size_t> fEqnIndicesInner;
53  std::vector<double> fZDCBegin;
54  std::vector<double> fZDCEnd;
55  G4double fNeckRadius;
56  // Parameter for the systematic uncertainty due to skin depth effect for the inner conductor.
57  // varies between 0. (default, current density is uniform between inner IC radius and outer IC radius),
58  // to 0.99, where all the current flows in only 1% of the outer radii..
60  G4double fSkinDepthIIRInv;
61  mutable std::ofstream fOutTraj;
62  //
63  // More variable for debugging and checking field values from the stepping Action
64  //
65  mutable double fEffectiveInnerRad;
66  mutable double fEffectiveOuterRad; // of the inner conductor.
67  mutable double fEffectiveSkinDepthFact;
68 
69 
70  //
71  // Added vector for Custom Horn1 Polygon.
72  //
74  std::vector<double> fRadsInnerC;
75  std::vector<double> fRadsOuterC;
76  //
77  inline void fillHorn1PolygonRadii(double z, double *rIn, double *rOut) const {
78  size_t kLow = 0;
79  size_t kHigh = fZDCBegin.size() - 1;
80  for (size_t k=0; k != fZDCBegin.size() - 1; k++) {
81  if ((z >= fZDCBegin[k]) && (z < fZDCBegin[k+1])) {
82  kLow = k;
83  kHigh = k+1;
84  const double dzFrac = (z - fZDCBegin[kLow])/(fZDCBegin[kHigh] - fZDCBegin[kLow]);
85  *rIn = fRadsInnerC[kLow] + dzFrac*(fRadsInnerC[kHigh] - fRadsInnerC[kLow]);
86  *rOut = fRadsOuterC[kLow] + dzFrac*(fRadsOuterC[kHigh] - fRadsOuterC[kLow]);
87 // std::cerr << " .......... z " << z << " k " << k << " rIn " << (*rIn) << " rOut " << (*rOut) << std::endl;
88  return;
89  }
90  }
91  *rIn = 1.0e10;
92  *rOut = 2.0e10;
93  }
94 
95 
96  void fillTrajectories(const double Point[3], double bx, double by) const;
97  //
98  // Implement the Skin depth for the Inner conductors.
99  // References: Zarko's Thesis (MINOS Document 5694-v1), section 5.2.4, p150 - 156)
100  // DeltaR : difference from the radial coordinate of the track and the inner radius of the inner conductor.
101  //
102  // Note: Approximate, because this reasoning is based on a cylindical (not tubular) conductor.
103  //
104  inline double getNormCurrDensityInnerC(double deltaR, double rOut) const {
105  if (deltaR < 0.) return 0.;
106  const double xby2 = fSkinDepthIIRInv*deltaR/2.; // x must be less < 1, otherwise Taylor expansion fails..
107  const double xby2Out = fSkinDepthIIRInv*rOut/2.; // x must be less < 1, otherwise Taylor expansion fails..
108  // keep only 3 terms..
109  const double ber = 1.0 - std::pow(xby2, 4.)/4. + std::pow(xby2, 8.)/576.;
110  const double bei = std::pow(xby2, 2.) - std::pow(xby2, 6.)/36 + std::pow(xby2, 10.)/14400.;
111  const double beNSq = ber*ber + bei*bei;
112  const double berOut = 1.0 - std::pow(xby2Out, 4.)/4. + std::pow(xby2Out, 8.)/576.;
113  const double beiOut = std::pow(xby2Out, 2.) - std::pow(xby2Out, 6.)/36 + std::pow(xby2Out, 10.)/14400.;
114  const double beNSqOut = berOut*berOut + beiOut*beiOut;
115  return std::sqrt(beNSq/beNSqOut);
116  }
117 
118  public:
119 
120  inline void SetHornCurrent(G4double ihorn) {fHornCurrent = ihorn;}
121  inline G4double GetHornCurrent() const { return fHornCurrent;}
122  inline void SetSkinDepthInnerRad(G4double f) {fSkinDepthInnerRad = f; fSkinDepthIIRInv= std::sqrt(2.0)/f;}
123  double GetEffectiveInnerRad() const { return fEffectiveInnerRad;}
124  double GetEffectiveOuterRad() const { return fEffectiveOuterRad;}
126 
127 
128  void dumpField() const;
129 
130 };
131 
132 class LBNEMagneticFieldDecayPipe : public G4MagneticField
133 {
134  public:
135  explicit LBNEMagneticFieldDecayPipe(bool isToroidal);
136 
137  virtual void GetFieldValue( const double Point[3], double *Bfield ) const;
138 
139  private:
140  G4bool isToroid;
141  G4double fWireCurrent;
142  G4double fWireRadius;
143 
144  public:
145 
146  inline void SetWireCurrent(G4double iC) {fWireCurrent = iC;}
147  inline G4double GetWireCurrent() const { return fWireCurrent;}
148  inline void SetWireRadius(G4double r) {fWireRadius = r;}
149  inline G4double GetWireRadius() const { return fWireRadius;}
150 };
151 #endif
152 
G4double GetHornCurrent() const
void SetSkinDepthInnerRad(G4double f)
double getNormCurrDensityInnerC(double deltaR, double rOut) const
void SetWireCurrent(G4double iC)
constexpr T pow(T x)
Definition: pow.h:72
virtual void GetFieldValue(const double Point[3], double *Bfield) const
std::vector< size_t > fEqnIndicesInner
std::vector< double > fRadsInnerC
std::vector< double > fZDCBegin
double GetEffectiveInnerRad() const
std::vector< double > fShift
double z
std::vector< double > fZDCEnd
std::vector< double > fShiftSlope
void SetHornCurrent(G4double ihorn)
G4RotationMatrix fRotMatrixHornContainer
void fillHorn1PolygonRadii(double z, double *rIn, double *rOut) const
double GetEffectiveOuterRad() const
std::vector< double > fRadsOuterC
LBNEMagneticFieldHorn(bool isHorn1)
G4double GetWireCurrent() const
std::vector< size_t > fEqnIndicesOuter
double GetEffectiveSkinDepthFact() const
void fillTrajectories(const double Point[3], double bx, double by) const