ATLAS Offline Software
AtlasFieldCache.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //
6 // AtlasFieldCache.cxx
7 //
8 // Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
9 //
10 // R.D.Schaffer -at- cern.ch
11 //
13 
14 #include <cmath>
15 #include <iostream>
16 
17 
18 namespace {
19 /* In Gaudi Units
20  * Units.tesla
21  * = Units.volt * Units.second / Units.meter2 = 1e-3
22  * So 1kT is 1
23  * Unit.gauss = 1e-4 * Units.tesla
24  * the number below is 0.1 * 1e-3 * 1e-4 = 1e-8
25  * So 0.1 Gauss in Units of kT (which is what we return)
26  */
27 constexpr double defaultB = 0.1 * Gaudi::Units::gauss;
28 
29 inline void defaultField(double* ATH_RESTRICT bxyz,
30  double* ATH_RESTRICT deriv) {
31  bxyz[0] = bxyz[1] = bxyz[2] = defaultB;
32  // return zero gradient if requested
33  if (deriv) {
34  for (int i = 0; i < 9; i++) {
35  deriv[i] = 0.;
36  }
37  }
38 }
39 }
40 
41 void
43  double* ATH_RESTRICT bxyz,
44  double* ATH_RESTRICT deriv)
45 {
46  // Allow for the case of no map for testing
47  if (m_fieldMap == nullptr) {
48  defaultField(bxyz, deriv);
49  return;
50  }
51 
52  const double x = xyz[0];
53  const double y = xyz[1];
54  const double z = xyz[2];
55  const double r = std::sqrt(x * x + y * y);
56  const double phi = std::atan2(y, x);
57 
58  // Check that the cached z,r, phi cell is valid
59  // and if we are still inside it
60  if (!m_cache3d.inside(z, r, phi)) {
61  // if not we need to find and cache a new cell
62  if (!fillFieldCache(z, r, phi)) {
63  // caching failed
64  // outside the valid map volume
65  defaultField(bxyz, deriv);
66  return;
67  }
68  }
69 
70  // do interpolation (cache3d has correct scale factor)
71  m_cache3d.getB(xyz, r, phi, bxyz, deriv);
72 
73  if (!m_cond) {
74  return;
75  }
76  // add biot savart component - must add in scale factor to avoid changing
77  // conductor SF since the conductor is part of the static magnetic field model
78  const size_t condSize = m_cond->size();
79  for (size_t i = 0; i < condSize; i++) {
80  //Heavy Eigen use from here
81  (*m_cond)[i].addBiotSavart(m_scaleToUse, xyz, bxyz, deriv);
82  }
83 }
84 
85 void
87  double* ATH_RESTRICT bxyz,
88  double* ATH_RESTRICT deriv)
89 {
90 
91  // Allow for the case of no map for testing
92  if (m_fieldMap == nullptr) {
93  defaultField(bxyz, deriv);
94  return;
95  }
96 
97  const double x = xyz[0];
98  const double y = xyz[1];
99  const double z = xyz[2];
100  const double r = std::sqrt(x * x + y * y);
101 
102  // Check that the cached z,r, cell is valid
103  // and if we are still inside it
104  if (!m_cacheZR.inside(z, r)) {
105  // cached cell is invalid -> refresh cached cell
106  if (!fillFieldCacheZR(z, r)) {
107  // No cell found -> outside the valid z-r map volume
108  // fallback to calling
109  // the full version of getField()
110  getField(xyz, bxyz, deriv);
111  return;
112  }
113  }
114  // do interpolation
115  m_cacheZR.getB(xyz, r, bxyz, deriv);
116 }
117 
beamspotman.r
def r
Definition: beamspotman.py:676
MagField::AtlasFieldCache::m_scaleToUse
double m_scaleToUse
Definition: AtlasFieldCache.h:95
MagField::AtlasFieldCache::getFieldZR
void getFieldZR(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field valaue on the z-r plane at given position works only inside the solenoid.
Definition: AtlasFieldCache.cxx:86
MagField::AtlasFieldCache::m_cond
const std::vector< BFieldCond > * m_cond
Pointer to the conductors in the current field zone (to compute Biot-Savart component) Owned by Atlas...
Definition: AtlasFieldCache.h:117
xyz
#define xyz
BFieldCache::getB
void getB(const double *ATH_RESTRICT xyz, double r, double phi, double *ATH_RESTRICT B, double *ATH_RESTRICT deriv=nullptr) const
Definition: BFieldCache.cxx:99
x
#define x
ATH_RESTRICT
#define ATH_RESTRICT
Definition: restrict.h:31
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
MagField::AtlasFieldCache::m_fieldMap
const AtlasFieldMap * m_fieldMap
handle to the magnetic field map - not owned
Definition: AtlasFieldCache.h:102
AtlasFieldCache.h
MagField::AtlasFieldCache::m_cache3d
BFieldCache m_cache3d
Full 3d field cell/cache This will be a cell inside a 3d field zone.
Definition: AtlasFieldCache.h:113
BFieldCache::inside
bool inside(double z, double r, double phi) const
y
#define y
python.SystemOfUnits.gauss
int gauss
Definition: SystemOfUnits.py:230
MagField::AtlasFieldCache::fillFieldCache
bool fillFieldCache(double z, double r, double phi)
fill given magnetic field zone *‍/
MagField::AtlasFieldCache::getField
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
Definition: AtlasFieldCache.cxx:42