Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:53

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0013 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0014 #include "Acts/Utilities/Result.hpp"
0015 
0016 #include <cstddef>
0017 
0018 namespace Acts {
0019 
0020 /// @ingroup MagneticField
0021 //
0022 /// @class SolenoidBField
0023 /// Implements a multi-coil solenoid magnetic field. On every call, the field
0024 /// is evaluated at that exact position. The field has radially symmetry, the
0025 /// field vectors point in +z direction.
0026 /// The config exposes a target field value in the center. This value is used
0027 /// to empirically determine a scale factor which reproduces this field value
0028 /// in the center.
0029 ///
0030 /// E_1(k^2) = complete elliptic integral of the 1st kind
0031 /// E_2(k^2) = complete elliptic integral of the 2nd kind
0032 ///
0033 /// E_1(k^2) and E_2(k^2) are usually indicated as K(k^2) and E(k^2) in
0034 /// literature,
0035 /// respectively
0036 ///              _
0037 ///     2       /  pi / 2          2    2          - 1 / 2
0038 /// E (k )  =   |         ( 1  -  k  sin {theta} )         dtheta
0039 ///  1         _/  0
0040 ///
0041 ///              _          ____________________
0042 ///     2       /  pi / 2| /       2    2
0043 /// E (k )  =   |        |/ 1  -  k  sin {theta} dtheta
0044 ///  2         _/  0
0045 ///
0046 /// k^2 = is a function of the point (r, z) and of the radius of the coil R
0047 ///
0048 ///  2           4Rr
0049 /// k   =  ---------------
0050 ///               2      2
0051 ///        (R + r)   +  z
0052 /// Using these, you can evaluate the two components B_r and B_z of the
0053 /// magnetic field:
0054 ///                            _                             _
0055 ///              mu  I        |  /     2 \                    |
0056 ///                0     kz   |  |2 - k  |    2          2    |
0057 /// B (r, z)  =  ----- ------ |  |-------|E (k )  -  E (k )   |
0058 ///  r            4pi     ___ |  |      2| 2          1       |
0059 ///                    | /  3 |_ \2 - 2k /                   _|
0060 ///                    |/ Rr
0061 ///
0062 ///                         _                                       _
0063 ///             mu  I      |  /         2      \                     |
0064 ///               0     k  |  | (R + r)k  - 2r |     2          2    |
0065 /// B (r,z)  =  ----- ---- |  | -------------- | E (k )  +  E (k )   |
0066 ///  z           4pi    __ |  |           2    |  2          1       |
0067 ///                   |/Rr |_ \   2r(1 - k )   /                    _|
0068 ///
0069 class SolenoidBField final : public MagneticFieldProvider {
0070  public:
0071   struct Cache {
0072     /// @brief Constructor with magnetic field context
0073     Cache(const MagneticFieldContext& /*mctx*/) {}
0074   };
0075 
0076   /// Config struct for the SolenoidBfield.
0077   struct Config {
0078     /// Radius at which the coils are located.
0079     double radius;
0080     /// Extent of the solenoid in z. It goes from
0081     /// -length/2 to +length/2 by convention
0082     double length;
0083     /// The number of coils that make up the solenoid
0084     std::size_t nCoils;
0085     /// The target magnetic field strength at the center.
0086     /// This will be used to scale coefficients
0087     double bMagCenter;
0088   };
0089 
0090   /// @brief the constructor with a shared pointer
0091   /// @note since it is a shared field, we enforce it to be const
0092   /// @tparam bField is the shared BField to be stored
0093   SolenoidBField(Config config);
0094 
0095   /// @brief Retrieve magnetic field value in local (r,z) coordinates
0096   ///
0097   /// @param [in] position local 2D position
0098   Vector2 getField(const Vector2& position) const;
0099 
0100   /// @copydoc MagneticFieldProvider::makeCache(const MagneticFieldContext&) const
0101   MagneticFieldProvider::Cache makeCache(
0102       const MagneticFieldContext& mctx) const override;
0103 
0104   /// @brief Get the B field at a position
0105   ///
0106   /// @param position The position to query at
0107   Vector3 getField(const Vector3& position) const;
0108 
0109   /// @copydoc MagneticFieldProvider::getField(const Vector3&,MagneticFieldProvider::Cache&) const
0110   Result<Vector3> getField(const Vector3& position,
0111                            MagneticFieldProvider::Cache& cache) const override;
0112 
0113  private:
0114   Config m_cfg;
0115   double m_scale;
0116   double m_dz;
0117   double m_R2;
0118 
0119   Vector2 multiCoilField(const Vector2& pos, double scale) const;
0120 
0121   Vector2 singleCoilField(const Vector2& pos, double scale) const;
0122 
0123   double B_r(const Vector2& pos, double scale) const;
0124 
0125   double B_z(const Vector2& pos, double scale) const;
0126 
0127   double k2(double r, double z) const;
0128 };
0129 
0130 }  // namespace Acts