Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Core/include/Acts/MagneticField/ToroidField.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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/Definitions/Units.hpp"
0013 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0014 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0015 #include "Acts/Utilities/Result.hpp"
0016 
0017 #include <array>
0018 #include <vector>
0019 
0020 namespace Acts {
0021 
0022 /// Toroid magnetic field implementation
0023 ///
0024 /// This class implements a toroid magnetic field configuration similar to
0025 /// those used in ATLAS and other detector systems. It uses Biot-Savart
0026 /// calculations with discrete current-carrying wire segments to compute
0027 /// the field at any position.
0028 class ToroidField final : public MagneticFieldProvider {
0029  public:
0030   /// Configuration for barrel toroid coils
0031   struct BarrelConfig {
0032     double R_in = 4.9 * UnitConstants::m;    ///< Inner radius
0033     double R_out = 10.0 * UnitConstants::m;  ///< Outer radius
0034     double c = 25.3 * UnitConstants::m;      ///< Coil length along z
0035     double b = 0.16 * UnitConstants::m;      ///< Coil width (radial)
0036     double I = 20500.0;                      ///< Current [A]
0037     int Nturns = 120;                        ///< Number of turns
0038   };
0039 
0040   /// Configuration for end-cap toroid (ECT) coils
0041   struct EctConfig {
0042     double R_in = 1.65 * 0.5 * UnitConstants::m;   ///< Inner radius ≈ 0.825 m
0043     double R_out = 10.7 * 0.5 * UnitConstants::m;  ///< Outer radius ≈ 5.35 m
0044     double c = 5.0 * UnitConstants::m;             ///< Coil length along z
0045     double b = 0.12 * UnitConstants::m;            ///< Coil width (radial)
0046     double I = 20500.0;                            ///< Current [A]
0047     int Nturns = 116;                              ///< Number of turns
0048     double gap = 0.5 * UnitConstants::m;  ///< Gap between barrel and endcap
0049   };
0050 
0051   /// Configuration for coil layout and discretization
0052   struct LayoutConfig {
0053     double theta0 = 22.5 * UnitConstants::degree;  ///< Initial azimuthal angle
0054     double thetaStep =
0055         45.0 * UnitConstants::degree;  ///< Angular spacing between coils
0056     int nCoils = 8;                    ///< Number of coils
0057 
0058     int nArc = 200;         ///< Number of segments in arc portions
0059     int nStraight = 160;    ///< Number of segments in straight portions
0060     bool closeLoop = true;  ///< Whether to close the coil loop
0061 
0062     double eps = 1e-18;  ///< Small epsilon for numerical stability
0063   };
0064 
0065   /// Full configuration for the toroid field
0066   struct Config {
0067     BarrelConfig barrel;  ///< Barrel coil configuration
0068     EctConfig ect;        ///< End-cap toroid configuration
0069     LayoutConfig layout;  ///< Layout and discretization parameters
0070 
0071     /// Per-coil current senses (applied to dl)
0072     /// Size must be nCoils; default filled in ctor if empty
0073     std::vector<int> barrelSigns;
0074     /// Per-coil current senses for endcaps
0075     /// Size must be 2*nCoils (first +z endcap [0..nCoils-1], then -z
0076     /// [nCoils..2*nCoils-1]); default filled in ctor if empty
0077     std::vector<int> ectSigns;
0078   };
0079 
0080   /// Cache for magnetic field provider
0081   struct Cache {};
0082 
0083   /// Construct with default configuration
0084   ToroidField();
0085 
0086   /// Construct with custom configuration
0087   /// @param cfg Configuration parameters
0088   explicit ToroidField(Config cfg);
0089 
0090   /// @copydoc MagneticFieldProvider::makeCache
0091   MagneticFieldProvider::Cache makeCache(
0092       const MagneticFieldContext& mctx) const override;
0093 
0094   /// @copydoc MagneticFieldProvider::getField
0095   Result<Vector3> getField(const Vector3& position,
0096                            MagneticFieldProvider::Cache& cache) const override;
0097 
0098   /// Get the configuration
0099   /// @return Configuration struct reference
0100   const Config& config() const { return m_cfg; }
0101 
0102  private:
0103   // Helpers (declared here, defined in .cpp)
0104   static std::vector<std::array<float, 2>> ectRacetrackRadial(
0105       float Lrho, float Lz, int nArc, int nStraight, bool close);
0106 
0107   static std::vector<std::array<double, 2>> racetrackRZ(double a, double b,
0108                                                         double Lz, int nArc,
0109                                                         int nStraight,
0110                                                         bool close);
0111 
0112   static void buildSegsMidsRZ(const std::vector<std::array<double, 2>>& rz,
0113                               std::vector<std::array<double, 2>>& d_rz,
0114                               std::vector<std::array<double, 2>>& m_rz);
0115 
0116   static void mapRingToXYZ(double l,
0117                            const std::vector<std::array<double, 2>>& m_rz,
0118                            const std::vector<std::array<double, 2>>& d_rz,
0119                            double phi, int sign, double zShift,
0120                            std::vector<std::array<double, 3>>& mids_out,
0121                            std::vector<std::array<double, 3>>& segs_out);
0122 
0123   void buildGeometry();
0124 
0125   Config m_cfg;
0126 
0127   // Precomputed geometry (float storage; double accumulation)
0128   std::vector<std::array<double, 3>> m_segs_barrel;
0129   std::vector<std::array<double, 3>> m_mids_barrel;
0130 
0131   std::vector<std::array<double, 3>> m_segs_ect;  // both endcaps combined
0132   std::vector<std::array<double, 3>> m_mids_ect;
0133 
0134   void accumulateBarrelField(double X, double Y, double Z, double eps,
0135                              double pref, double& bx, double& by,
0136                              double& bz) const;
0137 
0138   void accumulateEndcapField(double X, double Y, double Z, double eps,
0139                              double pref, double& bx, double& by,
0140                              double& bz) const;
0141 };
0142 
0143 }  // namespace Acts