From 35eeb952b2489f99430255984f4075305a2ebb2c Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Wed, 8 Jan 2025 12:20:18 -0800 Subject: [PATCH 01/24] Initial files for applying aperture to thick elements. --- src/initialization/InitElement.cpp | 25 +++++- src/particles/elements/Drift.H | 14 +++- src/particles/elements/mixin/aperture.H | 100 ++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 src/particles/elements/mixin/aperture.H diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index d106a4b86..e5913deab 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -93,6 +93,28 @@ namespace detail return values; } + + /** Read the Aperture parameters xmax and ymax from inputs + * + * @param pp_element the element being read + * @return key-value pairs for xmax and ymax + */ + std::map + query_aperture (amrex::ParmParse& pp_element) + { + amrex::ParticleReal xmax = 0; + amrex::ParticleReal ymax = 0; + pp_element.query("xmax", xmax); + pp_element.query("ymax", ymax); + + std::map values = { + {"xmax", xmax}, + {"ymax", ymax} + }; + + return values; + } + } // namespace detail /** Read a lattice element @@ -128,8 +150,9 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); - m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["xmax"], b["ymax"], nslice, element_name) ); } else if (element_type == "sbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index ef1e889af..8fba111b9 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -31,6 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "Drift"; @@ -42,6 +44,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param xmax horizontal aperture in m + * @param ymax vertical aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -50,12 +54,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal xmax = 0, + amrex::ParticleReal ymax = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), - Alignment(dx, dy, rotation_degree) + Alignment(dx, dy, rotation_degree), + Aperture(xmax, ymax) { } @@ -121,6 +128,11 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + if (m_xmax > 0 && m_ymax > 0) { + apply_aperture(x, y, idcpu); //value of idcpu? + } + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H new file mode 100644 index 000000000..941b0c0ba --- /dev/null +++ b/src/particles/elements/mixin/aperture.H @@ -0,0 +1,100 @@ +/* Copyright 2022-2023 The Regents of the University of California, through Lawrence + * Berkeley National Laboratory (subject to receipt of any required + * approvals from the U.S. Dept. of Energy). All rights reserved. + * + * This file is part of ImpactX. + * + * Authors: Axel Huebl + * License: BSD-3-Clause-LBNL + */ +#ifndef IMPACTX_ELEMENTS_MIXIN_APERTURE_H +#define IMPACTX_ELEMENTS_MIXIN_APERTURE_H + +#include "particles/ImpactXParticleContainer.H" + +#include + +#include +#include +#include + + +namespace impactx::elements +{ + /** This is a helper class for applying a transverse aperture restriction to thick lattice elements + */ + struct Aperture + { + + /** A finite-length element + * + * @param xmax horizontal aperture size in m + * @param ymax vertical aperture size in m + */ + Aperture ( + amrex::ParticleReal xmax, + amrex::ParticleReal ymax + ) + : m_xmax(xmax), m_ymax(ymax) + { + } + + Aperture () = default; + Aperture (Aperture const &) = default; + Aperture& operator= (Aperture const &) = default; + Aperture (Aperture&&) = default; + Aperture& operator= (Aperture&& rhs) = default; + + ~Aperture () = default; + + /** Apply the transverse aperture + * + * @param[inout] x horizontal position relative to reference particle + * @param[inout] y vertical position relative to reference particle + * @param idcpu particle global index + */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + void apply_aperture ( + amrex::ParticleReal & AMREX_RESTRICT x, + amrex::ParticleReal & AMREX_RESTRICT y, + uint64_t & AMREX_RESTRICT idcpu + ) const { + + // scale horizontal and vertical coordinates + amrex::ParticleReal const u = x / m_xmax; + amrex::ParticleReal const v = y / m_ymax; + + // compare against the aperture boundary + if (std::pow(u,2) + std::pow(v,2) > 1_prt) { + amrex::ParticleIDWrapper{idcpu}.make_invalid(); + } + + } + + /** Horizontal aperture size + * + * @return horizontal aperture size in m + */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + amrex::ParticleReal xmax () const + { + return m_xmax; + } + + /** Vertical aperture size + * + * @return vertical aperture size in m + */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + amrex::ParticleReal ymax () const + { + return m_ymax; + } + + amrex::ParticleReal m_xmax = 0; //! horizontal aperture size [m] + amrex::ParticleReal m_ymax = 0; //! vertical aperture size [m] + }; + +} // namespace impactx::elements + +#endif // IMPACTX_ELEMENTS_MIXIN_APERTURE_H From 073c87b329c0584cbbb00dad57690007ed206acc Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:14:52 -0800 Subject: [PATCH 02/24] Update aperture.H Add namespace amrex::literals --- src/particles/elements/mixin/aperture.H | 1 + 1 file changed, 1 insertion(+) diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index 941b0c0ba..4aa377a7a 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -59,6 +59,7 @@ namespace impactx::elements amrex::ParticleReal & AMREX_RESTRICT y, uint64_t & AMREX_RESTRICT idcpu ) const { + using namespace amrex::literals; // for _rt and _prt // scale horizontal and vertical coordinates amrex::ParticleReal const u = x / m_xmax; From 960aad9a037269cc2c0be045a7a40879e005f74e Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Wed, 8 Jan 2025 14:03:00 -0800 Subject: [PATCH 03/24] Add Python bindings for drift. --- src/python/elements.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 7d1488a55..98d8c9112 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -654,7 +654,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_DipEdge); - py::class_ py_Drift(me, "Drift"); + py::class_ py_Drift(me, "Drift"); py_Drift .def("__repr__", [](Drift const & drift) { @@ -669,6 +669,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -676,6 +678,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("xmax") = 0, + py::arg("ymax") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A drift." From f764db9c9dfefe20aaf3b7779d6f346d1978f2f3 Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:27:38 -0800 Subject: [PATCH 04/24] Update elements.cpp Add Python class for aperture mixin. --- src/python/elements.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 98d8c9112..19a9deaa7 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -214,6 +214,21 @@ void init_elements(py::module& m) "rotation error in the transverse plane in degree" ) ; + + py::class_(mx, "Aperture") + .def(py::init<>(), + "Mixin class for lattice elements with a transverse aperture." + ) + .def_property_readonly("xmax", + &elements::Aperture::xmax, + "horizontal aperture in m" + ) + .def_property_readonly("ymax", + &elements::Aperture::ymax, + "vertical aperture in m" + ) + ; + // diagnostics From ffe74a0a87cd82019b57280bd6e1b9c413c35d24 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:30:32 +0000 Subject: [PATCH 05/24] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/python/elements.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 19a9deaa7..9164ebf1f 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -214,7 +214,7 @@ void init_elements(py::module& m) "rotation error in the transverse plane in degree" ) ; - + py::class_(mx, "Aperture") .def(py::init<>(), "Mixin class for lattice elements with a transverse aperture." From 3bf409e5b7050066ce1483f18c75f8aef90529a1 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Thu, 9 Jan 2025 10:56:40 -0800 Subject: [PATCH 06/24] Add draft example. --- examples/CMakeLists.txt | 17 +++ examples/aperture/analysis_aperture_thick.py | 110 +++++++++++++++++++ examples/aperture/input_aperture_thick.in | 50 +++++++++ examples/aperture/run_aperture_thick.py | 66 +++++++++++ 4 files changed, 243 insertions(+) create mode 100755 examples/aperture/analysis_aperture_thick.py create mode 100644 examples/aperture/input_aperture_thick.in create mode 100755 examples/aperture/run_aperture_thick.py diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1783ad36d..00d2de9cc 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1056,3 +1056,20 @@ add_impactx_test(linac-segment.py examples/linac_segment/analysis_linac_segment.py OFF # no plot script yet ) + +# Drift with transverse aperture ################################################ +# +# w/o space charge +add_impactx_test(aperture-thick + examples/aperture/input_aperture_thick.in + ON # ImpactX MPI-parallel + examples/aperture/analysis_aperture_thick.py + OFF # no plot script yet +) +add_impactx_test(aperture-thick.py + examples/aperture/run_aperture_thick.py + OFF # ImpactX MPI-parallel + examples/aperture/analysis_aperture_thick.py + OFF # no plot script yet +) + diff --git a/examples/aperture/analysis_aperture_thick.py b/examples/aperture/analysis_aperture_thick.py new file mode 100755 index 000000000..702cb6bc9 --- /dev/null +++ b/examples/aperture/analysis_aperture_thick.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# +# Copyright 2022-2023 ImpactX contributors +# Authors: Axel Huebl, Chad Mitchell +# License: BSD-3-Clause-LBNL +# + +import numpy as np +import openpmd_api as io +from scipy.stats import moment + + +def get_moments(beam): + """Calculate standard deviations of beam position & momenta + and emittance values + + Returns + ------- + sigx, sigy, sigt, emittance_x, emittance_y, emittance_t + """ + sigx = moment(beam["position_x"], moment=2) ** 0.5 # variance -> std dev. + sigpx = moment(beam["momentum_x"], moment=2) ** 0.5 + sigy = moment(beam["position_y"], moment=2) ** 0.5 + sigpy = moment(beam["momentum_y"], moment=2) ** 0.5 + sigt = moment(beam["position_t"], moment=2) ** 0.5 + sigpt = moment(beam["momentum_t"], moment=2) ** 0.5 + + epstrms = beam.cov(ddof=0) + emittance_x = (sigx**2 * sigpx**2 - epstrms["position_x"]["momentum_x"] ** 2) ** 0.5 + emittance_y = (sigy**2 * sigpy**2 - epstrms["position_y"]["momentum_y"] ** 2) ** 0.5 + emittance_t = (sigt**2 * sigpt**2 - epstrms["position_t"]["momentum_t"] ** 2) ** 0.5 + + return (sigx, sigy, sigt, emittance_x, emittance_y, emittance_t) + + +# initial/final beam +series = io.Series("diags/openPMD/monitor.h5", io.Access.read_only) +last_step = list(series.iterations)[-1] +initial = series.iterations[1].particles["beam"].to_df() +final = series.iterations[last_step].particles["beam"].to_df() + +series_lost = io.Series("diags/openPMD/particles_lost.h5", io.Access.read_only) +particles_lost = series_lost.iterations[0].particles["beam"].to_df() + +# compare number of particles +num_particles = 10000 +assert num_particles == len(initial) +# we lost particles in apertures +assert num_particles > len(final) +assert num_particles == len(particles_lost) + len(final) + +print("Initial Beam:") +sigx, sigy, sigt, emittance_x, emittance_y, emittance_t = get_moments(initial) +print(f" sigx={sigx:e} sigy={sigy:e} sigt={sigt:e}") +print( + f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}" +) + +atol = 0.0 # ignored +rtol = 1.8 * num_particles**-0.5 # from random sampling of a smooth distribution +print(f" rtol={rtol} (ignored: atol~={atol})") + +assert np.allclose( + [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t], + [ + 1.559531175539e-3, + 2.205510139392e-3, + 1.0e-3, + 1.0e-6, + 2.0e-6, + 1.0e-6, + ], + rtol=rtol, + atol=atol, +) + +# particle-wise comparison against the rectangular aperture boundary +xmax = 1.0e-3 +ymax = 1.5e-3 + +# kept particles +dx = abs(final["position_x"]) - xmax +dy = abs(final["position_y"]) - ymax + +print() +print(f" x_max={final['position_x'].max()}") +print(f" x_min={final['position_x'].min()}") +assert np.less_equal(dx.max(), 0.0) + +print(f" y_max={final['position_y'].max()}") +print(f" y_min={final['position_y'].min()}") +assert np.less_equal(dy.max(), 0.0) + +# lost particles +dx = abs(particles_lost["position_x"]) - xmax +dy = abs(particles_lost["position_y"]) - ymax + +print() +print(f" x_max={particles_lost['position_x'].max()}") +print(f" x_min={particles_lost['position_x'].min()}") +assert np.greater_equal(dx.max(), 0.0) + +print(f" y_max={particles_lost['position_y'].max()}") +print(f" y_min={particles_lost['position_y'].min()}") +assert np.greater_equal(dy.max(), 0.0) + +# check that s is set correctly +lost_at_s = particles_lost["s_lost"] +drift_s = np.ones_like(lost_at_s) * 0.123 +assert np.allclose(lost_at_s, drift_s) diff --git a/examples/aperture/input_aperture_thick.in b/examples/aperture/input_aperture_thick.in new file mode 100644 index 000000000..5d0461456 --- /dev/null +++ b/examples/aperture/input_aperture_thick.in @@ -0,0 +1,50 @@ +############################################################################### +# Particle Beam(s) +############################################################################### +beam.npart = 10000 +beam.units = static +beam.kin_energy = 250.0 +beam.charge = 1.0e-9 +beam.particle = proton +beam.distribution = waterbag +beam.lambdaX = 1.559531175539e-3 +beam.lambdaY = 2.205510139392e-3 +beam.lambdaT = 1.0e-3 +beam.lambdaPx = 6.41218345413e-4 +beam.lambdaPy = 9.06819680526e-4 +beam.lambdaPt = 1.0e-3 +beam.muxpx = 0.0 +beam.muypy = 0.0 +beam.mutpt = 0.0 + + +############################################################################### +# Beamline: lattice elements and segments +############################################################################### +lattice.elements = monitor drift monitor +lattice.nslice = 1 + +monitor.type = beam_monitor +monitor.backend = h5 + +drift.type = drift +drift.ds = 0.123 +drift.xmax = 1.0e-3 +drift.ymax = 1.5e-3 + +# work-around for https://github.com/ECP-WarpX/impactx/issues/499 +amrex.the_arena_is_managed = 1 + + +############################################################################### +# Algorithms +############################################################################### +algo.particle_shape = 2 +algo.space_charge = false + + +############################################################################### +# Diagnostics +############################################################################### +diag.slice_step_diagnostics = true +diag.backend = h5 diff --git a/examples/aperture/run_aperture_thick.py b/examples/aperture/run_aperture_thick.py new file mode 100755 index 000000000..4263ded72 --- /dev/null +++ b/examples/aperture/run_aperture_thick.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# +# Copyright 2022-2023 ImpactX contributors +# Authors: Axel Huebl, Chad Mitchell +# License: BSD-3-Clause-LBNL +# +# -*- coding: utf-8 -*- + +import amrex.space3d as amr +from impactx import ImpactX, distribution, elements + +# work-around for https://github.com/ECP-WarpX/impactx/issues/499 +pp_amrex = amr.ParmParse("amrex") +pp_amrex.add("the_arena_is_managed", 1) + +sim = ImpactX() + +# set numerical parameters and IO control +sim.particle_shape = 2 # B-spline order +sim.space_charge = False +# sim.diagnostics = False # benchmarking +sim.slice_step_diagnostics = True +sim.particle_lost_diagnostics_backend = "h5" + +# domain decomposition & space charge mesh +sim.init_grids() + +# load a 250 MeV proton beam with an initial +# horizontal rms emittance of 1 um and an +# initial vertical rms emittance of 2 um +kin_energy_MeV = 250.0 # reference energy +bunch_charge_C = 1.0e-9 # used with space charge +npart = 10000 # number of macro particles + +# reference particle +ref = sim.particle_container().ref_particle() +ref.set_charge_qe(1.0).set_mass_MeV(938.27208816).set_kin_energy_MeV(kin_energy_MeV) + +# particle bunch +distr = distribution.Waterbag( + lambdaX=1.559531175539e-3, + lambdaY=2.205510139392e-3, + lambdaT=1.0e-3, + lambdaPx=6.41218345413e-4, + lambdaPy=9.06819680526e-4, + lambdaPt=1.0e-3, +) +sim.add_particles(bunch_charge_C, distr, npart) + +# add beam diagnostics +monitor = elements.BeamMonitor("monitor", backend="h5") + +# design the accelerator lattice +sim.lattice.extend( + [ + monitor, + elements.Drift(name="drift", ds=0.123, xmax=1.0e-3, ymax=1.5e-3), + monitor, + ] +) + +# run simulation +sim.track_particles() + +# clean shutdown +sim.finalize() From c550b950a02c327ddc9a49cdaaaeec89f0c4faaa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:57:22 +0000 Subject: [PATCH 07/24] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 00d2de9cc..7610f93cf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1072,4 +1072,3 @@ add_impactx_test(aperture-thick.py examples/aperture/analysis_aperture_thick.py OFF # no plot script yet ) - From 99967d8852ef0a54f0da1dddfc10c34afd74094f Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Thu, 9 Jan 2025 11:13:45 -0800 Subject: [PATCH 08/24] Move if conditional into mixin. --- src/particles/elements/Drift.H | 4 +--- src/particles/elements/mixin/aperture.H | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index 8fba111b9..dcc906b77 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -129,9 +129,7 @@ namespace impactx pt = ptout; // apply transverse aperture - if (m_xmax > 0 && m_ymax > 0) { - apply_aperture(x, y, idcpu); //value of idcpu? - } + apply_aperture(x, y, idcpu); //value of idcpu? // undo shift due to alignment errors of the element shift_out(x, y, px, py); diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index 4aa377a7a..fb5ffc36e 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -61,15 +61,21 @@ namespace impactx::elements ) const { using namespace amrex::literals; // for _rt and _prt - // scale horizontal and vertical coordinates - amrex::ParticleReal const u = x / m_xmax; - amrex::ParticleReal const v = y / m_ymax; + // skip aperture if xmax=0 or ymax=0 + if (m_xmax > 0 && m_ymax > 0) { + + // scale horizontal and vertical coordinates + amrex::ParticleReal const u = x / m_xmax; + amrex::ParticleReal const v = y / m_ymax; + + // compare against the aperture boundary + if (std::pow(u,2) + std::pow(v,2) > 1_prt) { + amrex::ParticleIDWrapper{idcpu}.make_invalid(); + } - // compare against the aperture boundary - if (std::pow(u,2) + std::pow(v,2) > 1_prt) { - amrex::ParticleIDWrapper{idcpu}.make_invalid(); } + } /** Horizontal aperture size From 5ff2ee4efdd4598bbbe837e779fb95bffb5e3154 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Thu, 9 Jan 2025 14:47:50 -0800 Subject: [PATCH 09/24] Add drift aperture input documentation. --- docs/source/usage/parameters.rst | 2 ++ docs/source/usage/python.rst | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index 3d391093c..a16a1ffa5 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -135,6 +135,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.xmax`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.ymax`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift_chromatic`` for a free drift, with chromatic effects included. diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index 16df118cc..6a26ee1ba 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -570,11 +570,16 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :param name: an optional name for the element -.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, xmax=0, ymax=0, nslice=1, name=None) A drift. :param ds: Segment length in m + :param dx: horizontal translation error in m + :param dy: vertical translation error in m + :param rotation: rotation error in the transverse plane [degrees] + :param xmax: horizontal half-aperture (elliptical) in m + :param ymax: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element From 578e7f284e2c8de3e572a6926c75d7d5d4213c2a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 22:50:03 +0000 Subject: [PATCH 10/24] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/source/usage/parameters.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index a16a1ffa5..7e49be210 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -136,7 +136,7 @@ Lattice Elements * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane * ``.xmax`` (``float``, in meters) horizontal half-aperture (elliptical) - * ``.ymax`` (``float``, in meters) vertical half-aperture (elliptical) + * ``.ymax`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift_chromatic`` for a free drift, with chromatic effects included. From a130d241e55f34e884344c7235bf96f525d4f452 Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:08:41 -0800 Subject: [PATCH 11/24] Apply suggestions from code review Small changes (excluding naming and std::optional). Co-authored-by: Axel Huebl --- examples/aperture/input_aperture_thick.in | 3 --- examples/aperture/run_aperture_thick.py | 5 ----- src/particles/elements/mixin/aperture.H | 14 +++++--------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/examples/aperture/input_aperture_thick.in b/examples/aperture/input_aperture_thick.in index 5d0461456..59dc41ca4 100644 --- a/examples/aperture/input_aperture_thick.in +++ b/examples/aperture/input_aperture_thick.in @@ -32,9 +32,6 @@ drift.ds = 0.123 drift.xmax = 1.0e-3 drift.ymax = 1.5e-3 -# work-around for https://github.com/ECP-WarpX/impactx/issues/499 -amrex.the_arena_is_managed = 1 - ############################################################################### # Algorithms diff --git a/examples/aperture/run_aperture_thick.py b/examples/aperture/run_aperture_thick.py index 4263ded72..bd68ce4cd 100755 --- a/examples/aperture/run_aperture_thick.py +++ b/examples/aperture/run_aperture_thick.py @@ -6,13 +6,8 @@ # # -*- coding: utf-8 -*- -import amrex.space3d as amr from impactx import ImpactX, distribution, elements -# work-around for https://github.com/ECP-WarpX/impactx/issues/499 -pp_amrex = amr.ParmParse("amrex") -pp_amrex.add("the_arena_is_managed", 1) - sim = ImpactX() # set numerical parameters and IO control diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index fb5ffc36e..18ca14eb9 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -1,21 +1,19 @@ -/* Copyright 2022-2023 The Regents of the University of California, through Lawrence +/* Copyright 2022-2025 The Regents of the University of California, through Lawrence * Berkeley National Laboratory (subject to receipt of any required * approvals from the U.S. Dept. of Energy). All rights reserved. * * This file is part of ImpactX. * - * Authors: Axel Huebl + * Authors: Axel Huebl, Chad Mitchell * License: BSD-3-Clause-LBNL */ #ifndef IMPACTX_ELEMENTS_MIXIN_APERTURE_H #define IMPACTX_ELEMENTS_MIXIN_APERTURE_H -#include "particles/ImpactXParticleContainer.H" - -#include - -#include #include +#include +#include +#include #include @@ -74,8 +72,6 @@ namespace impactx::elements } } - - } /** Horizontal aperture size From 13980efa9cf83d4dc35bc544f282cba57595337c Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:24:23 -0800 Subject: [PATCH 12/24] Update Drift.H Remove "maybe unused". --- src/particles/elements/Drift.H | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index dcc906b77..a493c71a2 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -77,7 +77,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -88,7 +88,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { From 0554261427c32a2fa84a05ff1feef9bdc07824c0 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Fri, 10 Jan 2025 10:39:37 -0800 Subject: [PATCH 13/24] Change name xmax -> x_aperture... --- docs/source/usage/parameters.rst | 4 +-- docs/source/usage/python.rst | 6 ++--- examples/aperture/input_aperture_thick.in | 4 +-- examples/aperture/run_aperture_thick.py | 2 +- src/initialization/InitElement.cpp | 18 +++++++------- src/particles/elements/Drift.H | 10 ++++---- src/particles/elements/mixin/aperture.H | 30 +++++++++++------------ src/python/elements.cpp | 4 +-- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index 7e49be210..a5b2efc87 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -135,8 +135,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane - * ``.xmax`` (``float``, in meters) horizontal half-aperture (elliptical) - * ``.ymax`` (``float``, in meters) vertical half-aperture (elliptical) + * ``.x_aperture`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.y_aperture`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift_chromatic`` for a free drift, with chromatic effects included. diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index 6a26ee1ba..a8ae412d5 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -570,7 +570,7 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :param name: an optional name for the element -.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, xmax=0, ymax=0, nslice=1, name=None) +.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, x_aperture=0, y_aperture=0, nslice=1, name=None) A drift. @@ -578,8 +578,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] - :param xmax: horizontal half-aperture (elliptical) in m - :param ymax: vertical half-aperture (elliptical) in m + :param x_aperture: horizontal half-aperture (elliptical) in m + :param y_aperture: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element diff --git a/examples/aperture/input_aperture_thick.in b/examples/aperture/input_aperture_thick.in index 59dc41ca4..339c0de16 100644 --- a/examples/aperture/input_aperture_thick.in +++ b/examples/aperture/input_aperture_thick.in @@ -29,8 +29,8 @@ monitor.backend = h5 drift.type = drift drift.ds = 0.123 -drift.xmax = 1.0e-3 -drift.ymax = 1.5e-3 +drift.x_aperture = 1.0e-3 +drift.y_aperture = 1.5e-3 ############################################################################### diff --git a/examples/aperture/run_aperture_thick.py b/examples/aperture/run_aperture_thick.py index bd68ce4cd..11895b180 100755 --- a/examples/aperture/run_aperture_thick.py +++ b/examples/aperture/run_aperture_thick.py @@ -49,7 +49,7 @@ sim.lattice.extend( [ monitor, - elements.Drift(name="drift", ds=0.123, xmax=1.0e-3, ymax=1.5e-3), + elements.Drift(name="drift", ds=0.123, x_aperture=1.0e-3, y_aperture=1.5e-3), monitor, ] ) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index e5913deab..3777e7013 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -94,22 +94,22 @@ namespace detail return values; } - /** Read the Aperture parameters xmax and ymax from inputs + /** Read the Aperture parameters x_aperture and y_aperture from inputs * * @param pp_element the element being read - * @return key-value pairs for xmax and ymax + * @return key-value pairs for x_aperture and y_aperture */ std::map query_aperture (amrex::ParmParse& pp_element) { - amrex::ParticleReal xmax = 0; - amrex::ParticleReal ymax = 0; - pp_element.query("xmax", xmax); - pp_element.query("ymax", ymax); + amrex::ParticleReal x_aperture = 0; + amrex::ParticleReal y_aperture = 0; + pp_element.query("x_aperture", x_aperture); + pp_element.query("y_aperture", y_aperture); std::map values = { - {"xmax", xmax}, - {"ymax", ymax} + {"x_aperture", x_aperture}, + {"y_aperture", y_aperture} }; return values; @@ -152,7 +152,7 @@ namespace detail auto a = detail::query_alignment(pp_element); auto b = detail::query_aperture(pp_element); - m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["xmax"], b["ymax"], nslice, element_name) ); + m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["x_aperture"], b["y_aperture"], nslice, element_name) ); } else if (element_type == "sbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index a493c71a2..43b0120ef 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -44,8 +44,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] - * @param xmax horizontal aperture in m - * @param ymax vertical aperture in m + * @param x_aperture horizontal half-aperture in m + * @param y_aperture vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -54,15 +54,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - amrex::ParticleReal xmax = 0, - amrex::ParticleReal ymax = 0, + amrex::ParticleReal x_aperture = 0, + amrex::ParticleReal y_aperture = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(xmax, ymax) + Aperture(x_aperture, y_aperture) { } diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index 18ca14eb9..6674f4ea1 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -26,14 +26,14 @@ namespace impactx::elements /** A finite-length element * - * @param xmax horizontal aperture size in m - * @param ymax vertical aperture size in m + * @param x_aperture horizontal half-aperture size in m + * @param y_aperture vertical half-aperture size in m */ Aperture ( - amrex::ParticleReal xmax, - amrex::ParticleReal ymax + amrex::ParticleReal x_aperture, + amrex::ParticleReal y_aperture ) - : m_xmax(xmax), m_ymax(ymax) + : m_x_aperture(x_aperture), m_y_aperture(y_aperture) { } @@ -59,12 +59,12 @@ namespace impactx::elements ) const { using namespace amrex::literals; // for _rt and _prt - // skip aperture if xmax=0 or ymax=0 - if (m_xmax > 0 && m_ymax > 0) { + // skip aperture application if x_aperture <= 0 or y_aperture <= 0 + if (m_x_aperture > 0 && m_y_aperture > 0) { // scale horizontal and vertical coordinates - amrex::ParticleReal const u = x / m_xmax; - amrex::ParticleReal const v = y / m_ymax; + amrex::ParticleReal const u = x / m_x_aperture; + amrex::ParticleReal const v = y / m_y_aperture; // compare against the aperture boundary if (std::pow(u,2) + std::pow(v,2) > 1_prt) { @@ -79,9 +79,9 @@ namespace impactx::elements * @return horizontal aperture size in m */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - amrex::ParticleReal xmax () const + amrex::ParticleReal x_aperture () const { - return m_xmax; + return m_x_aperture; } /** Vertical aperture size @@ -89,13 +89,13 @@ namespace impactx::elements * @return vertical aperture size in m */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - amrex::ParticleReal ymax () const + amrex::ParticleReal y_aperture () const { - return m_ymax; + return m_y_aperture; } - amrex::ParticleReal m_xmax = 0; //! horizontal aperture size [m] - amrex::ParticleReal m_ymax = 0; //! vertical aperture size [m] + amrex::ParticleReal m_x_aperture = 0; //! horizontal aperture size [m] + amrex::ParticleReal m_y_aperture = 0; //! vertical aperture size [m] }; } // namespace impactx::elements diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 9164ebf1f..ee6db7f7d 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -693,8 +693,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, - py::arg("xmax") = 0, - py::arg("ymax") = 0, + py::arg("x_aperture") = 0, + py::arg("y_aperture") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A drift." From fb572fe2bf42b8d65044f78d6086dc67703ad2a0 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Fri, 10 Jan 2025 10:47:17 -0800 Subject: [PATCH 14/24] Fix one missing xmax -> x_aperture in elements.cpp. --- src/python/elements.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/elements.cpp b/src/python/elements.cpp index ee6db7f7d..670e13061 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -219,12 +219,12 @@ void init_elements(py::module& m) .def(py::init<>(), "Mixin class for lattice elements with a transverse aperture." ) - .def_property_readonly("xmax", - &elements::Aperture::xmax, + .def_property_readonly("x_aperture", + &elements::Aperture::x_aperture, "horizontal aperture in m" ) - .def_property_readonly("ymax", - &elements::Aperture::ymax, + .def_property_readonly("y_aperture", + &elements::Aperture::y_aperture, "vertical aperture in m" ) ; From 68bb406bd3678f9888236240be64ecd4f12f1fec Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Fri, 10 Jan 2025 12:16:28 -0800 Subject: [PATCH 15/24] Modify naming x_aperture -> aperture_x. --- docs/source/usage/parameters.rst | 4 +-- docs/source/usage/python.rst | 6 ++--- examples/aperture/input_aperture_thick.in | 4 +-- examples/aperture/run_aperture_thick.py | 2 +- src/initialization/InitElement.cpp | 18 +++++++------- src/particles/elements/Drift.H | 10 ++++---- src/particles/elements/mixin/aperture.H | 30 +++++++++++------------ src/python/elements.cpp | 12 ++++----- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index a5b2efc87..4d4c5be6b 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -135,8 +135,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane - * ``.x_aperture`` (``float``, in meters) horizontal half-aperture (elliptical) - * ``.y_aperture`` (``float``, in meters) vertical half-aperture (elliptical) + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift_chromatic`` for a free drift, with chromatic effects included. diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index a8ae412d5..8bdcd1dbe 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -570,7 +570,7 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :param name: an optional name for the element -.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, x_aperture=0, y_aperture=0, nslice=1, name=None) +.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A drift. @@ -578,8 +578,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] - :param x_aperture: horizontal half-aperture (elliptical) in m - :param y_aperture: vertical half-aperture (elliptical) in m + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element diff --git a/examples/aperture/input_aperture_thick.in b/examples/aperture/input_aperture_thick.in index 339c0de16..0921240b0 100644 --- a/examples/aperture/input_aperture_thick.in +++ b/examples/aperture/input_aperture_thick.in @@ -29,8 +29,8 @@ monitor.backend = h5 drift.type = drift drift.ds = 0.123 -drift.x_aperture = 1.0e-3 -drift.y_aperture = 1.5e-3 +drift.aperture_x = 1.0e-3 +drift.aperture_y = 1.5e-3 ############################################################################### diff --git a/examples/aperture/run_aperture_thick.py b/examples/aperture/run_aperture_thick.py index 11895b180..6184c7946 100755 --- a/examples/aperture/run_aperture_thick.py +++ b/examples/aperture/run_aperture_thick.py @@ -49,7 +49,7 @@ sim.lattice.extend( [ monitor, - elements.Drift(name="drift", ds=0.123, x_aperture=1.0e-3, y_aperture=1.5e-3), + elements.Drift(name="drift", ds=0.123, aperture_x=1.0e-3, aperture_y=1.5e-3), monitor, ] ) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index 3777e7013..aba8cdcb3 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -94,22 +94,22 @@ namespace detail return values; } - /** Read the Aperture parameters x_aperture and y_aperture from inputs + /** Read the Aperture parameters aperture_x and aperture_y from inputs * * @param pp_element the element being read - * @return key-value pairs for x_aperture and y_aperture + * @return key-value pairs for aperture_x and aperture_y */ std::map query_aperture (amrex::ParmParse& pp_element) { - amrex::ParticleReal x_aperture = 0; - amrex::ParticleReal y_aperture = 0; - pp_element.query("x_aperture", x_aperture); - pp_element.query("y_aperture", y_aperture); + amrex::ParticleReal aperture_x = 0; + amrex::ParticleReal aperture_y = 0; + pp_element.query("aperture_x", aperture_x); + pp_element.query("aperture_y", aperture_y); std::map values = { - {"x_aperture", x_aperture}, - {"y_aperture", y_aperture} + {"aperture_x", aperture_x}, + {"aperture_y", aperture_y} }; return values; @@ -152,7 +152,7 @@ namespace detail auto a = detail::query_alignment(pp_element); auto b = detail::query_aperture(pp_element); - m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["x_aperture"], b["y_aperture"], nslice, element_name) ); + m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["y_aperture"], nslice, element_name) ); } else if (element_type == "sbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index 43b0120ef..129f3412f 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -44,8 +44,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] - * @param x_aperture horizontal half-aperture in m - * @param y_aperture vertical half-aperture in m + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -54,15 +54,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - amrex::ParticleReal x_aperture = 0, - amrex::ParticleReal y_aperture = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(x_aperture, y_aperture) + Aperture(aperture_x, aperture_y) { } diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index 6674f4ea1..f77f6c2fe 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -26,14 +26,14 @@ namespace impactx::elements /** A finite-length element * - * @param x_aperture horizontal half-aperture size in m - * @param y_aperture vertical half-aperture size in m + * @param aperture_x horizontal half-aperture size in m + * @param aperture_y vertical half-aperture size in m */ Aperture ( - amrex::ParticleReal x_aperture, - amrex::ParticleReal y_aperture + amrex::ParticleReal aperture_x, + amrex::ParticleReal aperture_y ) - : m_x_aperture(x_aperture), m_y_aperture(y_aperture) + : m_aperture_x(aperture_x), m_aperture_y(aperture_y) { } @@ -59,12 +59,12 @@ namespace impactx::elements ) const { using namespace amrex::literals; // for _rt and _prt - // skip aperture application if x_aperture <= 0 or y_aperture <= 0 - if (m_x_aperture > 0 && m_y_aperture > 0) { + // skip aperture application if aperture_x <= 0 or aperture_y <= 0 + if (m_aperture_x > 0 && m_aperture_y > 0) { // scale horizontal and vertical coordinates - amrex::ParticleReal const u = x / m_x_aperture; - amrex::ParticleReal const v = y / m_y_aperture; + amrex::ParticleReal const u = x / m_aperture_x; + amrex::ParticleReal const v = y / m_aperture_y; // compare against the aperture boundary if (std::pow(u,2) + std::pow(v,2) > 1_prt) { @@ -79,9 +79,9 @@ namespace impactx::elements * @return horizontal aperture size in m */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - amrex::ParticleReal x_aperture () const + amrex::ParticleReal aperture_x () const { - return m_x_aperture; + return m_aperture_x; } /** Vertical aperture size @@ -89,13 +89,13 @@ namespace impactx::elements * @return vertical aperture size in m */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - amrex::ParticleReal y_aperture () const + amrex::ParticleReal aperture_y () const { - return m_y_aperture; + return m_aperture_y; } - amrex::ParticleReal m_x_aperture = 0; //! horizontal aperture size [m] - amrex::ParticleReal m_y_aperture = 0; //! vertical aperture size [m] + amrex::ParticleReal m_aperture_x = 0; //! horizontal aperture size [m] + amrex::ParticleReal m_aperture_y = 0; //! vertical aperture size [m] }; } // namespace impactx::elements diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 670e13061..58d1e8358 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -219,12 +219,12 @@ void init_elements(py::module& m) .def(py::init<>(), "Mixin class for lattice elements with a transverse aperture." ) - .def_property_readonly("x_aperture", - &elements::Aperture::x_aperture, + .def_property_readonly("aperture_x", + &elements::Aperture::aperture_x, "horizontal aperture in m" ) - .def_property_readonly("y_aperture", - &elements::Aperture::y_aperture, + .def_property_readonly("aperture_y", + &elements::Aperture::aperture_y, "vertical aperture in m" ) ; @@ -693,8 +693,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, - py::arg("x_aperture") = 0, - py::arg("y_aperture") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A drift." From 144e529f1bbbcac01297e9885695a71f64e5f068 Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Fri, 10 Jan 2025 12:23:11 -0800 Subject: [PATCH 16/24] Update src/initialization/InitElement.cpp --- src/initialization/InitElement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index aba8cdcb3..b049c9a82 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -152,7 +152,7 @@ namespace detail auto a = detail::query_alignment(pp_element); auto b = detail::query_aperture(pp_element); - m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["y_aperture"], nslice, element_name) ); + m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "sbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); From 77c1d1770371d8dde4d4656a7cff0bba4f0f90e9 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 13 Jan 2025 14:35:32 -0800 Subject: [PATCH 17/24] Test workflow for adding elements using CFbend. --- src/initialization/InitElement.cpp | 3 ++- src/particles/elements/CFbend.H | 14 ++++++++++++-- src/python/elements.cpp | 6 +++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index b049c9a82..3913a6d58 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -166,12 +166,13 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal rc, k; pp_element.get("rc", rc); pp_element.get("k", k); - m_lattice.emplace_back( CFbend(ds, rc, k, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( CFbend(ds, rc, k, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "dipedge") { auto a = detail::query_alignment(pp_element); diff --git a/src/particles/elements/CFbend.H b/src/particles/elements/CFbend.H index 409f70146..891292179 100644 --- a/src/particles/elements/CFbend.H +++ b/src/particles/elements/CFbend.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -31,6 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "CFbend"; @@ -48,6 +50,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -58,12 +62,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_rc(rc), m_k(k) { } @@ -79,7 +86,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -90,7 +97,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -177,6 +184,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 58d1e8358..46a80bb8f 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -1170,7 +1170,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Sbend); - py::class_ py_CFbend(me, "CFbend"); + py::class_ py_CFbend(me, "CFbend"); py_CFbend .def("__repr__", [](CFbend const & cfbend) { @@ -1189,6 +1189,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -1198,6 +1200,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "An ideal combined function bend (sector bend with quadrupole component)." From 14f4a4c69dc83bb636cc6ba1e45a90a0347d788c Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 13 Jan 2025 17:41:23 -0800 Subject: [PATCH 18/24] Add aperture input to all thick elements. --- src/initialization/InitElement.cpp | 39 ++++++++----- src/particles/elements/ChrDrift.H | 16 +++++- src/particles/elements/ChrPlasmaLens.H | 14 ++++- src/particles/elements/ChrQuad.H | 14 ++++- src/particles/elements/ChrUniformAcc.H | 14 ++++- src/particles/elements/ConstF.H | 14 ++++- src/particles/elements/ExactDrift.H | 16 +++++- src/particles/elements/ExactSbend.H | 14 ++++- src/particles/elements/Quad.H | 14 ++++- src/particles/elements/RFCavity.H | 16 +++++- src/particles/elements/Sbend.H | 14 ++++- src/particles/elements/SoftQuad.H | 16 +++++- src/particles/elements/SoftSol.H | 16 +++++- src/particles/elements/Sol.H | 14 ++++- src/python/elements.cpp | 76 ++++++++++++++++++++++---- 15 files changed, 251 insertions(+), 56 deletions(-) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index 5c59f3a33..ec19c1d41 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -144,11 +144,12 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal k; pp_element.get("k", k); - m_lattice.emplace_back( Quad(ds, k, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( Quad(ds, k, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "drift") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -160,11 +161,12 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal rc; pp_element.get("rc", rc); - m_lattice.emplace_back( Sbend(ds, rc, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( Sbend(ds, rc, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "cfbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -191,13 +193,14 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::Real kx, ky, kt; pp_element.get("kx", kx); pp_element.get("ky", ky); pp_element.get("kt", kt); - m_lattice.emplace_back( ConstF(ds, kx, ky, kt, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ConstF(ds, kx, ky, kt, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "buncher") { auto a = detail::query_alignment(pp_element); @@ -242,6 +245,7 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal escale, freq, phase; int mapsteps = mapsteps_default; @@ -255,16 +259,17 @@ namespace detail detail::queryAddResize(pp_element, "cos_coefficients", cos_coef); detail::queryAddResize(pp_element, "sin_coefficients", sin_coef); - m_lattice.emplace_back( RFCavity(ds, escale, freq, phase, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice, element_name) ); + m_lattice.emplace_back( RFCavity(ds, escale, freq, phase, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], mapsteps, nslice, element_name) ); } else if (element_type == "solenoid") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal ks; pp_element.get("ks", ks); - m_lattice.emplace_back( Sol(ds, ks, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( Sol(ds, ks, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "prot") { amrex::ParticleReal phi_in, phi_out; @@ -284,6 +289,7 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal bscale; int mapsteps = mapsteps_default; @@ -297,11 +303,12 @@ namespace detail 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, units, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice, element_name) ); + m_lattice.emplace_back( SoftSolenoid(ds, bscale, cos_coef, sin_coef, units, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], mapsteps, nslice, element_name) ); } else if (element_type == "quadrupole_softedge") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal gscale; int mapsteps = mapsteps_default; @@ -313,16 +320,18 @@ namespace detail detail::queryAddResize(pp_element, "cos_coefficients", cos_coef); detail::queryAddResize(pp_element, "sin_coefficients", sin_coef); - m_lattice.emplace_back( SoftQuadrupole(ds, gscale, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice, element_name) ); + m_lattice.emplace_back( SoftQuadrupole(ds, gscale, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], mapsteps, nslice, element_name) ); } else if (element_type == "drift_chromatic") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); - m_lattice.emplace_back( ChrDrift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ChrDrift(ds, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "quad_chromatic") { auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); amrex::ParticleReal k; @@ -330,10 +339,11 @@ namespace detail pp_element.get("k", k); pp_element.queryAdd("units", units); - m_lattice.emplace_back( ChrQuad(ds, k, units, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ChrQuad(ds, k, units, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "plasma_lens_chromatic") { auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); amrex::ParticleReal k; @@ -341,7 +351,7 @@ namespace detail pp_element.get("k", k); pp_element.queryAdd("units", units); - m_lattice.emplace_back( ChrPlasmaLens(ds, k, units, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ChrPlasmaLens(ds, k, units, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "tapered_plasma_lens") { auto a = detail::query_alignment(pp_element); @@ -358,29 +368,32 @@ namespace detail { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); - m_lattice.emplace_back( ExactDrift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ExactDrift(ds, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "sbend_exact") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal phi; amrex::ParticleReal B = 0.0; pp_element.get("phi", phi); pp_element.queryAdd("B", B); - m_lattice.emplace_back( ExactSbend(ds, phi, B, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ExactSbend(ds, phi, B, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "uniform_acc_chromatic") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); + auto b = detail::query_aperture(pp_element); amrex::ParticleReal ez, bz; pp_element.get("ez", ez); pp_element.get("bz", bz); - m_lattice.emplace_back( ChrAcc(ds, ez, bz, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); + m_lattice.emplace_back( ChrAcc(ds, ez, bz, a["dx"], a["dy"], a["rotation_degree"], b["aperture_x"], b["aperture_y"], nslice, element_name) ); } else if (element_type == "thin_dipole") { auto a = detail::query_alignment(pp_element); diff --git a/src/particles/elements/ChrDrift.H b/src/particles/elements/ChrDrift.H index 6b59d8b06..71909e3e7 100644 --- a/src/particles/elements/ChrDrift.H +++ b/src/particles/elements/ChrDrift.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -30,6 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ChrDrift"; @@ -44,6 +46,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -52,12 +56,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), - Alignment(dx, dy, rotation_degree) + Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y) { } @@ -72,7 +79,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -83,7 +90,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -133,6 +140,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/ChrPlasmaLens.H b/src/particles/elements/ChrPlasmaLens.H index bfe0fe78c..703d5149c 100644 --- a/src/particles/elements/ChrPlasmaLens.H +++ b/src/particles/elements/ChrPlasmaLens.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -30,6 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ChrPlasmaLens"; @@ -50,6 +52,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -60,12 +64,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_k(k), m_unit(unit) { } @@ -81,7 +88,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -92,7 +99,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -171,6 +178,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/ChrQuad.H b/src/particles/elements/ChrQuad.H index 5e246341b..0cdbf9fc2 100644 --- a/src/particles/elements/ChrQuad.H +++ b/src/particles/elements/ChrQuad.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -31,6 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ChrQuad"; @@ -53,6 +55,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -63,12 +67,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_k(k), m_unit(unit) { } @@ -84,7 +91,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -95,7 +102,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -210,6 +217,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/ChrUniformAcc.H b/src/particles/elements/ChrUniformAcc.H index 45d7fd056..28085fd48 100644 --- a/src/particles/elements/ChrUniformAcc.H +++ b/src/particles/elements/ChrUniformAcc.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -30,6 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ChrAcc"; @@ -48,6 +50,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -58,12 +62,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_ez(ez), m_bz(bz) { } @@ -79,7 +86,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -90,7 +97,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -173,6 +180,9 @@ namespace impactx py = py/bgf; pt = pt/bgf; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/ConstF.H b/src/particles/elements/ConstF.H index 10ab1077c..8c7b74c1a 100644 --- a/src/particles/elements/ConstF.H +++ b/src/particles/elements/ConstF.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -30,6 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ConstF"; @@ -44,6 +46,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -55,12 +59,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_kx(kx), m_ky(ky), m_kt(kt) { } @@ -76,7 +83,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -87,7 +94,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart) const { using namespace amrex::literals; // for _rt and _prt @@ -128,6 +135,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/ExactDrift.H b/src/particles/elements/ExactDrift.H index 6f3a4060f..e563914fc 100644 --- a/src/particles/elements/ExactDrift.H +++ b/src/particles/elements/ExactDrift.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -30,6 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ExactDrift"; @@ -41,6 +43,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -49,12 +53,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), - Alignment(dx, dy, rotation_degree) + Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y) { } @@ -70,7 +77,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -81,7 +88,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -124,6 +131,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/ExactSbend.H b/src/particles/elements/ExactSbend.H index 083ae0c58..3a9a9fccc 100644 --- a/src/particles/elements/ExactSbend.H +++ b/src/particles/elements/ExactSbend.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -32,6 +33,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "ExactSbend"; @@ -56,6 +58,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -66,12 +70,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_phi(phi * degree2rad), m_B(B) { } @@ -96,7 +103,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -107,7 +114,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -160,6 +167,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/Quad.H b/src/particles/elements/Quad.H index be0464ea8..5396c34eb 100644 --- a/src/particles/elements/Quad.H +++ b/src/particles/elements/Quad.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -30,6 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "Quad"; @@ -45,6 +47,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -54,12 +58,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_k(k) { } @@ -75,7 +82,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -86,7 +93,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -152,6 +159,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/RFCavity.H b/src/particles/elements/RFCavity.H index c9fc02d57..80f8df407 100644 --- a/src/particles/elements/RFCavity.H +++ b/src/particles/elements/RFCavity.H @@ -13,6 +13,7 @@ #include "particles/ImpactXParticleContainer.H" #include "particles/integrators/Integrators.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/named.H" #include "mixin/thick.H" @@ -106,7 +107,8 @@ namespace RFCavityData : public elements::Named, public elements::BeamOptic, public elements::Thick, - public elements::Alignment + public elements::Alignment, + public elements::Aperture { static constexpr auto type = "RFCavity"; using PType = ImpactXParticleContainer::ParticleType; @@ -122,6 +124,8 @@ namespace RFCavityData * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param mapsteps number of integration steps per slice used for * map and reference particle push in applied fields * @param nslice number of slices used for the application of space charge @@ -137,6 +141,8 @@ namespace RFCavityData amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int mapsteps = 1, int nslice = 1, std::optional name = std::nullopt @@ -144,6 +150,7 @@ namespace RFCavityData : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_escale(escale), m_freq(freq), m_phase(phase), m_mapsteps(mapsteps), m_id(RFCavityData::next_id) { // next created RF cavity has another id for its data @@ -188,7 +195,7 @@ namespace RFCavityData * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -199,7 +206,7 @@ namespace RFCavityData amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, [[maybe_unused]] RefPart const & refpart ) const { @@ -229,6 +236,9 @@ namespace RFCavityData t = out[5]; pt = out[6]; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/Sbend.H b/src/particles/elements/Sbend.H index c6f67d9ad..ba7fc116f 100644 --- a/src/particles/elements/Sbend.H +++ b/src/particles/elements/Sbend.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -31,6 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "Sbend"; @@ -43,6 +45,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -52,12 +56,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_rc(rc) { } @@ -73,7 +80,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -84,7 +91,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -138,6 +145,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/SoftQuad.H b/src/particles/elements/SoftQuad.H index 187f55803..fa55333e3 100644 --- a/src/particles/elements/SoftQuad.H +++ b/src/particles/elements/SoftQuad.H @@ -13,6 +13,7 @@ #include "particles/ImpactXParticleContainer.H" #include "particles/integrators/Integrators.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/named.H" #include "mixin/thick.H" @@ -115,7 +116,8 @@ namespace SoftQuadrupoleData : public elements::Named, public elements::BeamOptic, public elements::Thick, - public elements::Alignment + public elements::Alignment, + public elements::Aperture { static constexpr auto type = "SoftQuadrupole"; using PType = ImpactXParticleContainer::ParticleType; @@ -129,6 +131,8 @@ namespace SoftQuadrupoleData * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param mapsteps number of integration steps per slice used for * map and reference particle push in applied fields * @param nslice number of slices used for the application of space charge @@ -142,6 +146,8 @@ namespace SoftQuadrupoleData amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int mapsteps = 1, int nslice = 1, std::optional name = std::nullopt @@ -149,6 +155,7 @@ namespace SoftQuadrupoleData : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_gscale(gscale), m_mapsteps(mapsteps), m_id(SoftQuadrupoleData::next_id) { // next created soft quad has another id for its data @@ -193,7 +200,7 @@ namespace SoftQuadrupoleData * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -204,7 +211,7 @@ namespace SoftQuadrupoleData amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, [[maybe_unused]] RefPart const & refpart ) const { @@ -234,6 +241,9 @@ namespace SoftQuadrupoleData t = out[5]; pt = out[6]; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/SoftSol.H b/src/particles/elements/SoftSol.H index 5152f604c..3e8ac6dd4 100644 --- a/src/particles/elements/SoftSol.H +++ b/src/particles/elements/SoftSol.H @@ -13,6 +13,7 @@ #include "particles/ImpactXParticleContainer.H" #include "particles/integrators/Integrators.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/named.H" #include "mixin/thick.H" @@ -120,7 +121,8 @@ namespace SoftSolenoidData : public elements::Named, public elements::BeamOptic, public elements::Thick, - public elements::Alignment + public elements::Alignment, + public elements::Aperture { static constexpr auto type = "SoftSolenoid"; using PType = ImpactXParticleContainer::ParticleType; @@ -139,6 +141,8 @@ namespace SoftSolenoidData * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param mapsteps number of integration steps per slice used for * map and reference particle push in applied fields * @param nslice number of slices used for the application of space charge @@ -153,6 +157,8 @@ namespace SoftSolenoidData amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int mapsteps = 1, int nslice = 1, std::optional name = std::nullopt @@ -160,6 +166,7 @@ namespace SoftSolenoidData : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_bscale(bscale), m_unit(unit), m_mapsteps(mapsteps), m_id(SoftSolenoidData::next_id) { // next created soft solenoid has another id for its data @@ -204,7 +211,7 @@ namespace SoftSolenoidData * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -215,7 +222,7 @@ namespace SoftSolenoidData amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, [[maybe_unused]] RefPart const & refpart ) const { @@ -245,6 +252,9 @@ namespace SoftSolenoidData t = out[5]; pt = out[6]; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/particles/elements/Sol.H b/src/particles/elements/Sol.H index 8573648a0..5f041dd48 100644 --- a/src/particles/elements/Sol.H +++ b/src/particles/elements/Sol.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/alignment.H" +#include "mixin/aperture.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" #include "mixin/named.H" @@ -31,6 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, + public elements::Aperture, public elements::NoFinalize { static constexpr auto type = "Sol"; @@ -44,6 +46,8 @@ namespace impactx * @param dx horizontal translation error in m * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] + * @param aperture_x horizontal half-aperture in m + * @param aperture_y vertical half-aperture in m * @param nslice number of slices used for the application of space charge * @param name a user defined and not necessarily unique name of the element */ @@ -53,12 +57,15 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, + amrex::ParticleReal aperture_x = 0, + amrex::ParticleReal aperture_y = 0, int nslice = 1, std::optional name = std::nullopt ) : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), + Aperture(aperture_x, aperture_y), m_ks(ks) { } @@ -74,7 +81,7 @@ namespace impactx * @param px particle momentum in x * @param py particle momentum in y * @param pt particle momentum in t - * @param idcpu particle global index (unused) + * @param idcpu particle global index * @param refpart reference particle */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -85,7 +92,7 @@ namespace impactx amrex::ParticleReal & AMREX_RESTRICT px, amrex::ParticleReal & AMREX_RESTRICT py, amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + uint64_t & AMREX_RESTRICT idcpu, RefPart const & refpart ) const { @@ -145,6 +152,9 @@ namespace impactx py = pyout; pt = ptout; + // apply transverse aperture + apply_aperture(x, y, idcpu); + // undo shift due to alignment errors of the element shift_out(x, y, px, py); } diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 56ec5bc43..45cf7a0cb 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -414,7 +414,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Aperture); - py::class_ py_ChrDrift(me, "ChrDrift"); + py::class_ py_ChrDrift(me, "ChrDrift"); py_ChrDrift .def("__repr__", [](ChrDrift const & chr_drift) { @@ -429,6 +429,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -436,6 +438,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A Drift with chromatic effects included." @@ -443,7 +447,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrDrift); - py::class_ py_ChrQuad(me, "ChrQuad"); + py::class_ py_ChrQuad(me, "ChrQuad"); py_ChrQuad .def("__repr__", [](ChrQuad const & chr_quad) { @@ -461,6 +465,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -470,6 +476,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A Quadrupole magnet with chromatic effects included." @@ -487,7 +495,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrQuad); - py::class_ py_ChrPlasmaLens(me, "ChrPlasmaLens"); + py::class_ py_ChrPlasmaLens(me, "ChrPlasmaLens"); py_ChrPlasmaLens .def("__repr__", [](ChrPlasmaLens const & chr_pl_lens) { @@ -505,6 +513,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -514,6 +524,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "An active Plasma Lens with chromatic effects included." @@ -550,6 +562,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -559,6 +573,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A region of Uniform Acceleration, with chromatic effects included." @@ -576,7 +592,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrAcc); - py::class_ py_ConstF(me, "ConstF"); + py::class_ py_ConstF(me, "ConstF"); py_ConstF .def("__repr__", [](ConstF const & constf) { @@ -597,6 +613,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -607,6 +625,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A linear Constant Focusing element." @@ -718,7 +738,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Drift); - py::class_ py_ExactDrift(me, "ExactDrift"); + py::class_ py_ExactDrift(me, "ExactDrift"); py_ExactDrift .def("__repr__", [](ExactDrift const & exact_drift) { @@ -733,6 +753,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -740,6 +762,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A Drift using the exact nonlinear map." @@ -747,7 +771,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ExactDrift); - py::class_ py_ExactSbend(me, "ExactSbend"); + py::class_ py_ExactSbend(me, "ExactSbend"); py_ExactSbend .def("__repr__", [](ExactSbend const & exact_sbend) { @@ -766,6 +790,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -775,6 +801,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "An ideal sector bend using the exact nonlinear map. When B = 0, the reference bending radius is defined by r0 = length / (angle in rad), corresponding to a magnetic field of B = rigidity / r0; otherwise the reference bending radius is defined by r0 = rigidity / B." @@ -1046,7 +1074,7 @@ void init_elements(py::module& m) ) ; - py::class_ py_Quad(me, "Quad"); + py::class_ py_Quad(me, "Quad"); py_Quad .def("__repr__", [](Quad const & quad) { @@ -1063,6 +1091,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -1071,6 +1101,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "A Quadrupole magnet." @@ -1083,7 +1115,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Quad); - py::class_ py_RFCavity(me, "RFCavity"); + py::class_ py_RFCavity(me, "RFCavity"); py_RFCavity .def("__repr__", [](RFCavity const & rfc) { @@ -1106,6 +1138,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, int, std::optional @@ -1119,6 +1153,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("mapsteps") = 1, py::arg("nslice") = 1, py::arg("name") = py::none(), @@ -1149,7 +1185,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_RFCavity); - py::class_ py_Sbend(me, "Sbend"); + py::class_ py_Sbend(me, "Sbend"); py_Sbend .def("__repr__", [](Sbend const & sbend) { @@ -1166,6 +1202,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -1174,6 +1212,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "An ideal sector bend." @@ -1323,7 +1363,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ShortRF); - py::class_ py_SoftSolenoid(me, "SoftSolenoid"); + py::class_ py_SoftSolenoid(me, "SoftSolenoid"); py_SoftSolenoid .def("__repr__", [](SoftSolenoid const & soft_sol) { @@ -1343,6 +1383,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, int, std::optional @@ -1355,6 +1397,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("mapsteps") = 1, py::arg("nslice") = 1, py::arg("name") = py::none(), @@ -1380,7 +1424,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_SoftSolenoid); - py::class_ py_Sol(me, "Sol"); + py::class_ py_Sol(me, "Sol"); py_Sol .def("__repr__", [](Sol const & sol) { @@ -1397,6 +1441,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, std::optional >(), @@ -1405,6 +1451,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("nslice") = 1, py::arg("name") = py::none(), "An ideal hard-edge Solenoid magnet." @@ -1451,7 +1499,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_PRot); - py::class_ py_SoftQuadrupole(me, "SoftQuadrupole"); + py::class_ py_SoftQuadrupole(me, "SoftQuadrupole"); py_SoftQuadrupole .def("__repr__", [](SoftQuadrupole const & soft_quad) { @@ -1470,6 +1518,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, + amrex::ParticleReal, + amrex::ParticleReal, int, int, std::optional @@ -1481,6 +1531,8 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("aperture_x") = 0, + py::arg("aperture_y") = 0, py::arg("mapsteps") = 1, py::arg("nslice") = 1, py::arg("name") = py::none(), From 2d10f4f3d8c7616fad2d13b2049c6bf837bda983 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Tue, 14 Jan 2025 09:34:53 -0800 Subject: [PATCH 19/24] Update thin Aperture element naming. --- examples/aperture/input_absorber.in | 4 ++-- examples/aperture/input_aperture.in | 4 ++-- examples/aperture/input_aperture_periodic.in | 4 ++-- examples/aperture/run_absorber.py | 4 ++-- examples/aperture/run_aperture.py | 2 +- examples/aperture/run_aperture_periodic.py | 4 ++-- src/initialization/InitElement.cpp | 8 +++---- src/particles/elements/Aperture.H | 18 ++++++++-------- src/python/elements.cpp | 22 ++++++++++---------- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/examples/aperture/input_absorber.in b/examples/aperture/input_absorber.in index 129229983..a564fd6ba 100644 --- a/examples/aperture/input_absorber.in +++ b/examples/aperture/input_absorber.in @@ -32,8 +32,8 @@ drift.ds = 0.123 collimator.type = aperture collimator.shape = rectangular -collimator.xmax = 1.0e-3 -collimator.ymax = 1.5e-3 +collimator.aperture_x = 1.0e-3 +collimator.aperture_y = 1.5e-3 collimator.action = absorb ############################################################################### diff --git a/examples/aperture/input_aperture.in b/examples/aperture/input_aperture.in index 4a1c32a4d..41218fc79 100644 --- a/examples/aperture/input_aperture.in +++ b/examples/aperture/input_aperture.in @@ -32,8 +32,8 @@ drift.ds = 0.123 collimator.type = aperture collimator.shape = rectangular -collimator.xmax = 1.0e-3 -collimator.ymax = 1.5e-3 +collimator.aperture_x = 1.0e-3 +collimator.aperture_y = 1.5e-3 ############################################################################### diff --git a/examples/aperture/input_aperture_periodic.in b/examples/aperture/input_aperture_periodic.in index eaec8f1ed..c1c707924 100644 --- a/examples/aperture/input_aperture_periodic.in +++ b/examples/aperture/input_aperture_periodic.in @@ -32,8 +32,8 @@ drift.ds = 0.123 pepperpot.type = aperture pepperpot.shape = rectangular -pepperpot.xmax = 1.5e-4 -pepperpot.ymax = 1.0e-4 +pepperpot.aperture_x = 1.5e-4 +pepperpot.aperture_y = 1.0e-4 pepperpot.repeat_x = 1.0e-3 pepperpot.repeat_y = 1.0e-3 diff --git a/examples/aperture/run_absorber.py b/examples/aperture/run_absorber.py index e93c46026..12f7a2c6c 100755 --- a/examples/aperture/run_absorber.py +++ b/examples/aperture/run_absorber.py @@ -52,8 +52,8 @@ elements.Drift(name="drift", ds=0.123), elements.Aperture( name="collimator", - xmax=1.0e-3, - ymax=1.5e-3, + aperture_x=1.0e-3, + aperture_y=1.5e-3, shape="rectangular", action="absorb", ), diff --git a/examples/aperture/run_aperture.py b/examples/aperture/run_aperture.py index 1d186db5e..b80922639 100755 --- a/examples/aperture/run_aperture.py +++ b/examples/aperture/run_aperture.py @@ -51,7 +51,7 @@ monitor, elements.Drift(name="drift", ds=0.123), elements.Aperture( - name="collimator", xmax=1.0e-3, ymax=1.5e-3, shape="rectangular" + name="collimator", aperture_x=1.0e-3, aperture_y=1.5e-3, shape="rectangular" ), monitor, ] diff --git a/examples/aperture/run_aperture_periodic.py b/examples/aperture/run_aperture_periodic.py index c0568718d..6e7cc03bf 100755 --- a/examples/aperture/run_aperture_periodic.py +++ b/examples/aperture/run_aperture_periodic.py @@ -52,8 +52,8 @@ elements.Drift(name="drift", ds=0.123), elements.Aperture( name="pepperpot", - xmax=1.5e-4, - ymax=1.0e-4, + aperture_x=1.5e-4, + aperture_y=1.0e-4, repeat_x=1.0e-3, repeat_y=1.0e-3, shape="rectangular", diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index ec19c1d41..18077d5e6 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -423,13 +423,13 @@ namespace detail { auto a = detail::query_alignment(pp_element); - amrex::Real xmax, ymax; + amrex::Real aperture_x, aperture_y; amrex::ParticleReal repeat_x = 0.0; amrex::ParticleReal repeat_y = 0.0; std::string shape_str = "rectangular"; std::string action_str = "transmit"; - pp_element.get("xmax", xmax); - pp_element.get("ymax", ymax); + pp_element.get("aperture_x", aperture_x); + pp_element.get("aperture_y", aperture_y); pp_element.queryAdd("repeat_x", repeat_x); pp_element.queryAdd("repeat_y", repeat_y); pp_element.queryAdd("shape", shape_str); @@ -445,7 +445,7 @@ namespace detail Aperture::Action::transmit : Aperture::Action::absorb; - m_lattice.emplace_back( Aperture(xmax, ymax, repeat_x, repeat_y, shape, action, a["dx"], a["dy"], a["rotation_degree"], element_name) ); + m_lattice.emplace_back( Aperture(aperture_x, aperture_y, repeat_x, repeat_y, shape, action, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "beam_monitor") { std::string openpmd_name = element_name; diff --git a/src/particles/elements/Aperture.H b/src/particles/elements/Aperture.H index bf5621793..324b6d5ab 100644 --- a/src/particles/elements/Aperture.H +++ b/src/particles/elements/Aperture.H @@ -58,8 +58,8 @@ namespace impactx * * @param shape aperture shape * @param action specify action of domain (transmit/absorb) - * @param xmax maximum value of horizontal coordinate (m) - * @param ymax maximum value of vertical coordinate (m) + * @param aperture_x horizontal half-aperture (m) + * @param aperture_y vertical half-aperture (m) * @param repeat_x horizontal period for repeated masking, optional (m) * @param repeat_y vertical period for repeated masking, optional (m) * @param dx horizontal translation error in m @@ -68,8 +68,8 @@ namespace impactx * @param name a user defined and not necessarily unique name of the element */ Aperture ( - amrex::ParticleReal xmax, - amrex::ParticleReal ymax, + amrex::ParticleReal aperture_x, + amrex::ParticleReal aperture_y, amrex::ParticleReal repeat_x, amrex::ParticleReal repeat_y, Shape shape, @@ -81,7 +81,7 @@ namespace impactx ) : Named(std::move(name)), Alignment(dx, dy, rotation_degree), - m_shape(shape), m_action(action), m_xmax(xmax), m_ymax(ymax), m_repeat_x(repeat_x), m_repeat_y(repeat_y) + m_shape(shape), m_action(action), m_aperture_x(aperture_x), m_aperture_y(aperture_y), m_repeat_x(repeat_x), m_repeat_y(repeat_y) { } @@ -128,8 +128,8 @@ namespace impactx v = (m_repeat_y==0.0) ? y : (std::fmod(std::abs(y)+dy,m_repeat_y)-dy); // scale horizontal and vertical coordinates - u = u / m_xmax; - v = v / m_ymax; + u = u / m_aperture_x; + v = v / m_aperture_y; // compare against the aperture boundary switch (m_action) @@ -181,8 +181,8 @@ namespace impactx Shape m_shape; //! aperture type (rectangular, elliptical) Action m_action; //! action type (transmit, absorb) - amrex::ParticleReal m_xmax; //! maximum horizontal coordinate - amrex::ParticleReal m_ymax; //! maximum vertical coordinate + amrex::ParticleReal m_aperture_x; //! maximum horizontal coordinate + amrex::ParticleReal m_aperture_y; //! maximum vertical coordinate amrex::ParticleReal m_repeat_x; //! horizontal period for repeated masking amrex::ParticleReal m_repeat_y; //! vertical period for repeated masking diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 45cf7a0cb..726f5b2a9 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -321,8 +321,8 @@ void init_elements(py::module& m) } ) .def(py::init([]( - amrex::ParticleReal xmax, - amrex::ParticleReal ymax, + amrex::ParticleReal aperture_x, + amrex::ParticleReal aperture_y, amrex::ParticleReal repeat_x, amrex::ParticleReal repeat_y, std::string const & shape, @@ -345,10 +345,10 @@ void init_elements(py::module& m) Aperture::Action const a = action == "transmit" ? Aperture::Action::transmit : Aperture::Action::absorb; - return new Aperture(xmax, ymax, repeat_x, repeat_y, s, a, dx, dy, rotation_degree, name); + return new Aperture(aperture_x, aperture_y, repeat_x, repeat_y, s, a, dx, dy, rotation_degree, name); }), - py::arg("xmax"), - py::arg("ymax"), + py::arg("aperture_x"), + py::arg("aperture_y"), py::arg("repeat_x") = 0, py::arg("repeat_y") = 0, py::arg("shape") = "rectangular", @@ -391,14 +391,14 @@ void init_elements(py::module& m) }, "action type (transmit, absorb)" ) - .def_property("xmax", - [](Aperture & ap) { return ap.m_xmax; }, - [](Aperture & ap, amrex::ParticleReal xmax) { ap.m_xmax = xmax; }, + .def_property("aperture_x", + [](Aperture & ap) { return ap.m_aperture_x; }, + [](Aperture & ap, amrex::ParticleReal aperture_x) { ap.m_aperture_x = aperture_x; }, "maximum horizontal coordinate" ) - .def_property("ymax", - [](Aperture & ap) { return ap.m_ymax; }, - [](Aperture & ap, amrex::ParticleReal ymax) { ap.m_ymax = ymax; }, + .def_property("aperture_y", + [](Aperture & ap) { return ap.m_aperture_y; }, + [](Aperture & ap, amrex::ParticleReal aperture_y) { ap.m_aperture_y = aperture_y; }, "maximum vertical coordinate" ) .def_property("repeat_x", From 39a7dbf09a933a82df56639afcea9e5ed8172e36 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Tue, 14 Jan 2025 10:47:37 -0800 Subject: [PATCH 20/24] Update element parameter docs. --- docs/source/usage/parameters.rst | 32 +++++++++++++++-- docs/source/usage/python.rst | 62 +++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index fab2851d7..20d55b178 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -127,6 +127,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift`` for a free drift. This requires these additional parameters: @@ -147,6 +149,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift_exact`` for a free drift, using the exact nonlinear map. This requires these additional parameters: @@ -155,6 +159,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``quad`` for a quadrupole. This requires these additional parameters: @@ -169,6 +175,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``quad_chromatic`` for A Quadrupole magnet, with chromatic effects included. @@ -188,6 +196,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``quadrupole_softedge`` for a soft-edge quadrupole. This requires these additional parameters: @@ -201,6 +211,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.mapsteps`` (``integer``) number of integration steps per slice used for map and reference particle push in applied fields (default: ``1``) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) @@ -219,6 +231,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``sbend`` for a bending magnet. This requires these additional parameters: @@ -228,6 +242,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``sbend_exact`` for a bending magnet using the exact nonlinear map for the bend body. The map corresponds to the map described in: @@ -241,6 +257,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``solenoid`` for an ideal hard-edge solenoid magnet. This requires these additional parameters: @@ -251,6 +269,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``solenoid_softedge`` for a soft-edge solenoid. This requires these additional parameters: @@ -269,6 +289,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.mapsteps`` (``integer``) number of integration steps per slice used for map and reference particle push in applied fields (default: ``1``) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) @@ -291,6 +313,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``rfcavity`` a radiofrequency cavity. @@ -306,6 +330,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.mapsteps`` (``integer``) number of integration steps per slice used for map and reference particle push in applied fields (default: ``1``) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) @@ -349,6 +375,8 @@ Lattice Elements * ``.dx`` (``float``, in meters) horizontal translation error * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``linear_map`` for a custom, linear transport matrix. @@ -427,8 +455,8 @@ Lattice Elements * ``aperture`` for a thin collimator element applying a transverse aperture boundary. This requires these additional parameters: - * ``.xmax`` (``float``, in meters) maximum value of the horizontal coordinate - * ``.ymax`` (``float``, in meters) maximum value of the vertical coordinate + * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical or rectangular) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical or rectangular) * ``.repeat_x`` (``float``, in meters) horizontal period for repeated aperture masking (inactive by default) * ``.repeat_y`` (``float``, in meters) vertical period for repeated aperture masking (inactive by default) * ``.shape`` (``string``) shape of the aperture boundary: ``rectangular`` (default) or ``elliptical`` diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index f782fe4a4..c239de25c 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -507,7 +507,7 @@ This module provides elements for the accelerator lattice. :param madx_file: file name to MAD-X file with beamline elements :param nslice: number of slices used for the application of space charge -.. py:class:: impactx.elements.CFbend(ds, rc, k, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.CFbend(ds, rc, k, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A combined function bending magnet. This is an ideal Sbend with a normal quadrupole field component. @@ -520,10 +520,12 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.ConstF(ds, kx, ky, kt, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ConstF(ds, kx, ky, kt, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A linear Constant Focusing element. @@ -534,6 +536,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -583,7 +587,7 @@ This module provides elements for the accelerator lattice. :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.ChrDrift(ds, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ChrDrift(ds, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A drift with chromatic effects included. The Hamiltonian is expanded through second order in the transverse variables (x,px,y,py), with the exact pt @@ -593,10 +597,12 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.ExactDrift(ds, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ExactDrift(ds, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A drift using the exact nonlinear transfer map. @@ -604,6 +610,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -753,7 +761,7 @@ This module provides elements for the accelerator lattice. This function is called for the reference particle as it passes through the element. The reference particle is updated *before* the beam particles are pushed. -.. py:class:: impactx.elements.Quad(ds, k, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.Quad(ds, k, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A Quadrupole magnet. @@ -765,10 +773,12 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.ChrQuad(ds, k, unit=0, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ChrQuad(ds, k, unit=0, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) A Quadrupole magnet, with chromatic effects included. The Hamiltonian is expanded through second order in the transverse variables (x,px,y,py), with the exact pt @@ -784,6 +794,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -795,7 +807,7 @@ This module provides elements for the accelerator lattice. unit specification for quad strength -.. py:class:: impactx.elements.ChrPlasmaLens(ds, k, unit=0, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ChrPlasmaLens(ds, k, unit=0, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) An active cylindrically symmetric plasma lens, with chromatic effects included. The Hamiltonian is expanded through second order in the transverse variables @@ -809,6 +821,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -820,7 +834,7 @@ This module provides elements for the accelerator lattice. unit specification for plasma lens focusing strength -.. py:class:: impactx.elements.ChrAcc(ds, ez, bz, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ChrAcc(ds, ez, bz, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) Acceleration in a uniform field Ez, with a uniform solenoidal field Bz. @@ -835,6 +849,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -846,7 +862,7 @@ This module provides elements for the accelerator lattice. magnetic field strength in 1/m -.. py:class:: impactx.elements.RFCavity(ds, escale, freq, phase, cos_coefficients, sin_coefficients, dx=0, dy=0, rotation=0, mapsteps=1, nslice=1, name=None) +.. py:class:: impactx.elements.RFCavity(ds, escale, freq, phase, cos_coefficients, sin_coefficients, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, mapsteps=1, nslice=1, name=None) A radiofrequency cavity. @@ -861,11 +877,13 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param mapsteps: number of integration steps per slice used for map and reference particle push in applied fields :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.Sbend(ds, rc, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.Sbend(ds, rc, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) An ideal sector bend. @@ -874,10 +892,12 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.ExactSbend(ds, phi, B=0.0, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.ExactSbend(ds, phi, B=0.0, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) An ideal sector bend using the exact nonlinear map. The model consists of a uniform bending field B_y with a hard edge. Pole faces are normal to the entry and exit velocity of the reference particle. @@ -893,6 +913,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -918,7 +940,7 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :param name: an optional name for the element -.. py:class:: impactx.elements.SoftSolenoid(ds, bscale, cos_coefficients, sin_coefficients, unit=0, dx=0, dy=0, rotation=0, mapsteps=1, nslice=1, name=None) +.. py:class:: impactx.elements.SoftSolenoid(ds, bscale, cos_coefficients, sin_coefficients, unit=0, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, mapsteps=1, nslice=1, name=None) A soft-edge solenoid. @@ -934,11 +956,13 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param mapsteps: number of integration steps per slice used for map and reference particle push in applied fields :param nslice: number of slices used for the application of space charge :param name: an optional name for the element -.. py:class:: impactx.elements.Sol(ds, ks, dx=0, dy=0, rotation=0, nslice=1, name=None) +.. py:class:: impactx.elements.Sol(ds, ks, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, nslice=1, name=None) An ideal hard-edge Solenoid magnet. @@ -947,6 +971,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element @@ -968,12 +994,12 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :param name: an optional name for the element -.. py:class:: impactx.elements.Aperture(xmax, ymax, shape="rectangular", dx=0, dy=0, rotation=0, name=None) +.. py:class:: impactx.elements.Aperture(aperture_x, aperture_y, shape="rectangular", dx=0, dy=0, rotation=0, name=None) A thin collimator element, applying a transverse aperture boundary. - :param xmax: maximum allowed value of the horizontal coordinate (meter) - :param ymax: maximum allowed value of the vertical coordinate (meter) + :param aperture_x: horizontal half-aperture (rectangular or elliptical) in m + :param aperture_y: vertical half-aperture (rectangular or elliptical) in m :param repeat_x: horizontal period for repeated aperture masking (inactive by default) (meter) :param repeat_y: vertical period for repeated aperture masking (inactive by default) (meter) :param shape: aperture boundary shape: ``"rectangular"`` (default) or ``"elliptical"`` @@ -999,7 +1025,7 @@ This module provides elements for the accelerator lattice. maximum vertical coordinate -.. py:class:: impactx.elements.SoftQuadrupole(ds, gscale, cos_coefficients, sin_coefficients, dx=0, dy=0, rotation=0, mapsteps=1, nslice=1, name=None) +.. py:class:: impactx.elements.SoftQuadrupole(ds, gscale, cos_coefficients, sin_coefficients, dx=0, dy=0, rotation=0, aperture_x=0, aperture_y=0, mapsteps=1, nslice=1, name=None) A soft-edge quadrupole. @@ -1012,6 +1038,8 @@ This module provides elements for the accelerator lattice. :param dx: horizontal translation error in m :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] + :param aperture_x: horizontal half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param mapsteps: number of integration steps per slice used for map and reference particle push in applied fields :param nslice: number of slices used for the application of space charge :param name: an optional name for the element From 941536c3672363fda2c525250f6370c0892cc8b9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:56:58 +0000 Subject: [PATCH 21/24] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/source/usage/parameters.rst | 2 +- docs/source/usage/python.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index 20d55b178..823e65c38 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -128,7 +128,7 @@ Lattice Elements * ``.dy`` (``float``, in meters) vertical translation error * ``.rotation`` (``float``, in degrees) rotation error in the transverse plane * ``.aperture_x`` (``float``, in meters) horizontal half-aperture (elliptical) - * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) + * ``.aperture_y`` (``float``, in meters) vertical half-aperture (elliptical) * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) * ``drift`` for a free drift. This requires these additional parameters: diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index c239de25c..4c8c03b81 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -521,7 +521,7 @@ This module provides elements for the accelerator lattice. :param dy: vertical translation error in m :param rotation: rotation error in the transverse plane [degrees] :param aperture_x: horizontal half-aperture (elliptical) in m - :param aperture_y: vertical half-aperture (elliptical) in m + :param aperture_y: vertical half-aperture (elliptical) in m :param nslice: number of slices used for the application of space charge :param name: an optional name for the element From eec7bdd7edff8b6fc847e1e7fd0d5645dec1d76c Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 14 Jan 2025 18:06:41 -0800 Subject: [PATCH 22/24] Rename Mixin Class: `PipeAperture` --- src/particles/elements/CFbend.H | 4 +-- src/particles/elements/ChrDrift.H | 4 +-- src/particles/elements/ChrPlasmaLens.H | 4 +-- src/particles/elements/ChrQuad.H | 4 +-- src/particles/elements/ChrUniformAcc.H | 4 +-- src/particles/elements/ConstF.H | 4 +-- src/particles/elements/Drift.H | 4 +-- src/particles/elements/ExactDrift.H | 4 +-- src/particles/elements/ExactSbend.H | 4 +-- src/particles/elements/Quad.H | 4 +-- src/particles/elements/RFCavity.H | 4 +-- src/particles/elements/Sbend.H | 4 +-- src/particles/elements/SoftQuad.H | 4 +-- src/particles/elements/SoftSol.H | 4 +-- src/particles/elements/Sol.H | 4 +-- src/particles/elements/mixin/aperture.H | 18 ++++++------- src/python/elements.cpp | 36 ++++++++++++------------- 17 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/particles/elements/CFbend.H b/src/particles/elements/CFbend.H index 891292179..9a2492b62 100644 --- a/src/particles/elements/CFbend.H +++ b/src/particles/elements/CFbend.H @@ -32,7 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "CFbend"; @@ -70,7 +70,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_rc(rc), m_k(k) { } diff --git a/src/particles/elements/ChrDrift.H b/src/particles/elements/ChrDrift.H index 71909e3e7..507019239 100644 --- a/src/particles/elements/ChrDrift.H +++ b/src/particles/elements/ChrDrift.H @@ -31,7 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ChrDrift"; @@ -64,7 +64,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y) + PipeAperture(aperture_x, aperture_y) { } diff --git a/src/particles/elements/ChrPlasmaLens.H b/src/particles/elements/ChrPlasmaLens.H index 703d5149c..8c5990c51 100644 --- a/src/particles/elements/ChrPlasmaLens.H +++ b/src/particles/elements/ChrPlasmaLens.H @@ -31,7 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ChrPlasmaLens"; @@ -72,7 +72,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_k(k), m_unit(unit) { } diff --git a/src/particles/elements/ChrQuad.H b/src/particles/elements/ChrQuad.H index 0cdbf9fc2..82875fcec 100644 --- a/src/particles/elements/ChrQuad.H +++ b/src/particles/elements/ChrQuad.H @@ -32,7 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ChrQuad"; @@ -75,7 +75,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_k(k), m_unit(unit) { } diff --git a/src/particles/elements/ChrUniformAcc.H b/src/particles/elements/ChrUniformAcc.H index 28085fd48..338cbde8c 100644 --- a/src/particles/elements/ChrUniformAcc.H +++ b/src/particles/elements/ChrUniformAcc.H @@ -31,7 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ChrAcc"; @@ -70,7 +70,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_ez(ez), m_bz(bz) { } diff --git a/src/particles/elements/ConstF.H b/src/particles/elements/ConstF.H index 8c7b74c1a..3202d1c6b 100644 --- a/src/particles/elements/ConstF.H +++ b/src/particles/elements/ConstF.H @@ -31,7 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ConstF"; @@ -67,7 +67,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_kx(kx), m_ky(ky), m_kt(kt) { } diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index f08e10292..1171cf69f 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -34,7 +34,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "Drift"; @@ -64,7 +64,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y) + PipeAperture(aperture_x, aperture_y) { } diff --git a/src/particles/elements/ExactDrift.H b/src/particles/elements/ExactDrift.H index e563914fc..581bb4b6e 100644 --- a/src/particles/elements/ExactDrift.H +++ b/src/particles/elements/ExactDrift.H @@ -31,7 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ExactDrift"; @@ -61,7 +61,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y) + PipeAperture(aperture_x, aperture_y) { } diff --git a/src/particles/elements/ExactSbend.H b/src/particles/elements/ExactSbend.H index 3a9a9fccc..a78d46640 100644 --- a/src/particles/elements/ExactSbend.H +++ b/src/particles/elements/ExactSbend.H @@ -33,7 +33,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "ExactSbend"; @@ -78,7 +78,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_phi(phi * degree2rad), m_B(B) { } diff --git a/src/particles/elements/Quad.H b/src/particles/elements/Quad.H index 5396c34eb..791a88c1a 100644 --- a/src/particles/elements/Quad.H +++ b/src/particles/elements/Quad.H @@ -31,7 +31,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "Quad"; @@ -66,7 +66,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_k(k) { } diff --git a/src/particles/elements/RFCavity.H b/src/particles/elements/RFCavity.H index 80f8df407..c843f629d 100644 --- a/src/particles/elements/RFCavity.H +++ b/src/particles/elements/RFCavity.H @@ -108,7 +108,7 @@ namespace RFCavityData public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture + public elements::PipeAperture { static constexpr auto type = "RFCavity"; using PType = ImpactXParticleContainer::ParticleType; @@ -150,7 +150,7 @@ namespace RFCavityData : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_escale(escale), m_freq(freq), m_phase(phase), m_mapsteps(mapsteps), m_id(RFCavityData::next_id) { // next created RF cavity has another id for its data diff --git a/src/particles/elements/Sbend.H b/src/particles/elements/Sbend.H index ba7fc116f..946394e51 100644 --- a/src/particles/elements/Sbend.H +++ b/src/particles/elements/Sbend.H @@ -32,7 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "Sbend"; @@ -64,7 +64,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_rc(rc) { } diff --git a/src/particles/elements/SoftQuad.H b/src/particles/elements/SoftQuad.H index fa55333e3..481236be4 100644 --- a/src/particles/elements/SoftQuad.H +++ b/src/particles/elements/SoftQuad.H @@ -117,7 +117,7 @@ namespace SoftQuadrupoleData public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture + public elements::PipeAperture { static constexpr auto type = "SoftQuadrupole"; using PType = ImpactXParticleContainer::ParticleType; @@ -155,7 +155,7 @@ namespace SoftQuadrupoleData : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_gscale(gscale), m_mapsteps(mapsteps), m_id(SoftQuadrupoleData::next_id) { // next created soft quad has another id for its data diff --git a/src/particles/elements/SoftSol.H b/src/particles/elements/SoftSol.H index 3e8ac6dd4..d4e4330b0 100644 --- a/src/particles/elements/SoftSol.H +++ b/src/particles/elements/SoftSol.H @@ -122,7 +122,7 @@ namespace SoftSolenoidData public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture + public elements::PipeAperture { static constexpr auto type = "SoftSolenoid"; using PType = ImpactXParticleContainer::ParticleType; @@ -166,7 +166,7 @@ namespace SoftSolenoidData : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_bscale(bscale), m_unit(unit), m_mapsteps(mapsteps), m_id(SoftSolenoidData::next_id) { // next created soft solenoid has another id for its data diff --git a/src/particles/elements/Sol.H b/src/particles/elements/Sol.H index 5f041dd48..193612706 100644 --- a/src/particles/elements/Sol.H +++ b/src/particles/elements/Sol.H @@ -32,7 +32,7 @@ namespace impactx public elements::BeamOptic, public elements::Thick, public elements::Alignment, - public elements::Aperture, + public elements::PipeAperture, public elements::NoFinalize { static constexpr auto type = "Sol"; @@ -65,7 +65,7 @@ namespace impactx : Named(std::move(name)), Thick(ds, nslice), Alignment(dx, dy, rotation_degree), - Aperture(aperture_x, aperture_y), + PipeAperture(aperture_x, aperture_y), m_ks(ks) { } diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index f77f6c2fe..9916ff2f1 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -21,15 +21,15 @@ namespace impactx::elements { /** This is a helper class for applying a transverse aperture restriction to thick lattice elements */ - struct Aperture + struct PipeAperture { - /** A finite-length element + /** A finite-length element with a constant elliptical aperture over s. * * @param aperture_x horizontal half-aperture size in m * @param aperture_y vertical half-aperture size in m */ - Aperture ( + PipeAperture ( amrex::ParticleReal aperture_x, amrex::ParticleReal aperture_y ) @@ -37,13 +37,13 @@ namespace impactx::elements { } - Aperture () = default; - Aperture (Aperture const &) = default; - Aperture& operator= (Aperture const &) = default; - Aperture (Aperture&&) = default; - Aperture& operator= (Aperture&& rhs) = default; + PipeAperture () = default; + PipeAperture (PipeAperture const &) = default; + PipeAperture& operator= (PipeAperture const &) = default; + PipeAperture (PipeAperture&&) = default; + PipeAperture& operator= (PipeAperture&& rhs) = default; - ~Aperture () = default; + ~PipeAperture () = default; /** Apply the transverse aperture * diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 726f5b2a9..152824f80 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -216,16 +216,16 @@ void init_elements(py::module& m) ) ; - py::class_(mx, "Aperture") + py::class_(mx, "PipeAperture") .def(py::init<>(), - "Mixin class for lattice elements with a transverse aperture." + "Mixin class for applying a transverse aperture restriction to thick lattice elements." ) .def_property_readonly("aperture_x", - &elements::Aperture::aperture_x, + &elements::PipeAperture::aperture_x, "horizontal aperture in m" ) .def_property_readonly("aperture_y", - &elements::Aperture::aperture_y, + &elements::PipeAperture::aperture_y, "vertical aperture in m" ) ; @@ -414,7 +414,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Aperture); - py::class_ py_ChrDrift(me, "ChrDrift"); + py::class_ py_ChrDrift(me, "ChrDrift"); py_ChrDrift .def("__repr__", [](ChrDrift const & chr_drift) { @@ -447,7 +447,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrDrift); - py::class_ py_ChrQuad(me, "ChrQuad"); + py::class_ py_ChrQuad(me, "ChrQuad"); py_ChrQuad .def("__repr__", [](ChrQuad const & chr_quad) { @@ -495,7 +495,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrQuad); - py::class_ py_ChrPlasmaLens(me, "ChrPlasmaLens"); + py::class_ py_ChrPlasmaLens(me, "ChrPlasmaLens"); py_ChrPlasmaLens .def("__repr__", [](ChrPlasmaLens const & chr_pl_lens) { @@ -592,7 +592,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrAcc); - py::class_ py_ConstF(me, "ConstF"); + py::class_ py_ConstF(me, "ConstF"); py_ConstF .def("__repr__", [](ConstF const & constf) { @@ -705,7 +705,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_DipEdge); - py::class_ py_Drift(me, "Drift"); + py::class_ py_Drift(me, "Drift"); py_Drift .def("__repr__", [](Drift const & drift) { @@ -738,7 +738,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Drift); - py::class_ py_ExactDrift(me, "ExactDrift"); + py::class_ py_ExactDrift(me, "ExactDrift"); py_ExactDrift .def("__repr__", [](ExactDrift const & exact_drift) { @@ -771,7 +771,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ExactDrift); - py::class_ py_ExactSbend(me, "ExactSbend"); + py::class_ py_ExactSbend(me, "ExactSbend"); py_ExactSbend .def("__repr__", [](ExactSbend const & exact_sbend) { @@ -1074,7 +1074,7 @@ void init_elements(py::module& m) ) ; - py::class_ py_Quad(me, "Quad"); + py::class_ py_Quad(me, "Quad"); py_Quad .def("__repr__", [](Quad const & quad) { @@ -1115,7 +1115,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Quad); - py::class_ py_RFCavity(me, "RFCavity"); + py::class_ py_RFCavity(me, "RFCavity"); py_RFCavity .def("__repr__", [](RFCavity const & rfc) { @@ -1185,7 +1185,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_RFCavity); - py::class_ py_Sbend(me, "Sbend"); + py::class_ py_Sbend(me, "Sbend"); py_Sbend .def("__repr__", [](Sbend const & sbend) { @@ -1226,7 +1226,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Sbend); - py::class_ py_CFbend(me, "CFbend"); + py::class_ py_CFbend(me, "CFbend"); py_CFbend .def("__repr__", [](CFbend const & cfbend) { @@ -1363,7 +1363,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ShortRF); - py::class_ py_SoftSolenoid(me, "SoftSolenoid"); + py::class_ py_SoftSolenoid(me, "SoftSolenoid"); py_SoftSolenoid .def("__repr__", [](SoftSolenoid const & soft_sol) { @@ -1424,7 +1424,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_SoftSolenoid); - py::class_ py_Sol(me, "Sol"); + py::class_ py_Sol(me, "Sol"); py_Sol .def("__repr__", [](Sol const & sol) { @@ -1499,7 +1499,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_PRot); - py::class_ py_SoftQuadrupole(me, "SoftQuadrupole"); + py::class_ py_SoftQuadrupole(me, "SoftQuadrupole"); py_SoftQuadrupole .def("__repr__", [](SoftQuadrupole const & soft_quad) { From 01706a79f2be3fa44004d441446ecb25b77eca08 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 14 Jan 2025 18:07:59 -0800 Subject: [PATCH 23/24] Python: Mixin Elements w/o Constructor We do not want to create variables from them. --- src/python/elements.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 152824f80..1b4101a48 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -158,14 +158,6 @@ void init_elements(py::module& m) ; py::class_(mx, "Thick") - .def(py::init< - amrex::ParticleReal, - amrex::ParticleReal - >(), - py::arg("ds"), - py::arg("nslice") = 1, - "Mixin class for lattice elements with finite length." - ) .def_property("ds", [](elements::Thick & th) { return th.m_ds; }, [](elements::Thick & th, amrex::ParticleReal ds) { th.m_ds = ds; }, @@ -179,9 +171,6 @@ void init_elements(py::module& m) ; py::class_(mx, "Thin") - .def(py::init<>(), - "Mixin class for lattice elements with zero length." - ) .def_property_readonly("ds", &elements::Thin::ds, "segment length in m" @@ -193,9 +182,6 @@ void init_elements(py::module& m) ; py::class_(mx, "Alignment") - .def(py::init<>(), - "Mixin class for lattice elements with horizontal/vertical alignment errors." - ) .def_property("dx", [](elements::Alignment & a) { return a.dx(); }, [](elements::Alignment & a, amrex::ParticleReal dx) { a.m_dx = dx; }, @@ -217,9 +203,6 @@ void init_elements(py::module& m) ; py::class_(mx, "PipeAperture") - .def(py::init<>(), - "Mixin class for applying a transverse aperture restriction to thick lattice elements." - ) .def_property_readonly("aperture_x", &elements::PipeAperture::aperture_x, "horizontal aperture in m" @@ -231,9 +214,6 @@ void init_elements(py::module& m) ; py::class_(mx, "LinearTransport") - .def(py::init<>(), - "Mixin class for linear transport approximation via matrices." - ) // type of map .def_property_readonly_static("Map6x6", [](py::object /* lt */){ return py::type::of(); }, From 87f85e9caf81ef6b471163eeb0b9dc050aaa9146 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 14 Jan 2025 18:17:56 -0800 Subject: [PATCH 24/24] C++: Add `mixin::` Element Namespace Mirror directory structure and separate from "physical" elements as we do in Python. --- src/initialization/InitElement.cpp | 2 +- src/particles/elements/Aperture.H | 10 +- src/particles/elements/Buncher.H | 10 +- src/particles/elements/CFbend.H | 12 +- src/particles/elements/ChrDrift.H | 12 +- src/particles/elements/ChrPlasmaLens.H | 12 +- src/particles/elements/ChrQuad.H | 12 +- src/particles/elements/ChrUniformAcc.H | 12 +- src/particles/elements/ConstF.H | 12 +- src/particles/elements/DipEdge.H | 10 +- src/particles/elements/Drift.H | 16 +-- src/particles/elements/Empty.H | 4 +- src/particles/elements/ExactDrift.H | 12 +- src/particles/elements/ExactSbend.H | 12 +- src/particles/elements/Kicker.H | 10 +- src/particles/elements/LinearMap.H | 10 +- src/particles/elements/Marker.H | 6 +- src/particles/elements/Multipole.H | 10 +- src/particles/elements/NonlinearLens.H | 10 +- src/particles/elements/PRot.H | 8 +- src/particles/elements/PlaneXYRot.H | 10 +- src/particles/elements/Programmable.H | 2 +- src/particles/elements/Quad.H | 12 +- src/particles/elements/RFCavity.H | 10 +- src/particles/elements/Sbend.H | 12 +- src/particles/elements/ShortRF.H | 10 +- src/particles/elements/SoftQuad.H | 10 +- src/particles/elements/SoftSol.H | 10 +- src/particles/elements/Sol.H | 12 +- src/particles/elements/TaperedPL.H | 10 +- src/particles/elements/ThinDipole.H | 10 +- src/particles/elements/diagnostics/openPMD.H | 2 +- src/particles/elements/mixin/alignment.H | 4 +- src/particles/elements/mixin/aperture.H | 10 +- src/particles/elements/mixin/beamoptic.H | 4 +- .../elements/mixin/lineartransport.H | 4 +- src/particles/elements/mixin/named.H | 4 +- src/particles/elements/mixin/nofinalize.H | 4 +- src/particles/elements/mixin/thick.H | 4 +- src/particles/elements/mixin/thin.H | 4 +- src/python/elements.cpp | 118 +++++++++--------- 41 files changed, 234 insertions(+), 234 deletions(-) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index 622ed2998..92a33e5fd 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -502,7 +502,7 @@ namespace detail amrex::ParticleReal ds = 0.0; pp_element.queryAdd("ds", ds); - elements::LinearTransport::Map6x6 transport_map = elements::LinearTransport::Map6x6::Identity(); + elements::mixin::LinearTransport::Map6x6 transport_map = elements::mixin::LinearTransport::Map6x6::Identity(); // safe to ParmParse inputs for reproducibility for (int i=1; i<=6; ++i) { diff --git a/src/particles/elements/Aperture.H b/src/particles/elements/Aperture.H index 324b6d5ab..d9bea0602 100644 --- a/src/particles/elements/Aperture.H +++ b/src/particles/elements/Aperture.H @@ -26,11 +26,11 @@ namespace impactx { struct Aperture - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "Aperture"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Buncher.H b/src/particles/elements/Buncher.H index 0ca7efb1e..3079875ee 100644 --- a/src/particles/elements/Buncher.H +++ b/src/particles/elements/Buncher.H @@ -26,11 +26,11 @@ namespace impactx { struct Buncher - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "Buncher"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/CFbend.H b/src/particles/elements/CFbend.H index 9a2492b62..8b2d7c990 100644 --- a/src/particles/elements/CFbend.H +++ b/src/particles/elements/CFbend.H @@ -28,12 +28,12 @@ namespace impactx { struct CFbend - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "CFbend"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ChrDrift.H b/src/particles/elements/ChrDrift.H index 507019239..4b75742ee 100644 --- a/src/particles/elements/ChrDrift.H +++ b/src/particles/elements/ChrDrift.H @@ -27,12 +27,12 @@ namespace impactx { struct ChrDrift - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ChrDrift"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ChrPlasmaLens.H b/src/particles/elements/ChrPlasmaLens.H index 8c5990c51..6648078b6 100644 --- a/src/particles/elements/ChrPlasmaLens.H +++ b/src/particles/elements/ChrPlasmaLens.H @@ -27,12 +27,12 @@ namespace impactx { struct ChrPlasmaLens - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ChrPlasmaLens"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ChrQuad.H b/src/particles/elements/ChrQuad.H index 82875fcec..46f488963 100644 --- a/src/particles/elements/ChrQuad.H +++ b/src/particles/elements/ChrQuad.H @@ -28,12 +28,12 @@ namespace impactx { struct ChrQuad - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ChrQuad"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ChrUniformAcc.H b/src/particles/elements/ChrUniformAcc.H index 338cbde8c..738a60876 100644 --- a/src/particles/elements/ChrUniformAcc.H +++ b/src/particles/elements/ChrUniformAcc.H @@ -27,12 +27,12 @@ namespace impactx { struct ChrAcc - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ChrAcc"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ConstF.H b/src/particles/elements/ConstF.H index 3202d1c6b..2dc27ce3b 100644 --- a/src/particles/elements/ConstF.H +++ b/src/particles/elements/ConstF.H @@ -27,12 +27,12 @@ namespace impactx { struct ConstF - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ConstF"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/DipEdge.H b/src/particles/elements/DipEdge.H index 12b528e5f..825bd0112 100644 --- a/src/particles/elements/DipEdge.H +++ b/src/particles/elements/DipEdge.H @@ -26,11 +26,11 @@ namespace impactx { struct DipEdge - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "DipEdge"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index 1171cf69f..e1e87040f 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -30,12 +30,12 @@ namespace impactx { struct Drift - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "Drift"; using PType = ImpactXParticleContainer::ParticleType; @@ -178,7 +178,7 @@ namespace impactx * @returns 6x6 transport matrix */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - elements::LinearTransport::Map6x6 + elements::mixin::LinearTransport::Map6x6 transport_map (RefPart & AMREX_RESTRICT refpart) const { using namespace amrex::literals; // for _rt and _prt @@ -191,7 +191,7 @@ namespace impactx amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // assign linear map matrix elements - elements::LinearTransport::Map6x6 R = elements::LinearTransport::Map6x6::Identity(); + elements::mixin::LinearTransport::Map6x6 R = elements::mixin::LinearTransport::Map6x6::Identity(); R(1,2) = slice_ds; R(3,4) = slice_ds; R(5,6) = slice_ds / betgam2; diff --git a/src/particles/elements/Empty.H b/src/particles/elements/Empty.H index 9ce3eece8..30b29d3ac 100644 --- a/src/particles/elements/Empty.H +++ b/src/particles/elements/Empty.H @@ -22,8 +22,8 @@ namespace impactx { struct Empty - : public elements::Thin, - public elements::NoFinalize + : public elements::mixin::Thin, + public elements::mixin::NoFinalize { static constexpr auto type = "None"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ExactDrift.H b/src/particles/elements/ExactDrift.H index 581bb4b6e..db8703330 100644 --- a/src/particles/elements/ExactDrift.H +++ b/src/particles/elements/ExactDrift.H @@ -27,12 +27,12 @@ namespace impactx { struct ExactDrift - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ExactDrift"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ExactSbend.H b/src/particles/elements/ExactSbend.H index a78d46640..040082df7 100644 --- a/src/particles/elements/ExactSbend.H +++ b/src/particles/elements/ExactSbend.H @@ -29,12 +29,12 @@ namespace impactx { struct ExactSbend - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "ExactSbend"; static constexpr amrex::ParticleReal degree2rad = ablastr::constant::math::pi / 180.0; diff --git a/src/particles/elements/Kicker.H b/src/particles/elements/Kicker.H index 7bd3c17c0..cd3556ed1 100644 --- a/src/particles/elements/Kicker.H +++ b/src/particles/elements/Kicker.H @@ -26,11 +26,11 @@ namespace impactx { struct Kicker - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "Kicker"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/LinearMap.H b/src/particles/elements/LinearMap.H index 472ae12be..4d66c9131 100644 --- a/src/particles/elements/LinearMap.H +++ b/src/particles/elements/LinearMap.H @@ -26,11 +26,11 @@ namespace impactx { struct LinearMap - : public elements::Named, - public elements::BeamOptic, - public elements::Alignment, - public elements::LinearTransport, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Alignment, + public elements::mixin::LinearTransport, + public elements::mixin::NoFinalize { static constexpr auto type = "LinearMap"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Marker.H b/src/particles/elements/Marker.H index 3291aff79..5fd90ab88 100644 --- a/src/particles/elements/Marker.H +++ b/src/particles/elements/Marker.H @@ -22,9 +22,9 @@ namespace impactx { struct Marker - : public elements::Named, - public elements::Thin, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::Thin, + public elements::mixin::NoFinalize { static constexpr auto type = "Marker"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Multipole.H b/src/particles/elements/Multipole.H index f2db02d58..121c2665b 100644 --- a/src/particles/elements/Multipole.H +++ b/src/particles/elements/Multipole.H @@ -26,11 +26,11 @@ namespace impactx { struct Multipole - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "Multipole"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/NonlinearLens.H b/src/particles/elements/NonlinearLens.H index 8413d000e..d268e0366 100644 --- a/src/particles/elements/NonlinearLens.H +++ b/src/particles/elements/NonlinearLens.H @@ -26,11 +26,11 @@ namespace impactx { struct NonlinearLens - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "NonlinearLens"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/PRot.H b/src/particles/elements/PRot.H index 242a82534..5683c1e6f 100644 --- a/src/particles/elements/PRot.H +++ b/src/particles/elements/PRot.H @@ -28,10 +28,10 @@ namespace impactx { struct PRot - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::NoFinalize { static constexpr auto type = "PRot"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/PlaneXYRot.H b/src/particles/elements/PlaneXYRot.H index eeb56bfca..250deb4d6 100644 --- a/src/particles/elements/PlaneXYRot.H +++ b/src/particles/elements/PlaneXYRot.H @@ -29,11 +29,11 @@ namespace impactx { struct PlaneXYRot - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "PlaneXYRot"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Programmable.H b/src/particles/elements/Programmable.H index 2227fd64b..582612424 100644 --- a/src/particles/elements/Programmable.H +++ b/src/particles/elements/Programmable.H @@ -23,7 +23,7 @@ namespace impactx { struct Programmable - : public elements::Named + : public elements::mixin::Named { static constexpr auto type = "Programmable"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Quad.H b/src/particles/elements/Quad.H index 791a88c1a..eb828f9a3 100644 --- a/src/particles/elements/Quad.H +++ b/src/particles/elements/Quad.H @@ -27,12 +27,12 @@ namespace impactx { struct Quad - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "Quad"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/RFCavity.H b/src/particles/elements/RFCavity.H index c843f629d..08b978d63 100644 --- a/src/particles/elements/RFCavity.H +++ b/src/particles/elements/RFCavity.H @@ -104,11 +104,11 @@ namespace RFCavityData } // namespace RFCavityData struct RFCavity - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture { static constexpr auto type = "RFCavity"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Sbend.H b/src/particles/elements/Sbend.H index 946394e51..30447dd11 100644 --- a/src/particles/elements/Sbend.H +++ b/src/particles/elements/Sbend.H @@ -28,12 +28,12 @@ namespace impactx { struct Sbend - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "Sbend"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ShortRF.H b/src/particles/elements/ShortRF.H index 64546503a..024e007fb 100644 --- a/src/particles/elements/ShortRF.H +++ b/src/particles/elements/ShortRF.H @@ -26,11 +26,11 @@ namespace impactx { struct ShortRF - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "ShortRF"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/SoftQuad.H b/src/particles/elements/SoftQuad.H index 481236be4..839eebfc3 100644 --- a/src/particles/elements/SoftQuad.H +++ b/src/particles/elements/SoftQuad.H @@ -113,11 +113,11 @@ namespace SoftQuadrupoleData } // namespace SoftQuadrupoleData struct SoftQuadrupole - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture { static constexpr auto type = "SoftQuadrupole"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/SoftSol.H b/src/particles/elements/SoftSol.H index d4e4330b0..be76ea081 100644 --- a/src/particles/elements/SoftSol.H +++ b/src/particles/elements/SoftSol.H @@ -118,11 +118,11 @@ namespace SoftSolenoidData } // namespace SoftSolenoidData struct SoftSolenoid - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture { static constexpr auto type = "SoftSolenoid"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/Sol.H b/src/particles/elements/Sol.H index 193612706..10ea4fd81 100644 --- a/src/particles/elements/Sol.H +++ b/src/particles/elements/Sol.H @@ -28,12 +28,12 @@ namespace impactx { struct Sol - : public elements::Named, - public elements::BeamOptic, - public elements::Thick, - public elements::Alignment, - public elements::PipeAperture, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thick, + public elements::mixin::Alignment, + public elements::mixin::PipeAperture, + public elements::mixin::NoFinalize { static constexpr auto type = "Sol"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/TaperedPL.H b/src/particles/elements/TaperedPL.H index 2f7dabad4..8039e2a97 100644 --- a/src/particles/elements/TaperedPL.H +++ b/src/particles/elements/TaperedPL.H @@ -26,11 +26,11 @@ namespace impactx { struct TaperedPL - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "TaperedPL"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/ThinDipole.H b/src/particles/elements/ThinDipole.H index 097cb85c4..14ed4f062 100644 --- a/src/particles/elements/ThinDipole.H +++ b/src/particles/elements/ThinDipole.H @@ -24,11 +24,11 @@ namespace impactx { struct ThinDipole - : public elements::Named, - public elements::BeamOptic, - public elements::Thin, - public elements::Alignment, - public elements::NoFinalize + : public elements::mixin::Named, + public elements::mixin::BeamOptic, + public elements::mixin::Thin, + public elements::mixin::Alignment, + public elements::mixin::NoFinalize { static constexpr auto type = "ThinDipole"; using PType = ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/diagnostics/openPMD.H b/src/particles/elements/diagnostics/openPMD.H index f5ee0d4a8..6d47ecee6 100644 --- a/src/particles/elements/diagnostics/openPMD.H +++ b/src/particles/elements/diagnostics/openPMD.H @@ -63,7 +63,7 @@ namespace detail * same series name as an existing instance. */ struct BeamMonitor - : public elements::Thin + : public elements::mixin::Thin { static constexpr auto type = "BeamMonitor"; using PType = typename ImpactXParticleContainer::ParticleType; diff --git a/src/particles/elements/mixin/alignment.H b/src/particles/elements/mixin/alignment.H index d108c4e1b..283e85147 100644 --- a/src/particles/elements/mixin/alignment.H +++ b/src/particles/elements/mixin/alignment.H @@ -19,7 +19,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for lattice elements with horizontal/vertical alignment errors */ @@ -147,6 +147,6 @@ namespace impactx::elements amrex::ParticleReal m_rotation = 0; //! rotation error in the transverse plane [rad] }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_ALIGNMENT_H diff --git a/src/particles/elements/mixin/aperture.H b/src/particles/elements/mixin/aperture.H index 9916ff2f1..be336bc08 100644 --- a/src/particles/elements/mixin/aperture.H +++ b/src/particles/elements/mixin/aperture.H @@ -7,8 +7,8 @@ * Authors: Axel Huebl, Chad Mitchell * License: BSD-3-Clause-LBNL */ -#ifndef IMPACTX_ELEMENTS_MIXIN_APERTURE_H -#define IMPACTX_ELEMENTS_MIXIN_APERTURE_H +#ifndef IMPACTX_ELEMENTS_MIXIN_PIPE_APERTURE_H +#define IMPACTX_ELEMENTS_MIXIN_PIPE_APERTURE_H #include #include @@ -17,7 +17,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for applying a transverse aperture restriction to thick lattice elements */ @@ -98,6 +98,6 @@ namespace impactx::elements amrex::ParticleReal m_aperture_y = 0; //! vertical aperture size [m] }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin -#endif // IMPACTX_ELEMENTS_MIXIN_APERTURE_H +#endif // IMPACTX_ELEMENTS_MIXIN_PIPE_APERTURE_H diff --git a/src/particles/elements/mixin/beamoptic.H b/src/particles/elements/mixin/beamoptic.H index 0616b5374..bd1d5f314 100644 --- a/src/particles/elements/mixin/beamoptic.H +++ b/src/particles/elements/mixin/beamoptic.H @@ -19,7 +19,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { namespace detail { @@ -190,6 +190,6 @@ namespace detail } }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_BEAMOPTIC_H diff --git a/src/particles/elements/mixin/lineartransport.H b/src/particles/elements/mixin/lineartransport.H index 9fce44ff6..add40df61 100644 --- a/src/particles/elements/mixin/lineartransport.H +++ b/src/particles/elements/mixin/lineartransport.H @@ -20,7 +20,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for lattice elements that can be expressed as linear transport maps. */ @@ -47,6 +47,6 @@ namespace impactx::elements // Map6x6 m_transport_map; ///< linearized map }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_LINEAR_TRANSPORT_H diff --git a/src/particles/elements/mixin/named.H b/src/particles/elements/mixin/named.H index f06a6d86c..1ebaea4fc 100644 --- a/src/particles/elements/mixin/named.H +++ b/src/particles/elements/mixin/named.H @@ -21,7 +21,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for lattice elements with a user-defined name */ @@ -148,6 +148,6 @@ namespace impactx::elements char * m_name = nullptr; //! a user defined and not necessarily unique name of the element }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_NAMED_H diff --git a/src/particles/elements/mixin/nofinalize.H b/src/particles/elements/mixin/nofinalize.H index 3ab5a9607..7ea6e4da0 100644 --- a/src/particles/elements/mixin/nofinalize.H +++ b/src/particles/elements/mixin/nofinalize.H @@ -11,7 +11,7 @@ #define IMPACTX_ELEMENTS_MIXIN_NOFINALIZE_H -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for lattice elements that need no finalize function. * @@ -29,6 +29,6 @@ namespace impactx::elements } }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_NOFINALIZE_H diff --git a/src/particles/elements/mixin/thick.H b/src/particles/elements/mixin/thick.H index 4572d2a67..85a9917d5 100644 --- a/src/particles/elements/mixin/thick.H +++ b/src/particles/elements/mixin/thick.H @@ -16,7 +16,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for lattice elements with finite length */ @@ -59,6 +59,6 @@ namespace impactx::elements int m_nslice; //! number of slices used for the application of space charge }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_THICK_H diff --git a/src/particles/elements/mixin/thin.H b/src/particles/elements/mixin/thin.H index b9c165e64..87138a95c 100644 --- a/src/particles/elements/mixin/thin.H +++ b/src/particles/elements/mixin/thin.H @@ -16,7 +16,7 @@ #include -namespace impactx::elements +namespace impactx::elements::mixin { /** This is a helper class for lattice elements with zero length */ @@ -54,6 +54,6 @@ namespace impactx::elements } }; -} // namespace impactx::elements +} // namespace impactx::elements::mixin #endif // IMPACTX_ELEMENTS_MIXIN_THIN_H diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 6220e33f2..3e601c580 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -154,87 +154,87 @@ void init_elements(py::module& m) "Mixin classes for accelerator lattice elements in ImpactX" ); - py::class_(mx, "Named") + py::class_(mx, "Named") .def_property("name", - [](elements::Named & nm) { return nm.name(); }, - [](elements::Named & nm, std::string new_name) { nm.set_name(new_name); }, + [](elements::mixin::Named & nm) { return nm.name(); }, + [](elements::mixin::Named & nm, std::string new_name) { nm.set_name(new_name); }, "segment length in m" ) - .def_property_readonly("has_name", &elements::Named::has_name) + .def_property_readonly("has_name", &elements::mixin::Named::has_name) ; - py::class_(mx, "Thick") + py::class_(mx, "Thick") .def_property("ds", - [](elements::Thick & th) { return th.m_ds; }, - [](elements::Thick & th, amrex::ParticleReal ds) { th.m_ds = ds; }, + [](elements::mixin::Thick & th) { return th.m_ds; }, + [](elements::mixin::Thick & th, amrex::ParticleReal ds) { th.m_ds = ds; }, "segment length in m" ) .def_property("nslice", - [](elements::Thick & th) { return th.m_nslice; }, - [](elements::Thick & th, int nslice) { th.m_nslice = nslice; }, + [](elements::mixin::Thick & th) { return th.m_nslice; }, + [](elements::mixin::Thick & th, int nslice) { th.m_nslice = nslice; }, "number of slices used for the application of space charge" ) ; - py::class_(mx, "Thin") + py::class_(mx, "Thin") .def_property_readonly("ds", - &elements::Thin::ds, + &elements::mixin::Thin::ds, "segment length in m" ) .def_property_readonly("nslice", - &elements::Thin::nslice, + &elements::mixin::Thin::nslice, "number of slices used for the application of space charge" ) ; - py::class_(mx, "Alignment") + py::class_(mx, "Alignment") .def_property("dx", - [](elements::Alignment & a) { return a.dx(); }, - [](elements::Alignment & a, amrex::ParticleReal dx) { a.m_dx = dx; }, + [](elements::mixin::Alignment & a) { return a.dx(); }, + [](elements::mixin::Alignment & a, amrex::ParticleReal dx) { a.m_dx = dx; }, "horizontal translation error in m" ) .def_property("dy", - [](elements::Alignment & a) { return a.dy(); }, - [](elements::Alignment & a, amrex::ParticleReal dy) { a.m_dy = dy; }, + [](elements::mixin::Alignment & a) { return a.dy(); }, + [](elements::mixin::Alignment & a, amrex::ParticleReal dy) { a.m_dy = dy; }, "vertical translation error in m" ) .def_property("rotation", - [](elements::Alignment & a) { return a.rotation(); }, - [](elements::Alignment & a, amrex::ParticleReal rotation_degree) + [](elements::mixin::Alignment & a) { return a.rotation(); }, + [](elements::mixin::Alignment & a, amrex::ParticleReal rotation_degree) { - a.m_rotation = rotation_degree * elements::Alignment::degree2rad; + a.m_rotation = rotation_degree * elements::mixin::Alignment::degree2rad; }, "rotation error in the transverse plane in degree" ) ; - py::class_(mx, "PipeAperture") + py::class_(mx, "PipeAperture") .def_property_readonly("aperture_x", - &elements::PipeAperture::aperture_x, + &elements::mixin::PipeAperture::aperture_x, "horizontal aperture in m" ) .def_property_readonly("aperture_y", - &elements::PipeAperture::aperture_y, + &elements::mixin::PipeAperture::aperture_y, "vertical aperture in m" ) ; - py::class_(mx, "LinearTransport") + py::class_(mx, "LinearTransport") // type of map .def_property_readonly_static("Map6x6", - [](py::object /* lt */){ return py::type::of(); }, + [](py::object /* lt */){ return py::type::of(); }, "1-indexed, Fortran-ordered, 6x6 linear transport map type" ) // values of the map //.def_property_readonly("R", - // [](elements::LinearTransport const & lt) { return lt.m_transport_map; }, + // [](elements::mixin::LinearTransport const & lt) { return lt.m_transport_map; }, // "1-indexed, Fortran-ordered, 6x6 linear transport map values" //) ; // diagnostics - py::class_ py_BeamMonitor(me, "BeamMonitor"); + py::class_ py_BeamMonitor(me, "BeamMonitor"); py_BeamMonitor .def(py::init(), py::arg("name"), @@ -295,7 +295,7 @@ void init_elements(py::module& m) // beam optics - py::class_ py_Aperture(me, "Aperture"); + py::class_ py_Aperture(me, "Aperture"); py_Aperture .def("__repr__", [](Aperture const & ap) { @@ -400,7 +400,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Aperture); - py::class_ py_ChrDrift(me, "ChrDrift"); + py::class_ py_ChrDrift(me, "ChrDrift"); py_ChrDrift .def("__repr__", [](ChrDrift const & chr_drift) { @@ -433,7 +433,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrDrift); - py::class_ py_ChrQuad(me, "ChrQuad"); + py::class_ py_ChrQuad(me, "ChrQuad"); py_ChrQuad .def("__repr__", [](ChrQuad const & chr_quad) { @@ -481,7 +481,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrQuad); - py::class_ py_ChrPlasmaLens(me, "ChrPlasmaLens"); + py::class_ py_ChrPlasmaLens(me, "ChrPlasmaLens"); py_ChrPlasmaLens .def("__repr__", [](ChrPlasmaLens const & chr_pl_lens) { @@ -529,7 +529,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrPlasmaLens); - py::class_ py_ChrAcc(me, "ChrAcc"); + py::class_ py_ChrAcc(me, "ChrAcc"); py_ChrAcc .def("__repr__", [](ChrAcc const & chr_acc) { @@ -578,7 +578,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ChrAcc); - py::class_ py_ConstF(me, "ConstF"); + py::class_ py_ConstF(me, "ConstF"); py_ConstF .def("__repr__", [](ConstF const & constf) { @@ -635,7 +635,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ConstF); - py::class_ py_DipEdge(me, "DipEdge"); + py::class_ py_DipEdge(me, "DipEdge"); py_DipEdge .def("__repr__", [](DipEdge const & dip_edge) { @@ -691,7 +691,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_DipEdge); - py::class_ py_Drift(me, "Drift"); + py::class_ py_Drift(me, "Drift"); py_Drift .def("__repr__", [](Drift const & drift) { @@ -724,7 +724,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Drift); - py::class_ py_ExactDrift(me, "ExactDrift"); + py::class_ py_ExactDrift(me, "ExactDrift"); py_ExactDrift .def("__repr__", [](ExactDrift const & exact_drift) { @@ -757,7 +757,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ExactDrift); - py::class_ py_ExactSbend(me, "ExactSbend"); + py::class_ py_ExactSbend(me, "ExactSbend"); py_ExactSbend .def("__repr__", [](ExactSbend const & exact_sbend) { @@ -806,7 +806,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ExactSbend); - py::class_ py_Kicker(me, "Kicker"); + py::class_ py_Kicker(me, "Kicker"); py_Kicker .def("__repr__", [](Kicker const & kicker) { @@ -858,7 +858,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Kicker); - py::class_ py_Multipole(me, "Multipole"); + py::class_ py_Multipole(me, "Multipole"); py_Multipole .def("__repr__", [](Multipole const & multipole) { @@ -907,7 +907,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Multipole); - py::class_ py_Empty(me, "Empty"); + py::class_ py_Empty(me, "Empty"); py_Empty .def("__repr__", [](Empty const & /* empty */) { @@ -920,7 +920,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Empty); - py::class_ py_Marker(me, "Marker"); + py::class_ py_Marker(me, "Marker"); py_Marker .def("__repr__", [](Marker const & marker) { @@ -933,7 +933,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Marker); - py::class_ py_NonlinearLens(me, "NonlinearLens"); + py::class_ py_NonlinearLens(me, "NonlinearLens"); py_NonlinearLens .def("__repr__", [](NonlinearLens const & nl) { @@ -973,7 +973,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_NonlinearLens); - py::class_ py_PlaneXYRot(me, "PlaneXYRot"); + py::class_ py_PlaneXYRot(me, "PlaneXYRot"); py_PlaneXYRot .def("__repr__", [](PlaneXYRot const & plane_xyrot) { @@ -1005,7 +1005,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_PlaneXYRot); - py::class_(me, "Programmable", py::dynamic_attr()) + py::class_(me, "Programmable", py::dynamic_attr()) .def("__repr__", [](Programmable const & prg) { return element_name( @@ -1060,7 +1060,7 @@ void init_elements(py::module& m) ) ; - py::class_ py_Quad(me, "Quad"); + py::class_ py_Quad(me, "Quad"); py_Quad .def("__repr__", [](Quad const & quad) { @@ -1101,7 +1101,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Quad); - py::class_ py_RFCavity(me, "RFCavity"); + py::class_ py_RFCavity(me, "RFCavity"); py_RFCavity .def("__repr__", [](RFCavity const & rfc) { @@ -1171,7 +1171,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_RFCavity); - py::class_ py_Sbend(me, "Sbend"); + py::class_ py_Sbend(me, "Sbend"); py_Sbend .def("__repr__", [](Sbend const & sbend) { @@ -1212,7 +1212,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Sbend); - py::class_ py_CFbend(me, "CFbend"); + py::class_ py_CFbend(me, "CFbend"); py_CFbend .def("__repr__", [](CFbend const & cfbend) { @@ -1261,7 +1261,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_CFbend); - py::class_ py_Buncher(me, "Buncher"); + py::class_ py_Buncher(me, "Buncher"); py_Buncher .def("__repr__", [](Buncher const & buncher) { @@ -1301,7 +1301,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Buncher); - py::class_ py_ShortRF(me, "ShortRF"); + py::class_ py_ShortRF(me, "ShortRF"); py_ShortRF .def("__repr__", [](ShortRF const & short_rf) { @@ -1349,7 +1349,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ShortRF); - py::class_ py_SoftSolenoid(me, "SoftSolenoid"); + py::class_ py_SoftSolenoid(me, "SoftSolenoid"); py_SoftSolenoid .def("__repr__", [](SoftSolenoid const & soft_sol) { @@ -1410,7 +1410,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_SoftSolenoid); - py::class_ py_Sol(me, "Sol"); + py::class_ py_Sol(me, "Sol"); py_Sol .def("__repr__", [](Sol const & sol) { @@ -1451,7 +1451,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Sol); - py::class_ py_PRot(me, "PRot"); + py::class_ py_PRot(me, "PRot"); py_PRot .def("__repr__", [](PRot const & prot) { @@ -1485,7 +1485,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_PRot); - py::class_ py_SoftQuadrupole(me, "SoftQuadrupole"); + py::class_ py_SoftQuadrupole(me, "SoftQuadrupole"); py_SoftQuadrupole .def("__repr__", [](SoftQuadrupole const & soft_quad) { @@ -1539,7 +1539,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_SoftQuadrupole); - py::class_ py_ThinDipole(me, "ThinDipole"); + py::class_ py_ThinDipole(me, "ThinDipole"); py_ThinDipole .def("__repr__", [](ThinDipole const & thin_dp) { @@ -1579,7 +1579,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_ThinDipole); - py::class_ py_TaperedPL(me, "TaperedPL"); + py::class_ py_TaperedPL(me, "TaperedPL"); py_TaperedPL .def("__repr__", [](TaperedPL const & taperedpl) { @@ -1633,7 +1633,7 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_TaperedPL); - py::class_ py_LinearMap(me, "LinearMap"); + py::class_ py_LinearMap(me, "LinearMap"); py_LinearMap .def("__repr__", [](LinearMap const & linearmap) { @@ -1643,7 +1643,7 @@ void init_elements(py::module& m) } ) .def(py::init< - elements::LinearTransport::Map6x6, + elements::mixin::LinearTransport::Map6x6, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, @@ -1660,7 +1660,7 @@ void init_elements(py::module& m) ) .def_property("R", [](LinearMap & linearmap) { return linearmap.m_transport_map; }, - [](LinearMap & linearmap, elements::LinearTransport::Map6x6 R) { linearmap.m_transport_map = R; }, + [](LinearMap & linearmap, elements::mixin::LinearTransport::Map6x6 R) { linearmap.m_transport_map = R; }, "linear map as a 6x6 transport matrix" ) .def_property("ds",