ATLAS Offline Software
Loading...
Searching...
No Matches
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
18namespace {
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 */
27constexpr double defaultB = 0.1 * Gaudi::Units::gauss;
28
29inline 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
41void
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
85void
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
Scalar phi() const
phi method
#define y
#define xyz
#define x
#define z
bool fillFieldCacheZR(double z, double r)
fill Z-R cache for solenoid *‍/
const AtlasFieldMap * m_fieldMap
handle to the magnetic field map - not owned
BFieldCache m_cache3d
Full 3d field cell/cache This will be a cell inside a 3d field zone.
BFieldCacheZR m_cacheZR
Fast 2d field cell/cache.
bool fillFieldCache(double z, double r, double phi)
fill given magnetic field zone *‍/
const std::vector< BFieldCond > * m_cond
Pointer to the conductors in the current field zone (to compute Biot-Savart component) Owned by Atlas...
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,...
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.
int r
Definition globals.cxx:22
#define ATH_RESTRICT
Definition restrict.h:31