From ca5ed801d0dbbd787abbdbea2dfcf020eca2776c Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 29 Apr 2024 16:49:45 -0700 Subject: [PATCH] Add SI units option to soft-edge solenoid. --- docs/source/usage/parameters.rst | 7 ++++++- docs/source/usage/python.rst | 5 ++++- src/initialization/InitElement.cpp | 4 +++- src/particles/elements/SoftSol.H | 21 +++++++++++++++++---- src/python/elements.cpp | 4 +++- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index 002a4591f..2f16cbed2 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -369,11 +369,16 @@ Lattice Elements * ``solenoid_softedge`` for a soft-edge solenoid. This requires these additional parameters: * ``.ds`` (``float``, in meters) the segment length - * ``.bscale`` (``float``, in inverse meters) Scaling factor for on-axis magnetic field Bz + * ``.bscale`` (``float``, in inverse meters) Scaling factor for on-axis longitudinal magnetic field + = (magnetic field Bz in T) / (magnetic rigidity in T-m) - if units = 0 + + OR = magnetic field Bz in T - if units = 1 + * ``.cos_coefficients`` (array of ``float``) cos coefficients in Fourier expansion of the on-axis magnetic field Bz (optional); default is a thin-shell model from `DOI:10.1016/J.NIMA.2022.166706 `__ * ``.sin_coefficients`` (array of ``float``) sin coefficients in Fourier expansion of the on-axis magnetic field Bz (optional); default is a thin-shell model from `DOI:10.1016/J.NIMA.2022.166706 `__ + * ``.units`` (``integer``) specification of units (default: ``0``) * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index 309498e55..ab517ed6e 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -831,11 +831,14 @@ This module provides elements for the accelerator lattice. A soft-edge solenoid. :param ds: Segment length in m. - :param bscale: Scaling factor for on-axis magnetic field Bz in inverse meters + :param bscale: Scaling factor for on-axis magnetic field Bz in inverse meters (if units = 0) + = (magnetic field Bz in T) / (rigidity in T-m) + OR Magnetic field Bz in T (SI units, if units = 1) :param cos_coefficients: array of ``float`` cosine coefficients in Fourier expansion of on-axis magnetic field Bz (optional); default is a thin-shell model from `DOI:10.1016/J.NIMA.2022.166706 `__ :param sin_coefficients: array of ``float`` sine coefficients in Fourier expansion of on-axis magnetic field Bz (optional); default is a thin-shell model from `DOI:10.1016/J.NIMA.2022.166706 `__ + :param units: specification of units for scaling of the on-axis longitudinal magnetic field :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index 9bac02b30..9c5afd6b6 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -252,15 +252,17 @@ namespace detail amrex::ParticleReal bscale; int mapsteps = mapsteps_default; + int units = 0; Sol_field_data const bz; std::vector cos_coef = bz.default_cos_coef; std::vector sin_coef = bz.default_sin_coef; pp_element.get("bscale", bscale); + pp_element.queryAdd("units", units); pp_element.queryAdd("mapsteps", mapsteps); detail::queryAddResize(pp_element, "cos_coefficients", cos_coef); detail::queryAddResize(pp_element, "sin_coefficients", sin_coef); - m_lattice.emplace_back( SoftSolenoid(ds, bscale, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice) ); + m_lattice.emplace_back( SoftSolenoid(ds, bscale, cos_coef, sin_coef, units, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice) ); } else if (element_type == "quadrupole_softedge") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); diff --git a/src/particles/elements/SoftSol.H b/src/particles/elements/SoftSol.H index 4be82eb2a..7b95d8c8a 100644 --- a/src/particles/elements/SoftSol.H +++ b/src/particles/elements/SoftSol.H @@ -126,9 +126,14 @@ namespace SoftSolenoidData /** A soft-edge solenoid * * @param ds Segment length in m - * @param bscale Scaling factor for on-axis magnetic field Bz in 1/m + * @param bscale Scaling factor for on-axis longitudinal magnetic field in 1/m (MAD-X convention) + * = (Bz in T) / (rigidity in T-m) + * OR Magnetic field Bz in T (SI units) * @param cos_coef cosine coefficients in Fourier expansion of on-axis magnetic field Bz * @param sin_coef sine coefficients in Fourier expansion of on-axis magnetic field Bz + * @param unit Unit specification + * unit = 0 MADX convention (default) + * unit = 1 SI units * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] @@ -141,6 +146,7 @@ namespace SoftSolenoidData amrex::ParticleReal bscale, std::vector cos_coef, std::vector sin_coef, + int unit, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, @@ -149,7 +155,7 @@ namespace SoftSolenoidData ) : Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - m_bscale(bscale), m_mapsteps(mapsteps), m_id(SoftSolenoidData::next_id) + m_bscale(bscale), m_unit(unit), m_mapsteps(mapsteps), m_id(SoftSolenoidData::next_id) { // next created soft solenoid has another id for its data SoftSolenoidData::next_id++; @@ -445,7 +451,10 @@ namespace SoftSolenoidData amrex::ParticleReal const pt = refpart.pt; // Define parameters and intermediate constants - amrex::ParticleReal const B0 = m_bscale; + amrex::ParticleReal B0 = m_bscale; + if (m_unit == 1) { + B0 = m_bscale / refpart.rigidity_Tm(); + } // push the reference particle auto [bz, bzp, bzint] = Sol_Bfield(zeval); @@ -491,7 +500,10 @@ namespace SoftSolenoidData amrex::ParticleReal const z = zeval; // Define parameters and intermediate constants - amrex::ParticleReal const B0 = m_bscale; + amrex::ParticleReal B0 = m_bscale; + if (m_unit == 1) { + B0 = m_bscale / refpart.rigidity_Tm(); + } // push the reference particle auto [bz, bzp, bzint] = Sol_Bfield(z); @@ -546,6 +558,7 @@ namespace SoftSolenoidData } amrex::ParticleReal m_bscale; //! scaling factor for solenoid Bz field + int m_unit; //! unit specification for quad strength int m_mapsteps; //! number of map integration steps per slice int m_id; //! unique soft solenoid id used for data lookup map diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 5325933f3..9ebd4bb58 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -992,6 +992,7 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, int, int >(), @@ -999,6 +1000,7 @@ void init_elements(py::module& m) py::arg("bscale"), py::arg("cos_coefficients"), py::arg("sin_coefficients"), + py::arg("unit") = 0, py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, @@ -1156,7 +1158,7 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, - R"doc(A thin nonlinear plasma lens with A thin nonlinear plasma lens with transverse (horizontal) taper + R"doc(A thin nonlinear plasma lens with transverse (horizontal) taper .. math::